summaryrefslogtreecommitdiff
path: root/drivers/s390/net/qeth_core_sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/net/qeth_core_sys.c')
-rw-r--r--drivers/s390/net/qeth_core_sys.c83
1 files changed, 56 insertions, 27 deletions
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 33505c2a0e3a..9ff2b36fdc43 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -416,7 +416,11 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
qeth_dev_layer2_store);
-static ssize_t qeth_dev_large_send_show(struct device *dev,
+#define ATTR_QETH_ISOLATION_NONE ("none")
+#define ATTR_QETH_ISOLATION_FWD ("forward")
+#define ATTR_QETH_ISOLATION_DROP ("drop")
+
+static ssize_t qeth_dev_isolation_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev_get_drvdata(dev);
@@ -424,44 +428,69 @@ static ssize_t qeth_dev_large_send_show(struct device *dev,
if (!card)
return -EINVAL;
- switch (card->options.large_send) {
- case QETH_LARGE_SEND_NO:
- return sprintf(buf, "%s\n", "no");
- case QETH_LARGE_SEND_TSO:
- return sprintf(buf, "%s\n", "TSO");
+ switch (card->options.isolation) {
+ case ISOLATION_MODE_NONE:
+ return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
+ case ISOLATION_MODE_FWD:
+ return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
+ case ISOLATION_MODE_DROP:
+ return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
default:
- return sprintf(buf, "%s\n", "N/A");
+ return snprintf(buf, 5, "%s\n", "N/A");
}
}
-static ssize_t qeth_dev_large_send_store(struct device *dev,
+static ssize_t qeth_dev_isolation_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev_get_drvdata(dev);
- enum qeth_large_send_types type;
+ enum qeth_ipa_isolation_modes isolation;
int rc = 0;
- char *tmp;
+ char *tmp, *curtoken;
+ curtoken = (char *) buf;
- if (!card)
- return -EINVAL;
- tmp = strsep((char **) &buf, "\n");
- if (!strcmp(tmp, "no")) {
- type = QETH_LARGE_SEND_NO;
- } else if (!strcmp(tmp, "TSO")) {
- type = QETH_LARGE_SEND_TSO;
+ if (!card) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ /* check for unknown, too, in case we do not yet know who we are */
+ if (card->info.type != QETH_CARD_TYPE_OSAE &&
+ card->info.type != QETH_CARD_TYPE_UNKNOWN) {
+ rc = -EOPNOTSUPP;
+ dev_err(&card->gdev->dev, "Adapter does not "
+ "support QDIO data connection isolation\n");
+ goto out;
+ }
+
+ /* parse input into isolation mode */
+ tmp = strsep(&curtoken, "\n");
+ if (!strcmp(tmp, ATTR_QETH_ISOLATION_NONE)) {
+ isolation = ISOLATION_MODE_NONE;
+ } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_FWD)) {
+ isolation = ISOLATION_MODE_FWD;
+ } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_DROP)) {
+ isolation = ISOLATION_MODE_DROP;
} else {
- return -EINVAL;
+ rc = -EINVAL;
+ goto out;
}
- if (card->options.large_send == type)
- return count;
- rc = qeth_set_large_send(card, type);
- if (rc)
- return rc;
- return count;
+ rc = count;
+
+ /* defer IP assist if device is offline (until discipline->set_online)*/
+ card->options.isolation = isolation;
+ if (card->state == CARD_STATE_SOFTSETUP ||
+ card->state == CARD_STATE_UP) {
+ int ipa_rc = qeth_set_access_ctrl_online(card);
+ if (ipa_rc != 0)
+ rc = ipa_rc;
+ }
+out:
+ return rc;
}
-static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show,
- qeth_dev_large_send_store);
+static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
+ qeth_dev_isolation_store);
static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
{
@@ -582,7 +611,7 @@ static struct attribute *qeth_device_attrs[] = {
&dev_attr_recover.attr,
&dev_attr_performance_stats.attr,
&dev_attr_layer2.attr,
- &dev_attr_large_send.attr,
+ &dev_attr_isolation.attr,
NULL,
};