aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netdevice.h14
-rw-r--r--net/core/dev.c20
-rw-r--r--net/core/net-sysfs.c14
3 files changed, 48 insertions, 0 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e20979dfd6a9..45cfd797eb77 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1041,6 +1041,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
1041 * TX queue. 1041 * TX queue.
1042 * int (*ndo_get_iflink)(const struct net_device *dev); 1042 * int (*ndo_get_iflink)(const struct net_device *dev);
1043 * Called to get the iflink value of this device. 1043 * Called to get the iflink value of this device.
1044 * void (*ndo_change_proto_down)(struct net_device *dev,
1045 * bool proto_down);
1046 * This function is used to pass protocol port error state information
1047 * to the switch driver. The switch driver can react to the proto_down
1048 * by doing a phys down on the associated switch port.
1049 *
1044 */ 1050 */
1045struct net_device_ops { 1051struct net_device_ops {
1046 int (*ndo_init)(struct net_device *dev); 1052 int (*ndo_init)(struct net_device *dev);
@@ -1211,6 +1217,8 @@ struct net_device_ops {
1211 int queue_index, 1217 int queue_index,
1212 u32 maxrate); 1218 u32 maxrate);
1213 int (*ndo_get_iflink)(const struct net_device *dev); 1219 int (*ndo_get_iflink)(const struct net_device *dev);
1220 int (*ndo_change_proto_down)(struct net_device *dev,
1221 bool proto_down);
1214}; 1222};
1215 1223
1216/** 1224/**
@@ -1502,6 +1510,10 @@ enum netdev_priv_flags {
1502 * 1510 *
1503 * @qdisc_tx_busylock: XXX: need comments on this one 1511 * @qdisc_tx_busylock: XXX: need comments on this one
1504 * 1512 *
1513 * @proto_down: protocol port state information can be sent to the
1514 * switch driver and used to set the phys state of the
1515 * switch port.
1516 *
1505 * FIXME: cleanup struct net_device such that network protocol info 1517 * FIXME: cleanup struct net_device such that network protocol info
1506 * moves out. 1518 * moves out.
1507 */ 1519 */
@@ -1762,6 +1774,7 @@ struct net_device {
1762#endif 1774#endif
1763 struct phy_device *phydev; 1775 struct phy_device *phydev;
1764 struct lock_class_key *qdisc_tx_busylock; 1776 struct lock_class_key *qdisc_tx_busylock;
1777 bool proto_down;
1765}; 1778};
1766#define to_net_dev(d) container_of(d, struct net_device, dev) 1779#define to_net_dev(d) container_of(d, struct net_device, dev)
1767 1780
@@ -2982,6 +2995,7 @@ int dev_get_phys_port_id(struct net_device *dev,
2982 struct netdev_phys_item_id *ppid); 2995 struct netdev_phys_item_id *ppid);
2983int dev_get_phys_port_name(struct net_device *dev, 2996int dev_get_phys_port_name(struct net_device *dev,
2984 char *name, size_t len); 2997 char *name, size_t len);
2998int dev_change_proto_down(struct net_device *dev, bool proto_down);
2985struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev); 2999struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev);
2986struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, 3000struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
2987 struct netdev_queue *txq, int *ret); 3001 struct netdev_queue *txq, int *ret);
diff --git a/net/core/dev.c b/net/core/dev.c
index 69445a33ace6..8810b6bbebfe 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6075,6 +6075,26 @@ int dev_get_phys_port_name(struct net_device *dev,
6075EXPORT_SYMBOL(dev_get_phys_port_name); 6075EXPORT_SYMBOL(dev_get_phys_port_name);
6076 6076
6077/** 6077/**
6078 * dev_change_proto_down - update protocol port state information
6079 * @dev: device
6080 * @proto_down: new value
6081 *
6082 * This info can be used by switch drivers to set the phys state of the
6083 * port.
6084 */
6085int dev_change_proto_down(struct net_device *dev, bool proto_down)
6086{
6087 const struct net_device_ops *ops = dev->netdev_ops;
6088
6089 if (!ops->ndo_change_proto_down)
6090 return -EOPNOTSUPP;
6091 if (!netif_device_present(dev))
6092 return -ENODEV;
6093 return ops->ndo_change_proto_down(dev, proto_down);
6094}
6095EXPORT_SYMBOL(dev_change_proto_down);
6096
6097/**
6078 * dev_new_index - allocate an ifindex 6098 * dev_new_index - allocate an ifindex
6079 * @net: the applicable net namespace 6099 * @net: the applicable net namespace
6080 * 6100 *
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 18b34d771ed4..194c1d03b2b3 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -404,6 +404,19 @@ static ssize_t group_store(struct device *dev, struct device_attribute *attr,
404NETDEVICE_SHOW(group, fmt_dec); 404NETDEVICE_SHOW(group, fmt_dec);
405static DEVICE_ATTR(netdev_group, S_IRUGO | S_IWUSR, group_show, group_store); 405static DEVICE_ATTR(netdev_group, S_IRUGO | S_IWUSR, group_show, group_store);
406 406
407static int change_proto_down(struct net_device *dev, unsigned long proto_down)
408{
409 return dev_change_proto_down(dev, (bool) proto_down);
410}
411
412static ssize_t proto_down_store(struct device *dev,
413 struct device_attribute *attr,
414 const char *buf, size_t len)
415{
416 return netdev_store(dev, attr, buf, len, change_proto_down);
417}
418NETDEVICE_SHOW_RW(proto_down, fmt_dec);
419
407static ssize_t phys_port_id_show(struct device *dev, 420static ssize_t phys_port_id_show(struct device *dev,
408 struct device_attribute *attr, char *buf) 421 struct device_attribute *attr, char *buf)
409{ 422{
@@ -501,6 +514,7 @@ static struct attribute *net_class_attrs[] = {
501 &dev_attr_phys_port_id.attr, 514 &dev_attr_phys_port_id.attr,
502 &dev_attr_phys_port_name.attr, 515 &dev_attr_phys_port_name.attr,
503 &dev_attr_phys_switch_id.attr, 516 &dev_attr_phys_switch_id.attr,
517 &dev_attr_proto_down.attr,
504 NULL, 518 NULL,
505}; 519};
506ATTRIBUTE_GROUPS(net_class); 520ATTRIBUTE_GROUPS(net_class);