Skip to content

Commit 762ca6e

Browse files
Hariprasad KelamPaolo Abeni
authored andcommitted
octeontx2-af: Quiesce traffic before NIX block reset
During initialization, the AF driver resets all blocks. The RPM (MAC) block and NIX block operate on a credit-based model. When the NIX block resets during active traffic flow, it doesn't release credits to the RPM block. This causes the RPM FIFO to overflow, leading to receive traffic struck. To address this issue, the patch introduces the following changes: 1. Stop receiving traffic at the MAC level during AF driver initialization. 2. Perform an X2P reset (prevents RXFIFO of all LMACS from pushing data) 3. Reset the NIX block. 4. Clear the X2P reset and re-enable receiving traffic. Fixes: 54d5578 ("octeontx2-af: Reset all RVU blocks") Signed-off-by: Hariprasad Kelam <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 6fc2164 commit 762ca6e

File tree

8 files changed

+145
-6
lines changed

8 files changed

+145
-6
lines changed

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

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,24 @@ u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id)
214214
return (cfg & CMR_P2X_SEL_MASK) >> CMR_P2X_SEL_SHIFT;
215215
}
216216

217+
static u8 cgx_get_nix_resetbit(struct cgx *cgx)
218+
{
219+
int first_lmac;
220+
u8 p2x;
221+
222+
/* non 98XX silicons supports only NIX0 block */
223+
if (cgx->pdev->subsystem_device != PCI_SUBSYS_DEVID_98XX)
224+
return CGX_NIX0_RESET;
225+
226+
first_lmac = find_first_bit(&cgx->lmac_bmap, cgx->max_lmac_per_mac);
227+
p2x = cgx_lmac_get_p2x(cgx->cgx_id, first_lmac);
228+
229+
if (p2x == CMR_P2X_SEL_NIX1)
230+
return CGX_NIX1_RESET;
231+
else
232+
return CGX_NIX0_RESET;
233+
}
234+
217235
/* Ensure the required lock for event queue(where asynchronous events are
218236
* posted) is acquired before calling this API. Else an asynchronous event(with
219237
* latest link status) can reach the destination before this function returns
@@ -1724,6 +1742,8 @@ static int cgx_lmac_init(struct cgx *cgx)
17241742
lmac->lmac_type = cgx->mac_ops->get_lmac_type(cgx, lmac->lmac_id);
17251743
}
17261744

1745+
/* Start X2P reset on given MAC block */
1746+
cgx->mac_ops->mac_x2p_reset(cgx, true);
17271747
return cgx_lmac_verify_fwi_version(cgx);
17281748

17291749
err_bitmap_free:
@@ -1789,6 +1809,45 @@ static u8 cgx_get_rxid_mapoffset(struct cgx *cgx)
17891809
return 0x60;
17901810
}
17911811

1812+
static void cgx_x2p_reset(void *cgxd, bool enable)
1813+
{
1814+
struct cgx *cgx = cgxd;
1815+
int lmac_id;
1816+
u64 cfg;
1817+
1818+
if (enable) {
1819+
for_each_set_bit(lmac_id, &cgx->lmac_bmap, cgx->max_lmac_per_mac)
1820+
cgx->mac_ops->mac_enadis_rx(cgx, lmac_id, false);
1821+
1822+
usleep_range(1000, 2000);
1823+
1824+
cfg = cgx_read(cgx, 0, CGXX_CMR_GLOBAL_CONFIG);
1825+
cfg |= cgx_get_nix_resetbit(cgx) | CGX_NSCI_DROP;
1826+
cgx_write(cgx, 0, CGXX_CMR_GLOBAL_CONFIG, cfg);
1827+
} else {
1828+
cfg = cgx_read(cgx, 0, CGXX_CMR_GLOBAL_CONFIG);
1829+
cfg &= ~(cgx_get_nix_resetbit(cgx) | CGX_NSCI_DROP);
1830+
cgx_write(cgx, 0, CGXX_CMR_GLOBAL_CONFIG, cfg);
1831+
}
1832+
}
1833+
1834+
static int cgx_enadis_rx(void *cgxd, int lmac_id, bool enable)
1835+
{
1836+
struct cgx *cgx = cgxd;
1837+
u64 cfg;
1838+
1839+
if (!is_lmac_valid(cgx, lmac_id))
1840+
return -ENODEV;
1841+
1842+
cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_CFG);
1843+
if (enable)
1844+
cfg |= DATA_PKT_RX_EN;
1845+
else
1846+
cfg &= ~DATA_PKT_RX_EN;
1847+
cgx_write(cgx, lmac_id, CGXX_CMRX_CFG, cfg);
1848+
return 0;
1849+
}
1850+
17921851
static struct mac_ops cgx_mac_ops = {
17931852
.name = "cgx",
17941853
.csr_offset = 0,
@@ -1820,6 +1879,8 @@ static struct mac_ops cgx_mac_ops = {
18201879
.mac_get_pfc_frm_cfg = cgx_lmac_get_pfc_frm_cfg,
18211880
.mac_reset = cgx_lmac_reset,
18221881
.mac_stats_reset = cgx_stats_reset,
1882+
.mac_x2p_reset = cgx_x2p_reset,
1883+
.mac_enadis_rx = cgx_enadis_rx,
18231884
};
18241885

18251886
static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
#define CGX_LMAC_TYPE_MASK 0xF
3333
#define CGXX_CMRX_INT 0x040
3434
#define FW_CGX_INT BIT_ULL(1)
35+
#define CGXX_CMR_GLOBAL_CONFIG 0x08
36+
#define CGX_NIX0_RESET BIT_ULL(2)
37+
#define CGX_NIX1_RESET BIT_ULL(3)
38+
#define CGX_NSCI_DROP BIT_ULL(9)
3539
#define CGXX_CMRX_INT_ENA_W1S 0x058
3640
#define CGXX_CMRX_RX_ID_MAP 0x060
3741
#define CGXX_CMRX_RX_STAT0 0x070

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ struct mac_ops {
132132
int (*get_fec_stats)(void *cgxd, int lmac_id,
133133
struct cgx_fec_stats_rsp *rsp);
134134
int (*mac_stats_reset)(void *cgxd, int lmac_id);
135+
void (*mac_x2p_reset)(void *cgxd, bool enable);
136+
int (*mac_enadis_rx)(void *cgxd, int lmac_id, bool enable);
135137
};
136138

137139
struct cgx {

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ static struct mac_ops rpm_mac_ops = {
3939
.mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg,
4040
.mac_reset = rpm_lmac_reset,
4141
.mac_stats_reset = rpm_stats_reset,
42+
.mac_x2p_reset = rpm_x2p_reset,
43+
.mac_enadis_rx = rpm_enadis_rx,
4244
};
4345

4446
static struct mac_ops rpm2_mac_ops = {
@@ -72,6 +74,8 @@ static struct mac_ops rpm2_mac_ops = {
7274
.mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg,
7375
.mac_reset = rpm_lmac_reset,
7476
.mac_stats_reset = rpm_stats_reset,
77+
.mac_x2p_reset = rpm_x2p_reset,
78+
.mac_enadis_rx = rpm_enadis_rx,
7579
};
7680

7781
bool is_dev_rpm2(void *rpmd)
@@ -768,3 +772,41 @@ int rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr)
768772

769773
return 0;
770774
}
775+
776+
void rpm_x2p_reset(void *rpmd, bool enable)
777+
{
778+
rpm_t *rpm = rpmd;
779+
int lmac_id;
780+
u64 cfg;
781+
782+
if (enable) {
783+
for_each_set_bit(lmac_id, &rpm->lmac_bmap, rpm->max_lmac_per_mac)
784+
rpm->mac_ops->mac_enadis_rx(rpm, lmac_id, false);
785+
786+
usleep_range(1000, 2000);
787+
788+
cfg = rpm_read(rpm, 0, RPMX_CMR_GLOBAL_CFG);
789+
rpm_write(rpm, 0, RPMX_CMR_GLOBAL_CFG, cfg | RPM_NIX0_RESET);
790+
} else {
791+
cfg = rpm_read(rpm, 0, RPMX_CMR_GLOBAL_CFG);
792+
cfg &= ~RPM_NIX0_RESET;
793+
rpm_write(rpm, 0, RPMX_CMR_GLOBAL_CFG, cfg);
794+
}
795+
}
796+
797+
int rpm_enadis_rx(void *rpmd, int lmac_id, bool enable)
798+
{
799+
rpm_t *rpm = rpmd;
800+
u64 cfg;
801+
802+
if (!is_lmac_valid(rpm, lmac_id))
803+
return -ENODEV;
804+
805+
cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG);
806+
if (enable)
807+
cfg |= RPM_RX_EN;
808+
else
809+
cfg &= ~RPM_RX_EN;
810+
rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg);
811+
return 0;
812+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
/* Registers */
1919
#define RPMX_CMRX_CFG 0x00
20+
#define RPMX_CMR_GLOBAL_CFG 0x08
21+
#define RPM_NIX0_RESET BIT_ULL(3)
2022
#define RPMX_RX_TS_PREPEND BIT_ULL(22)
2123
#define RPMX_TX_PTP_1S_SUPPORT BIT_ULL(17)
2224
#define RPMX_CMRX_RX_ID_MAP 0x80
@@ -139,4 +141,6 @@ bool is_dev_rpm2(void *rpmd);
139141
int rpm_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp);
140142
int rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr);
141143
int rpm_stats_reset(void *rpmd, int lmac_id);
144+
void rpm_x2p_reset(void *rpmd, bool enable);
145+
int rpm_enadis_rx(void *rpmd, int lmac_id, bool enable);
142146
#endif /* RPM_H */

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,7 @@ static int rvu_setup_hw_resources(struct rvu *rvu)
11621162
}
11631163

11641164
rvu_program_channels(rvu);
1165+
cgx_start_linkup(rvu);
11651166

11661167
err = rvu_mcs_init(rvu);
11671168
if (err) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,7 @@ int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_
10251025
int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause);
10261026
void rvu_mac_reset(struct rvu *rvu, u16 pcifunc);
10271027
u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac);
1028+
void cgx_start_linkup(struct rvu *rvu);
10281029
int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
10291030
int type);
10301031
bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,

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

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ static void rvu_cgx_wq_destroy(struct rvu *rvu)
349349

350350
int rvu_cgx_init(struct rvu *rvu)
351351
{
352+
struct mac_ops *mac_ops;
352353
int cgx, err;
353354
void *cgxd;
354355

@@ -375,17 +376,42 @@ int rvu_cgx_init(struct rvu *rvu)
375376
if (err)
376377
return err;
377378

379+
/* Clear X2P reset on all MAC blocks */
380+
for (cgx = 0; cgx < rvu->cgx_cnt_max; cgx++) {
381+
cgxd = rvu_cgx_pdata(cgx, rvu);
382+
if (!cgxd)
383+
continue;
384+
mac_ops = get_mac_ops(cgxd);
385+
mac_ops->mac_x2p_reset(cgxd, false);
386+
}
387+
378388
/* Register for CGX events */
379389
err = cgx_lmac_event_handler_init(rvu);
380390
if (err)
381391
return err;
382392

383393
mutex_init(&rvu->cgx_cfg_lock);
384394

385-
/* Ensure event handler registration is completed, before
386-
* we turn on the links
387-
*/
388-
mb();
395+
return 0;
396+
}
397+
398+
void cgx_start_linkup(struct rvu *rvu)
399+
{
400+
unsigned long lmac_bmap;
401+
struct mac_ops *mac_ops;
402+
int cgx, lmac, err;
403+
void *cgxd;
404+
405+
/* Enable receive on all LMACS */
406+
for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
407+
cgxd = rvu_cgx_pdata(cgx, rvu);
408+
if (!cgxd)
409+
continue;
410+
mac_ops = get_mac_ops(cgxd);
411+
lmac_bmap = cgx_get_lmac_bmap(cgxd);
412+
for_each_set_bit(lmac, &lmac_bmap, rvu->hw->lmac_per_cgx)
413+
mac_ops->mac_enadis_rx(cgxd, lmac, true);
414+
}
389415

390416
/* Do link up for all CGX ports */
391417
for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
@@ -398,8 +424,6 @@ int rvu_cgx_init(struct rvu *rvu)
398424
"Link up process failed to start on cgx %d\n",
399425
cgx);
400426
}
401-
402-
return 0;
403427
}
404428

405429
int rvu_cgx_exit(struct rvu *rvu)

0 commit comments

Comments
 (0)