diff options
author | Radu Bulie <radu-andrei.bulie@nxp.com> | 2018-02-26 12:24:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-27 11:40:03 -0500 |
commit | c893238e5d9b279be4c73d7fdf0dc8986a6c118f (patch) | |
tree | 98f54d7c26d724c725f95927c2459f5870537097 | |
parent | 056a01ba9453258a56993e8645b7b922e55be81c (diff) |
dpaa_eth: Add allmulti option
This patch adds allmulticast option for memac, dtsec
and 10GEC controllers.
Signed-off-by: Radu Bulie <radu-andrei.bulie@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fman/fman_dtsec.c | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fman/fman_dtsec.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fman/fman_memac.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fman/fman_memac.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fman/fman_tgec.c | 33 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fman/fman_tgec.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fman/mac.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fman/mac.h | 2 |
9 files changed, 97 insertions, 5 deletions
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 9bd0ff03f389..159dc2df878d 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | |||
@@ -454,6 +454,16 @@ static void dpaa_set_rx_mode(struct net_device *net_dev) | |||
454 | err); | 454 | err); |
455 | } | 455 | } |
456 | 456 | ||
457 | if (!!(net_dev->flags & IFF_ALLMULTI) != priv->mac_dev->allmulti) { | ||
458 | priv->mac_dev->allmulti = !priv->mac_dev->allmulti; | ||
459 | err = priv->mac_dev->set_allmulti(priv->mac_dev->fman_mac, | ||
460 | priv->mac_dev->allmulti); | ||
461 | if (err < 0) | ||
462 | netif_err(priv, drv, net_dev, | ||
463 | "mac_dev->set_allmulti() = %d\n", | ||
464 | err); | ||
465 | } | ||
466 | |||
457 | err = priv->mac_dev->set_multi(net_dev, priv->mac_dev); | 467 | err = priv->mac_dev->set_multi(net_dev, priv->mac_dev); |
458 | if (err < 0) | 468 | if (err < 0) |
459 | netif_err(priv, drv, net_dev, "mac_dev->set_multi() = %d\n", | 469 | netif_err(priv, drv, net_dev, "mac_dev->set_multi() = %d\n", |
diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c index ea43b4974149..9a581faaa742 100644 --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c | |||
@@ -1117,6 +1117,25 @@ int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr) | |||
1117 | return 0; | 1117 | return 0; |
1118 | } | 1118 | } |
1119 | 1119 | ||
1120 | int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable) | ||
1121 | { | ||
1122 | u32 tmp; | ||
1123 | struct dtsec_regs __iomem *regs = dtsec->regs; | ||
1124 | |||
1125 | if (!is_init_done(dtsec->dtsec_drv_param)) | ||
1126 | return -EINVAL; | ||
1127 | |||
1128 | tmp = ioread32be(®s->rctrl); | ||
1129 | if (enable) | ||
1130 | tmp |= RCTRL_MPROM; | ||
1131 | else | ||
1132 | tmp &= ~RCTRL_MPROM; | ||
1133 | |||
1134 | iowrite32be(tmp, ®s->rctrl); | ||
1135 | |||
1136 | return 0; | ||
1137 | } | ||
1138 | |||
1120 | int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr) | 1139 | int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr) |
1121 | { | 1140 | { |
1122 | struct dtsec_regs __iomem *regs = dtsec->regs; | 1141 | struct dtsec_regs __iomem *regs = dtsec->regs; |
diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.h b/drivers/net/ethernet/freescale/fman/fman_dtsec.h index c4467c072058..1a689adf5a22 100644 --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.h +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.h | |||
@@ -55,5 +55,6 @@ int dtsec_set_exception(struct fman_mac *dtsec, | |||
55 | int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr); | 55 | int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr); |
56 | int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr); | 56 | int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr); |
57 | int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version); | 57 | int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version); |
58 | int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable); | ||
58 | 59 | ||
59 | #endif /* __DTSEC_H */ | 60 | #endif /* __DTSEC_H */ |
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c index c0296880feba..446a97b792e3 100644 --- a/drivers/net/ethernet/freescale/fman/fman_memac.c +++ b/drivers/net/ethernet/freescale/fman/fman_memac.c | |||
@@ -350,6 +350,7 @@ struct fman_mac { | |||
350 | struct fman_rev_info fm_rev_info; | 350 | struct fman_rev_info fm_rev_info; |
351 | bool basex_if; | 351 | bool basex_if; |
352 | struct phy_device *pcsphy; | 352 | struct phy_device *pcsphy; |
353 | bool allmulti_enabled; | ||
353 | }; | 354 | }; |
354 | 355 | ||
355 | static void add_addr_in_paddr(struct memac_regs __iomem *regs, u8 *adr, | 356 | static void add_addr_in_paddr(struct memac_regs __iomem *regs, u8 *adr, |
@@ -940,6 +941,29 @@ int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr) | |||
940 | return 0; | 941 | return 0; |
941 | } | 942 | } |
942 | 943 | ||
944 | int memac_set_allmulti(struct fman_mac *memac, bool enable) | ||
945 | { | ||
946 | u32 entry; | ||
947 | struct memac_regs __iomem *regs = memac->regs; | ||
948 | |||
949 | if (!is_init_done(memac->memac_drv_param)) | ||
950 | return -EINVAL; | ||
951 | |||
952 | if (enable) { | ||
953 | for (entry = 0; entry < HASH_TABLE_SIZE; entry++) | ||
954 | iowrite32be(entry | HASH_CTRL_MCAST_EN, | ||
955 | ®s->hashtable_ctrl); | ||
956 | } else { | ||
957 | for (entry = 0; entry < HASH_TABLE_SIZE; entry++) | ||
958 | iowrite32be(entry & ~HASH_CTRL_MCAST_EN, | ||
959 | ®s->hashtable_ctrl); | ||
960 | } | ||
961 | |||
962 | memac->allmulti_enabled = enable; | ||
963 | |||
964 | return 0; | ||
965 | } | ||
966 | |||
943 | int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr) | 967 | int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr) |
944 | { | 968 | { |
945 | struct memac_regs __iomem *regs = memac->regs; | 969 | struct memac_regs __iomem *regs = memac->regs; |
@@ -963,8 +987,12 @@ int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr) | |||
963 | break; | 987 | break; |
964 | } | 988 | } |
965 | } | 989 | } |
966 | if (list_empty(&memac->multicast_addr_hash->lsts[hash])) | 990 | |
967 | iowrite32be(hash & ~HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl); | 991 | if (!memac->allmulti_enabled) { |
992 | if (list_empty(&memac->multicast_addr_hash->lsts[hash])) | ||
993 | iowrite32be(hash & ~HASH_CTRL_MCAST_EN, | ||
994 | ®s->hashtable_ctrl); | ||
995 | } | ||
968 | 996 | ||
969 | return 0; | 997 | return 0; |
970 | } | 998 | } |
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.h b/drivers/net/ethernet/freescale/fman/fman_memac.h index c4a66469a907..b5a50338ed9a 100644 --- a/drivers/net/ethernet/freescale/fman/fman_memac.h +++ b/drivers/net/ethernet/freescale/fman/fman_memac.h | |||
@@ -57,5 +57,6 @@ int memac_set_exception(struct fman_mac *memac, | |||
57 | enum fman_mac_exceptions exception, bool enable); | 57 | enum fman_mac_exceptions exception, bool enable); |
58 | int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr); | 58 | int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr); |
59 | int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr); | 59 | int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr); |
60 | int memac_set_allmulti(struct fman_mac *memac, bool enable); | ||
60 | 61 | ||
61 | #endif /* __MEMAC_H */ | 62 | #endif /* __MEMAC_H */ |
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.c b/drivers/net/ethernet/freescale/fman/fman_tgec.c index 4b0f3a50b293..284735d4ebe9 100644 --- a/drivers/net/ethernet/freescale/fman/fman_tgec.c +++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c | |||
@@ -217,6 +217,7 @@ struct fman_mac { | |||
217 | struct tgec_cfg *cfg; | 217 | struct tgec_cfg *cfg; |
218 | void *fm; | 218 | void *fm; |
219 | struct fman_rev_info fm_rev_info; | 219 | struct fman_rev_info fm_rev_info; |
220 | bool allmulti_enabled; | ||
220 | }; | 221 | }; |
221 | 222 | ||
222 | static void set_mac_address(struct tgec_regs __iomem *regs, u8 *adr) | 223 | static void set_mac_address(struct tgec_regs __iomem *regs, u8 *adr) |
@@ -564,6 +565,29 @@ int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr) | |||
564 | return 0; | 565 | return 0; |
565 | } | 566 | } |
566 | 567 | ||
568 | int tgec_set_allmulti(struct fman_mac *tgec, bool enable) | ||
569 | { | ||
570 | u32 entry; | ||
571 | struct tgec_regs __iomem *regs = tgec->regs; | ||
572 | |||
573 | if (!is_init_done(tgec->cfg)) | ||
574 | return -EINVAL; | ||
575 | |||
576 | if (enable) { | ||
577 | for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++) | ||
578 | iowrite32be(entry | TGEC_HASH_MCAST_EN, | ||
579 | ®s->hashtable_ctrl); | ||
580 | } else { | ||
581 | for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++) | ||
582 | iowrite32be(entry & ~TGEC_HASH_MCAST_EN, | ||
583 | ®s->hashtable_ctrl); | ||
584 | } | ||
585 | |||
586 | tgec->allmulti_enabled = enable; | ||
587 | |||
588 | return 0; | ||
589 | } | ||
590 | |||
567 | int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr) | 591 | int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr) |
568 | { | 592 | { |
569 | struct tgec_regs __iomem *regs = tgec->regs; | 593 | struct tgec_regs __iomem *regs = tgec->regs; |
@@ -591,9 +615,12 @@ int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr) | |||
591 | break; | 615 | break; |
592 | } | 616 | } |
593 | } | 617 | } |
594 | if (list_empty(&tgec->multicast_addr_hash->lsts[hash])) | 618 | |
595 | iowrite32be((hash & ~TGEC_HASH_MCAST_EN), | 619 | if (!tgec->allmulti_enabled) { |
596 | ®s->hashtable_ctrl); | 620 | if (list_empty(&tgec->multicast_addr_hash->lsts[hash])) |
621 | iowrite32be((hash & ~TGEC_HASH_MCAST_EN), | ||
622 | ®s->hashtable_ctrl); | ||
623 | } | ||
597 | 624 | ||
598 | return 0; | 625 | return 0; |
599 | } | 626 | } |
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.h b/drivers/net/ethernet/freescale/fman/fman_tgec.h index 514bba9f47ce..cbbd3b422a98 100644 --- a/drivers/net/ethernet/freescale/fman/fman_tgec.h +++ b/drivers/net/ethernet/freescale/fman/fman_tgec.h | |||
@@ -51,5 +51,6 @@ int tgec_set_exception(struct fman_mac *tgec, | |||
51 | int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr); | 51 | int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr); |
52 | int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr); | 52 | int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr); |
53 | int tgec_get_version(struct fman_mac *tgec, u32 *mac_version); | 53 | int tgec_get_version(struct fman_mac *tgec, u32 *mac_version); |
54 | int tgec_set_allmulti(struct fman_mac *tgec, bool enable); | ||
54 | 55 | ||
55 | #endif /* __TGEC_H */ | 56 | #endif /* __TGEC_H */ |
diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c index 88c0a0636b44..4829dcd9e077 100644 --- a/drivers/net/ethernet/freescale/fman/mac.c +++ b/drivers/net/ethernet/freescale/fman/mac.c | |||
@@ -470,6 +470,7 @@ static void setup_dtsec(struct mac_device *mac_dev) | |||
470 | mac_dev->set_tx_pause = dtsec_set_tx_pause_frames; | 470 | mac_dev->set_tx_pause = dtsec_set_tx_pause_frames; |
471 | mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames; | 471 | mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames; |
472 | mac_dev->set_exception = dtsec_set_exception; | 472 | mac_dev->set_exception = dtsec_set_exception; |
473 | mac_dev->set_allmulti = dtsec_set_allmulti; | ||
473 | mac_dev->set_multi = set_multi; | 474 | mac_dev->set_multi = set_multi; |
474 | mac_dev->start = start; | 475 | mac_dev->start = start; |
475 | mac_dev->stop = stop; | 476 | mac_dev->stop = stop; |
@@ -488,6 +489,7 @@ static void setup_tgec(struct mac_device *mac_dev) | |||
488 | mac_dev->set_tx_pause = tgec_set_tx_pause_frames; | 489 | mac_dev->set_tx_pause = tgec_set_tx_pause_frames; |
489 | mac_dev->set_rx_pause = tgec_accept_rx_pause_frames; | 490 | mac_dev->set_rx_pause = tgec_accept_rx_pause_frames; |
490 | mac_dev->set_exception = tgec_set_exception; | 491 | mac_dev->set_exception = tgec_set_exception; |
492 | mac_dev->set_allmulti = tgec_set_allmulti; | ||
491 | mac_dev->set_multi = set_multi; | 493 | mac_dev->set_multi = set_multi; |
492 | mac_dev->start = start; | 494 | mac_dev->start = start; |
493 | mac_dev->stop = stop; | 495 | mac_dev->stop = stop; |
@@ -506,6 +508,7 @@ static void setup_memac(struct mac_device *mac_dev) | |||
506 | mac_dev->set_tx_pause = memac_set_tx_pause_frames; | 508 | mac_dev->set_tx_pause = memac_set_tx_pause_frames; |
507 | mac_dev->set_rx_pause = memac_accept_rx_pause_frames; | 509 | mac_dev->set_rx_pause = memac_accept_rx_pause_frames; |
508 | mac_dev->set_exception = memac_set_exception; | 510 | mac_dev->set_exception = memac_set_exception; |
511 | mac_dev->set_allmulti = memac_set_allmulti; | ||
509 | mac_dev->set_multi = set_multi; | 512 | mac_dev->set_multi = set_multi; |
510 | mac_dev->start = start; | 513 | mac_dev->start = start; |
511 | mac_dev->stop = stop; | 514 | mac_dev->stop = stop; |
diff --git a/drivers/net/ethernet/freescale/fman/mac.h b/drivers/net/ethernet/freescale/fman/mac.h index eefb3357e304..b520cec120ee 100644 --- a/drivers/net/ethernet/freescale/fman/mac.h +++ b/drivers/net/ethernet/freescale/fman/mac.h | |||
@@ -59,6 +59,7 @@ struct mac_device { | |||
59 | bool rx_pause_active; | 59 | bool rx_pause_active; |
60 | bool tx_pause_active; | 60 | bool tx_pause_active; |
61 | bool promisc; | 61 | bool promisc; |
62 | bool allmulti; | ||
62 | 63 | ||
63 | int (*init)(struct mac_device *mac_dev); | 64 | int (*init)(struct mac_device *mac_dev); |
64 | int (*start)(struct mac_device *mac_dev); | 65 | int (*start)(struct mac_device *mac_dev); |
@@ -66,6 +67,7 @@ struct mac_device { | |||
66 | void (*adjust_link)(struct mac_device *mac_dev); | 67 | void (*adjust_link)(struct mac_device *mac_dev); |
67 | int (*set_promisc)(struct fman_mac *mac_dev, bool enable); | 68 | int (*set_promisc)(struct fman_mac *mac_dev, bool enable); |
68 | int (*change_addr)(struct fman_mac *mac_dev, enet_addr_t *enet_addr); | 69 | int (*change_addr)(struct fman_mac *mac_dev, enet_addr_t *enet_addr); |
70 | int (*set_allmulti)(struct fman_mac *mac_dev, bool enable); | ||
69 | int (*set_multi)(struct net_device *net_dev, | 71 | int (*set_multi)(struct net_device *net_dev, |
70 | struct mac_device *mac_dev); | 72 | struct mac_device *mac_dev); |
71 | int (*set_rx_pause)(struct fman_mac *mac_dev, bool en); | 73 | int (*set_rx_pause)(struct fman_mac *mac_dev, bool en); |