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>
This commit is contained in:
parent
056a01ba94
commit
c893238e5d
|
@ -454,6 +454,16 @@ static void dpaa_set_rx_mode(struct net_device *net_dev)
|
|||
err);
|
||||
}
|
||||
|
||||
if (!!(net_dev->flags & IFF_ALLMULTI) != priv->mac_dev->allmulti) {
|
||||
priv->mac_dev->allmulti = !priv->mac_dev->allmulti;
|
||||
err = priv->mac_dev->set_allmulti(priv->mac_dev->fman_mac,
|
||||
priv->mac_dev->allmulti);
|
||||
if (err < 0)
|
||||
netif_err(priv, drv, net_dev,
|
||||
"mac_dev->set_allmulti() = %d\n",
|
||||
err);
|
||||
}
|
||||
|
||||
err = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
|
||||
if (err < 0)
|
||||
netif_err(priv, drv, net_dev, "mac_dev->set_multi() = %d\n",
|
||||
|
|
|
@ -1117,6 +1117,25 @@ int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
|
||||
{
|
||||
u32 tmp;
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
|
||||
if (!is_init_done(dtsec->dtsec_drv_param))
|
||||
return -EINVAL;
|
||||
|
||||
tmp = ioread32be(®s->rctrl);
|
||||
if (enable)
|
||||
tmp |= RCTRL_MPROM;
|
||||
else
|
||||
tmp &= ~RCTRL_MPROM;
|
||||
|
||||
iowrite32be(tmp, ®s->rctrl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
|
|
|
@ -55,5 +55,6 @@ int dtsec_set_exception(struct fman_mac *dtsec,
|
|||
int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
|
||||
int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
|
||||
int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version);
|
||||
int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable);
|
||||
|
||||
#endif /* __DTSEC_H */
|
||||
|
|
|
@ -350,6 +350,7 @@ struct fman_mac {
|
|||
struct fman_rev_info fm_rev_info;
|
||||
bool basex_if;
|
||||
struct phy_device *pcsphy;
|
||||
bool allmulti_enabled;
|
||||
};
|
||||
|
||||
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)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int memac_set_allmulti(struct fman_mac *memac, bool enable)
|
||||
{
|
||||
u32 entry;
|
||||
struct memac_regs __iomem *regs = memac->regs;
|
||||
|
||||
if (!is_init_done(memac->memac_drv_param))
|
||||
return -EINVAL;
|
||||
|
||||
if (enable) {
|
||||
for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
|
||||
iowrite32be(entry | HASH_CTRL_MCAST_EN,
|
||||
®s->hashtable_ctrl);
|
||||
} else {
|
||||
for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
|
||||
iowrite32be(entry & ~HASH_CTRL_MCAST_EN,
|
||||
®s->hashtable_ctrl);
|
||||
}
|
||||
|
||||
memac->allmulti_enabled = enable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
|
||||
{
|
||||
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)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (list_empty(&memac->multicast_addr_hash->lsts[hash]))
|
||||
iowrite32be(hash & ~HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl);
|
||||
|
||||
if (!memac->allmulti_enabled) {
|
||||
if (list_empty(&memac->multicast_addr_hash->lsts[hash]))
|
||||
iowrite32be(hash & ~HASH_CTRL_MCAST_EN,
|
||||
®s->hashtable_ctrl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -57,5 +57,6 @@ int memac_set_exception(struct fman_mac *memac,
|
|||
enum fman_mac_exceptions exception, bool enable);
|
||||
int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
|
||||
int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
|
||||
int memac_set_allmulti(struct fman_mac *memac, bool enable);
|
||||
|
||||
#endif /* __MEMAC_H */
|
||||
|
|
|
@ -217,6 +217,7 @@ struct fman_mac {
|
|||
struct tgec_cfg *cfg;
|
||||
void *fm;
|
||||
struct fman_rev_info fm_rev_info;
|
||||
bool allmulti_enabled;
|
||||
};
|
||||
|
||||
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)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tgec_set_allmulti(struct fman_mac *tgec, bool enable)
|
||||
{
|
||||
u32 entry;
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
|
||||
if (!is_init_done(tgec->cfg))
|
||||
return -EINVAL;
|
||||
|
||||
if (enable) {
|
||||
for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
|
||||
iowrite32be(entry | TGEC_HASH_MCAST_EN,
|
||||
®s->hashtable_ctrl);
|
||||
} else {
|
||||
for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
|
||||
iowrite32be(entry & ~TGEC_HASH_MCAST_EN,
|
||||
®s->hashtable_ctrl);
|
||||
}
|
||||
|
||||
tgec->allmulti_enabled = enable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
|
||||
{
|
||||
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)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (list_empty(&tgec->multicast_addr_hash->lsts[hash]))
|
||||
iowrite32be((hash & ~TGEC_HASH_MCAST_EN),
|
||||
®s->hashtable_ctrl);
|
||||
|
||||
if (!tgec->allmulti_enabled) {
|
||||
if (list_empty(&tgec->multicast_addr_hash->lsts[hash]))
|
||||
iowrite32be((hash & ~TGEC_HASH_MCAST_EN),
|
||||
®s->hashtable_ctrl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -51,5 +51,6 @@ int tgec_set_exception(struct fman_mac *tgec,
|
|||
int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
|
||||
int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
|
||||
int tgec_get_version(struct fman_mac *tgec, u32 *mac_version);
|
||||
int tgec_set_allmulti(struct fman_mac *tgec, bool enable);
|
||||
|
||||
#endif /* __TGEC_H */
|
||||
|
|
|
@ -470,6 +470,7 @@ static void setup_dtsec(struct mac_device *mac_dev)
|
|||
mac_dev->set_tx_pause = dtsec_set_tx_pause_frames;
|
||||
mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames;
|
||||
mac_dev->set_exception = dtsec_set_exception;
|
||||
mac_dev->set_allmulti = dtsec_set_allmulti;
|
||||
mac_dev->set_multi = set_multi;
|
||||
mac_dev->start = start;
|
||||
mac_dev->stop = stop;
|
||||
|
@ -488,6 +489,7 @@ static void setup_tgec(struct mac_device *mac_dev)
|
|||
mac_dev->set_tx_pause = tgec_set_tx_pause_frames;
|
||||
mac_dev->set_rx_pause = tgec_accept_rx_pause_frames;
|
||||
mac_dev->set_exception = tgec_set_exception;
|
||||
mac_dev->set_allmulti = tgec_set_allmulti;
|
||||
mac_dev->set_multi = set_multi;
|
||||
mac_dev->start = start;
|
||||
mac_dev->stop = stop;
|
||||
|
@ -506,6 +508,7 @@ static void setup_memac(struct mac_device *mac_dev)
|
|||
mac_dev->set_tx_pause = memac_set_tx_pause_frames;
|
||||
mac_dev->set_rx_pause = memac_accept_rx_pause_frames;
|
||||
mac_dev->set_exception = memac_set_exception;
|
||||
mac_dev->set_allmulti = memac_set_allmulti;
|
||||
mac_dev->set_multi = set_multi;
|
||||
mac_dev->start = start;
|
||||
mac_dev->stop = stop;
|
||||
|
|
|
@ -59,6 +59,7 @@ struct mac_device {
|
|||
bool rx_pause_active;
|
||||
bool tx_pause_active;
|
||||
bool promisc;
|
||||
bool allmulti;
|
||||
|
||||
int (*init)(struct mac_device *mac_dev);
|
||||
int (*start)(struct mac_device *mac_dev);
|
||||
|
@ -66,6 +67,7 @@ struct mac_device {
|
|||
void (*adjust_link)(struct mac_device *mac_dev);
|
||||
int (*set_promisc)(struct fman_mac *mac_dev, bool enable);
|
||||
int (*change_addr)(struct fman_mac *mac_dev, enet_addr_t *enet_addr);
|
||||
int (*set_allmulti)(struct fman_mac *mac_dev, bool enable);
|
||||
int (*set_multi)(struct net_device *net_dev,
|
||||
struct mac_device *mac_dev);
|
||||
int (*set_rx_pause)(struct fman_mac *mac_dev, bool en);
|
||||
|
|
Loading…
Reference in New Issue