aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-05-13 18:02:49 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-13 18:02:49 -0400
commit87e067cda6df60b55cea0239c2f3cee81e9f46df (patch)
tree3e8575e2c828f437ac0fbf9e65555218dee9e3c9
parentae8b42c6fc37ca1b7eb30898f5a65196bbb47291 (diff)
parent5a45e57a96dd0e42f1615630c26b4217e78a8908 (diff)
Merge branch 'arc_emac-next'
Beniamino Galvani says: ==================== arc_emac: promiscuous/multicast mode and netpoll support These patches add support for promiscuous mode, multicast filtering and netpoll to the ARC EMAC driver. They were both tested on a Radxa Rock board which uses a ARC EMAC IP core integrated in the Rockchip RK3188 SoC. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/arc/emac_main.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index d647a7d115ac..18e2faccebb0 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -13,6 +13,7 @@
13 * Vineet Gupta 13 * Vineet Gupta
14 */ 14 */
15 15
16#include <linux/crc32.h>
16#include <linux/etherdevice.h> 17#include <linux/etherdevice.h>
17#include <linux/interrupt.h> 18#include <linux/interrupt.h>
18#include <linux/io.h> 19#include <linux/io.h>
@@ -362,6 +363,15 @@ static irqreturn_t arc_emac_intr(int irq, void *dev_instance)
362 return IRQ_HANDLED; 363 return IRQ_HANDLED;
363} 364}
364 365
366#ifdef CONFIG_NET_POLL_CONTROLLER
367static void arc_emac_poll_controller(struct net_device *dev)
368{
369 disable_irq(dev->irq);
370 arc_emac_intr(dev->irq, dev);
371 enable_irq(dev->irq);
372}
373#endif
374
365/** 375/**
366 * arc_emac_open - Open the network device. 376 * arc_emac_open - Open the network device.
367 * @ndev: Pointer to the network device. 377 * @ndev: Pointer to the network device.
@@ -451,6 +461,41 @@ static int arc_emac_open(struct net_device *ndev)
451} 461}
452 462
453/** 463/**
464 * arc_emac_set_rx_mode - Change the receive filtering mode.
465 * @ndev: Pointer to the network device.
466 *
467 * This function enables/disables promiscuous or all-multicast mode
468 * and updates the multicast filtering list of the network device.
469 */
470static void arc_emac_set_rx_mode(struct net_device *ndev)
471{
472 struct arc_emac_priv *priv = netdev_priv(ndev);
473
474 if (ndev->flags & IFF_PROMISC) {
475 arc_reg_or(priv, R_CTRL, PROM_MASK);
476 } else {
477 arc_reg_clr(priv, R_CTRL, PROM_MASK);
478
479 if (ndev->flags & IFF_ALLMULTI) {
480 arc_reg_set(priv, R_LAFL, ~0);
481 arc_reg_set(priv, R_LAFH, ~0);
482 } else {
483 struct netdev_hw_addr *ha;
484 unsigned int filter[2] = { 0, 0 };
485 int bit;
486
487 netdev_for_each_mc_addr(ha, ndev) {
488 bit = ether_crc_le(ETH_ALEN, ha->addr) >> 26;
489 filter[bit >> 5] |= 1 << (bit & 31);
490 }
491
492 arc_reg_set(priv, R_LAFL, filter[0]);
493 arc_reg_set(priv, R_LAFH, filter[1]);
494 }
495 }
496}
497
498/**
454 * arc_emac_stop - Close the network device. 499 * arc_emac_stop - Close the network device.
455 * @ndev: Pointer to the network device. 500 * @ndev: Pointer to the network device.
456 * 501 *
@@ -620,6 +665,10 @@ static const struct net_device_ops arc_emac_netdev_ops = {
620 .ndo_start_xmit = arc_emac_tx, 665 .ndo_start_xmit = arc_emac_tx,
621 .ndo_set_mac_address = arc_emac_set_address, 666 .ndo_set_mac_address = arc_emac_set_address,
622 .ndo_get_stats = arc_emac_stats, 667 .ndo_get_stats = arc_emac_stats,
668 .ndo_set_rx_mode = arc_emac_set_rx_mode,
669#ifdef CONFIG_NET_POLL_CONTROLLER
670 .ndo_poll_controller = arc_emac_poll_controller,
671#endif
623}; 672};
624 673
625static int arc_emac_probe(struct platform_device *pdev) 674static int arc_emac_probe(struct platform_device *pdev)