1007f790cSJiri Pirko /* 2007f790cSJiri Pirko * net/switchdev/switchdev.c - Switch device API 3007f790cSJiri Pirko * Copyright (c) 2014 Jiri Pirko <[email protected]> 4007f790cSJiri Pirko * 5007f790cSJiri Pirko * This program is free software; you can redistribute it and/or modify 6007f790cSJiri Pirko * it under the terms of the GNU General Public License as published by 7007f790cSJiri Pirko * the Free Software Foundation; either version 2 of the License, or 8007f790cSJiri Pirko * (at your option) any later version. 9007f790cSJiri Pirko */ 10007f790cSJiri Pirko 11007f790cSJiri Pirko #include <linux/kernel.h> 12007f790cSJiri Pirko #include <linux/types.h> 13007f790cSJiri Pirko #include <linux/init.h> 14*03bf0c28SJiri Pirko #include <linux/mutex.h> 15*03bf0c28SJiri Pirko #include <linux/notifier.h> 16007f790cSJiri Pirko #include <linux/netdevice.h> 17007f790cSJiri Pirko #include <net/switchdev.h> 18007f790cSJiri Pirko 19007f790cSJiri Pirko /** 20007f790cSJiri Pirko * netdev_switch_parent_id_get - Get ID of a switch 21007f790cSJiri Pirko * @dev: port device 22007f790cSJiri Pirko * @psid: switch ID 23007f790cSJiri Pirko * 24007f790cSJiri Pirko * Get ID of a switch this port is part of. 25007f790cSJiri Pirko */ 26007f790cSJiri Pirko int netdev_switch_parent_id_get(struct net_device *dev, 27007f790cSJiri Pirko struct netdev_phys_item_id *psid) 28007f790cSJiri Pirko { 29007f790cSJiri Pirko const struct net_device_ops *ops = dev->netdev_ops; 30007f790cSJiri Pirko 31007f790cSJiri Pirko if (!ops->ndo_switch_parent_id_get) 32007f790cSJiri Pirko return -EOPNOTSUPP; 33007f790cSJiri Pirko return ops->ndo_switch_parent_id_get(dev, psid); 34007f790cSJiri Pirko } 35007f790cSJiri Pirko EXPORT_SYMBOL(netdev_switch_parent_id_get); 3638dcf357SScott Feldman 3738dcf357SScott Feldman /** 3838dcf357SScott Feldman * netdev_switch_port_stp_update - Notify switch device port of STP 3938dcf357SScott Feldman * state change 4038dcf357SScott Feldman * @dev: port device 4138dcf357SScott Feldman * @state: port STP state 4238dcf357SScott Feldman * 4338dcf357SScott Feldman * Notify switch device port of bridge port STP state change. 4438dcf357SScott Feldman */ 4538dcf357SScott Feldman int netdev_switch_port_stp_update(struct net_device *dev, u8 state) 4638dcf357SScott Feldman { 4738dcf357SScott Feldman const struct net_device_ops *ops = dev->netdev_ops; 4838dcf357SScott Feldman 4938dcf357SScott Feldman if (!ops->ndo_switch_port_stp_update) 5038dcf357SScott Feldman return -EOPNOTSUPP; 5138dcf357SScott Feldman WARN_ON(!ops->ndo_switch_parent_id_get); 5238dcf357SScott Feldman return ops->ndo_switch_port_stp_update(dev, state); 5338dcf357SScott Feldman } 5438dcf357SScott Feldman EXPORT_SYMBOL(netdev_switch_port_stp_update); 55*03bf0c28SJiri Pirko 56*03bf0c28SJiri Pirko static DEFINE_MUTEX(netdev_switch_mutex); 57*03bf0c28SJiri Pirko static RAW_NOTIFIER_HEAD(netdev_switch_notif_chain); 58*03bf0c28SJiri Pirko 59*03bf0c28SJiri Pirko /** 60*03bf0c28SJiri Pirko * register_netdev_switch_notifier - Register nofifier 61*03bf0c28SJiri Pirko * @nb: notifier_block 62*03bf0c28SJiri Pirko * 63*03bf0c28SJiri Pirko * Register switch device notifier. This should be used by code 64*03bf0c28SJiri Pirko * which needs to monitor events happening in particular device. 65*03bf0c28SJiri Pirko * Return values are same as for atomic_notifier_chain_register(). 66*03bf0c28SJiri Pirko */ 67*03bf0c28SJiri Pirko int register_netdev_switch_notifier(struct notifier_block *nb) 68*03bf0c28SJiri Pirko { 69*03bf0c28SJiri Pirko int err; 70*03bf0c28SJiri Pirko 71*03bf0c28SJiri Pirko mutex_lock(&netdev_switch_mutex); 72*03bf0c28SJiri Pirko err = raw_notifier_chain_register(&netdev_switch_notif_chain, nb); 73*03bf0c28SJiri Pirko mutex_unlock(&netdev_switch_mutex); 74*03bf0c28SJiri Pirko return err; 75*03bf0c28SJiri Pirko } 76*03bf0c28SJiri Pirko EXPORT_SYMBOL(register_netdev_switch_notifier); 77*03bf0c28SJiri Pirko 78*03bf0c28SJiri Pirko /** 79*03bf0c28SJiri Pirko * unregister_netdev_switch_notifier - Unregister nofifier 80*03bf0c28SJiri Pirko * @nb: notifier_block 81*03bf0c28SJiri Pirko * 82*03bf0c28SJiri Pirko * Unregister switch device notifier. 83*03bf0c28SJiri Pirko * Return values are same as for atomic_notifier_chain_unregister(). 84*03bf0c28SJiri Pirko */ 85*03bf0c28SJiri Pirko int unregister_netdev_switch_notifier(struct notifier_block *nb) 86*03bf0c28SJiri Pirko { 87*03bf0c28SJiri Pirko int err; 88*03bf0c28SJiri Pirko 89*03bf0c28SJiri Pirko mutex_lock(&netdev_switch_mutex); 90*03bf0c28SJiri Pirko err = raw_notifier_chain_unregister(&netdev_switch_notif_chain, nb); 91*03bf0c28SJiri Pirko mutex_unlock(&netdev_switch_mutex); 92*03bf0c28SJiri Pirko return err; 93*03bf0c28SJiri Pirko } 94*03bf0c28SJiri Pirko EXPORT_SYMBOL(unregister_netdev_switch_notifier); 95*03bf0c28SJiri Pirko 96*03bf0c28SJiri Pirko /** 97*03bf0c28SJiri Pirko * call_netdev_switch_notifiers - Call nofifiers 98*03bf0c28SJiri Pirko * @val: value passed unmodified to notifier function 99*03bf0c28SJiri Pirko * @dev: port device 100*03bf0c28SJiri Pirko * @info: notifier information data 101*03bf0c28SJiri Pirko * 102*03bf0c28SJiri Pirko * Call all network notifier blocks. This should be called by driver 103*03bf0c28SJiri Pirko * when it needs to propagate hardware event. 104*03bf0c28SJiri Pirko * Return values are same as for atomic_notifier_call_chain(). 105*03bf0c28SJiri Pirko */ 106*03bf0c28SJiri Pirko int call_netdev_switch_notifiers(unsigned long val, struct net_device *dev, 107*03bf0c28SJiri Pirko struct netdev_switch_notifier_info *info) 108*03bf0c28SJiri Pirko { 109*03bf0c28SJiri Pirko int err; 110*03bf0c28SJiri Pirko 111*03bf0c28SJiri Pirko info->dev = dev; 112*03bf0c28SJiri Pirko mutex_lock(&netdev_switch_mutex); 113*03bf0c28SJiri Pirko err = raw_notifier_call_chain(&netdev_switch_notif_chain, val, info); 114*03bf0c28SJiri Pirko mutex_unlock(&netdev_switch_mutex); 115*03bf0c28SJiri Pirko return err; 116*03bf0c28SJiri Pirko } 117*03bf0c28SJiri Pirko EXPORT_SYMBOL(call_netdev_switch_notifiers); 118