mirror of https://gitee.com/openkylin/linux.git
staging: dpaa2-switch: move the notifier register to module_init()
Move the notifier blocks register into the module_init() step, instead of object probe, so that all DPSW devices probed by the dpaa2-switch driver can use the same notifiers. This will enable us to have a more straightforward approach in determining if an event is intended for an object managed by this driver or not. Previously, the dpaa2_switch_port_dev_check() function was forced to also check the notifier block beside the net_device_ops structure to determine if the event is for us or not. Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
539dda3c5d
commit
16abb6ad6a
|
@ -80,7 +80,7 @@ static u16 dpaa2_switch_port_set_fdb(struct ethsw_port_priv *port_priv,
|
||||||
* to be present in that bridge
|
* to be present in that bridge
|
||||||
*/
|
*/
|
||||||
netdev_for_each_lower_dev(bridge_dev, other_dev, iter) {
|
netdev_for_each_lower_dev(bridge_dev, other_dev, iter) {
|
||||||
if (!dpaa2_switch_port_dev_check(other_dev, NULL))
|
if (!dpaa2_switch_port_dev_check(other_dev))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (other_dev == port_priv->netdev)
|
if (other_dev == port_priv->netdev)
|
||||||
|
@ -987,18 +987,9 @@ static const struct net_device_ops dpaa2_switch_port_ops = {
|
||||||
.ndo_get_phys_port_name = dpaa2_switch_port_get_phys_name,
|
.ndo_get_phys_port_name = dpaa2_switch_port_get_phys_name,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool dpaa2_switch_port_dev_check(const struct net_device *netdev,
|
bool dpaa2_switch_port_dev_check(const struct net_device *netdev)
|
||||||
struct notifier_block *nb)
|
|
||||||
{
|
{
|
||||||
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
|
return netdev->netdev_ops == &dpaa2_switch_port_ops;
|
||||||
|
|
||||||
if (netdev->netdev_ops == &dpaa2_switch_port_ops &&
|
|
||||||
(!nb || &port_priv->ethsw_data->port_nb == nb ||
|
|
||||||
&port_priv->ethsw_data->port_switchdev_nb == nb ||
|
|
||||||
&port_priv->ethsw_data->port_switchdevb_nb == nb))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dpaa2_switch_links_state_update(struct ethsw_core *ethsw)
|
static void dpaa2_switch_links_state_update(struct ethsw_core *ethsw)
|
||||||
|
@ -1429,7 +1420,7 @@ static int dpaa2_switch_port_bridge_join(struct net_device *netdev,
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
netdev_for_each_lower_dev(upper_dev, other_dev, iter) {
|
netdev_for_each_lower_dev(upper_dev, other_dev, iter) {
|
||||||
if (!dpaa2_switch_port_dev_check(other_dev, NULL))
|
if (!dpaa2_switch_port_dev_check(other_dev))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
other_port_priv = netdev_priv(other_dev);
|
other_port_priv = netdev_priv(other_dev);
|
||||||
|
@ -1529,7 +1520,7 @@ static int dpaa2_switch_port_netdevice_event(struct notifier_block *nb,
|
||||||
struct net_device *upper_dev;
|
struct net_device *upper_dev;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (!dpaa2_switch_port_dev_check(netdev, nb))
|
if (!dpaa2_switch_port_dev_check(netdev))
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
/* Handle just upper dev link/unlink for the moment */
|
/* Handle just upper dev link/unlink for the moment */
|
||||||
|
@ -1606,7 +1597,7 @@ static int dpaa2_switch_port_event(struct notifier_block *nb,
|
||||||
struct switchdev_notifier_fdb_info *fdb_info = ptr;
|
struct switchdev_notifier_fdb_info *fdb_info = ptr;
|
||||||
struct ethsw_core *ethsw = port_priv->ethsw_data;
|
struct ethsw_core *ethsw = port_priv->ethsw_data;
|
||||||
|
|
||||||
if (!dpaa2_switch_port_dev_check(dev, nb))
|
if (!dpaa2_switch_port_dev_check(dev))
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
if (event == SWITCHDEV_PORT_ATTR_SET)
|
if (event == SWITCHDEV_PORT_ATTR_SET)
|
||||||
|
@ -1673,7 +1664,7 @@ static int dpaa2_switch_port_blocking_event(struct notifier_block *nb,
|
||||||
{
|
{
|
||||||
struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
|
struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
|
||||||
|
|
||||||
if (!dpaa2_switch_port_dev_check(dev, nb))
|
if (!dpaa2_switch_port_dev_check(dev))
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -1687,41 +1678,6 @@ static int dpaa2_switch_port_blocking_event(struct notifier_block *nb,
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dpaa2_switch_register_notifier(struct device *dev)
|
|
||||||
{
|
|
||||||
struct ethsw_core *ethsw = dev_get_drvdata(dev);
|
|
||||||
int err;
|
|
||||||
|
|
||||||
ethsw->port_nb.notifier_call = dpaa2_switch_port_netdevice_event;
|
|
||||||
err = register_netdevice_notifier(ðsw->port_nb);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "Failed to register netdev notifier\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ethsw->port_switchdev_nb.notifier_call = dpaa2_switch_port_event;
|
|
||||||
err = register_switchdev_notifier(ðsw->port_switchdev_nb);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "Failed to register switchdev notifier\n");
|
|
||||||
goto err_switchdev_nb;
|
|
||||||
}
|
|
||||||
|
|
||||||
ethsw->port_switchdevb_nb.notifier_call = dpaa2_switch_port_blocking_event;
|
|
||||||
err = register_switchdev_blocking_notifier(ðsw->port_switchdevb_nb);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "Failed to register switchdev blocking notifier\n");
|
|
||||||
goto err_switchdev_blocking_nb;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_switchdev_blocking_nb:
|
|
||||||
unregister_switchdev_notifier(ðsw->port_switchdev_nb);
|
|
||||||
err_switchdev_nb:
|
|
||||||
unregister_netdevice_notifier(ðsw->port_nb);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build a linear skb based on a single-buffer frame descriptor */
|
/* Build a linear skb based on a single-buffer frame descriptor */
|
||||||
static struct sk_buff *dpaa2_switch_build_linear_skb(struct ethsw_core *ethsw,
|
static struct sk_buff *dpaa2_switch_build_linear_skb(struct ethsw_core *ethsw,
|
||||||
const struct dpaa2_fd *fd)
|
const struct dpaa2_fd *fd)
|
||||||
|
@ -2426,10 +2382,6 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev)
|
||||||
if (err)
|
if (err)
|
||||||
goto err_destroy_ordered_workqueue;
|
goto err_destroy_ordered_workqueue;
|
||||||
|
|
||||||
err = dpaa2_switch_register_notifier(dev);
|
|
||||||
if (err)
|
|
||||||
goto err_destroy_ordered_workqueue;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_destroy_ordered_workqueue:
|
err_destroy_ordered_workqueue:
|
||||||
|
@ -2496,38 +2448,12 @@ static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dpaa2_switch_unregister_notifier(struct device *dev)
|
|
||||||
{
|
|
||||||
struct ethsw_core *ethsw = dev_get_drvdata(dev);
|
|
||||||
struct notifier_block *nb;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
nb = ðsw->port_switchdevb_nb;
|
|
||||||
err = unregister_switchdev_blocking_notifier(nb);
|
|
||||||
if (err)
|
|
||||||
dev_err(dev,
|
|
||||||
"Failed to unregister switchdev blocking notifier (%d)\n",
|
|
||||||
err);
|
|
||||||
|
|
||||||
err = unregister_switchdev_notifier(ðsw->port_switchdev_nb);
|
|
||||||
if (err)
|
|
||||||
dev_err(dev,
|
|
||||||
"Failed to unregister switchdev notifier (%d)\n", err);
|
|
||||||
|
|
||||||
err = unregister_netdevice_notifier(ðsw->port_nb);
|
|
||||||
if (err)
|
|
||||||
dev_err(dev,
|
|
||||||
"Failed to unregister netdev notifier (%d)\n", err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dpaa2_switch_takedown(struct fsl_mc_device *sw_dev)
|
static void dpaa2_switch_takedown(struct fsl_mc_device *sw_dev)
|
||||||
{
|
{
|
||||||
struct device *dev = &sw_dev->dev;
|
struct device *dev = &sw_dev->dev;
|
||||||
struct ethsw_core *ethsw = dev_get_drvdata(dev);
|
struct ethsw_core *ethsw = dev_get_drvdata(dev);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
dpaa2_switch_unregister_notifier(dev);
|
|
||||||
|
|
||||||
err = dpsw_close(ethsw->mc_io, 0, ethsw->dpsw_handle);
|
err = dpsw_close(ethsw->mc_io, 0, ethsw->dpsw_handle);
|
||||||
if (err)
|
if (err)
|
||||||
dev_warn(dev, "dpsw_close err %d\n", err);
|
dev_warn(dev, "dpsw_close err %d\n", err);
|
||||||
|
@ -2761,7 +2687,93 @@ static struct fsl_mc_driver dpaa2_switch_drv = {
|
||||||
.match_id_table = dpaa2_switch_match_id_table
|
.match_id_table = dpaa2_switch_match_id_table
|
||||||
};
|
};
|
||||||
|
|
||||||
module_fsl_mc_driver(dpaa2_switch_drv);
|
static struct notifier_block dpaa2_switch_port_nb __read_mostly = {
|
||||||
|
.notifier_call = dpaa2_switch_port_netdevice_event,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct notifier_block dpaa2_switch_port_switchdev_nb = {
|
||||||
|
.notifier_call = dpaa2_switch_port_event,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct notifier_block dpaa2_switch_port_switchdev_blocking_nb = {
|
||||||
|
.notifier_call = dpaa2_switch_port_blocking_event,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int dpaa2_switch_register_notifiers(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = register_netdevice_notifier(&dpaa2_switch_port_nb);
|
||||||
|
if (err) {
|
||||||
|
pr_err("dpaa2-switch: failed to register net_device notifier (%d)\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = register_switchdev_notifier(&dpaa2_switch_port_switchdev_nb);
|
||||||
|
if (err) {
|
||||||
|
pr_err("dpaa2-switch: failed to register switchdev notifier (%d)\n", err);
|
||||||
|
goto err_switchdev_nb;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = register_switchdev_blocking_notifier(&dpaa2_switch_port_switchdev_blocking_nb);
|
||||||
|
if (err) {
|
||||||
|
pr_err("dpaa2-switch: failed to register switchdev blocking notifier (%d)\n", err);
|
||||||
|
goto err_switchdev_blocking_nb;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_switchdev_blocking_nb:
|
||||||
|
unregister_switchdev_notifier(&dpaa2_switch_port_switchdev_nb);
|
||||||
|
err_switchdev_nb:
|
||||||
|
unregister_netdevice_notifier(&dpaa2_switch_port_nb);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dpaa2_switch_unregister_notifiers(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = unregister_switchdev_blocking_notifier(&dpaa2_switch_port_switchdev_blocking_nb);
|
||||||
|
if (err)
|
||||||
|
pr_err("dpaa2-switch: failed to unregister switchdev blocking notifier (%d)\n",
|
||||||
|
err);
|
||||||
|
|
||||||
|
err = unregister_switchdev_notifier(&dpaa2_switch_port_switchdev_nb);
|
||||||
|
if (err)
|
||||||
|
pr_err("dpaa2-switch: failed to unregister switchdev notifier (%d)\n", err);
|
||||||
|
|
||||||
|
err = unregister_netdevice_notifier(&dpaa2_switch_port_nb);
|
||||||
|
if (err)
|
||||||
|
pr_err("dpaa2-switch: failed to unregister net_device notifier (%d)\n", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init dpaa2_switch_driver_init(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = fsl_mc_driver_register(&dpaa2_switch_drv);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = dpaa2_switch_register_notifiers();
|
||||||
|
if (err) {
|
||||||
|
fsl_mc_driver_unregister(&dpaa2_switch_drv);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit dpaa2_switch_driver_exit(void)
|
||||||
|
{
|
||||||
|
dpaa2_switch_unregister_notifiers();
|
||||||
|
fsl_mc_driver_unregister(&dpaa2_switch_drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(dpaa2_switch_driver_init);
|
||||||
|
module_exit(dpaa2_switch_driver_exit);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
MODULE_DESCRIPTION("DPAA2 Ethernet Switch Driver");
|
MODULE_DESCRIPTION("DPAA2 Ethernet Switch Driver");
|
||||||
|
|
|
@ -128,9 +128,6 @@ struct ethsw_core {
|
||||||
|
|
||||||
u8 vlans[VLAN_VID_MASK + 1];
|
u8 vlans[VLAN_VID_MASK + 1];
|
||||||
|
|
||||||
struct notifier_block port_nb;
|
|
||||||
struct notifier_block port_switchdev_nb;
|
|
||||||
struct notifier_block port_switchdevb_nb;
|
|
||||||
struct workqueue_struct *workqueue;
|
struct workqueue_struct *workqueue;
|
||||||
|
|
||||||
struct dpaa2_switch_fq fq[DPAA2_SWITCH_RX_NUM_FQS];
|
struct dpaa2_switch_fq fq[DPAA2_SWITCH_RX_NUM_FQS];
|
||||||
|
@ -167,7 +164,6 @@ static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dpaa2_switch_port_dev_check(const struct net_device *netdev,
|
bool dpaa2_switch_port_dev_check(const struct net_device *netdev);
|
||||||
struct notifier_block *nb);
|
|
||||||
|
|
||||||
#endif /* __ETHSW_H */
|
#endif /* __ETHSW_H */
|
||||||
|
|
Loading…
Reference in New Issue