2018-07-14 19:29:24 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2018-05-31 16:07:43 +08:00
|
|
|
/*
|
|
|
|
* RSS and Classifier definitions for Marvell PPv2 Network Controller
|
|
|
|
*
|
|
|
|
* Copyright (C) 2014 Marvell
|
|
|
|
*
|
|
|
|
* Marcin Wojtas <mw@semihalf.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _MVPP2_CLS_H_
|
|
|
|
#define _MVPP2_CLS_H_
|
|
|
|
|
2018-07-12 19:54:11 +08:00
|
|
|
#include "mvpp2.h"
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
#include "mvpp2_prs.h"
|
2018-07-12 19:54:11 +08:00
|
|
|
|
2018-05-31 16:07:43 +08:00
|
|
|
/* Classifier constants */
|
|
|
|
#define MVPP2_CLS_FLOWS_TBL_SIZE 512
|
|
|
|
#define MVPP2_CLS_FLOWS_TBL_DATA_WORDS 3
|
|
|
|
#define MVPP2_CLS_LKP_TBL_SIZE 64
|
|
|
|
#define MVPP2_CLS_RX_QUEUES 256
|
|
|
|
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
/* Classifier flow constants */
|
net: mvpp2: split ingress traffic into multiple flows
The PPv2 classifier allows to perform classification operations on each
ingress packet, based on the flow the packet is assigned to.
The current code uses only 1 flow per port, and the only classification
action consists of assigning the rx queue to the packet, depending on the
port.
In preparation for adding RSS support, we have to split all incoming
traffic into different flows. Since RSS assigns a rx queue depending on
the hash of some header fields, we have to make sure that the hash is
generated in a consistent way for all packets in the same flow.
What we call a "flow" is actually a set of attributes attached to a
packet that depends on various L2/L3/L4 info.
This patch introduces 52 flows, wich are a combination of various L2, L3
and L4 attributes :
- Whether or not the packet has a VLAN tag
- Whether the packet is IPv4, IPv6 or something else
- Whether the packet is TCP, UDP or something else
- Whether or not the packet is fragmented at L3 level.
The flow is associated to a packet by the Header Parser. Each flow
corresponds to an entry in the decoding table. This entry then points to
the sequence of classification lookups to be performed by the
classifier, represented in the flow table.
For now, the only lookup we perform is a C2 lookup to set the default
rx queue.
Header parser Dec table
Ingress pkt +-------------+ flow id +----------------------------+
------------->| TCAM + SRAM |-------->|TCP IPv4 w/ VLAN, not frag |
+-------------+ |TCP IPv4 w/o VLAN, not frag |
|TCP IPv4 w/ VLAN, frag |--+
|etc. | |
+----------------------------+ |
|
Flow table |
+------------+ +---------------------+ |
To RxQ <---| Classifier |<-------| flow 0: C2 lookup |<--------+
+------------+ | flow 1: C2 lookup |
| | ... |
+------------+ | flow 51 : C2 lookup |
| C2 engine | +---------------------+
+------------+
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:25 +08:00
|
|
|
|
|
|
|
#define MVPP2_FLOW_N_FIELDS 4
|
|
|
|
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
enum mvpp2_cls_engine {
|
|
|
|
MVPP22_CLS_ENGINE_C2 = 1,
|
|
|
|
MVPP22_CLS_ENGINE_C3A,
|
|
|
|
MVPP22_CLS_ENGINE_C3B,
|
|
|
|
MVPP22_CLS_ENGINE_C4,
|
|
|
|
MVPP22_CLS_ENGINE_C3HA = 6,
|
|
|
|
MVPP22_CLS_ENGINE_C3HB = 7,
|
|
|
|
};
|
|
|
|
|
net: mvpp2: split ingress traffic into multiple flows
The PPv2 classifier allows to perform classification operations on each
ingress packet, based on the flow the packet is assigned to.
The current code uses only 1 flow per port, and the only classification
action consists of assigning the rx queue to the packet, depending on the
port.
In preparation for adding RSS support, we have to split all incoming
traffic into different flows. Since RSS assigns a rx queue depending on
the hash of some header fields, we have to make sure that the hash is
generated in a consistent way for all packets in the same flow.
What we call a "flow" is actually a set of attributes attached to a
packet that depends on various L2/L3/L4 info.
This patch introduces 52 flows, wich are a combination of various L2, L3
and L4 attributes :
- Whether or not the packet has a VLAN tag
- Whether the packet is IPv4, IPv6 or something else
- Whether the packet is TCP, UDP or something else
- Whether or not the packet is fragmented at L3 level.
The flow is associated to a packet by the Header Parser. Each flow
corresponds to an entry in the decoding table. This entry then points to
the sequence of classification lookups to be performed by the
classifier, represented in the flow table.
For now, the only lookup we perform is a C2 lookup to set the default
rx queue.
Header parser Dec table
Ingress pkt +-------------+ flow id +----------------------------+
------------->| TCAM + SRAM |-------->|TCP IPv4 w/ VLAN, not frag |
+-------------+ |TCP IPv4 w/o VLAN, not frag |
|TCP IPv4 w/ VLAN, frag |--+
|etc. | |
+----------------------------+ |
|
Flow table |
+------------+ +---------------------+ |
To RxQ <---| Classifier |<-------| flow 0: C2 lookup |<--------+
+------------+ | flow 1: C2 lookup |
| | ... |
+------------+ | flow 51 : C2 lookup |
| C2 engine | +---------------------+
+------------+
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:25 +08:00
|
|
|
#define MVPP22_CLS_HEK_OPT_MAC_DA BIT(0)
|
2019-06-18 22:55:19 +08:00
|
|
|
#define MVPP22_CLS_HEK_OPT_VLAN_PRI BIT(1)
|
|
|
|
#define MVPP22_CLS_HEK_OPT_VLAN BIT(2)
|
|
|
|
#define MVPP22_CLS_HEK_OPT_L3_PROTO BIT(3)
|
|
|
|
#define MVPP22_CLS_HEK_OPT_IP4SA BIT(4)
|
|
|
|
#define MVPP22_CLS_HEK_OPT_IP4DA BIT(5)
|
|
|
|
#define MVPP22_CLS_HEK_OPT_IP6SA BIT(6)
|
|
|
|
#define MVPP22_CLS_HEK_OPT_IP6DA BIT(7)
|
|
|
|
#define MVPP22_CLS_HEK_OPT_L4SIP BIT(8)
|
|
|
|
#define MVPP22_CLS_HEK_OPT_L4DIP BIT(9)
|
|
|
|
#define MVPP22_CLS_HEK_N_FIELDS 10
|
net: mvpp2: split ingress traffic into multiple flows
The PPv2 classifier allows to perform classification operations on each
ingress packet, based on the flow the packet is assigned to.
The current code uses only 1 flow per port, and the only classification
action consists of assigning the rx queue to the packet, depending on the
port.
In preparation for adding RSS support, we have to split all incoming
traffic into different flows. Since RSS assigns a rx queue depending on
the hash of some header fields, we have to make sure that the hash is
generated in a consistent way for all packets in the same flow.
What we call a "flow" is actually a set of attributes attached to a
packet that depends on various L2/L3/L4 info.
This patch introduces 52 flows, wich are a combination of various L2, L3
and L4 attributes :
- Whether or not the packet has a VLAN tag
- Whether the packet is IPv4, IPv6 or something else
- Whether the packet is TCP, UDP or something else
- Whether or not the packet is fragmented at L3 level.
The flow is associated to a packet by the Header Parser. Each flow
corresponds to an entry in the decoding table. This entry then points to
the sequence of classification lookups to be performed by the
classifier, represented in the flow table.
For now, the only lookup we perform is a C2 lookup to set the default
rx queue.
Header parser Dec table
Ingress pkt +-------------+ flow id +----------------------------+
------------->| TCAM + SRAM |-------->|TCP IPv4 w/ VLAN, not frag |
+-------------+ |TCP IPv4 w/o VLAN, not frag |
|TCP IPv4 w/ VLAN, frag |--+
|etc. | |
+----------------------------+ |
|
Flow table |
+------------+ +---------------------+ |
To RxQ <---| Classifier |<-------| flow 0: C2 lookup |<--------+
+------------+ | flow 1: C2 lookup |
| | ... |
+------------+ | flow 51 : C2 lookup |
| C2 engine | +---------------------+
+------------+
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:25 +08:00
|
|
|
|
|
|
|
#define MVPP22_CLS_HEK_L4_OPTS (MVPP22_CLS_HEK_OPT_L4SIP | \
|
|
|
|
MVPP22_CLS_HEK_OPT_L4DIP)
|
|
|
|
|
|
|
|
#define MVPP22_CLS_HEK_IP4_2T (MVPP22_CLS_HEK_OPT_IP4SA | \
|
|
|
|
MVPP22_CLS_HEK_OPT_IP4DA)
|
|
|
|
|
|
|
|
#define MVPP22_CLS_HEK_IP6_2T (MVPP22_CLS_HEK_OPT_IP6SA | \
|
|
|
|
MVPP22_CLS_HEK_OPT_IP6DA)
|
|
|
|
|
|
|
|
/* The fifth tuple in "5T" is the L4_Info field */
|
|
|
|
#define MVPP22_CLS_HEK_IP4_5T (MVPP22_CLS_HEK_IP4_2T | \
|
|
|
|
MVPP22_CLS_HEK_L4_OPTS)
|
|
|
|
|
|
|
|
#define MVPP22_CLS_HEK_IP6_5T (MVPP22_CLS_HEK_IP6_2T | \
|
|
|
|
MVPP22_CLS_HEK_L4_OPTS)
|
|
|
|
|
2019-06-18 22:55:19 +08:00
|
|
|
#define MVPP22_CLS_HEK_TAGGED (MVPP22_CLS_HEK_OPT_VLAN | \
|
|
|
|
MVPP22_CLS_HEK_OPT_VLAN_PRI)
|
|
|
|
|
2018-07-12 19:54:26 +08:00
|
|
|
enum mvpp2_cls_field_id {
|
|
|
|
MVPP22_CLS_FIELD_MAC_DA = 0x03,
|
2019-06-18 22:55:19 +08:00
|
|
|
MVPP22_CLS_FIELD_VLAN_PRI = 0x05,
|
2018-07-12 19:54:26 +08:00
|
|
|
MVPP22_CLS_FIELD_VLAN = 0x06,
|
|
|
|
MVPP22_CLS_FIELD_L3_PROTO = 0x0f,
|
|
|
|
MVPP22_CLS_FIELD_IP4SA = 0x10,
|
|
|
|
MVPP22_CLS_FIELD_IP4DA = 0x11,
|
|
|
|
MVPP22_CLS_FIELD_IP6SA = 0x17,
|
|
|
|
MVPP22_CLS_FIELD_IP6DA = 0x1a,
|
|
|
|
MVPP22_CLS_FIELD_L4SIP = 0x1d,
|
|
|
|
MVPP22_CLS_FIELD_L4DIP = 0x1e,
|
|
|
|
};
|
|
|
|
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
/* Classifier C2 engine constants */
|
|
|
|
#define MVPP22_CLS_C2_TCAM_EN(data) ((data) << 16)
|
|
|
|
|
|
|
|
enum mvpp22_cls_c2_action {
|
|
|
|
MVPP22_C2_NO_UPD = 0,
|
|
|
|
MVPP22_C2_NO_UPD_LOCK,
|
|
|
|
MVPP22_C2_UPD,
|
|
|
|
MVPP22_C2_UPD_LOCK,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum mvpp22_cls_c2_fwd_action {
|
|
|
|
MVPP22_C2_FWD_NO_UPD = 0,
|
|
|
|
MVPP22_C2_FWD_NO_UPD_LOCK,
|
|
|
|
MVPP22_C2_FWD_SW,
|
|
|
|
MVPP22_C2_FWD_SW_LOCK,
|
|
|
|
MVPP22_C2_FWD_HW,
|
|
|
|
MVPP22_C2_FWD_HW_LOCK,
|
|
|
|
MVPP22_C2_FWD_HW_LOW_LAT,
|
|
|
|
MVPP22_C2_FWD_HW_LOW_LAT_LOCK,
|
|
|
|
};
|
|
|
|
|
2019-04-30 21:14:29 +08:00
|
|
|
enum mvpp22_cls_c2_color_action {
|
|
|
|
MVPP22_C2_COL_NO_UPD = 0,
|
|
|
|
MVPP22_C2_COL_NO_UPD_LOCK,
|
|
|
|
MVPP22_C2_COL_GREEN,
|
|
|
|
MVPP22_C2_COL_GREEN_LOCK,
|
|
|
|
MVPP22_C2_COL_YELLOW,
|
|
|
|
MVPP22_C2_COL_YELLOW_LOCK,
|
|
|
|
MVPP22_C2_COL_RED, /* Drop */
|
|
|
|
MVPP22_C2_COL_RED_LOCK, /* Drop */
|
|
|
|
};
|
|
|
|
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
#define MVPP2_CLS_C2_TCAM_WORDS 5
|
|
|
|
#define MVPP2_CLS_C2_ATTR_WORDS 5
|
|
|
|
|
|
|
|
struct mvpp2_cls_c2_entry {
|
|
|
|
u32 index;
|
2019-03-27 16:44:20 +08:00
|
|
|
/* TCAM lookup key */
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
u32 tcam[MVPP2_CLS_C2_TCAM_WORDS];
|
2019-03-27 16:44:20 +08:00
|
|
|
/* Actions to perform upon TCAM match */
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
u32 act;
|
2019-03-27 16:44:20 +08:00
|
|
|
/* Attributes relative to the actions to perform */
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
u32 attr[MVPP2_CLS_C2_ATTR_WORDS];
|
2019-03-27 16:44:20 +08:00
|
|
|
/* Entry validity */
|
|
|
|
u8 valid;
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
};
|
|
|
|
|
2019-04-30 21:14:27 +08:00
|
|
|
#define MVPP22_FLOW_ETHER_BIT BIT(0)
|
|
|
|
#define MVPP22_FLOW_IP4_BIT BIT(1)
|
|
|
|
#define MVPP22_FLOW_IP6_BIT BIT(2)
|
|
|
|
#define MVPP22_FLOW_TCP_BIT BIT(3)
|
|
|
|
#define MVPP22_FLOW_UDP_BIT BIT(4)
|
|
|
|
|
|
|
|
#define MVPP22_FLOW_TCP4 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP4_BIT | MVPP22_FLOW_TCP_BIT)
|
|
|
|
#define MVPP22_FLOW_TCP6 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP6_BIT | MVPP22_FLOW_TCP_BIT)
|
|
|
|
#define MVPP22_FLOW_UDP4 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP4_BIT | MVPP22_FLOW_UDP_BIT)
|
|
|
|
#define MVPP22_FLOW_UDP6 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP6_BIT | MVPP22_FLOW_UDP_BIT)
|
|
|
|
#define MVPP22_FLOW_IP4 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP4_BIT)
|
|
|
|
#define MVPP22_FLOW_IP6 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP6_BIT)
|
|
|
|
#define MVPP22_FLOW_ETHERNET (MVPP22_FLOW_ETHER_BIT)
|
|
|
|
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
/* Classifier C2 engine entries */
|
2019-03-27 16:44:22 +08:00
|
|
|
#define MVPP22_CLS_C2_N_ENTRIES 256
|
net: mvpp2: use classifier to assign default rx queue
The PPv2 Controller has a classifier, that can perform multiple lookup
operations for each packet, using different engines.
One of these engines is the C2 engine, which performs TCAM based lookups
on data extracted from the packet header. When a packet matches an
entry, the engine sets various attributes, used to perform
classification operations.
One of these attributes is the rx queue in which the packet should be sent.
The current code uses the lookup_id table (also called decoding table)
to assign the rx queue. However, this only works if we use one entry per
port in the decoding table, which won't be the case once we add RSS
lookups.
This patch uses the C2 engine to assign the rx queue to each packet.
The C2 engine is used through the flow table, which dictates what
classification operations are done for a given flow.
Right now, we have one flow per port, which contains every ingress
packet for this port.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:24 +08:00
|
|
|
|
2019-03-27 16:44:22 +08:00
|
|
|
/* Number of per-port dedicated entries in the C2 TCAM */
|
2019-04-30 21:14:28 +08:00
|
|
|
#define MVPP22_CLS_C2_PORT_N_FLOWS MVPP2_N_RFS_ENTRIES_PER_FLOW
|
2019-03-27 16:44:22 +08:00
|
|
|
|
2019-04-30 21:14:28 +08:00
|
|
|
/* Each port has oen range per flow type + one entry controling the global RSS
|
|
|
|
* setting and the default rx queue
|
|
|
|
*/
|
|
|
|
#define MVPP22_CLS_C2_PORT_RANGE (MVPP22_CLS_C2_PORT_N_FLOWS + 1)
|
|
|
|
#define MVPP22_CLS_C2_PORT_FIRST(p) ((p) * MVPP22_CLS_C2_PORT_RANGE)
|
|
|
|
#define MVPP22_CLS_C2_RSS_ENTRY(p) (MVPP22_CLS_C2_PORT_FIRST((p) + 1) - 1)
|
|
|
|
|
|
|
|
#define MVPP22_CLS_C2_PORT_FLOW_FIRST(p) (MVPP22_CLS_C2_PORT_FIRST(p))
|
|
|
|
|
|
|
|
#define MVPP22_CLS_C2_RFS_LOC(p, loc) (MVPP22_CLS_C2_PORT_FLOW_FIRST(p) + (loc))
|
net: mvpp2: split ingress traffic into multiple flows
The PPv2 classifier allows to perform classification operations on each
ingress packet, based on the flow the packet is assigned to.
The current code uses only 1 flow per port, and the only classification
action consists of assigning the rx queue to the packet, depending on the
port.
In preparation for adding RSS support, we have to split all incoming
traffic into different flows. Since RSS assigns a rx queue depending on
the hash of some header fields, we have to make sure that the hash is
generated in a consistent way for all packets in the same flow.
What we call a "flow" is actually a set of attributes attached to a
packet that depends on various L2/L3/L4 info.
This patch introduces 52 flows, wich are a combination of various L2, L3
and L4 attributes :
- Whether or not the packet has a VLAN tag
- Whether the packet is IPv4, IPv6 or something else
- Whether the packet is TCP, UDP or something else
- Whether or not the packet is fragmented at L3 level.
The flow is associated to a packet by the Header Parser. Each flow
corresponds to an entry in the decoding table. This entry then points to
the sequence of classification lookups to be performed by the
classifier, represented in the flow table.
For now, the only lookup we perform is a C2 lookup to set the default
rx queue.
Header parser Dec table
Ingress pkt +-------------+ flow id +----------------------------+
------------->| TCAM + SRAM |-------->|TCP IPv4 w/ VLAN, not frag |
+-------------+ |TCP IPv4 w/o VLAN, not frag |
|TCP IPv4 w/ VLAN, frag |--+
|etc. | |
+----------------------------+ |
|
Flow table |
+------------+ +---------------------+ |
To RxQ <---| Classifier |<-------| flow 0: C2 lookup |<--------+
+------------+ | flow 1: C2 lookup |
| | ... |
+------------+ | flow 51 : C2 lookup |
| C2 engine | +---------------------+
+------------+
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:25 +08:00
|
|
|
|
|
|
|
/* Packet flow ID */
|
|
|
|
enum mvpp2_prs_flow {
|
|
|
|
MVPP2_FL_START = 8,
|
|
|
|
MVPP2_FL_IP4_TCP_NF_UNTAG = MVPP2_FL_START,
|
|
|
|
MVPP2_FL_IP4_UDP_NF_UNTAG,
|
|
|
|
MVPP2_FL_IP4_TCP_NF_TAG,
|
|
|
|
MVPP2_FL_IP4_UDP_NF_TAG,
|
|
|
|
MVPP2_FL_IP6_TCP_NF_UNTAG,
|
|
|
|
MVPP2_FL_IP6_UDP_NF_UNTAG,
|
|
|
|
MVPP2_FL_IP6_TCP_NF_TAG,
|
|
|
|
MVPP2_FL_IP6_UDP_NF_TAG,
|
|
|
|
MVPP2_FL_IP4_TCP_FRAG_UNTAG,
|
|
|
|
MVPP2_FL_IP4_UDP_FRAG_UNTAG,
|
|
|
|
MVPP2_FL_IP4_TCP_FRAG_TAG,
|
|
|
|
MVPP2_FL_IP4_UDP_FRAG_TAG,
|
|
|
|
MVPP2_FL_IP6_TCP_FRAG_UNTAG,
|
|
|
|
MVPP2_FL_IP6_UDP_FRAG_UNTAG,
|
|
|
|
MVPP2_FL_IP6_TCP_FRAG_TAG,
|
|
|
|
MVPP2_FL_IP6_UDP_FRAG_TAG,
|
|
|
|
MVPP2_FL_IP4_UNTAG, /* non-TCP, non-UDP, same for below */
|
|
|
|
MVPP2_FL_IP4_TAG,
|
|
|
|
MVPP2_FL_IP6_UNTAG,
|
|
|
|
MVPP2_FL_IP6_TAG,
|
|
|
|
MVPP2_FL_NON_IP_UNTAG,
|
|
|
|
MVPP2_FL_NON_IP_TAG,
|
|
|
|
MVPP2_FL_LAST,
|
|
|
|
};
|
|
|
|
|
2019-03-27 16:44:08 +08:00
|
|
|
/* LU Type defined for all engines, and specified in the flow table */
|
|
|
|
#define MVPP2_CLS_LU_TYPE_MASK 0x3f
|
|
|
|
|
2019-06-18 22:55:16 +08:00
|
|
|
enum mvpp2_cls_lu_type {
|
|
|
|
/* rule->loc is used as a lu-type for the entries 0 - 62. */
|
|
|
|
MVPP22_CLS_LU_TYPE_ALL = 63,
|
|
|
|
};
|
|
|
|
|
2019-03-27 16:44:09 +08:00
|
|
|
#define MVPP2_N_FLOWS (MVPP2_FL_LAST - MVPP2_FL_START)
|
|
|
|
|
net: mvpp2: split ingress traffic into multiple flows
The PPv2 classifier allows to perform classification operations on each
ingress packet, based on the flow the packet is assigned to.
The current code uses only 1 flow per port, and the only classification
action consists of assigning the rx queue to the packet, depending on the
port.
In preparation for adding RSS support, we have to split all incoming
traffic into different flows. Since RSS assigns a rx queue depending on
the hash of some header fields, we have to make sure that the hash is
generated in a consistent way for all packets in the same flow.
What we call a "flow" is actually a set of attributes attached to a
packet that depends on various L2/L3/L4 info.
This patch introduces 52 flows, wich are a combination of various L2, L3
and L4 attributes :
- Whether or not the packet has a VLAN tag
- Whether the packet is IPv4, IPv6 or something else
- Whether the packet is TCP, UDP or something else
- Whether or not the packet is fragmented at L3 level.
The flow is associated to a packet by the Header Parser. Each flow
corresponds to an entry in the decoding table. This entry then points to
the sequence of classification lookups to be performed by the
classifier, represented in the flow table.
For now, the only lookup we perform is a C2 lookup to set the default
rx queue.
Header parser Dec table
Ingress pkt +-------------+ flow id +----------------------------+
------------->| TCAM + SRAM |-------->|TCP IPv4 w/ VLAN, not frag |
+-------------+ |TCP IPv4 w/o VLAN, not frag |
|TCP IPv4 w/ VLAN, frag |--+
|etc. | |
+----------------------------+ |
|
Flow table |
+------------+ +---------------------+ |
To RxQ <---| Classifier |<-------| flow 0: C2 lookup |<--------+
+------------+ | flow 1: C2 lookup |
| | ... |
+------------+ | flow 51 : C2 lookup |
| C2 engine | +---------------------+
+------------+
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-07-12 19:54:25 +08:00
|
|
|
struct mvpp2_cls_flow {
|
|
|
|
/* The L2-L4 traffic flow type */
|
|
|
|
int flow_type;
|
|
|
|
|
|
|
|
/* The first id in the flow table for this flow */
|
|
|
|
u16 flow_id;
|
|
|
|
|
|
|
|
/* The supported HEK fields for this flow */
|
|
|
|
u16 supported_hash_opts;
|
|
|
|
|
|
|
|
/* The Header Parser result_info that matches this flow */
|
|
|
|
struct mvpp2_prs_result_info prs_ri;
|
|
|
|
};
|
|
|
|
|
2019-04-30 21:14:28 +08:00
|
|
|
#define MVPP2_CLS_FLT_ENTRIES_PER_FLOW (MVPP2_MAX_PORTS + 1 + 16)
|
2019-03-27 16:44:19 +08:00
|
|
|
#define MVPP2_CLS_FLT_FIRST(id) (((id) - MVPP2_FL_START) * \
|
|
|
|
MVPP2_CLS_FLT_ENTRIES_PER_FLOW)
|
2019-04-30 21:14:28 +08:00
|
|
|
|
|
|
|
#define MVPP2_CLS_FLT_C2_RFS(port, id, rfs_n) (MVPP2_CLS_FLT_FIRST(id) + \
|
|
|
|
((port) * MVPP2_MAX_PORTS) + \
|
|
|
|
(rfs_n))
|
|
|
|
|
|
|
|
#define MVPP2_CLS_FLT_C2_RSS_ENTRY(id) (MVPP2_CLS_FLT_C2_RFS(MVPP2_MAX_PORTS, id, 0))
|
|
|
|
#define MVPP2_CLS_FLT_HASH_ENTRY(port, id) (MVPP2_CLS_FLT_C2_RSS_ENTRY(id) + 1 + (port))
|
2019-03-27 16:44:19 +08:00
|
|
|
#define MVPP2_CLS_FLT_LAST(id) (MVPP2_CLS_FLT_FIRST(id) + \
|
|
|
|
MVPP2_CLS_FLT_ENTRIES_PER_FLOW - 1)
|
2019-03-27 16:44:07 +08:00
|
|
|
|
2019-03-27 16:44:14 +08:00
|
|
|
/* Iterate on each classifier flow id. Sets 'i' to be the index of the first
|
|
|
|
* entry in the cls_flows table for each different flow_id.
|
|
|
|
* This relies on entries having the same flow_id in the cls_flows table being
|
|
|
|
* contiguous.
|
|
|
|
*/
|
|
|
|
#define for_each_cls_flow_id(i) \
|
|
|
|
for ((i) = 0; (i) < MVPP2_N_PRS_FLOWS; (i)++) \
|
|
|
|
if ((i) > 0 && \
|
|
|
|
cls_flows[(i)].flow_id == cls_flows[(i) - 1].flow_id) \
|
|
|
|
continue; \
|
|
|
|
else
|
|
|
|
|
|
|
|
/* Iterate on each classifier flow that has a given flow_type. Sets 'i' to be
|
|
|
|
* the index of the first entry in the cls_flow table for each different flow_id
|
|
|
|
* that has the given flow_type. This allows to operate on all flows that
|
|
|
|
* matches a given ethtool flow type.
|
|
|
|
*/
|
|
|
|
#define for_each_cls_flow_id_with_type(i, type) \
|
|
|
|
for_each_cls_flow_id((i)) \
|
|
|
|
if (cls_flows[(i)].flow_type != (type)) \
|
|
|
|
continue; \
|
|
|
|
else
|
|
|
|
|
2019-04-30 21:14:28 +08:00
|
|
|
#define for_each_cls_flow_id_containing_type(i, type) \
|
|
|
|
for_each_cls_flow_id((i)) \
|
|
|
|
if ((cls_flows[(i)].flow_type & (type)) != (type)) \
|
|
|
|
continue; \
|
|
|
|
else
|
|
|
|
|
2018-05-31 16:07:43 +08:00
|
|
|
struct mvpp2_cls_flow_entry {
|
|
|
|
u32 index;
|
|
|
|
u32 data[MVPP2_CLS_FLOWS_TBL_DATA_WORDS];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mvpp2_cls_lookup_entry {
|
|
|
|
u32 lkpid;
|
|
|
|
u32 way;
|
|
|
|
u32 data;
|
|
|
|
};
|
|
|
|
|
2019-05-24 18:05:52 +08:00
|
|
|
int mvpp22_port_rss_init(struct mvpp2_port *port);
|
2018-07-12 19:54:20 +08:00
|
|
|
|
2019-05-24 18:05:52 +08:00
|
|
|
int mvpp22_port_rss_enable(struct mvpp2_port *port);
|
|
|
|
int mvpp22_port_rss_disable(struct mvpp2_port *port);
|
|
|
|
|
|
|
|
int mvpp22_port_rss_ctx_create(struct mvpp2_port *port, u32 *rss_ctx);
|
|
|
|
int mvpp22_port_rss_ctx_delete(struct mvpp2_port *port, u32 rss_ctx);
|
|
|
|
|
|
|
|
int mvpp22_port_rss_ctx_indir_set(struct mvpp2_port *port, u32 rss_ctx,
|
|
|
|
const u32 *indir);
|
|
|
|
int mvpp22_port_rss_ctx_indir_get(struct mvpp2_port *port, u32 rss_ctx,
|
|
|
|
u32 *indir);
|
2018-07-12 19:54:26 +08:00
|
|
|
|
2018-07-12 19:54:27 +08:00
|
|
|
int mvpp2_ethtool_rxfh_get(struct mvpp2_port *port, struct ethtool_rxnfc *info);
|
|
|
|
int mvpp2_ethtool_rxfh_set(struct mvpp2_port *port, struct ethtool_rxnfc *info);
|
|
|
|
|
2018-05-31 16:07:43 +08:00
|
|
|
void mvpp2_cls_init(struct mvpp2 *priv);
|
|
|
|
|
|
|
|
void mvpp2_cls_port_config(struct mvpp2_port *port);
|
|
|
|
|
|
|
|
void mvpp2_cls_oversize_rxq_set(struct mvpp2_port *port);
|
|
|
|
|
2018-07-14 19:29:27 +08:00
|
|
|
int mvpp2_cls_flow_eng_get(struct mvpp2_cls_flow_entry *fe);
|
|
|
|
|
|
|
|
u16 mvpp2_flow_get_hek_fields(struct mvpp2_cls_flow_entry *fe);
|
|
|
|
|
2019-03-27 16:44:10 +08:00
|
|
|
const struct mvpp2_cls_flow *mvpp2_cls_flow_get(int flow);
|
2018-07-14 19:29:27 +08:00
|
|
|
|
2018-07-14 19:29:28 +08:00
|
|
|
u32 mvpp2_cls_flow_hits(struct mvpp2 *priv, int index);
|
|
|
|
|
2018-07-14 19:29:27 +08:00
|
|
|
void mvpp2_cls_flow_read(struct mvpp2 *priv, int index,
|
|
|
|
struct mvpp2_cls_flow_entry *fe);
|
|
|
|
|
2018-07-14 19:29:28 +08:00
|
|
|
u32 mvpp2_cls_lookup_hits(struct mvpp2 *priv, int index);
|
|
|
|
|
2018-07-14 19:29:27 +08:00
|
|
|
void mvpp2_cls_lookup_read(struct mvpp2 *priv, int lkpid, int way,
|
|
|
|
struct mvpp2_cls_lookup_entry *le);
|
|
|
|
|
2018-07-14 19:29:28 +08:00
|
|
|
u32 mvpp2_cls_c2_hit_count(struct mvpp2 *priv, int c2_index);
|
|
|
|
|
2018-07-14 19:29:27 +08:00
|
|
|
void mvpp2_cls_c2_read(struct mvpp2 *priv, int index,
|
|
|
|
struct mvpp2_cls_c2_entry *c2);
|
|
|
|
|
2019-04-30 21:14:28 +08:00
|
|
|
int mvpp2_ethtool_cls_rule_get(struct mvpp2_port *port,
|
|
|
|
struct ethtool_rxnfc *rxnfc);
|
|
|
|
|
|
|
|
int mvpp2_ethtool_cls_rule_ins(struct mvpp2_port *port,
|
|
|
|
struct ethtool_rxnfc *info);
|
|
|
|
|
|
|
|
int mvpp2_ethtool_cls_rule_del(struct mvpp2_port *port,
|
|
|
|
struct ethtool_rxnfc *info);
|
|
|
|
|
2018-05-31 16:07:43 +08:00
|
|
|
#endif
|