Skip to content

Commit 1286c50

Browse files
SruChalladavem330
authored andcommitted
octeontx2-af: modify FLR sequence for CPT
On OcteonTX2 platform CPT instruction enqueue is only possible via LMTST operations. The existing FLR sequence mentioned in HRM requires a dummy LMTST to CPT but LMTST can't be submitted from AF driver. So, HW team provided a new sequence to avoid dummy LMTST. This patch adds code for the same. Signed-off-by: Srujana Challa <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f58cf76 commit 1286c50

File tree

3 files changed

+53
-47
lines changed

3 files changed

+53
-47
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ struct rvu {
459459
struct rvu_pfvf *pf;
460460
struct rvu_pfvf *hwvf;
461461
struct mutex rsrc_lock; /* Serialize resource alloc/free */
462+
struct mutex alias_lock; /* Serialize bar2 alias access */
462463
int vfs; /* Number of VFs attached to RVU */
463464
int nix_blkaddr[MAX_NIX_BLKS];
464465

@@ -546,6 +547,17 @@ static inline u64 rvupf_read64(struct rvu *rvu, u64 offset)
546547
return readq(rvu->pfreg_base + offset);
547548
}
548549

550+
static inline void rvu_bar2_sel_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
551+
{
552+
/* HW requires read back of RVU_AF_BAR2_SEL register to make sure completion of
553+
* write operation.
554+
*/
555+
rvu_write64(rvu, block, offset, val);
556+
rvu_read64(rvu, block, offset);
557+
/* Barrier to ensure read completes before accessing LF registers */
558+
mb();
559+
}
560+
549561
/* Silicon revisions */
550562
static inline bool is_rvu_pre_96xx_C0(struct rvu *rvu)
551563
{

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

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -930,68 +930,63 @@ static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr)
930930
dev_warn(rvu->dev, "Poll for RXC zombie count hits hard loop counter\n");
931931
}
932932

933-
#define INPROG_INFLIGHT(reg) ((reg) & 0x1FF)
934-
#define INPROG_GRB_PARTIAL(reg) ((reg) & BIT_ULL(31))
935-
#define INPROG_GRB(reg) (((reg) >> 32) & 0xFF)
936-
#define INPROG_GWB(reg) (((reg) >> 40) & 0xFF)
933+
#define INFLIGHT GENMASK_ULL(8, 0)
934+
#define GRB_CNT GENMASK_ULL(39, 32)
935+
#define GWB_CNT GENMASK_ULL(47, 40)
936+
#define XQ_XOR GENMASK_ULL(63, 63)
937+
#define DQPTR GENMASK_ULL(19, 0)
938+
#define NQPTR GENMASK_ULL(51, 32)
937939

938940
static void cpt_lf_disable_iqueue(struct rvu *rvu, int blkaddr, int slot)
939941
{
940-
int i = 0, hard_lp_ctr = 100000;
941-
u64 inprog, grp_ptr;
942-
u16 nq_ptr, dq_ptr;
942+
int timeout = 1000000;
943+
u64 inprog, inst_ptr;
944+
u64 qsize, pending;
945+
int i = 0;
943946

944947
/* Disable instructions enqueuing */
945948
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_CTL), 0x0);
946949

947-
/* Disable executions in the LF's queue */
948950
inprog = rvu_read64(rvu, blkaddr,
949951
CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG));
950-
inprog &= ~BIT_ULL(16);
952+
inprog |= BIT_ULL(16);
951953
rvu_write64(rvu, blkaddr,
952954
CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG), inprog);
953955

954-
/* Wait for CPT queue to become execution-quiescent */
956+
qsize = rvu_read64(rvu, blkaddr,
957+
CPT_AF_BAR2_ALIASX(slot, CPT_LF_Q_SIZE)) & 0x7FFF;
955958
do {
956-
inprog = rvu_read64(rvu, blkaddr,
957-
CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG));
958-
if (INPROG_GRB_PARTIAL(inprog)) {
959-
i = 0;
960-
hard_lp_ctr--;
961-
} else {
962-
i++;
963-
}
964-
965-
grp_ptr = rvu_read64(rvu, blkaddr,
966-
CPT_AF_BAR2_ALIASX(slot,
967-
CPT_LF_Q_GRP_PTR));
968-
nq_ptr = (grp_ptr >> 32) & 0x7FFF;
969-
dq_ptr = grp_ptr & 0x7FFF;
970-
971-
} while (hard_lp_ctr && (i < 10) && (nq_ptr != dq_ptr));
959+
inst_ptr = rvu_read64(rvu, blkaddr,
960+
CPT_AF_BAR2_ALIASX(slot, CPT_LF_Q_INST_PTR));
961+
pending = (FIELD_GET(XQ_XOR, inst_ptr) * qsize * 40) +
962+
FIELD_GET(NQPTR, inst_ptr) -
963+
FIELD_GET(DQPTR, inst_ptr);
964+
udelay(1);
965+
timeout--;
966+
} while ((pending != 0) && (timeout != 0));
972967

973-
if (hard_lp_ctr == 0)
974-
dev_warn(rvu->dev, "CPT FLR hits hard loop counter\n");
968+
if (timeout == 0)
969+
dev_warn(rvu->dev, "TIMEOUT: CPT poll on pending instructions\n");
975970

976-
i = 0;
977-
hard_lp_ctr = 100000;
971+
timeout = 1000000;
972+
/* Wait for CPT queue to become execution-quiescent */
978973
do {
979974
inprog = rvu_read64(rvu, blkaddr,
980975
CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG));
981976

982-
if ((INPROG_INFLIGHT(inprog) == 0) &&
983-
(INPROG_GWB(inprog) < 40) &&
984-
((INPROG_GRB(inprog) == 0) ||
985-
(INPROG_GRB((inprog)) == 40))) {
977+
if ((FIELD_GET(INFLIGHT, inprog) == 0) &&
978+
(FIELD_GET(GRB_CNT, inprog) == 0)) {
986979
i++;
987980
} else {
988981
i = 0;
989-
hard_lp_ctr--;
982+
timeout--;
990983
}
991-
} while (hard_lp_ctr && (i < 10));
984+
} while ((timeout != 0) && (i < 10));
992985

993-
if (hard_lp_ctr == 0)
994-
dev_warn(rvu->dev, "CPT FLR hits hard loop counter\n");
986+
if (timeout == 0)
987+
dev_warn(rvu->dev, "TIMEOUT: CPT poll on inflight count\n");
988+
/* Wait for 2 us to flush all queue writes to memory */
989+
udelay(2);
995990
}
996991

997992
int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int slot)
@@ -1001,18 +996,15 @@ int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int s
1001996
if (is_cpt_pf(rvu, pcifunc) || is_cpt_vf(rvu, pcifunc))
1002997
cpt_rxc_teardown(rvu, blkaddr);
1003998

999+
mutex_lock(&rvu->alias_lock);
10041000
/* Enable BAR2 ALIAS for this pcifunc. */
10051001
reg = BIT_ULL(16) | pcifunc;
1006-
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg);
1002+
rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg);
10071003

10081004
cpt_lf_disable_iqueue(rvu, blkaddr, slot);
10091005

1010-
/* Set group drop to help clear out hardware */
1011-
reg = rvu_read64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG));
1012-
reg |= BIT_ULL(17);
1013-
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG), reg);
1014-
1015-
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0);
1006+
rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0);
1007+
mutex_unlock(&rvu->alias_lock);
10161008

10171009
return 0;
10181010
}
@@ -1147,7 +1139,7 @@ int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc)
11471139

11481140
/* Enable BAR2 ALIAS for this pcifunc. */
11491141
reg = BIT_ULL(16) | pcifunc;
1150-
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg);
1142+
rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg);
11511143

11521144
for (i = 0; i < max_ctx_entries; i++) {
11531145
cam_data = rvu_read64(rvu, blkaddr, CPT_AF_CTX_CAM_DATA(i));
@@ -1160,7 +1152,7 @@ int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc)
11601152
reg);
11611153
}
11621154
}
1163-
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0);
1155+
rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0);
11641156

11651157
unlock:
11661158
mutex_unlock(&rvu->rsrc_lock);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,8 @@
545545

546546
#define CPT_LF_CTL 0x10
547547
#define CPT_LF_INPROG 0x40
548+
#define CPT_LF_Q_SIZE 0x100
549+
#define CPT_LF_Q_INST_PTR 0x110
548550
#define CPT_LF_Q_GRP_PTR 0x120
549551
#define CPT_LF_CTX_FLUSH 0x510
550552

0 commit comments

Comments
 (0)