Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba722f9b authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-ethernet-ti-cpsw-fix-mcast-packet-lost'



Ivan Khoronzhuk says:

====================
net: ethernet: ti: cpsw fix mcast packet lost

The patchset omits redundant refresh of mcast address table and
prevents mcast packet lost.

Based on net-next/master
tested on am572x evm
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5985d563 5da19489
Loading
Loading
Loading
Loading
+28 −18
Original line number Diff line number Diff line
@@ -570,7 +570,7 @@ static inline int cpsw_get_slave_port(u32 slave_num)
	return slave_num + 1;
}

static void cpsw_add_mcast(struct cpsw_priv *priv, u8 *addr)
static void cpsw_add_mcast(struct cpsw_priv *priv, const u8 *addr)
{
	struct cpsw_common *cpsw = priv->cpsw;

@@ -662,16 +662,35 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
	}
}

static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr)
{
	struct cpsw_priv *priv = netdev_priv(ndev);

	cpsw_add_mcast(priv, addr);
	return 0;
}

static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;
	int vid;
	int vid, flags;

	if (cpsw->data.dual_emac)
	if (cpsw->data.dual_emac) {
		vid = cpsw->slaves[priv->emac_port].port_vlan;
	else
		vid = cpsw->data.default_vlan;
		flags = ALE_VLAN;
	} else {
		vid = 0;
		flags = 0;
	}

	cpsw_ale_del_mcast(cpsw->ale, addr, 0, flags, vid);
	return 0;
}

static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
{
	struct cpsw_common *cpsw = ndev_to_cpsw(ndev);

	if (ndev->flags & IFF_PROMISC) {
		/* Enable promiscuous mode */
@@ -684,19 +703,9 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
	}

	/* Restore allmulti on vlans if necessary */
	cpsw_ale_set_allmulti(cpsw->ale, priv->ndev->flags & IFF_ALLMULTI);

	/* Clear all mcast from ALE */
	cpsw_ale_flush_multicast(cpsw->ale, ALE_ALL_PORTS, vid);
	cpsw_ale_set_allmulti(cpsw->ale, ndev->flags & IFF_ALLMULTI);

	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, ha->addr);
		}
	}
	__dev_mc_sync(ndev, cpsw_add_mc_addr, cpsw_del_mc_addr);
}

static void cpsw_intr_enable(struct cpsw_common *cpsw)
@@ -1956,6 +1965,7 @@ static int cpsw_ndo_stop(struct net_device *ndev)
	struct cpsw_common *cpsw = priv->cpsw;

	cpsw_info(priv, ifdown, "shutting down cpsw device\n");
	__dev_mc_unsync(priv->ndev, cpsw_del_mc_addr);
	netif_tx_stop_all_queues(priv->ndev);
	netif_carrier_off(priv->ndev);

+6 −6
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
		addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8);
}

static inline void cpsw_ale_set_addr(u32 *ale_entry, u8 *addr)
static inline void cpsw_ale_set_addr(u32 *ale_entry, const u8 *addr)
{
	int i;

@@ -175,7 +175,7 @@ static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry)
	return idx;
}

static int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr, u16 vid)
static int cpsw_ale_match_addr(struct cpsw_ale *ale, const u8 *addr, u16 vid)
{
	u32 ale_entry[ALE_ENTRY_WORDS];
	int type, idx;
@@ -309,7 +309,7 @@ static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry,
	}
}

int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
		       int flags, u16 vid)
{
	u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
@@ -336,7 +336,7 @@ int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
}
EXPORT_SYMBOL_GPL(cpsw_ale_add_ucast);

int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
		       int flags, u16 vid)
{
	u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
@@ -352,7 +352,7 @@ int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
}
EXPORT_SYMBOL_GPL(cpsw_ale_del_ucast);

int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
		       int flags, u16 vid, int mcast_state)
{
	u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
@@ -386,7 +386,7 @@ int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
}
EXPORT_SYMBOL_GPL(cpsw_ale_add_mcast);

int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
		       int flags, u16 vid)
{
	u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
+4 −4
Original line number Diff line number Diff line
@@ -105,13 +105,13 @@ void cpsw_ale_start(struct cpsw_ale *ale);
void cpsw_ale_stop(struct cpsw_ale *ale);

int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid);
int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
		       int flags, u16 vid);
int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
		       int flags, u16 vid);
int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
		       int flags, u16 vid, int mcast_state);
int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
		       int flags, u16 vid);
int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
			int reg_mcast, int unreg_mcast);