diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h index 04d140218f4560de088d5055e035ef5915e2e2e8..67cce2736806d1054d75ab87ac211f93d210e273 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h @@ -126,6 +126,8 @@ #define MVPP22_CLS_C2_TCAM_DATA4 0x1b20 #define MVPP22_CLS_C2_LU_TYPE(lu) ((lu) & 0x3f) #define MVPP22_CLS_C2_PORT_ID(port) ((port) << 8) +#define MVPP22_CLS_C2_TCAM_INV 0x1b24 +#define MVPP22_CLS_C2_TCAM_INV_BIT BIT(31) #define MVPP22_CLS_C2_HIT_CTR 0x1b50 #define MVPP22_CLS_C2_ACT 0x1b60 #define MVPP22_CLS_C2_ACT_RSS_EN(act) (((act) & 0x3) << 19) diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c index 482de582f994d2dfd7f7292e0f5d811ab8916d20..7a889a925714dc62a915373de783563056cd0026 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c @@ -489,8 +489,16 @@ static void mvpp2_cls_flow_lkp_init(struct mvpp2 *priv, static void mvpp2_cls_c2_write(struct mvpp2 *priv, struct mvpp2_cls_c2_entry *c2) { + u32 val; mvpp2_write(priv, MVPP22_CLS_C2_TCAM_IDX, c2->index); + val = mvpp2_read(priv, MVPP22_CLS_C2_TCAM_INV); + if (c2->valid) + val &= ~MVPP22_CLS_C2_TCAM_INV_BIT; + else + val |= MVPP22_CLS_C2_TCAM_INV_BIT; + mvpp2_write(priv, MVPP22_CLS_C2_TCAM_INV, val); + mvpp2_write(priv, MVPP22_CLS_C2_ACT, c2->act); mvpp2_write(priv, MVPP22_CLS_C2_ATTR0, c2->attr[0]); @@ -509,6 +517,7 @@ static void mvpp2_cls_c2_write(struct mvpp2 *priv, void mvpp2_cls_c2_read(struct mvpp2 *priv, int index, struct mvpp2_cls_c2_entry *c2) { + u32 val; mvpp2_write(priv, MVPP22_CLS_C2_TCAM_IDX, index); c2->index = index; @@ -525,6 +534,9 @@ void mvpp2_cls_c2_read(struct mvpp2 *priv, int index, c2->attr[1] = mvpp2_read(priv, MVPP22_CLS_C2_ATTR1); c2->attr[2] = mvpp2_read(priv, MVPP22_CLS_C2_ATTR2); c2->attr[3] = mvpp2_read(priv, MVPP22_CLS_C2_ATTR3); + + val = mvpp2_read(priv, MVPP22_CLS_C2_TCAM_INV); + c2->valid = !(val & MVPP22_CLS_C2_TCAM_INV_BIT); } /* Initialize the flow table entries for the given flow */ @@ -807,6 +819,8 @@ static void mvpp2_port_c2_cls_init(struct mvpp2_port *port) c2.attr[0] = MVPP22_CLS_C2_ATTR0_QHIGH(qh) | MVPP22_CLS_C2_ATTR0_QLOW(ql); + c2.valid = true; + mvpp2_cls_c2_write(port->priv, &c2); } @@ -815,6 +829,7 @@ void mvpp2_cls_init(struct mvpp2 *priv) { struct mvpp2_cls_lookup_entry le; struct mvpp2_cls_flow_entry fe; + struct mvpp2_cls_c2_entry c2; int index; /* Enable classifier */ @@ -838,6 +853,14 @@ void mvpp2_cls_init(struct mvpp2 *priv) mvpp2_cls_lookup_write(priv, &le); } + /* Clear C2 TCAM engine table */ + memset(&c2, 0, sizeof(c2)); + c2.valid = false; + for (index = 0; index < MVPP22_CLS_C2_N_ENTRIES; index++) { + c2.index = index; + mvpp2_cls_c2_write(priv, &c2); + } + mvpp2_cls_port_init_flows(priv); } diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.h index 36299b57599ccfec510aa883609e6adf72d7ecc4..bb3ea84c2888c4fafb8f6acce54156a5282dfbd2 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.h +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.h @@ -97,9 +97,14 @@ enum mvpp22_cls_c2_fwd_action { struct mvpp2_cls_c2_entry { u32 index; + /* TCAM lookup key */ u32 tcam[MVPP2_CLS_C2_TCAM_WORDS]; + /* Actions to perform upon TCAM match */ u32 act; + /* Attributes relative to the actions to perform */ u32 attr[MVPP2_CLS_C2_ATTR_WORDS]; + /* Entry validity */ + u8 valid; }; /* Classifier C2 engine entries */