net: tsec: add support for promiscuous mode

The Freescale TSEC can be a DSA master, and the ports of the attached
DSA switch can have different MAC addresses compared to the TSEC.
Nonetheless, the TSEC must receive the packets on behalf of those switch
ports. Therefore, implement the promiscuous mode method to allow DSA to
set this.

Note that the init_registers() function called from eth_ops :: start
overwrites this setting. There is no reason why the RCTRL register
should be zero-initialized, so just stop clearing it so that the setting
we applied in eth_ops :: set_promisc sticks.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index 0ce9765..4354753 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -156,6 +156,19 @@
 	return 0;
 }
 
+static int tsec_set_promisc(struct udevice *dev, bool enable)
+{
+	struct tsec_private *priv = dev_get_priv(dev);
+	struct tsec __iomem *regs = priv->regs;
+
+	if (enable)
+		setbits_be32(&regs->rctrl, RCTRL_PROM);
+	else
+		clrbits_be32(&regs->rctrl, RCTRL_PROM);
+
+	return 0;
+}
+
 /*
  * Initialized required registers to appropriate values, zeroing
  * those we don't care about (unless zero is bad, in which case,
@@ -186,8 +199,6 @@
 	out_be32(&regs->hash.gaddr6, 0);
 	out_be32(&regs->hash.gaddr7, 0);
 
-	out_be32(&regs->rctrl, 0x00000000);
-
 	/* Init RMON mib registers */
 	memset((void *)&regs->rmon, 0, sizeof(regs->rmon));
 
@@ -454,7 +465,7 @@
 		0x71, 0x72};
 
 	/* Enable promiscuous mode */
-	setbits_be32(&regs->rctrl, 0x8);
+	setbits_be32(&regs->rctrl, RCTRL_PROM);
 	/* Enable loopback mode */
 	setbits_be32(&regs->maccfg1, MACCFG1_LOOPBACK);
 	/* Enable transmit and receive */
@@ -506,7 +517,7 @@
 	if (fail)
 		panic("eTSEC init fail!\n");
 	/* Disable promiscuous mode */
-	clrbits_be32(&regs->rctrl, 0x8);
+	clrbits_be32(&regs->rctrl, RCTRL_PROM);
 	/* Disable loopback mode */
 	clrbits_be32(&regs->maccfg1, MACCFG1_LOOPBACK);
 }
@@ -932,6 +943,7 @@
 	.free_pkt = tsec_free_pkt,
 	.stop = tsec_halt,
 	.mcast = tsec_mcast_addr,
+	.set_promisc = tsec_set_promisc,
 };
 
 static struct tsec_data etsec2_data = {