netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2012-10-16 22:45 [PATCH 0/6] Add CPTS PTP driver support Mugunthan V N
@ 2012-10-16 22:45 ` Mugunthan V N
  2012-10-18  2:49   ` Richard Cochran
  2012-10-21 11:26   ` Richard Cochran
  0 siblings, 2 replies; 7+ messages in thread
From: Mugunthan V N @ 2012-10-16 22:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, Richard Cochran, Mugunthan V N

Adding multicast address to ALE table via netdev ops to subscribe, transmit
or receive multicast frames to and from the network

Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/net/ethernet/ti/cpsw.c     |   27 +++++++++++++++++++++++++++
 drivers/net/ethernet/ti/cpsw_ale.c |   31 ++++++++++++++++++++++++++++---
 drivers/net/ethernet/ti/cpsw_ale.h |    1 +
 3 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index cdf9ecc..b6af1c6 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -75,6 +75,8 @@ do {								\
 #define cpsw_slave_reg(priv, slave, reg)				\
 	((slave)->regs + (priv)->slave_reg_ofs[(reg)])
 
+#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)
@@ -271,6 +273,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);
@@ -721,6 +747,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
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index ca0d48a..0e9ccc2 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 #include <linux/stat.h>
 #include <linux/sysfs.h>
+#include <linux/etherdevice.h>
 
 #include "cpsw_ale.h"
 
@@ -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,
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h
index a95b37b..2bd09cb 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.h
+++ b/drivers/net/ethernet/ti/cpsw_ale.h
@@ -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,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2012-10-16 22:45 ` [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Mugunthan V N
@ 2012-10-18  2:49   ` Richard Cochran
  2012-10-21 11:26   ` Richard Cochran
  1 sibling, 0 replies; 7+ messages in thread
From: Richard Cochran @ 2012-10-18  2:49 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem

On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
> Adding multicast address to ALE table via netdev ops to subscribe, transmit
> or receive multicast frames to and from the network

Is this somehow related to the time stamping function? If so, how?

Thanks,
Richard

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2012-10-16 22:45 ` [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Mugunthan V N
  2012-10-18  2:49   ` Richard Cochran
@ 2012-10-21 11:26   ` Richard Cochran
  2012-10-22 10:46     ` N, Mugunthan V
  1 sibling, 1 reply; 7+ messages in thread
From: Richard Cochran @ 2012-10-21 11:26 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem

On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
> @@ -271,6 +273,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;

Why can't we support promiscuous mode here?

Thanks,
Richard

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2012-10-21 11:26   ` Richard Cochran
@ 2012-10-22 10:46     ` N, Mugunthan V
  0 siblings, 0 replies; 7+ messages in thread
From: N, Mugunthan V @ 2012-10-22 10:46 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net

> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Sunday, October 21, 2012 4:56 PM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast
> address to ALE table
> 
> On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
> > @@ -271,6 +273,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;
> 
> Why can't we support promiscuous mode here?
> 

To support promiscuous mode, ALE has to be disabled and but this will
lead to disabling Switch functionality in hardware. So this is not
implemented as of now, It is under development.

Regards
Mugunthan V N

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
@ 2014-09-02 18:22 Graeme Smecher
  2014-09-03  8:28 ` Mugunthan V N
  0 siblings, 1 reply; 7+ messages in thread
From: Graeme Smecher @ 2014-09-02 18:22 UTC (permalink / raw)
  To: netdev; +Cc: Mugunthan V N

Hi Mugunthan,

> On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
> > Adding multicast address to ALE table via netdev ops to subscribe, transmit
> > or receive multicast frames to and from the network
> 
> Is this somehow related to the time stamping function? If so, how?
> 
> Thanks,
> Richard

Can you give me a brief description of this (relatively ancient) patch? Your
original e-mail is visible here:

	http://marc.info/?l=linux-netdev&m=135042754927177&w=2

I'm wondering if this patch needs to be backported to older CPSW driver
snapshots (specifically, TI's 2.6.37 branch for dm81xx.) It appears to
fix a multicast bug I'm tracking down, but it's difficult to know for
sure without a good description of what problem the patch addresses. (I
don't want to commit code that fixes my hardware by accident.)

For a little more information, you can refer to my e2e.ti.com post:

	http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/365586.aspx

I'm slowly learning about ALE filtering, but a quick reply from a
domain expert would be very helpful.

best,
Graeme

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2014-09-02 18:22 [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Graeme Smecher
@ 2014-09-03  8:28 ` Mugunthan V N
  2014-09-03 19:01   ` Graeme Smecher
  0 siblings, 1 reply; 7+ messages in thread
From: Mugunthan V N @ 2014-09-03  8:28 UTC (permalink / raw)
  To: Graeme Smecher, netdev

Hi Graeme

There is already a support for add multicast in v2.6.37 cpsw driver, if
there is a bug and you found a fix, can go a head and fix that. The
patch you have mentioned is an upstream patch with was done on top of
am335x platform, so there might be bugs fixed and added into the patch
which are not in v2.6.37 cpsw driver.

Regards
Mugunthan V N

On Tuesday 02 September 2014 11:52 PM, Graeme Smecher wrote:
> Hi Mugunthan,
> 
>> On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
>>> Adding multicast address to ALE table via netdev ops to subscribe, transmit
>>> or receive multicast frames to and from the network
>>
>> Is this somehow related to the time stamping function? If so, how?
>>
>> Thanks,
>> Richard
> 
> Can you give me a brief description of this (relatively ancient) patch? Your
> original e-mail is visible here:
> 
> 	http://marc.info/?l=linux-netdev&m=135042754927177&w=2
> 
> I'm wondering if this patch needs to be backported to older CPSW driver
> snapshots (specifically, TI's 2.6.37 branch for dm81xx.) It appears to
> fix a multicast bug I'm tracking down, but it's difficult to know for
> sure without a good description of what problem the patch addresses. (I
> don't want to commit code that fixes my hardware by accident.)
> 
> For a little more information, you can refer to my e2e.ti.com post:
> 
> 	http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/365586.aspx
> 
> I'm slowly learning about ALE filtering, but a quick reply from a
> domain expert would be very helpful.
> 
> best,
> Graeme
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2014-09-03  8:28 ` Mugunthan V N
@ 2014-09-03 19:01   ` Graeme Smecher
  0 siblings, 0 replies; 7+ messages in thread
From: Graeme Smecher @ 2014-09-03 19:01 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev

Hi Mungathan,

FYI, I think the multicast bug I'm working on also affects dual EMAC
mode in upstream cpsw.c. I will add a 2.6.37-specific patch on my e2e
forum post (link below), but this is a heads-up for code you maintain.

Symptoms: each port in dual EMAC mode trashes the other port's multicast
reception.

Cause: cpsw_ndo_set_rx_mode does the following:

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_add_mcast(priv, (u8 *)ha->addr);
}
}

This code can be invoked by eth0 or eth1, which have potentially
differing multicast lists. However, cpsw_ale_flush_multicast() trashes
ALL multicast entries in the ALE, affecting both ports. Only the entries
for the net_device that invoked cpsw_ndo_set_rx_mode() are restored.

To fix this, you will have to pass a correct port_mask to
cpsw_ale_flush_multicast(), and correct the free-entry check at the
bottom of cpsw_ale_flush_mcast().

best,
Graeme

On Wed, 2014-09-03 at 13:58 +0530, Mugunthan V N wrote: 
> Hi Graeme
> 
> There is already a support for add multicast in v2.6.37 cpsw driver, if
> there is a bug and you found a fix, can go a head and fix that. The
> patch you have mentioned is an upstream patch with was done on top of
> am335x platform, so there might be bugs fixed and added into the patch
> which are not in v2.6.37 cpsw driver.
> 
> Regards
> Mugunthan V N
> 
> On Tuesday 02 September 2014 11:52 PM, Graeme Smecher wrote:
> > Hi Mugunthan,
> > 
> >> On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
> >>> Adding multicast address to ALE table via netdev ops to subscribe, transmit
> >>> or receive multicast frames to and from the network
> >>
> >> Is this somehow related to the time stamping function? If so, how?
> >>
> >> Thanks,
> >> Richard
> > 
> > Can you give me a brief description of this (relatively ancient) patch? Your
> > original e-mail is visible here:
> > 
> > 	http://marc.info/?l=linux-netdev&m=135042754927177&w=2
> > 
> > I'm wondering if this patch needs to be backported to older CPSW driver
> > snapshots (specifically, TI's 2.6.37 branch for dm81xx.) It appears to
> > fix a multicast bug I'm tracking down, but it's difficult to know for
> > sure without a good description of what problem the patch addresses. (I
> > don't want to commit code that fixes my hardware by accident.)
> > 
> > For a little more information, you can refer to my e2e.ti.com post:
> > 
> > 	http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/365586.aspx
> > 
> > I'm slowly learning about ALE filtering, but a quick reply from a
> > domain expert would be very helpful.
> > 
> > best,
> > Graeme
> > 
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-09-03 19:01 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-02 18:22 [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Graeme Smecher
2014-09-03  8:28 ` Mugunthan V N
2014-09-03 19:01   ` Graeme Smecher
  -- strict thread matches above, loose matches on Subject: below --
2012-10-16 22:45 [PATCH 0/6] Add CPTS PTP driver support Mugunthan V N
2012-10-16 22:45 ` [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Mugunthan V N
2012-10-18  2:49   ` Richard Cochran
2012-10-21 11:26   ` Richard Cochran
2012-10-22 10:46     ` N, Mugunthan V

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).