net: sun4i-emac: add promiscuous support

The sun4i-emac driver is rather primitive, and doesn't support
promiscuous mode. This makes usage such as bridging impossible,
which is a shame on virtualization capable HW such as the
Allwinner A20.

The fix is fairly simple: move the RX setup code to the ndo_set_rx_mode
vector, and add the required HW configuration when IFF_PROMISC is passed
by the core code.

This has been tested on a generic A20 box running a few virtual
machines hanging off a bridge with the EMAC chip as the link to the
outside world.

Cc: Stefan Roese <sr@denx.de>
Cc: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Stefan Roese <sr@denx.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Marc Zyngier and committed by David S. Miller cec9ae50 0af764e3

+21 -9
+21 -9
drivers/net/ethernet/allwinner/sun4i-emac.c
··· 268 268 writel(reg_val | EMAC_TX_MODE_ABORTED_FRAME_EN, 269 269 db->membase + EMAC_TX_MODE_REG); 270 270 271 - /* set up RX */ 272 - reg_val = readl(db->membase + EMAC_RX_CTL_REG); 273 - 274 - writel(reg_val | EMAC_RX_CTL_PASS_LEN_OOR_EN | 275 - EMAC_RX_CTL_ACCEPT_UNICAST_EN | EMAC_RX_CTL_DA_FILTER_EN | 276 - EMAC_RX_CTL_ACCEPT_MULTICAST_EN | 277 - EMAC_RX_CTL_ACCEPT_BROADCAST_EN, 278 - db->membase + EMAC_RX_CTL_REG); 279 - 280 271 /* set MAC */ 281 272 /* set MAC CTL0 */ 282 273 reg_val = readl(db->membase + EMAC_MAC_CTL0_REG); ··· 298 307 db->membase + EMAC_MAC_MAXF_REG); 299 308 300 309 return 0; 310 + } 311 + 312 + static void emac_set_rx_mode(struct net_device *ndev) 313 + { 314 + struct emac_board_info *db = netdev_priv(ndev); 315 + unsigned int reg_val; 316 + 317 + /* set up RX */ 318 + reg_val = readl(db->membase + EMAC_RX_CTL_REG); 319 + 320 + if (ndev->flags & IFF_PROMISC) 321 + reg_val |= EMAC_RX_CTL_PASS_ALL_EN; 322 + else 323 + reg_val &= ~EMAC_RX_CTL_PASS_ALL_EN; 324 + 325 + writel(reg_val | EMAC_RX_CTL_PASS_LEN_OOR_EN | 326 + EMAC_RX_CTL_ACCEPT_UNICAST_EN | EMAC_RX_CTL_DA_FILTER_EN | 327 + EMAC_RX_CTL_ACCEPT_MULTICAST_EN | 328 + EMAC_RX_CTL_ACCEPT_BROADCAST_EN, 329 + db->membase + EMAC_RX_CTL_REG); 301 330 } 302 331 303 332 static unsigned int emac_powerup(struct net_device *ndev) ··· 793 782 .ndo_stop = emac_stop, 794 783 .ndo_start_xmit = emac_start_xmit, 795 784 .ndo_tx_timeout = emac_timeout, 785 + .ndo_set_rx_mode = emac_set_rx_mode, 796 786 .ndo_do_ioctl = emac_ioctl, 797 787 .ndo_change_mtu = eth_change_mtu, 798 788 .ndo_validate_addr = eth_validate_addr,