Commit 60724d4bae14cd295b27b1610cad9a2720eb0860

Authored by Florian Fainelli
Committed by David S. Miller
1 parent 3f7832c26c

net: dsa: Add support for DSA specific notifiers

In preparation for communicating a given DSA network device's port
number and switch index, create a specialized DSA notifier and two
events: DSA_PORT_REGISTER and DSA_PORT_UNREGISTER that communicate: the
slave network device (slave_dev), port number and switch number in the
tree.

This will be later used for network device drivers like bcmsysport which
needs to cooperate with its DSA network devices to set-up queue mapping
and scheduling.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 3 changed files with 81 additions and 0 deletions Side-by-side Diff

... ... @@ -471,5 +471,50 @@
471 471 }
472 472 #endif /* CONFIG_PM_SLEEP */
473 473  
  474 +enum dsa_notifier_type {
  475 + DSA_PORT_REGISTER,
  476 + DSA_PORT_UNREGISTER,
  477 +};
  478 +
  479 +struct dsa_notifier_info {
  480 + struct net_device *dev;
  481 +};
  482 +
  483 +struct dsa_notifier_register_info {
  484 + struct dsa_notifier_info info; /* must be first */
  485 + struct net_device *master;
  486 + unsigned int port_number;
  487 + unsigned int switch_number;
  488 +};
  489 +
  490 +static inline struct net_device *
  491 +dsa_notifier_info_to_dev(const struct dsa_notifier_info *info)
  492 +{
  493 + return info->dev;
  494 +}
  495 +
  496 +#if IS_ENABLED(CONFIG_NET_DSA)
  497 +int register_dsa_notifier(struct notifier_block *nb);
  498 +int unregister_dsa_notifier(struct notifier_block *nb);
  499 +int call_dsa_notifiers(unsigned long val, struct net_device *dev,
  500 + struct dsa_notifier_info *info);
  501 +#else
  502 +static inline int register_dsa_notifier(struct notifier_block *nb)
  503 +{
  504 + return 0;
  505 +}
  506 +
  507 +static inline int unregister_dsa_notifier(struct notifier_block *nb)
  508 +{
  509 + return 0;
  510 +}
  511 +
  512 +static inline int call_dsa_notifiers(unsigned long val, struct net_device *dev,
  513 + struct dsa_notifier_info *info)
  514 +{
  515 + return NOTIFY_DONE;
  516 +}
  517 +#endif
  518 +
474 519 #endif
... ... @@ -14,6 +14,7 @@
14 14 #include <linux/platform_device.h>
15 15 #include <linux/slab.h>
16 16 #include <linux/module.h>
  17 +#include <linux/notifier.h>
17 18 #include <linux/of.h>
18 19 #include <linux/of_mdio.h>
19 20 #include <linux/of_platform.h>
... ... @@ -260,6 +261,28 @@
260 261 {
261 262 return queue_work(dsa_owq, work);
262 263 }
  264 +
  265 +static ATOMIC_NOTIFIER_HEAD(dsa_notif_chain);
  266 +
  267 +int register_dsa_notifier(struct notifier_block *nb)
  268 +{
  269 + return atomic_notifier_chain_register(&dsa_notif_chain, nb);
  270 +}
  271 +EXPORT_SYMBOL_GPL(register_dsa_notifier);
  272 +
  273 +int unregister_dsa_notifier(struct notifier_block *nb)
  274 +{
  275 + return atomic_notifier_chain_unregister(&dsa_notif_chain, nb);
  276 +}
  277 +EXPORT_SYMBOL_GPL(unregister_dsa_notifier);
  278 +
  279 +int call_dsa_notifiers(unsigned long val, struct net_device *dev,
  280 + struct dsa_notifier_info *info)
  281 +{
  282 + info->dev = dev;
  283 + return atomic_notifier_call_chain(&dsa_notif_chain, val, info);
  284 +}
  285 +EXPORT_SYMBOL_GPL(call_dsa_notifiers);
263 286  
264 287 static int __init dsa_init_module(void)
265 288 {
... ... @@ -1116,6 +1116,7 @@
1116 1116  
1117 1117 int dsa_slave_create(struct dsa_port *port, const char *name)
1118 1118 {
  1119 + struct dsa_notifier_register_info rinfo = { };
1119 1120 struct dsa_switch *ds = port->ds;
1120 1121 struct net_device *master;
1121 1122 struct net_device *slave_dev;
... ... @@ -1177,6 +1178,12 @@
1177 1178 goto out_free;
1178 1179 }
1179 1180  
  1181 + rinfo.info.dev = slave_dev;
  1182 + rinfo.master = master;
  1183 + rinfo.port_number = p->dp->index;
  1184 + rinfo.switch_number = p->dp->ds->index;
  1185 + call_dsa_notifiers(DSA_PORT_REGISTER, slave_dev, &rinfo.info);
  1186 +
1180 1187 ret = register_netdev(slave_dev);
1181 1188 if (ret) {
1182 1189 netdev_err(master, "error %d registering interface %s\n",
... ... @@ -1200,6 +1207,7 @@
1200 1207 void dsa_slave_destroy(struct net_device *slave_dev)
1201 1208 {
1202 1209 struct dsa_slave_priv *p = netdev_priv(slave_dev);
  1210 + struct dsa_notifier_register_info rinfo = { };
1203 1211 struct device_node *port_dn;
1204 1212  
1205 1213 port_dn = p->dp->dn;
... ... @@ -1211,6 +1219,11 @@
1211 1219 if (of_phy_is_fixed_link(port_dn))
1212 1220 of_phy_deregister_fixed_link(port_dn);
1213 1221 }
  1222 + rinfo.info.dev = slave_dev;
  1223 + rinfo.master = p->dp->cpu_dp->netdev;
  1224 + rinfo.port_number = p->dp->index;
  1225 + rinfo.switch_number = p->dp->ds->index;
  1226 + call_dsa_notifiers(DSA_PORT_UNREGISTER, slave_dev, &rinfo.info);
1214 1227 unregister_netdev(slave_dev);
1215 1228 free_percpu(p->stats64);
1216 1229 free_netdev(slave_dev);