summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/ti/cpsw.c
diff options
context:
space:
mode:
authorMugunthan V N <mugunthanvnm@ti.com>2012-10-29 08:45:11 +0000
committerDavid S. Miller <davem@davemloft.net>2012-11-01 12:21:29 -0400
commit5c50a856d550b3bf6a731f6e33a794ed5c519817 (patch)
tree3435bb193aac26e54094a022f809cbe33079a4f0 /drivers/net/ethernet/ti/cpsw.c
parent8ef29f8aae524bd51298fb10ac6a5ce6c4c5a3d8 (diff)
drivers: net: ethernet: cpsw: add multicast address to ALE table
Adding multicast address to ALE table via netdev ops to subscribe, transmit or receive multicast frames to and from the network Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com> Acked-by: Richard Cochran <richardcochran@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ti/cpsw.c')
-rw-r--r--drivers/net/ethernet/ti/cpsw.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index df55e2403746..63b046fc2bba 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -70,6 +70,8 @@ do { \
dev_notice(priv->dev, format, ## __VA_ARGS__); \
} while (0)
+#define ALE_ALL_PORTS 0x7
+
#define CPSW_MAJOR_VERSION(reg) (reg >> 8 & 0x7)
#define CPSW_MINOR_VERSION(reg) (reg & 0xff)
#define CPSW_RTL_VERSION(reg) ((reg >> 11) & 0x1f)
@@ -228,6 +230,30 @@ struct cpsw_priv {
(func)((priv)->slaves + idx, ##arg); \
} while (0)
+static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+{
+ struct cpsw_priv *priv = netdev_priv(ndev);
+
+ if (ndev->flags & IFF_PROMISC) {
+ /* Enable promiscuous mode */
+ dev_err(priv->dev, "Ignoring Promiscuous mode\n");
+ return;
+ }
+
+ /* Clear all mcast from ALE */
+ cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port);
+
+ if (!netdev_mc_empty(ndev)) {
+ struct netdev_hw_addr *ha;
+
+ /* program multicast address list into ALE register */
+ netdev_for_each_mc_addr(ha, ndev) {
+ cpsw_ale_add_mcast(priv->ale, (u8 *)ha->addr,
+ ALE_ALL_PORTS << priv->host_port, 0, 0);
+ }
+ }
+}
+
static void cpsw_intr_enable(struct cpsw_priv *priv)
{
__raw_writel(0xFF, &priv->ss_regs->tx_en);
@@ -673,6 +699,7 @@ static const struct net_device_ops cpsw_netdev_ops = {
.ndo_change_mtu = eth_change_mtu,
.ndo_tx_timeout = cpsw_ndo_tx_timeout,
.ndo_get_stats = cpsw_ndo_get_stats,
+ .ndo_set_rx_mode = cpsw_ndo_set_rx_mode,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = cpsw_ndo_poll_controller,
#endif