diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index 0b5db52149bc..bcc902f44318 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -490,6 +490,8 @@ static int stmmac_test_hfilt(struct stmmac_priv *priv)
unsigned char gd_addr[ETH_ALEN] = {0x01, 0xee, 0xdd, 0xcc, 0xbb, 0xaa};
unsigned char bd_addr[ETH_ALEN] = {0x01, 0x01, 0x02, 0x03, 0x04, 0x05};
struct stmmac_packet_attrs attr = { };
+ struct net_device *dummy_dev;
+ struct netdev_hw_addr *ha;
int ret;
ret = stmmac_filter_check(priv);@@ -499,9 +501,18 @@ static int stmmac_test_hfilt(struct stmmac_priv *priv)
if (netdev_mc_count(priv->dev) >= priv->hw->multicast_filter_bins)
return -EOPNOTSUPP;
+ dummy_dev = alloc_etherdev(0);
+ if (!dummy_dev)
+ return -ENOMEM;
+
+ /* Remove all MC addresses */
+ netdev_for_each_mc_addr(ha, priv->dev)
+ dev_mc_add(dummy_dev, ha->addr);
+ dev_mc_flush(priv->dev);
+
ret = dev_mc_add(priv->dev, gd_addr);
if (ret)
- return ret;
+ goto sync;
attr.dst = gd_addr;
@@ -518,6 +529,11 @@ static int stmmac_test_hfilt(struct stmmac_priv *priv)
cleanup:
dev_mc_del(priv->dev, gd_addr);
+sync:
+ /* Restore MC addresses */
+ netdev_for_each_mc_addr(ha, dummy_dev)
+ dev_mc_add(priv->dev, ha->addr);
+ free_netdev(dummy_dev);
return ret;
}
@@ -526,14 +542,25 @@ static int stmmac_test_pfilt(struct stmmac_priv *priv)
unsigned char gd_addr[ETH_ALEN] = {0x00, 0x01, 0x44, 0x55, 0x66, 0x77};
unsigned char bd_addr[ETH_ALEN] = {0x08, 0x00, 0x22, 0x33, 0x44, 0x55};
struct stmmac_packet_attrs attr = { };
+ struct net_device *dummy_dev;
+ struct netdev_hw_addr *ha;
int ret;
if (stmmac_filter_check(priv))
return -EOPNOTSUPP;
+ dummy_dev = alloc_etherdev(0);
+ if (!dummy_dev)
+ return -ENOMEM;
+
+ /* Remove all UC addresses */
+ netdev_for_each_uc_addr(ha, priv->dev)
+ dev_uc_add(dummy_dev, ha->addr);
+ dev_uc_flush(priv->dev);
+
ret = dev_uc_add(priv->dev, gd_addr);
if (ret)
- return ret;
+ goto sync;
attr.dst = gd_addr;
@@ -550,28 +577,21 @@ static int stmmac_test_pfilt(struct stmmac_priv *priv)
cleanup:
dev_uc_del(priv->dev, gd_addr);
+sync:
+ /* Restore UC addresses */
+ netdev_for_each_uc_addr(ha, dummy_dev)
+ dev_uc_add(priv->dev, ha->addr);
+ free_netdev(dummy_dev);
return ret;
}
-static int stmmac_dummy_sync(struct net_device *netdev, const u8 *addr)
-{
- return 0;
-}
-
-static void stmmac_test_set_rx_mode(struct net_device *netdev)
-{
- /* As we are in test mode of ethtool we already own the rtnl lock
- * so no address will change from user. We can just call the
- * ndo_set_rx_mode() callback directly */
- if (netdev->netdev_ops->ndo_set_rx_mode)
- netdev->netdev_ops->ndo_set_rx_mode(netdev);
-}
-
static int stmmac_test_mcfilt(struct stmmac_priv *priv)
{
unsigned char uc_addr[ETH_ALEN] = {0x00, 0x01, 0x44, 0x55, 0x66, 0x77};
unsigned char mc_addr[ETH_ALEN] = {0x01, 0x01, 0x44, 0x55, 0x66, 0x77};
struct stmmac_packet_attrs attr = { };
+ struct net_device *dummy_dev;
+ struct netdev_hw_addr *ha;
int ret;
if (stmmac_filter_check(priv))@@ -579,13 +599,21 @@ static int stmmac_test_mcfilt(struct stmmac_priv *priv)
if (!priv->hw->multicast_filter_bins)
return -EOPNOTSUPP;
- /* Remove all MC addresses */
- __dev_mc_unsync(priv->dev, NULL);
- stmmac_test_set_rx_mode(priv->dev);
+ dummy_dev = alloc_etherdev(0);
+ if (!dummy_dev)
+ return -ENOMEM;
+
+ /* Remove all UC and MC addresses */
+ netdev_for_each_uc_addr(ha, priv->dev)
+ dev_uc_add(dummy_dev, ha->addr);
+ netdev_for_each_mc_addr(ha, priv->dev)
+ dev_mc_add(dummy_dev, ha->addr);
+ dev_uc_flush(priv->dev);
+ dev_mc_flush(priv->dev);
ret = dev_uc_add(priv->dev, uc_addr);
if (ret)
- goto cleanup;
+ goto sync;
attr.dst = uc_addr;
@@ -602,8 +630,13 @@ static int stmmac_test_mcfilt(struct stmmac_priv *priv)
cleanup:
dev_uc_del(priv->dev, uc_addr);
- __dev_mc_sync(priv->dev, stmmac_dummy_sync, NULL);
- stmmac_test_set_rx_mode(priv->dev);
+sync:
+ /* Restore UC and MC addresses */
+ netdev_for_each_uc_addr(ha, dummy_dev)
+ dev_uc_add(priv->dev, ha->addr);
+ netdev_for_each_mc_addr(ha, dummy_dev)
+ dev_mc_add(priv->dev, ha->addr);
+ free_netdev(dummy_dev);
return ret;
}
@@ -612,6 +645,8 @@ static int stmmac_test_ucfilt(struct stmmac_priv *priv)
unsigned char uc_addr[ETH_ALEN] = {0x00, 0x01, 0x44, 0x55, 0x66, 0x77};
unsigned char mc_addr[ETH_ALEN] = {0x01, 0x01, 0x44, 0x55, 0x66, 0x77};
struct stmmac_packet_attrs attr = { };
+ struct net_device *dummy_dev;
+ struct netdev_hw_addr *ha;
int ret;
if (stmmac_filter_check(priv))@@ -619,13 +654,21 @@ static int stmmac_test_ucfilt(struct stmmac_priv *priv)
if (!priv->hw->multicast_filter_bins)
return -EOPNOTSUPP;
- /* Remove all UC addresses */
- __dev_uc_unsync(priv->dev, NULL);
- stmmac_test_set_rx_mode(priv->dev);
+ dummy_dev = alloc_etherdev(0);
+ if (!dummy_dev)
+ return -ENOMEM;
+
+ /* Remove all UC and MC addresses */
+ netdev_for_each_uc_addr(ha, priv->dev)
+ dev_uc_add(dummy_dev, ha->addr);
+ netdev_for_each_mc_addr(ha, priv->dev)
+ dev_mc_add(dummy_dev, ha->addr);
+ dev_uc_flush(priv->dev);
+ dev_mc_flush(priv->dev);
ret = dev_mc_add(priv->dev, mc_addr);
if (ret)
- goto cleanup;
+ goto sync;
attr.dst = mc_addr;
@@ -642,8 +685,13 @@ static int stmmac_test_ucfilt(struct stmmac_priv *priv)
cleanup:
dev_mc_del(priv->dev, mc_addr);
- __dev_uc_sync(priv->dev, stmmac_dummy_sync, NULL);
- stmmac_test_set_rx_mode(priv->dev);
+sync:
+ /* Restore UC and MC addresses */
+ netdev_for_each_uc_addr(ha, dummy_dev)
+ dev_uc_add(priv->dev, ha->addr);
+ netdev_for_each_mc_addr(ha, dummy_dev)
+ dev_mc_add(priv->dev, ha->addr);
+ free_netdev(dummy_dev);
return ret;
}
--
2.7.4