aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
authorSander Vanheule <sander@svanheule.net>2022-09-09 21:25:17 +0200
committerSander Vanheule <sander@svanheule.net>2022-10-23 22:33:08 +0200
commit9f6cbc78cd5da260d3fba83aae95f32e05e5f6a7 (patch)
tree6dca4db9d8fad8e30774febf58922de13111ad36 /target
parent039e5be4af2497bd40414eedb6f83a1c75d06cca (diff)
downloadupstream-9f6cbc78cd5da260d3fba83aae95f32e05e5f6a7.tar.gz
upstream-9f6cbc78cd5da260d3fba83aae95f32e05e5f6a7.tar.bz2
upstream-9f6cbc78cd5da260d3fba83aae95f32e05e5f6a7.zip
realtek: consistently flood RMA frames
The switches support different actions for incoming ethernet multicast frames with Reserved Multicast Addresses (01-80-C2-00-00-{01-2F}). The current code will set the 2-bit action field to FLOOD (0x3) for most classes, but the highest bit is always unset for the relevant control registers. This means the DROP (0x1) action being used for these classes; whatever class the MSB happens to be in. For RTL838x, this results in {20,23-2F} frames being dropped, instead of flooding all ports. On other switch generations, {0F,1F,2F} frames are dropped. This is inconsistent, and appears to be a mistake. Remove this inconsistency by flooding all multicast frames with RMA addresses. Signed-off-by: Sander Vanheule <sander@svanheule.net>
Diffstat (limited to 'target')
-rw-r--r--target/linux/realtek/files-5.10/drivers/net/ethernet/rtl838x_eth.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/target/linux/realtek/files-5.10/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-5.10/drivers/net/ethernet/rtl838x_eth.c
index 7a6057b445..f5424bbfa3 100644
--- a/target/linux/realtek/files-5.10/drivers/net/ethernet/rtl838x_eth.c
+++ b/target/linux/realtek/files-5.10/drivers/net/ethernet/rtl838x_eth.c
@@ -1032,20 +1032,30 @@ static int rtl838x_eth_stop(struct net_device *ndev)
static void rtl838x_eth_set_multicast_list(struct net_device *ndev)
{
+ /*
+ * Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
+ * CTRL_0_FULL = GENMASK(21, 0) = 0x3FFFFF
+ */
if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
sw_w32(0x0, RTL838X_RMA_CTRL_0);
sw_w32(0x0, RTL838X_RMA_CTRL_1);
}
if (ndev->flags & IFF_ALLMULTI)
- sw_w32(0x1fffff, RTL838X_RMA_CTRL_0);
+ sw_w32(GENMASK(21, 0), RTL838X_RMA_CTRL_0);
if (ndev->flags & IFF_PROMISC) {
- sw_w32(0x1fffff, RTL838X_RMA_CTRL_0);
+ sw_w32(GENMASK(21, 0), RTL838X_RMA_CTRL_0);
sw_w32(0x7fff, RTL838X_RMA_CTRL_1);
}
}
static void rtl839x_eth_set_multicast_list(struct net_device *ndev)
{
+ /*
+ * Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
+ * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
+ * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00
+ * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
+ */
if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
sw_w32(0x0, RTL839X_RMA_CTRL_0);
sw_w32(0x0, RTL839X_RMA_CTRL_1);
@@ -1053,54 +1063,54 @@ static void rtl839x_eth_set_multicast_list(struct net_device *ndev)
sw_w32(0x0, RTL839X_RMA_CTRL_3);
}
if (ndev->flags & IFF_ALLMULTI) {
- sw_w32(0x7fffffff, RTL839X_RMA_CTRL_0);
- sw_w32(0x7fffffff, RTL839X_RMA_CTRL_1);
- sw_w32(0x7fffffff, RTL839X_RMA_CTRL_2);
+ sw_w32(GENMASK(31, 2), RTL839X_RMA_CTRL_0);
+ sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_1);
+ sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_2);
}
if (ndev->flags & IFF_PROMISC) {
- sw_w32(0x7fffffff, RTL839X_RMA_CTRL_0);
- sw_w32(0x7fffffff, RTL839X_RMA_CTRL_1);
- sw_w32(0x7fffffff, RTL839X_RMA_CTRL_2);
+ sw_w32(GENMASK(31, 2), RTL839X_RMA_CTRL_0);
+ sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_1);
+ sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_2);
sw_w32(0x3ff, RTL839X_RMA_CTRL_3);
}
}
static void rtl930x_eth_set_multicast_list(struct net_device *ndev)
{
- if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
+ /*
+ * Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
+ * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
+ * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00
+ * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
+ */
+ if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
+ sw_w32(GENMASK(31, 2), RTL930X_RMA_CTRL_0);
+ sw_w32(GENMASK(31, 0), RTL930X_RMA_CTRL_1);
+ sw_w32(GENMASK(31, 0), RTL930X_RMA_CTRL_2);
+ } else {
sw_w32(0x0, RTL930X_RMA_CTRL_0);
sw_w32(0x0, RTL930X_RMA_CTRL_1);
sw_w32(0x0, RTL930X_RMA_CTRL_2);
}
- if (ndev->flags & IFF_ALLMULTI) {
- sw_w32(0x7fffffff, RTL930X_RMA_CTRL_0);
- sw_w32(0x7fffffff, RTL930X_RMA_CTRL_1);
- sw_w32(0x7fffffff, RTL930X_RMA_CTRL_2);
- }
- if (ndev->flags & IFF_PROMISC) {
- sw_w32(0x7fffffff, RTL930X_RMA_CTRL_0);
- sw_w32(0x7fffffff, RTL930X_RMA_CTRL_1);
- sw_w32(0x7fffffff, RTL930X_RMA_CTRL_2);
- }
}
static void rtl931x_eth_set_multicast_list(struct net_device *ndev)
{
- if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
+ /*
+ * Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
+ * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
+ * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00.
+ * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
+ */
+ if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
+ sw_w32(GENMASK(31, 2), RTL931X_RMA_CTRL_0);
+ sw_w32(GENMASK(31, 0), RTL931X_RMA_CTRL_1);
+ sw_w32(GENMASK(31, 0), RTL931X_RMA_CTRL_2);
+ } else {
sw_w32(0x0, RTL931X_RMA_CTRL_0);
sw_w32(0x0, RTL931X_RMA_CTRL_1);
sw_w32(0x0, RTL931X_RMA_CTRL_2);
}
- if (ndev->flags & IFF_ALLMULTI) {
- sw_w32(0x7fffffff, RTL931X_RMA_CTRL_0);
- sw_w32(0x7fffffff, RTL931X_RMA_CTRL_1);
- sw_w32(0x7fffffff, RTL931X_RMA_CTRL_2);
- }
- if (ndev->flags & IFF_PROMISC) {
- sw_w32(0x7fffffff, RTL931X_RMA_CTRL_0);
- sw_w32(0x7fffffff, RTL931X_RMA_CTRL_1);
- sw_w32(0x7fffffff, RTL931X_RMA_CTRL_2);
- }
}
static void rtl838x_eth_tx_timeout(struct net_device *ndev, unsigned int txqueue)