16
16
#define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE 0x1
17
17
#define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY 0x3
18
18
19
+ static u8 cdns_pcie_get_fn_from_vfn (struct cdns_pcie * pcie , u8 fn , u8 vfn )
20
+ {
21
+ u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET ;
22
+ u32 first_vf_offset , stride ;
23
+
24
+ if (vfn == 0 )
25
+ return fn ;
26
+
27
+ first_vf_offset = cdns_pcie_ep_fn_readw (pcie , fn , cap + PCI_SRIOV_VF_OFFSET );
28
+ stride = cdns_pcie_ep_fn_readw (pcie , fn , cap + PCI_SRIOV_VF_STRIDE );
29
+ fn = fn + first_vf_offset + ((vfn - 1 ) * stride );
30
+
31
+ return fn ;
32
+ }
33
+
19
34
static int cdns_pcie_ep_write_header (struct pci_epc * epc , u8 fn , u8 vfn ,
20
35
struct pci_epf_header * hdr )
21
36
{
22
37
struct cdns_pcie_ep * ep = epc_get_drvdata (epc );
38
+ u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET ;
23
39
struct cdns_pcie * pcie = & ep -> pcie ;
40
+ u32 reg ;
41
+
42
+ if (vfn > 1 ) {
43
+ dev_err (& epc -> dev , "Only Virtual Function #1 has deviceID\n" );
44
+ return - EINVAL ;
45
+ } else if (vfn == 1 ) {
46
+ reg = cap + PCI_SRIOV_VF_DID ;
47
+ cdns_pcie_ep_fn_writew (pcie , fn , reg , hdr -> deviceid );
48
+ return 0 ;
49
+ }
24
50
25
51
cdns_pcie_ep_fn_writew (pcie , fn , PCI_DEVICE_ID , hdr -> deviceid );
26
52
cdns_pcie_ep_fn_writeb (pcie , fn , PCI_REVISION_ID , hdr -> revid );
@@ -92,21 +118,30 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
92
118
93
119
addr0 = lower_32_bits (bar_phys );
94
120
addr1 = upper_32_bits (bar_phys );
121
+
122
+ if (vfn == 1 )
123
+ reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG (bar , fn );
124
+ else
125
+ reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG (bar , fn );
126
+ b = (bar < BAR_4 ) ? bar : bar - BAR_4 ;
127
+
128
+ if (vfn == 0 || vfn == 1 ) {
129
+ cfg = cdns_pcie_readl (pcie , reg );
130
+ cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK (b ) |
131
+ CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK (b ));
132
+ cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE (b , aperture ) |
133
+ CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL (b , ctrl ));
134
+ cdns_pcie_writel (pcie , reg , cfg );
135
+ }
136
+
137
+ fn = cdns_pcie_get_fn_from_vfn (pcie , fn , vfn );
95
138
cdns_pcie_writel (pcie , CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0 (fn , bar ),
96
139
addr0 );
97
140
cdns_pcie_writel (pcie , CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1 (fn , bar ),
98
141
addr1 );
99
142
100
- reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG (bar , fn );
101
- b = (bar < BAR_4 ) ? bar : bar - BAR_4 ;
102
-
103
- cfg = cdns_pcie_readl (pcie , reg );
104
- cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK (b ) |
105
- CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK (b ));
106
- cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE (b , aperture ) |
107
- CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL (b , ctrl ));
108
- cdns_pcie_writel (pcie , reg , cfg );
109
-
143
+ if (vfn > 0 )
144
+ epf = & epf -> epf [vfn - 1 ];
110
145
epf -> epf_bar [bar ] = epf_bar ;
111
146
112
147
return 0 ;
@@ -121,19 +156,27 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
121
156
enum pci_barno bar = epf_bar -> barno ;
122
157
u32 reg , cfg , b , ctrl ;
123
158
124
- reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG (bar , fn );
159
+ if (vfn == 1 )
160
+ reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG (bar , fn );
161
+ else
162
+ reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG (bar , fn );
125
163
b = (bar < BAR_4 ) ? bar : bar - BAR_4 ;
126
164
127
- ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED ;
128
- cfg = cdns_pcie_readl (pcie , reg );
129
- cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK (b ) |
130
- CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK (b ));
131
- cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL (b , ctrl );
132
- cdns_pcie_writel (pcie , reg , cfg );
165
+ if (vfn == 0 || vfn == 1 ) {
166
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED ;
167
+ cfg = cdns_pcie_readl (pcie , reg );
168
+ cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK (b ) |
169
+ CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK (b ));
170
+ cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL (b , ctrl );
171
+ cdns_pcie_writel (pcie , reg , cfg );
172
+ }
133
173
174
+ fn = cdns_pcie_get_fn_from_vfn (pcie , fn , vfn );
134
175
cdns_pcie_writel (pcie , CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0 (fn , bar ), 0 );
135
176
cdns_pcie_writel (pcie , CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1 (fn , bar ), 0 );
136
177
178
+ if (vfn > 0 )
179
+ epf = & epf -> epf [vfn - 1 ];
137
180
epf -> epf_bar [bar ] = NULL ;
138
181
}
139
182
@@ -151,6 +194,7 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
151
194
return - EINVAL ;
152
195
}
153
196
197
+ fn = cdns_pcie_get_fn_from_vfn (pcie , fn , vfn );
154
198
cdns_pcie_set_outbound_region (pcie , 0 , fn , r , false, addr , pci_addr , size );
155
199
156
200
set_bit (r , & ep -> ob_region_map );
@@ -186,6 +230,8 @@ static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
186
230
u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET ;
187
231
u16 flags ;
188
232
233
+ fn = cdns_pcie_get_fn_from_vfn (pcie , fn , vfn );
234
+
189
235
/*
190
236
* Set the Multiple Message Capable bitfield into the Message Control
191
237
* register.
@@ -206,6 +252,8 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
206
252
u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET ;
207
253
u16 flags , mme ;
208
254
255
+ fn = cdns_pcie_get_fn_from_vfn (pcie , fn , vfn );
256
+
209
257
/* Validate that the MSI feature is actually enabled. */
210
258
flags = cdns_pcie_ep_fn_readw (pcie , fn , cap + PCI_MSI_FLAGS );
211
259
if (!(flags & PCI_MSI_FLAGS_ENABLE ))
@@ -227,6 +275,8 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
227
275
u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET ;
228
276
u32 val , reg ;
229
277
278
+ func_no = cdns_pcie_get_fn_from_vfn (pcie , func_no , vfunc_no );
279
+
230
280
reg = cap + PCI_MSIX_FLAGS ;
231
281
val = cdns_pcie_ep_fn_readw (pcie , func_no , reg );
232
282
if (!(val & PCI_MSIX_FLAGS_ENABLE ))
@@ -246,6 +296,8 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
246
296
u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET ;
247
297
u32 val , reg ;
248
298
299
+ fn = cdns_pcie_get_fn_from_vfn (pcie , fn , vfn );
300
+
249
301
reg = cap + PCI_MSIX_FLAGS ;
250
302
val = cdns_pcie_ep_fn_readw (pcie , fn , reg );
251
303
val &= ~PCI_MSIX_FLAGS_QSIZE ;
@@ -265,8 +317,8 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
265
317
return 0 ;
266
318
}
267
319
268
- static void cdns_pcie_ep_assert_intx (struct cdns_pcie_ep * ep , u8 fn ,
269
- u8 intx , bool is_asserted )
320
+ static void cdns_pcie_ep_assert_intx (struct cdns_pcie_ep * ep , u8 fn , u8 intx ,
321
+ bool is_asserted )
270
322
{
271
323
struct cdns_pcie * pcie = & ep -> pcie ;
272
324
unsigned long flags ;
@@ -335,6 +387,8 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
335
387
u8 msi_count ;
336
388
u64 pci_addr , pci_addr_mask = 0xff ;
337
389
390
+ fn = cdns_pcie_get_fn_from_vfn (pcie , fn , vfn );
391
+
338
392
/* Check whether the MSI feature has been enabled by the PCI host. */
339
393
flags = cdns_pcie_ep_fn_readw (pcie , fn , cap + PCI_MSI_FLAGS );
340
394
if (!(flags & PCI_MSI_FLAGS_ENABLE ))
@@ -388,6 +442,8 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
388
442
int ret ;
389
443
int i ;
390
444
445
+ fn = cdns_pcie_get_fn_from_vfn (pcie , fn , vfn );
446
+
391
447
/* Check whether the MSI feature has been enabled by the PCI host. */
392
448
flags = cdns_pcie_ep_fn_readw (pcie , fn , cap + PCI_MSI_FLAGS );
393
449
if (!(flags & PCI_MSI_FLAGS_ENABLE ))
@@ -438,6 +494,12 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
438
494
u16 flags ;
439
495
u8 bir ;
440
496
497
+ epf = & ep -> epf [fn ];
498
+ if (vfn > 0 )
499
+ epf = & epf -> epf [vfn - 1 ];
500
+
501
+ fn = cdns_pcie_get_fn_from_vfn (pcie , fn , vfn );
502
+
441
503
/* Check whether the MSI-X feature has been enabled by the PCI host. */
442
504
flags = cdns_pcie_ep_fn_readw (pcie , fn , cap + PCI_MSIX_FLAGS );
443
505
if (!(flags & PCI_MSIX_FLAGS_ENABLE ))
@@ -448,7 +510,6 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
448
510
bir = tbl_offset & PCI_MSIX_TABLE_BIR ;
449
511
tbl_offset &= PCI_MSIX_TABLE_OFFSET ;
450
512
451
- epf = & ep -> epf [fn ];
452
513
msix_tbl = epf -> epf_bar [bir ]-> addr + tbl_offset ;
453
514
msg_addr = msix_tbl [(interrupt_num - 1 )].msg_addr ;
454
515
msg_data = msix_tbl [(interrupt_num - 1 )].msg_data ;
@@ -475,9 +536,15 @@ static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
475
536
u16 interrupt_num )
476
537
{
477
538
struct cdns_pcie_ep * ep = epc_get_drvdata (epc );
539
+ struct cdns_pcie * pcie = & ep -> pcie ;
540
+ struct device * dev = pcie -> dev ;
478
541
479
542
switch (type ) {
480
543
case PCI_EPC_IRQ_LEGACY :
544
+ if (vfn > 0 ) {
545
+ dev_err (dev , "Cannot raise legacy interrupts for VF\n" );
546
+ return - EINVAL ;
547
+ }
481
548
return cdns_pcie_ep_send_legacy_irq (ep , fn , vfn , 0 );
482
549
483
550
case PCI_EPC_IRQ_MSI :
@@ -515,6 +582,13 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
515
582
return 0 ;
516
583
}
517
584
585
+ static const struct pci_epc_features cdns_pcie_epc_vf_features = {
586
+ .linkup_notifier = false,
587
+ .msi_capable = true,
588
+ .msix_capable = true,
589
+ .align = 65536 ,
590
+ };
591
+
518
592
static const struct pci_epc_features cdns_pcie_epc_features = {
519
593
.linkup_notifier = false,
520
594
.msi_capable = true,
@@ -525,7 +599,10 @@ static const struct pci_epc_features cdns_pcie_epc_features = {
525
599
static const struct pci_epc_features *
526
600
cdns_pcie_ep_get_features (struct pci_epc * epc , u8 func_no , u8 vfunc_no )
527
601
{
528
- return & cdns_pcie_epc_features ;
602
+ if (!vfunc_no )
603
+ return & cdns_pcie_epc_features ;
604
+
605
+ return & cdns_pcie_epc_vf_features ;
529
606
}
530
607
531
608
static const struct pci_epc_ops cdns_pcie_epc_ops = {
@@ -551,9 +628,11 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
551
628
struct platform_device * pdev = to_platform_device (dev );
552
629
struct device_node * np = dev -> of_node ;
553
630
struct cdns_pcie * pcie = & ep -> pcie ;
631
+ struct cdns_pcie_epf * epf ;
554
632
struct resource * res ;
555
633
struct pci_epc * epc ;
556
634
int ret ;
635
+ int i ;
557
636
558
637
pcie -> is_rc = false;
559
638
@@ -598,6 +677,25 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
598
677
if (!ep -> epf )
599
678
return - ENOMEM ;
600
679
680
+ epc -> max_vfs = devm_kcalloc (dev , epc -> max_functions ,
681
+ sizeof (* epc -> max_vfs ), GFP_KERNEL );
682
+ if (!epc -> max_vfs )
683
+ return - ENOMEM ;
684
+
685
+ ret = of_property_read_u8_array (np , "max-virtual-functions" ,
686
+ epc -> max_vfs , epc -> max_functions );
687
+ if (ret == 0 ) {
688
+ for (i = 0 ; i < epc -> max_functions ; i ++ ) {
689
+ epf = & ep -> epf [i ];
690
+ if (epc -> max_vfs [i ] == 0 )
691
+ continue ;
692
+ epf -> epf = devm_kcalloc (dev , epc -> max_vfs [i ],
693
+ sizeof (* ep -> epf ), GFP_KERNEL );
694
+ if (!epf -> epf )
695
+ return - ENOMEM ;
696
+ }
697
+ }
698
+
601
699
ret = pci_epc_mem_init (epc , pcie -> mem_res -> start ,
602
700
resource_size (pcie -> mem_res ), PAGE_SIZE );
603
701
if (ret < 0 ) {
0 commit comments