|
@@ -120,6 +120,7 @@
|
|
|
#include <linux/netdevice.h>
|
|
|
#include <linux/etherdevice.h>
|
|
|
#include <linux/io.h>
|
|
|
+#include <linux/notifier.h>
|
|
|
|
|
|
#include "xgbe.h"
|
|
|
#include "xgbe-common.h"
|
|
@@ -399,35 +400,6 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
- /* Create the PHY/ANEG name based on netdev name */
|
|
|
- snprintf(pdata->an_name, sizeof(pdata->an_name) - 1, "%s-pcs",
|
|
|
- netdev_name(netdev));
|
|
|
-
|
|
|
- /* Create the ECC name based on netdev name */
|
|
|
- snprintf(pdata->ecc_name, sizeof(pdata->ecc_name) - 1, "%s-ecc",
|
|
|
- netdev_name(netdev));
|
|
|
-
|
|
|
- /* Create the I2C name based on netdev name */
|
|
|
- snprintf(pdata->i2c_name, sizeof(pdata->i2c_name) - 1, "%s-i2c",
|
|
|
- netdev_name(netdev));
|
|
|
-
|
|
|
- /* Create workqueues */
|
|
|
- pdata->dev_workqueue =
|
|
|
- create_singlethread_workqueue(netdev_name(netdev));
|
|
|
- if (!pdata->dev_workqueue) {
|
|
|
- netdev_err(netdev, "device workqueue creation failed\n");
|
|
|
- ret = -ENOMEM;
|
|
|
- goto err_netdev;
|
|
|
- }
|
|
|
-
|
|
|
- pdata->an_workqueue =
|
|
|
- create_singlethread_workqueue(pdata->an_name);
|
|
|
- if (!pdata->an_workqueue) {
|
|
|
- netdev_err(netdev, "phy workqueue creation failed\n");
|
|
|
- ret = -ENOMEM;
|
|
|
- goto err_wq;
|
|
|
- }
|
|
|
-
|
|
|
if (IS_REACHABLE(CONFIG_PTP_1588_CLOCK))
|
|
|
xgbe_ptp_register(pdata);
|
|
|
|
|
@@ -439,14 +411,6 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata)
|
|
|
pdata->rx_ring_count);
|
|
|
|
|
|
return 0;
|
|
|
-
|
|
|
-err_wq:
|
|
|
- destroy_workqueue(pdata->dev_workqueue);
|
|
|
-
|
|
|
-err_netdev:
|
|
|
- unregister_netdev(netdev);
|
|
|
-
|
|
|
- return ret;
|
|
|
}
|
|
|
|
|
|
void xgbe_deconfig_netdev(struct xgbe_prv_data *pdata)
|
|
@@ -461,18 +425,42 @@ void xgbe_deconfig_netdev(struct xgbe_prv_data *pdata)
|
|
|
unregister_netdev(netdev);
|
|
|
|
|
|
pdata->phy_if.phy_exit(pdata);
|
|
|
+}
|
|
|
|
|
|
- flush_workqueue(pdata->an_workqueue);
|
|
|
- destroy_workqueue(pdata->an_workqueue);
|
|
|
+static int xgbe_netdev_event(struct notifier_block *nb, unsigned long event,
|
|
|
+ void *data)
|
|
|
+{
|
|
|
+ struct net_device *netdev = netdev_notifier_info_to_dev(data);
|
|
|
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
|
|
|
|
|
|
- flush_workqueue(pdata->dev_workqueue);
|
|
|
- destroy_workqueue(pdata->dev_workqueue);
|
|
|
+ if (netdev->netdev_ops != xgbe_get_netdev_ops())
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case NETDEV_CHANGENAME:
|
|
|
+ xgbe_debugfs_rename(pdata);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+out:
|
|
|
+ return NOTIFY_DONE;
|
|
|
}
|
|
|
|
|
|
+static struct notifier_block xgbe_netdev_notifier = {
|
|
|
+ .notifier_call = xgbe_netdev_event,
|
|
|
+};
|
|
|
+
|
|
|
static int __init xgbe_mod_init(void)
|
|
|
{
|
|
|
int ret;
|
|
|
|
|
|
+ ret = register_netdevice_notifier(&xgbe_netdev_notifier);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
ret = xgbe_platform_init();
|
|
|
if (ret)
|
|
|
return ret;
|
|
@@ -489,6 +477,8 @@ static void __exit xgbe_mod_exit(void)
|
|
|
xgbe_pci_exit();
|
|
|
|
|
|
xgbe_platform_exit();
|
|
|
+
|
|
|
+ unregister_netdevice_notifier(&xgbe_netdev_notifier);
|
|
|
}
|
|
|
|
|
|
module_init(xgbe_mod_init);
|