Skip to content

Commit 7165159

Browse files
Ryceancurrygregkh
authored andcommitted
net: bcmgenet: use promisc for unsupported filters
[ Upstream commit 35cbef9 ] Currently we silently ignore filters if we cannot meet the filter requirements. This will lead to the MAC dropping packets that are expected to pass. A better solution would be to set the NIC to promisc mode when the required filters cannot be met. Also correct the number of MDF filters supported. It should be 17, not 16. Signed-off-by: Justin Chen <justinpopo6@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 0efd6f2 commit 7165159

1 file changed

Lines changed: 26 additions & 31 deletions

File tree

drivers/net/ethernet/broadcom/genet/bcmgenet.c

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3090,39 +3090,42 @@ static void bcmgenet_timeout(struct net_device *dev)
30903090
netif_tx_wake_all_queues(dev);
30913091
}
30923092

3093-
#define MAX_MC_COUNT 16
3093+
#define MAX_MDF_FILTER 17
30943094

30953095
static inline void bcmgenet_set_mdf_addr(struct bcmgenet_priv *priv,
30963096
unsigned char *addr,
3097-
int *i,
3098-
int *mc)
3097+
int *i)
30993098
{
3100-
u32 reg;
3101-
31023099
bcmgenet_umac_writel(priv, addr[0] << 8 | addr[1],
31033100
UMAC_MDF_ADDR + (*i * 4));
31043101
bcmgenet_umac_writel(priv, addr[2] << 24 | addr[3] << 16 |
31053102
addr[4] << 8 | addr[5],
31063103
UMAC_MDF_ADDR + ((*i + 1) * 4));
3107-
reg = bcmgenet_umac_readl(priv, UMAC_MDF_CTRL);
3108-
reg |= (1 << (MAX_MC_COUNT - *mc));
3109-
bcmgenet_umac_writel(priv, reg, UMAC_MDF_CTRL);
31103104
*i += 2;
3111-
(*mc)++;
31123105
}
31133106

31143107
static void bcmgenet_set_rx_mode(struct net_device *dev)
31153108
{
31163109
struct bcmgenet_priv *priv = netdev_priv(dev);
31173110
struct netdev_hw_addr *ha;
3118-
int i, mc;
3111+
int i, nfilter;
31193112
u32 reg;
31203113

31213114
netif_dbg(priv, hw, dev, "%s: %08X\n", __func__, dev->flags);
31223115

3123-
/* Promiscuous mode */
3116+
/* Number of filters needed */
3117+
nfilter = netdev_uc_count(dev) + netdev_mc_count(dev) + 2;
3118+
3119+
/*
3120+
* Turn on promicuous mode for three scenarios
3121+
* 1. IFF_PROMISC flag is set
3122+
* 2. IFF_ALLMULTI flag is set
3123+
* 3. The number of filters needed exceeds the number filters
3124+
* supported by the hardware.
3125+
*/
31243126
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
3125-
if (dev->flags & IFF_PROMISC) {
3127+
if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) ||
3128+
(nfilter > MAX_MDF_FILTER)) {
31263129
reg |= CMD_PROMISC;
31273130
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
31283131
bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL);
@@ -3132,32 +3135,24 @@ static void bcmgenet_set_rx_mode(struct net_device *dev)
31323135
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
31333136
}
31343137

3135-
/* UniMac doesn't support ALLMULTI */
3136-
if (dev->flags & IFF_ALLMULTI) {
3137-
netdev_warn(dev, "ALLMULTI is not supported\n");
3138-
return;
3139-
}
3140-
31413138
/* update MDF filter */
31423139
i = 0;
3143-
mc = 0;
31443140
/* Broadcast */
3145-
bcmgenet_set_mdf_addr(priv, dev->broadcast, &i, &mc);
3141+
bcmgenet_set_mdf_addr(priv, dev->broadcast, &i);
31463142
/* my own address.*/
3147-
bcmgenet_set_mdf_addr(priv, dev->dev_addr, &i, &mc);
3148-
/* Unicast list*/
3149-
if (netdev_uc_count(dev) > (MAX_MC_COUNT - mc))
3150-
return;
3143+
bcmgenet_set_mdf_addr(priv, dev->dev_addr, &i);
31513144

3152-
if (!netdev_uc_empty(dev))
3153-
netdev_for_each_uc_addr(ha, dev)
3154-
bcmgenet_set_mdf_addr(priv, ha->addr, &i, &mc);
3155-
/* Multicast */
3156-
if (netdev_mc_empty(dev) || netdev_mc_count(dev) >= (MAX_MC_COUNT - mc))
3157-
return;
3145+
/* Unicast */
3146+
netdev_for_each_uc_addr(ha, dev)
3147+
bcmgenet_set_mdf_addr(priv, ha->addr, &i);
31583148

3149+
/* Multicast */
31593150
netdev_for_each_mc_addr(ha, dev)
3160-
bcmgenet_set_mdf_addr(priv, ha->addr, &i, &mc);
3151+
bcmgenet_set_mdf_addr(priv, ha->addr, &i);
3152+
3153+
/* Enable filters */
3154+
reg = GENMASK(MAX_MDF_FILTER - 1, MAX_MDF_FILTER - nfilter);
3155+
bcmgenet_umac_writel(priv, reg, UMAC_MDF_CTRL);
31613156
}
31623157

31633158
/* Set the hardware MAC address. */

0 commit comments

Comments
 (0)