Skip to content

Commit 54d5578

Browse files
sgoutham-marvelldavem330
authored andcommitted
octeontx2-af: Reset all RVU blocks
Go through all BLKADDRs and check which ones are implemented on this silicon and do a HW reset of each implemented block. Also added all RVU AF and PF register offsets. Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 54494aa commit 54d5578

File tree

4 files changed

+260
-0
lines changed

4 files changed

+260
-0
lines changed

drivers/net/ethernet/marvell/octeontx2/af/rvu.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/sysfs.h>
1717

1818
#include "rvu.h"
19+
#include "rvu_reg.h"
1920

2021
#define DRV_NAME "octeontx2-af"
2122
#define DRV_STRING "Marvell OcteonTX2 RVU Admin Function Driver"
@@ -33,6 +34,69 @@ MODULE_LICENSE("GPL v2");
3334
MODULE_VERSION(DRV_VERSION);
3435
MODULE_DEVICE_TABLE(pci, rvu_id_table);
3536

37+
/* Poll a RVU block's register 'offset', for a 'zero'
38+
* or 'nonzero' at bits specified by 'mask'
39+
*/
40+
int rvu_poll_reg(struct rvu *rvu, u64 block, u64 offset, u64 mask, bool zero)
41+
{
42+
void __iomem *reg;
43+
int timeout = 100;
44+
u64 reg_val;
45+
46+
reg = rvu->afreg_base + ((block << 28) | offset);
47+
while (timeout) {
48+
reg_val = readq(reg);
49+
if (zero && !(reg_val & mask))
50+
return 0;
51+
if (!zero && (reg_val & mask))
52+
return 0;
53+
usleep_range(1, 2);
54+
timeout--;
55+
}
56+
return -EBUSY;
57+
}
58+
59+
static void rvu_check_block_implemented(struct rvu *rvu)
60+
{
61+
struct rvu_hwinfo *hw = rvu->hw;
62+
struct rvu_block *block;
63+
int blkid;
64+
u64 cfg;
65+
66+
/* For each block check if 'implemented' bit is set */
67+
for (blkid = 0; blkid < BLK_COUNT; blkid++) {
68+
block = &hw->block[blkid];
69+
cfg = rvupf_read64(rvu, RVU_PF_BLOCK_ADDRX_DISC(blkid));
70+
if (cfg & BIT_ULL(11))
71+
block->implemented = true;
72+
}
73+
}
74+
75+
static void rvu_block_reset(struct rvu *rvu, int blkaddr, u64 rst_reg)
76+
{
77+
struct rvu_block *block = &rvu->hw->block[blkaddr];
78+
79+
if (!block->implemented)
80+
return;
81+
82+
rvu_write64(rvu, blkaddr, rst_reg, BIT_ULL(0));
83+
rvu_poll_reg(rvu, blkaddr, rst_reg, BIT_ULL(63), true);
84+
}
85+
86+
static void rvu_reset_all_blocks(struct rvu *rvu)
87+
{
88+
/* Do a HW reset of all RVU blocks */
89+
rvu_block_reset(rvu, BLKADDR_NPA, NPA_AF_BLK_RST);
90+
rvu_block_reset(rvu, BLKADDR_NIX0, NIX_AF_BLK_RST);
91+
rvu_block_reset(rvu, BLKADDR_NPC, NPC_AF_BLK_RST);
92+
rvu_block_reset(rvu, BLKADDR_SSO, SSO_AF_BLK_RST);
93+
rvu_block_reset(rvu, BLKADDR_TIM, TIM_AF_BLK_RST);
94+
rvu_block_reset(rvu, BLKADDR_CPT0, CPT_AF_BLK_RST);
95+
rvu_block_reset(rvu, BLKADDR_NDC0, NDC_AF_BLK_RST);
96+
rvu_block_reset(rvu, BLKADDR_NDC1, NDC_AF_BLK_RST);
97+
rvu_block_reset(rvu, BLKADDR_NDC2, NDC_AF_BLK_RST);
98+
}
99+
36100
static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
37101
{
38102
struct device *dev = &pdev->dev;
@@ -43,6 +107,12 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
43107
if (!rvu)
44108
return -ENOMEM;
45109

110+
rvu->hw = devm_kzalloc(dev, sizeof(struct rvu_hwinfo), GFP_KERNEL);
111+
if (!rvu->hw) {
112+
devm_kfree(dev, rvu);
113+
return -ENOMEM;
114+
}
115+
46116
pci_set_drvdata(pdev, rvu);
47117
rvu->pdev = pdev;
48118
rvu->dev = &pdev->dev;
@@ -80,6 +150,11 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
80150
goto err_release_regions;
81151
}
82152

153+
/* Check which blocks the HW supports */
154+
rvu_check_block_implemented(rvu);
155+
156+
rvu_reset_all_blocks(rvu);
157+
83158
return 0;
84159

85160
err_release_regions:
@@ -88,6 +163,7 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
88163
pci_disable_device(pdev);
89164
err_freemem:
90165
pci_set_drvdata(pdev, NULL);
166+
devm_kfree(&pdev->dev, rvu->hw);
91167
devm_kfree(dev, rvu);
92168
return err;
93169
}
@@ -100,6 +176,7 @@ static void rvu_remove(struct pci_dev *pdev)
100176
pci_disable_device(pdev);
101177
pci_set_drvdata(pdev, NULL);
102178

179+
devm_kfree(&pdev->dev, rvu->hw);
103180
devm_kfree(&pdev->dev, rvu);
104181
}
105182

drivers/net/ethernet/marvell/octeontx2/af/rvu.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#ifndef RVU_H
1212
#define RVU_H
1313

14+
#include "rvu_struct.h"
15+
1416
/* PCI device IDs */
1517
#define PCI_DEVID_OCTEONTX2_RVU_AF 0xA065
1618

@@ -21,11 +23,46 @@
2123

2224
#define NAME_SIZE 32
2325

26+
struct rvu_block {
27+
bool implemented;
28+
};
29+
30+
struct rvu_hwinfo {
31+
struct rvu_block block[BLK_COUNT]; /* Block info */
32+
};
33+
2434
struct rvu {
2535
void __iomem *afreg_base;
2636
void __iomem *pfreg_base;
2737
struct pci_dev *pdev;
2838
struct device *dev;
39+
struct rvu_hwinfo *hw;
2940
};
3041

42+
static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
43+
{
44+
writeq(val, rvu->afreg_base + ((block << 28) | offset));
45+
}
46+
47+
static inline u64 rvu_read64(struct rvu *rvu, u64 block, u64 offset)
48+
{
49+
return readq(rvu->afreg_base + ((block << 28) | offset));
50+
}
51+
52+
static inline void rvupf_write64(struct rvu *rvu, u64 offset, u64 val)
53+
{
54+
writeq(val, rvu->pfreg_base + offset);
55+
}
56+
57+
static inline u64 rvupf_read64(struct rvu *rvu, u64 offset)
58+
{
59+
return readq(rvu->pfreg_base + offset);
60+
}
61+
62+
/* Function Prototypes
63+
* RVU
64+
*/
65+
66+
int rvu_poll_reg(struct rvu *rvu, u64 block, u64 offset, u64 mask, bool zero);
67+
3168
#endif /* RVU_H */
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/* SPDX-License-Identifier: GPL-2.0
2+
* Marvell OcteonTx2 RVU Admin Function driver
3+
*
4+
* Copyright (C) 2018 Marvell International Ltd.
5+
*
6+
* This program is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License version 2 as
8+
* published by the Free Software Foundation.
9+
*/
10+
11+
#ifndef RVU_REG_H
12+
#define RVU_REG_H
13+
14+
/* Admin function registers */
15+
#define RVU_AF_MSIXTR_BASE (0x10)
16+
#define RVU_AF_ECO (0x20)
17+
#define RVU_AF_BLK_RST (0x30)
18+
#define RVU_AF_PF_BAR4_ADDR (0x40)
19+
#define RVU_AF_RAS (0x100)
20+
#define RVU_AF_RAS_W1S (0x108)
21+
#define RVU_AF_RAS_ENA_W1S (0x110)
22+
#define RVU_AF_RAS_ENA_W1C (0x118)
23+
#define RVU_AF_GEN_INT (0x120)
24+
#define RVU_AF_GEN_INT_W1S (0x128)
25+
#define RVU_AF_GEN_INT_ENA_W1S (0x130)
26+
#define RVU_AF_GEN_INT_ENA_W1C (0x138)
27+
#define RVU_AF_AFPF_MBOX0 (0x02000)
28+
#define RVU_AF_AFPF_MBOX1 (0x02008)
29+
#define RVU_AF_AFPFX_MBOXX(a, b) (0x2000 | (a) << 4 | (b) << 3)
30+
#define RVU_AF_PFME_STATUS (0x2800)
31+
#define RVU_AF_PFTRPEND (0x2810)
32+
#define RVU_AF_PFTRPEND_W1S (0x2820)
33+
#define RVU_AF_PF_RST (0x2840)
34+
#define RVU_AF_HWVF_RST (0x2850)
35+
#define RVU_AF_PFAF_MBOX_INT (0x2880)
36+
#define RVU_AF_PFAF_MBOX_INT_W1S (0x2888)
37+
#define RVU_AF_PFAF_MBOX_INT_ENA_W1S (0x2890)
38+
#define RVU_AF_PFAF_MBOX_INT_ENA_W1C (0x2898)
39+
#define RVU_AF_PFFLR_INT (0x28a0)
40+
#define RVU_AF_PFFLR_INT_W1S (0x28a8)
41+
#define RVU_AF_PFFLR_INT_ENA_W1S (0x28b0)
42+
#define RVU_AF_PFFLR_INT_ENA_W1C (0x28b8)
43+
#define RVU_AF_PFME_INT (0x28c0)
44+
#define RVU_AF_PFME_INT_W1S (0x28c8)
45+
#define RVU_AF_PFME_INT_ENA_W1S (0x28d0)
46+
#define RVU_AF_PFME_INT_ENA_W1C (0x28d8)
47+
48+
/* Admin function's privileged PF/VF registers */
49+
#define RVU_PRIV_CONST (0x8000000)
50+
#define RVU_PRIV_GEN_CFG (0x8000010)
51+
#define RVU_PRIV_CLK_CFG (0x8000020)
52+
#define RVU_PRIV_ACTIVE_PC (0x8000030)
53+
#define RVU_PRIV_PFX_CFG(a) (0x8000100 | (a) << 16)
54+
#define RVU_PRIV_PFX_MSIX_CFG(a) (0x8000110 | (a) << 16)
55+
#define RVU_PRIV_PFX_ID_CFG(a) (0x8000120 | (a) << 16)
56+
#define RVU_PRIV_PFX_INT_CFG(a) (0x8000200 | (a) << 16)
57+
#define RVU_PRIV_PFX_NIX_CFG (0x8000300)
58+
#define RVU_PRIV_PFX_NPA_CFG (0x8000310)
59+
#define RVU_PRIV_PFX_SSO_CFG (0x8000320)
60+
#define RVU_PRIV_PFX_SSOW_CFG (0x8000330)
61+
#define RVU_PRIV_PFX_TIM_CFG (0x8000340)
62+
#define RVU_PRIV_PFX_CPT_CFG (0x8000350)
63+
#define RVU_PRIV_BLOCK_TYPEX_REV(a) (0x8000400 | (a) << 3)
64+
#define RVU_PRIV_HWVFX_INT_CFG(a) (0x8001280 | (a) << 16)
65+
#define RVU_PRIV_HWVFX_NIX_CFG (0x8001300)
66+
#define RVU_PRIV_HWVFX_NPA_CFG (0x8001310)
67+
#define RVU_PRIV_HWVFX_SSO_CFG (0x8001320)
68+
#define RVU_PRIV_HWVFX_SSOW_CFG (0x8001330)
69+
#define RVU_PRIV_HWVFX_TIM_CFG (0x8001340)
70+
#define RVU_PRIV_HWVFX_CPT_CFG (0x8001350)
71+
72+
/* RVU PF registers */
73+
#define RVU_PF_VFX_PFVF_MBOX0 (0x00000)
74+
#define RVU_PF_VFX_PFVF_MBOX1 (0x00008)
75+
#define RVU_PF_VFX_PFVF_MBOXX(a, b) (0x0 | (a) << 12 | (b) << 3)
76+
#define RVU_PF_VF_BAR4_ADDR (0x10)
77+
#define RVU_PF_BLOCK_ADDRX_DISC(a) (0x200 | (a) << 3)
78+
#define RVU_PF_VFME_STATUSX(a) (0x800 | (a) << 3)
79+
#define RVU_PF_VFTRPENDX(a) (0x820 | (a) << 3)
80+
#define RVU_PF_VFTRPEND_W1SX(a) (0x840 | (a) << 3)
81+
#define RVU_PF_VFPF_MBOX_INTX(a) (0x880 | (a) << 3)
82+
#define RVU_PF_VFPF_MBOX_INT_W1SX(a) (0x8A0 | (a) << 3)
83+
#define RVU_PF_VFPF_MBOX_INT_ENA_W1SX(a) (0x8C0 | (a) << 3)
84+
#define RVU_PF_VFPF_MBOX_INT_ENA_W1CX(a) (0x8E0 | (a) << 3)
85+
#define RVU_PF_VFFLR_INTX(a) (0x900 | (a) << 3)
86+
#define RVU_PF_VFFLR_INT_W1SX(a) (0x920 | (a) << 3)
87+
#define RVU_PF_VFFLR_INT_ENA_W1SX(a) (0x940 | (a) << 3)
88+
#define RVU_PF_VFFLR_INT_ENA_W1CX(a) (0x960 | (a) << 3)
89+
#define RVU_PF_VFME_INTX(a) (0x980 | (a) << 3)
90+
#define RVU_PF_VFME_INT_W1SX(a) (0x9A0 | (a) << 3)
91+
#define RVU_PF_VFME_INT_ENA_W1SX(a) (0x9C0 | (a) << 3)
92+
#define RVU_PF_VFME_INT_ENA_W1CX(a) (0x9E0 | (a) << 3)
93+
#define RVU_PF_PFAF_MBOX0 (0xC00)
94+
#define RVU_PF_PFAF_MBOX1 (0xC08)
95+
#define RVU_PF_PFAF_MBOXX(a) (0xC00 | (a) << 3)
96+
#define RVU_PF_INT (0xc20)
97+
#define RVU_PF_INT_W1S (0xc28)
98+
#define RVU_PF_INT_ENA_W1S (0xc30)
99+
#define RVU_PF_INT_ENA_W1C (0xc38)
100+
#define RVU_PF_MSIX_VECX_ADDR(a) (0x000 | (a) << 4)
101+
#define RVU_PF_MSIX_VECX_CTL(a) (0x008 | (a) << 4)
102+
#define RVU_PF_MSIX_PBAX(a) (0xF0000 | (a) << 3)
103+
104+
#define NPA_AF_BLK_RST (0x0000)
105+
#define NIX_AF_BLK_RST (0x00B0)
106+
#define SSO_AF_BLK_RST (0x10f8)
107+
#define TIM_AF_BLK_RST (0x10)
108+
#define CPT_AF_BLK_RST (0x46000)
109+
#define NDC_AF_BLK_RST (0x002F0)
110+
#define NPC_AF_BLK_RST (0x00040)
111+
112+
#endif /* RVU_REG_H */
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* SPDX-License-Identifier: GPL-2.0
2+
* Marvell OcteonTx2 RVU Admin Function driver
3+
*
4+
* Copyright (C) 2018 Marvell International Ltd.
5+
*
6+
* This program is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License version 2 as
8+
* published by the Free Software Foundation.
9+
*/
10+
11+
#ifndef RVU_STRUCT_H
12+
#define RVU_STRUCT_H
13+
14+
/* RVU Block Address Enumeration */
15+
enum rvu_block_addr_e {
16+
BLKADDR_RVUM = 0x0ULL,
17+
BLKADDR_LMT = 0x1ULL,
18+
BLKADDR_MSIX = 0x2ULL,
19+
BLKADDR_NPA = 0x3ULL,
20+
BLKADDR_NIX0 = 0x4ULL,
21+
BLKADDR_NIX1 = 0x5ULL,
22+
BLKADDR_NPC = 0x6ULL,
23+
BLKADDR_SSO = 0x7ULL,
24+
BLKADDR_SSOW = 0x8ULL,
25+
BLKADDR_TIM = 0x9ULL,
26+
BLKADDR_CPT0 = 0xaULL,
27+
BLKADDR_CPT1 = 0xbULL,
28+
BLKADDR_NDC0 = 0xcULL,
29+
BLKADDR_NDC1 = 0xdULL,
30+
BLKADDR_NDC2 = 0xeULL,
31+
BLK_COUNT = 0xfULL,
32+
};
33+
34+
#endif /* RVU_STRUCT_H */

0 commit comments

Comments
 (0)