mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
ba722f9b6f
3 changed files with 38 additions and 28 deletions
|
@ -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);
|
||||
cpsw_ale_set_allmulti(cpsw->ale, ndev->flags & IFF_ALLMULTI);
|
||||
|
||||
/* Clear all mcast from ALE */
|
||||
cpsw_ale_flush_multicast(cpsw->ale, ALE_ALL_PORTS, vid);
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue