From 9f48b9db9a22bdbcff8a629b3d2e4a81dcd4ed26 Mon Sep 17 00:00:00 2001 From: Eugene Crosser Date: Tue, 14 Jan 2014 15:54:13 +0100 Subject: qeth: bridgeport support - address notifications Introduce functions to enable and disable bridgeport address notification feature, sysfs attributes for access to these functions from userspace, and udev events emitted when a host joins or exits a bridgeport-enabled HiperSocket channel. Signed-off-by: Eugene Crosser Signed-off-by: Frank Blaschka Reviewed-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l2_sys.c | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'drivers/s390/net/qeth_l2_sys.c') diff --git a/drivers/s390/net/qeth_l2_sys.c b/drivers/s390/net/qeth_l2_sys.c index 17fd4cd888f9..ae1bc04b8653 100644 --- a/drivers/s390/net/qeth_l2_sys.c +++ b/drivers/s390/net/qeth_l2_sys.c @@ -119,9 +119,63 @@ static ssize_t qeth_bridge_port_state_show(struct device *dev, static DEVICE_ATTR(bridge_state, 0644, qeth_bridge_port_state_show, NULL); +static ssize_t qeth_bridgeport_hostnotification_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct qeth_card *card = dev_get_drvdata(dev); + int enabled; + + if (!card) + return -EINVAL; + + mutex_lock(&card->conf_mutex); + + enabled = card->options.sbp.hostnotification; + + mutex_unlock(&card->conf_mutex); + + return sprintf(buf, "%d\n", enabled); +} + +static ssize_t qeth_bridgeport_hostnotification_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct qeth_card *card = dev_get_drvdata(dev); + int rc = 0; + int enable; + + if (!card) + return -EINVAL; + + if (sysfs_streq(buf, "0")) + enable = 0; + else if (sysfs_streq(buf, "1")) + enable = 1; + else + return -EINVAL; + + mutex_lock(&card->conf_mutex); + + if (qeth_card_hw_is_reachable(card)) { + rc = qeth_bridgeport_an_set(card, enable); + if (!rc) + card->options.sbp.hostnotification = enable; + } else + card->options.sbp.hostnotification = enable; + + mutex_unlock(&card->conf_mutex); + + return rc ? rc : count; +} + +static DEVICE_ATTR(bridge_hostnotify, 0644, + qeth_bridgeport_hostnotification_show, + qeth_bridgeport_hostnotification_store); + static struct attribute *qeth_l2_bridgeport_attrs[] = { &dev_attr_bridge_role.attr, &dev_attr_bridge_state.attr, + &dev_attr_bridge_hostnotify.attr, NULL, }; @@ -147,6 +201,8 @@ void qeth_l2_remove_device_attributes(struct device *dev) */ void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card) { + int rc; + if (!card) return; if (!card->options.sbp.supported_funcs) @@ -158,4 +214,10 @@ void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card) qeth_bridgeport_query_ports(card, &card->options.sbp.role, NULL); } + if (card->options.sbp.hostnotification) { + rc = qeth_bridgeport_an_set(card, 1); + if (rc) + card->options.sbp.hostnotification = 0; + } else + qeth_bridgeport_an_set(card, 0); } -- cgit v1.2.3