diff options
| author | David S. Miller <davem@davemloft.net> | 2020-07-21 02:48:22 +0300 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2020-07-21 02:48:22 +0300 |
| commit | 202a5d5a7aa5560052bd43ee4454212b26016164 (patch) | |
| tree | c0624b765dec69ddd84fda731835322feaca29b7 /include | |
| parent | 88a3c45482f63373f7cce37a182cd6f40429a5ac (diff) | |
| parent | 9c0c7014f38206a2b63e7e832edf2e881a7b49ad (diff) | |
| download | linux-202a5d5a7aa5560052bd43ee4454212b26016164.tar.xz | |
Merge branch 'net-dsa-Setup-dsa_netdev_ops'
Florian Fainelli says:
====================
net: dsa: Setup dsa_netdev_ops
This patch series addresses the overloading of a DSA CPU/management
interface's netdev_ops for the purpose of providing useful information
from the switch side.
Up until now we had duplicated the existing netdev_ops structure and
added specific function pointers to return information of interest. Here
we have a more controlled way of doing this by involving the specific
netdev_ops function pointers that we want to be patched, which is easier
for auditing code in the future. As a byproduct we can now maintain
netdev_ops pointer comparisons which would be failing before (no known
in tree problems because of that though).
Let me know if this approach looks reasonable to you and we might do the
same with our ethtool_ops overloading as well.
Changes in v2:
- use static inline int vs. static int inline (Kbuild robot)
- fixed typos in patch 4 (Andrew)
- avoid using macros (Andrew)
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
| -rw-r--r-- | include/net/dsa.h | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/include/net/dsa.h b/include/net/dsa.h index 6fa418ff1175..f1b63d06d132 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -86,6 +86,18 @@ struct dsa_device_ops { enum dsa_tag_protocol proto; }; +/* This structure defines the control interfaces that are overlayed by the + * DSA layer on top of the DSA CPU/management net_device instance. This is + * used by the core net_device layer while calling various net_device_ops + * function pointers. + */ +struct dsa_netdevice_ops { + int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, + int cmd); + int (*ndo_get_phys_port_name)(struct net_device *dev, char *name, + size_t len); +}; + #define DSA_TAG_DRIVER_ALIAS "dsa_tag-" #define MODULE_ALIAS_DSA_TAG_DRIVER(__proto) \ MODULE_ALIAS(DSA_TAG_DRIVER_ALIAS __stringify(__proto##_VALUE)) @@ -217,7 +229,7 @@ struct dsa_port { /* * Original copy of the master netdev net_device_ops */ - const struct net_device_ops *orig_ndo_ops; + const struct dsa_netdevice_ops *netdev_ops; bool setup; }; @@ -679,6 +691,63 @@ static inline bool dsa_can_decode(const struct sk_buff *skb, return false; } +#if IS_ENABLED(CONFIG_NET_DSA) +static inline int __dsa_netdevice_ops_check(struct net_device *dev) +{ + int err = -EOPNOTSUPP; + + if (!dev->dsa_ptr) + return err; + + if (!dev->dsa_ptr->netdev_ops) + return err; + + return 0; +} + +static inline int dsa_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, + int cmd) +{ + const struct dsa_netdevice_ops *ops; + int err; + + err = __dsa_netdevice_ops_check(dev); + if (err) + return err; + + ops = dev->dsa_ptr->netdev_ops; + + return ops->ndo_do_ioctl(dev, ifr, cmd); +} + +static inline int dsa_ndo_get_phys_port_name(struct net_device *dev, + char *name, size_t len) +{ + const struct dsa_netdevice_ops *ops; + int err; + + err = __dsa_netdevice_ops_check(dev); + if (err) + return err; + + ops = dev->dsa_ptr->netdev_ops; + + return ops->ndo_get_phys_port_name(dev, name, len); +} +#else +static inline int dsa_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, + int cmd) +{ + return -EOPNOTSUPP; +} + +static inline int dsa_ndo_get_phys_port_name(struct net_device *dev, + char *name, size_t len) +{ + return -EOPNOTSUPP; +} +#endif + void dsa_unregister_switch(struct dsa_switch *ds); int dsa_register_switch(struct dsa_switch *ds); struct dsa_switch *dsa_switch_find(int tree_index, int sw_index); |
