summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2015-07-14 16:43:19 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-16 00:39:40 -0400
commitd746d707a8b1421a4ba46b497cb5d59e20161645 (patch)
tree12d68963f6b74053f2d86fe50baef6233791a67f
parent07e6a97da1eba064bb35cfd5c121e90865393a60 (diff)
net core: Add protodown support.
This patch introduces the proto_down flag that can be used by user space applications to notify switch drivers that errors have been detected on the device. The switch driver can react to protodown notification by doing a phys down on the associated switch port. Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com> Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com> Signed-off-by: Wilson Kok <wkok@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-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);