diff options
author | David S. Miller <davem@davemloft.net> | 2014-05-13 18:02:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-13 18:02:49 -0400 |
commit | 87e067cda6df60b55cea0239c2f3cee81e9f46df (patch) | |
tree | 3e8575e2c828f437ac0fbf9e65555218dee9e3c9 | |
parent | ae8b42c6fc37ca1b7eb30898f5a65196bbb47291 (diff) | |
parent | 5a45e57a96dd0e42f1615630c26b4217e78a8908 (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.c | 49 |
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 | ||
367 | static 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 | */ | ||
470 | static 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 | ||
625 | static int arc_emac_probe(struct platform_device *pdev) | 674 | static int arc_emac_probe(struct platform_device *pdev) |