Skip to content

Commit

Permalink
drivers: net: ethernet: cpsw: add multicast address to ALE table
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mugunthan V N authored and David S. Miller committed Nov 1, 2012
1 parent 8ef29f8 commit 5c50a85
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
27 changes: 27 additions & 0 deletions drivers/net/ethernet/ti/cpsw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
31 changes: 28 additions & 3 deletions drivers/net/ethernet/ti/cpsw_ale.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/io.h>
#include <linux/stat.h>
#include <linux/sysfs.h>
#include <linux/etherdevice.h>

#include "cpsw_ale.h"

Expand Down Expand Up @@ -211,10 +212,34 @@ static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry,
mask &= ~port_mask;

/* free if only remaining port is host port */
if (mask == BIT(ale->params.ale_ports))
cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
else
if (mask)
cpsw_ale_set_port_mask(ale_entry, mask);
else
cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
}

int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask)
{
u32 ale_entry[ALE_ENTRY_WORDS];
int ret, idx;

for (idx = 0; idx < ale->params.ale_entries; idx++) {
cpsw_ale_read(ale, idx, ale_entry);
ret = cpsw_ale_get_entry_type(ale_entry);
if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR)
continue;

if (cpsw_ale_get_mcast(ale_entry)) {
u8 addr[6];

cpsw_ale_get_addr(ale_entry, addr);
if (!is_broadcast_ether_addr(addr))
cpsw_ale_flush_mcast(ale, ale_entry, port_mask);
}

cpsw_ale_write(ale, idx, ale_entry);
}
return 0;
}

static void cpsw_ale_flush_ucast(struct cpsw_ale *ale, u32 *ale_entry,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/ti/cpsw_ale.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ void cpsw_ale_stop(struct cpsw_ale *ale);

int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout);
int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask);
int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask);
int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, int flags);
int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port);
int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
Expand Down

0 comments on commit 5c50a85

Please sign in to comment.