Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/815118/?format=api
{ "id": 815118, "url": "http://patchwork.ozlabs.org/api/1.2/patches/815118/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/20170918191822.65142-3-jwi@linux.vnet.ibm.com/", "project": { "id": 7, "url": "http://patchwork.ozlabs.org/api/1.2/projects/7/?format=api", "name": "Linux network development", "link_name": "netdev", "list_id": "netdev.vger.kernel.org", "list_email": "netdev@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20170918191822.65142-3-jwi@linux.vnet.ibm.com>", "list_archive_url": null, "date": "2017-09-18T19:18:15", "name": "[net-next,2/9] s390/qeth: add VNICC enable/disable support", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": true, "hash": "ad81c7a0165693b64d1ffa13c01156b6ed097087", "submitter": { "id": 71397, "url": "http://patchwork.ozlabs.org/api/1.2/people/71397/?format=api", "name": "Julian Wiedmann", "email": "jwi@linux.vnet.ibm.com" }, "delegate": { "id": 34, "url": "http://patchwork.ozlabs.org/api/1.2/users/34/?format=api", "username": "davem", "first_name": "David", "last_name": "Miller", "email": "davem@davemloft.net" }, "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/20170918191822.65142-3-jwi@linux.vnet.ibm.com/mbox/", "series": [ { "id": 3715, "url": "http://patchwork.ozlabs.org/api/1.2/series/3715/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=3715", "date": "2017-09-18T19:18:13", "name": "s390/qeth: updates 2017-09-18", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/3715/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/815118/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/815118/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<netdev-owner@vger.kernel.org>", "X-Original-To": "patchwork-incoming@ozlabs.org", "Delivered-To": "patchwork-incoming@ozlabs.org", "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)", "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xwwn16VNPz9rxm\n\tfor <patchwork-incoming@ozlabs.org>;\n\tTue, 19 Sep 2017 05:19:49 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751283AbdIRTT2 (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 18 Sep 2017 15:19:28 -0400", "from mx0b-001b2d01.pphosted.com ([148.163.158.5]:49350 \"EHLO\n\tmx0a-001b2d01.pphosted.com\" rhost-flags-OK-OK-OK-FAIL)\n\tby vger.kernel.org with ESMTP id S1750733AbdIRTT0 (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Mon, 18 Sep 2017 15:19:26 -0400", "from pps.filterd (m0098420.ppops.net [127.0.0.1])\n\tby mx0b-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id\n\tv8IJJHMf038633\n\tfor <netdev@vger.kernel.org>; Mon, 18 Sep 2017 15:19:26 -0400", "from e06smtp11.uk.ibm.com (e06smtp11.uk.ibm.com [195.75.94.107])\n\tby mx0b-001b2d01.pphosted.com with ESMTP id 2d2m4mg8ng-1\n\t(version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT)\n\tfor <netdev@vger.kernel.org>; Mon, 18 Sep 2017 15:19:25 -0400", "from localhost\n\tby e06smtp11.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use\n\tOnly! Violators will be prosecuted\n\tfor <netdev@vger.kernel.org> from <jwi@linux.vnet.ibm.com>;\n\tMon, 18 Sep 2017 20:19:23 +0100", "from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198)\n\tby e06smtp11.uk.ibm.com (192.168.101.141) with IBM ESMTP SMTP\n\tGateway: Authorized Use Only! Violators will be prosecuted; \n\tMon, 18 Sep 2017 20:19:20 +0100", "from d06av21.portsmouth.uk.ibm.com (d06av21.portsmouth.uk.ibm.com\n\t[9.149.105.232])\n\tby b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with\n\tESMTP id v8IJJKp012058802; Mon, 18 Sep 2017 19:19:20 GMT", "from d06av21.portsmouth.uk.ibm.com (unknown [127.0.0.1])\n\tby IMSVA (Postfix) with ESMTP id 0091C5203F;\n\tMon, 18 Sep 2017 19:14:21 +0100 (BST)", "from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9])\n\tby d06av21.portsmouth.uk.ibm.com (Postfix) with ESMTPS id A6ADE52047; \n\tMon, 18 Sep 2017 19:14:20 +0100 (BST)" ], "From": "Julian Wiedmann <jwi@linux.vnet.ibm.com>", "To": "David Miller <davem@davemloft.net>", "Cc": "<netdev@vger.kernel.org>, <linux-s390@vger.kernel.org>,\n\tMartin Schwidefsky <schwidefsky@de.ibm.com>,\n\tHeiko Carstens <heiko.carstens@de.ibm.com>,\n\tStefan Raspl <raspl@linux.vnet.ibm.com>,\n\tUrsula Braun <ubraun@linux.vnet.ibm.com>,\n\tJulian Wiedmann <jwi@linux.vnet.ibm.com>", "Subject": "[PATCH net-next 2/9] s390/qeth: add VNICC enable/disable support", "Date": "Mon, 18 Sep 2017 21:18:15 +0200", "X-Mailer": "git-send-email 2.13.5", "In-Reply-To": "<20170918191822.65142-1-jwi@linux.vnet.ibm.com>", "References": "<20170918191822.65142-1-jwi@linux.vnet.ibm.com>", "X-TM-AS-GCONF": "00", "x-cbid": "17091819-0040-0000-0000-000003FADCAC", "X-IBM-AV-DETECTION": "SAVI=unused REMOTE=unused XFE=unused", "x-cbparentid": "17091819-0041-0000-0000-0000209C0A6F", "Message-Id": "<20170918191822.65142-3-jwi@linux.vnet.ibm.com>", "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10432:, ,\n\tdefinitions=2017-09-18_08:, , signatures=0", "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n\tspamscore=0 suspectscore=0\n\tmalwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam\n\tadjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000\n\tdefinitions=main-1709180272", "Sender": "netdev-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<netdev.vger.kernel.org>", "X-Mailing-List": "netdev@vger.kernel.org" }, "content": "From: Hans Wippel <hwippel@linux.vnet.ibm.com>\n\nHiperSocket devices allow enabling and disabling so called VNIC\nCharacteristics (VNICC) that influence how the underlying hardware\nhandles packets. These VNICCs are:\n\n* Flooding VNICC: Flooding allows specifying if packets to unknown\n destination MAC addresses are received by the qeth device.\n\n* Multicast flooding VNICC: Multicast flooding allows specifying if\n packets to multicast MAC addresses are received by the qeth device.\n\n* Learning VNICC: If learning is enabled on a qeth device, the device\n learns the source MAC addresses of outgoing packets and incoming\n packets to those learned MAC addresses are received.\n\n* Takeover setvmac VNICC: If takeover setvmac is configured on a qeth\n device, the MAC address of this device can be configured on a\n different qeth device with the setvmac IPA command.\n\n* Takeover by learning VNICC: If takeover learning is enabled on a qeth\n device, the MAC address of this device can be learned (learning VNICC)\n on a different qeth device.\n\n* BridgePort invisible VNICC: If BridgePort invisible is enabled on a\n qeth device, (1) packets from this device are not sent to a BridgePort\n enabled qeth device and (2) packets coming from a BridgePort enabled\n qeth device are not received by this device.\n\n* Receive broadcast VNICC: Receive broadcast allows configuring if a\n qeth device receives packets with the broadcast destination MAC\n address.\n\nThis patch adds support for the IPA commands that are required to enable\nand disable these VNIC characteristics on qeth devices. As a\nprerequisite, it also adds the query commands IPA command.\n\nThe query commands IPA command allows requesting the supported commands\nfor each characteristic from the underlying hardware.\n\nAdditionally, this patch provides users with a sysfs user interface to\nenable/disable the VNICCs mentioned above.\n\nSigned-off-by: Hans Wippel <hwippel@linux.vnet.ibm.com>\nReviewed-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>\nSigned-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>\n---\n drivers/s390/net/qeth_core.h | 6 ++\n drivers/s390/net/qeth_core_mpc.h | 31 ++++++\n drivers/s390/net/qeth_l2.h | 4 +\n drivers/s390/net/qeth_l2_main.c | 207 +++++++++++++++++++++++++++++++++++++++\n drivers/s390/net/qeth_l2_sys.c | 158 +++++++++++++++++++++++++++---\n 5 files changed, 392 insertions(+), 14 deletions(-)", "diff": "diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h\nindex b96438df8fd4..2236c0c9744a 100644\n--- a/drivers/s390/net/qeth_core.h\n+++ b/drivers/s390/net/qeth_core.h\n@@ -186,6 +186,12 @@ struct qeth_vnicc_info {\n \t/* supported/currently configured VNICCs; updated in IPA exchanges */\n \tu32 sup_chars;\n \tu32 cur_chars;\n+\t/* supported commands: bitmasks which VNICCs support respective cmd */\n+\tu32 set_char_sup;\n+\t/* characteristics wanted/configured by user */\n+\tu32 wanted_chars;\n+\t/* has user explicitly enabled rx_bcast while online? */\n+\tbool rx_bcast_enabled;\n };\n \n static inline int qeth_is_ipa_supported(struct qeth_ipa_info *ipa,\ndiff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h\nindex c13816b8c92f..7f67a81a2ae6 100644\n--- a/drivers/s390/net/qeth_core_mpc.h\n+++ b/drivers/s390/net/qeth_core_mpc.h\n@@ -559,6 +559,22 @@ struct qeth_ipacmd_diagass {\n /* VNIC Characteristics IPA Command: *****************************************/\n /* IPA commands/sub commands for VNICC */\n #define IPA_VNICC_QUERY_CHARS\t\t0x00000000L\n+#define IPA_VNICC_QUERY_CMDS\t\t0x00000001L\n+#define IPA_VNICC_ENABLE\t\t0x00000002L\n+#define IPA_VNICC_DISABLE\t\t0x00000004L\n+\n+/* VNICC flags */\n+#define QETH_VNICC_FLOODING\t\t0x80000000\n+#define QETH_VNICC_MCAST_FLOODING\t0x40000000\n+#define QETH_VNICC_LEARNING\t\t0x20000000\n+#define QETH_VNICC_TAKEOVER_SETVMAC\t0x10000000\n+#define QETH_VNICC_TAKEOVER_LEARNING\t0x08000000\n+#define QETH_VNICC_BRIDGE_INVISIBLE\t0x04000000\n+#define QETH_VNICC_RX_BCAST\t\t0x02000000\n+\n+/* VNICC default values */\n+#define QETH_VNICC_ALL\t\t\t0xff000000\n+#define QETH_VNICC_DEFAULT\t\tQETH_VNICC_RX_BCAST\n \n /* VNICC header */\n struct qeth_ipacmd_vnicc_hdr {\n@@ -573,10 +589,25 @@ struct qeth_vnicc_sub_hdr {\n \tu32 sub_command;\n };\n \n+/* query supported commands for VNIC characteristic */\n+struct qeth_vnicc_query_cmds {\n+\tu32 vnic_char;\n+\tu32 sup_cmds;\n+};\n+\n+/* enable/disable VNIC characteristic */\n+struct qeth_vnicc_set_char {\n+\tu32 vnic_char;\n+};\n+\n /* complete VNICC IPA command message */\n struct qeth_ipacmd_vnicc {\n \tstruct qeth_ipacmd_vnicc_hdr hdr;\n \tstruct qeth_vnicc_sub_hdr sub_hdr;\n+\tunion {\n+\t\tstruct qeth_vnicc_query_cmds query_cmds;\n+\t\tstruct qeth_vnicc_set_char set_char;\n+\t};\n };\n \n /* SETBRIDGEPORT IPA Command:\t *********************************************/\ndiff --git a/drivers/s390/net/qeth_l2.h b/drivers/s390/net/qeth_l2.h\nindex 0d59f9a45ea9..0619018c76f9 100644\n--- a/drivers/s390/net/qeth_l2.h\n+++ b/drivers/s390/net/qeth_l2.h\n@@ -14,6 +14,10 @@ int qeth_l2_create_device_attributes(struct device *);\n void qeth_l2_remove_device_attributes(struct device *);\n void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card);\n \n+int qeth_l2_vnicc_set_state(struct qeth_card *card, u32 vnicc, bool state);\n+int qeth_l2_vnicc_get_state(struct qeth_card *card, u32 vnicc, bool *state);\n+bool qeth_l2_vnicc_is_in_use(struct qeth_card *card);\n+\n struct qeth_mac {\n \tu8 mac_addr[OSA_ADDR_LEN];\n \tu8 is_uc:1;\ndiff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c\nindex 2fa273b40dd1..36a7fd7255e3 100644\n--- a/drivers/s390/net/qeth_l2_main.c\n+++ b/drivers/s390/net/qeth_l2_main.c\n@@ -33,6 +33,7 @@ static void qeth_bridge_state_change(struct qeth_card *card,\n \t\t\t\t\tstruct qeth_ipa_cmd *cmd);\n static void qeth_bridge_host_event(struct qeth_card *card,\n \t\t\t\t\tstruct qeth_ipa_cmd *cmd);\n+static void qeth_l2_vnicc_set_defaults(struct qeth_card *card);\n static void qeth_l2_vnicc_init(struct qeth_card *card);\n \n static int qeth_l2_verify_dev(struct net_device *dev)\n@@ -920,6 +921,7 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)\n \thash_init(card->mac_htable);\n \tcard->options.layer2 = 1;\n \tcard->info.hwtrap = 0;\n+\tqeth_l2_vnicc_set_defaults(card);\n \treturn 0;\n }\n \n@@ -2049,6 +2051,12 @@ int qeth_bridgeport_an_set(struct qeth_card *card, int enable)\n }\n EXPORT_SYMBOL_GPL(qeth_bridgeport_an_set);\n \n+static bool qeth_bridgeport_is_in_use(struct qeth_card *card)\n+{\n+\treturn (card->options.sbp.role || card->options.sbp.reflect_promisc ||\n+\t\tcard->options.sbp.hostnotification);\n+}\n+\n /* VNIC Characteristics support */\n \n /* handle VNICC IPA command return codes; convert to error codes */\n@@ -2086,6 +2094,12 @@ static int qeth_l2_vnicc_makerc(struct qeth_card *card, int ipa_rc)\n /* generic VNICC request call back control */\n struct _qeth_l2_vnicc_request_cbctl {\n \tu32 sub_cmd;\n+\tstruct {\n+\t\tu32 vnic_char;\n+\t} param;\n+\tstruct {\n+\t\tu32 *sup_cmds;\n+\t} result;\n };\n \n /* generic VNICC request call back */\n@@ -2093,6 +2107,8 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card,\n \t\t\t\t struct qeth_reply *reply,\n \t\t\t\t unsigned long data)\n {\n+\tstruct _qeth_l2_vnicc_request_cbctl *cbctl =\n+\t\t(struct _qeth_l2_vnicc_request_cbctl *) reply->param;\n \tstruct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;\n \tstruct qeth_ipacmd_vnicc *rep = &cmd->data.vnicc;\n \n@@ -2103,6 +2119,9 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card,\n \tcard->options.vnicc.sup_chars = rep->hdr.sup;\n \tcard->options.vnicc.cur_chars = rep->hdr.cur;\n \n+\tif (cbctl->sub_cmd == IPA_VNICC_QUERY_CMDS)\n+\t\t*cbctl->result.sup_cmds = rep->query_cmds.sup_cmds;\n+\n \treturn 0;\n }\n \n@@ -2134,6 +2153,15 @@ static int qeth_l2_vnicc_request(struct qeth_card *card,\n \tswitch (cbctl->sub_cmd) {\n \tcase IPA_VNICC_QUERY_CHARS:\n \t\tbreak;\n+\tcase IPA_VNICC_QUERY_CMDS:\n+\t\treq->sub_hdr.data_length += sizeof(req->query_cmds);\n+\t\treq->query_cmds.vnic_char = cbctl->param.vnic_char;\n+\t\tbreak;\n+\tcase IPA_VNICC_ENABLE:\n+\tcase IPA_VNICC_DISABLE:\n+\t\treq->sub_hdr.data_length += sizeof(req->set_char);\n+\t\treq->set_char.vnic_char = cbctl->param.vnic_char;\n+\t\tbreak;\n \tdefault:\n \t\tqeth_release_buffer(iob->channel, iob);\n \t\treturn -EOPNOTSUPP;\n@@ -2158,15 +2186,194 @@ static int qeth_l2_vnicc_query_chars(struct qeth_card *card)\n \treturn qeth_l2_vnicc_request(card, &cbctl);\n }\n \n+/* VNICC query sub commands request */\n+static int qeth_l2_vnicc_query_cmds(struct qeth_card *card, u32 vnic_char,\n+\t\t\t\t u32 *sup_cmds)\n+{\n+\tstruct _qeth_l2_vnicc_request_cbctl cbctl;\n+\n+\t/* prepare callback control */\n+\tcbctl.sub_cmd = IPA_VNICC_QUERY_CMDS;\n+\tcbctl.param.vnic_char = vnic_char;\n+\tcbctl.result.sup_cmds = sup_cmds;\n+\n+\tQETH_CARD_TEXT(card, 2, \"vniccqcm\");\n+\treturn qeth_l2_vnicc_request(card, &cbctl);\n+}\n+\n+/* VNICC enable/disable characteristic request */\n+static int qeth_l2_vnicc_set_char(struct qeth_card *card, u32 vnic_char,\n+\t\t\t\t u32 cmd)\n+{\n+\tstruct _qeth_l2_vnicc_request_cbctl cbctl;\n+\n+\t/* prepare callback control */\n+\tcbctl.sub_cmd = cmd;\n+\tcbctl.param.vnic_char = vnic_char;\n+\n+\tQETH_CARD_TEXT(card, 2, \"vniccedc\");\n+\treturn qeth_l2_vnicc_request(card, &cbctl);\n+}\n+\n+/* set current VNICC flag state; called from sysfs store function */\n+int qeth_l2_vnicc_set_state(struct qeth_card *card, u32 vnicc, bool state)\n+{\n+\tint rc = 0;\n+\tu32 cmd;\n+\n+\tQETH_CARD_TEXT(card, 2, \"vniccsch\");\n+\n+\t/* do not change anything if BridgePort is enabled */\n+\tif (qeth_bridgeport_is_in_use(card))\n+\t\treturn -EBUSY;\n+\n+\t/* check if characteristic and enable/disable are supported */\n+\tif (!(card->options.vnicc.sup_chars & vnicc) ||\n+\t !(card->options.vnicc.set_char_sup & vnicc))\n+\t\treturn -EOPNOTSUPP;\n+\n+\t/* set enable/disable command and store wanted characteristic */\n+\tif (state) {\n+\t\tcmd = IPA_VNICC_ENABLE;\n+\t\tcard->options.vnicc.wanted_chars |= vnicc;\n+\t} else {\n+\t\tcmd = IPA_VNICC_DISABLE;\n+\t\tcard->options.vnicc.wanted_chars &= ~vnicc;\n+\t}\n+\n+\t/* do we need to do anything? */\n+\tif (card->options.vnicc.cur_chars == card->options.vnicc.wanted_chars)\n+\t\treturn rc;\n+\n+\t/* if card is not ready, simply stop here */\n+\tif (!qeth_card_hw_is_reachable(card)) {\n+\t\tif (state)\n+\t\t\tcard->options.vnicc.cur_chars |= vnicc;\n+\t\telse\n+\t\t\tcard->options.vnicc.cur_chars &= ~vnicc;\n+\t\treturn rc;\n+\t}\n+\n+\trc = qeth_l2_vnicc_set_char(card, vnicc, cmd);\n+\tif (rc)\n+\t\tcard->options.vnicc.wanted_chars =\n+\t\t\tcard->options.vnicc.cur_chars;\n+\telse if (state && vnicc == QETH_VNICC_RX_BCAST)\n+\t\tcard->options.vnicc.rx_bcast_enabled = true;\n+\n+\treturn rc;\n+}\n+\n+/* get current VNICC flag state; called from sysfs show function */\n+int qeth_l2_vnicc_get_state(struct qeth_card *card, u32 vnicc, bool *state)\n+{\n+\tint rc = 0;\n+\n+\tQETH_CARD_TEXT(card, 2, \"vniccgch\");\n+\n+\t/* do not get anything if BridgePort is enabled */\n+\tif (qeth_bridgeport_is_in_use(card))\n+\t\treturn -EBUSY;\n+\n+\t/* check if characteristic is supported */\n+\tif (!(card->options.vnicc.sup_chars & vnicc))\n+\t\treturn -EOPNOTSUPP;\n+\n+\t/* if card is ready, query current VNICC state */\n+\tif (qeth_card_hw_is_reachable(card))\n+\t\trc = qeth_l2_vnicc_query_chars(card);\n+\n+\t*state = (card->options.vnicc.cur_chars & vnicc) ? true : false;\n+\treturn rc;\n+}\n+\n+/* check if VNICC is currently enabled */\n+bool qeth_l2_vnicc_is_in_use(struct qeth_card *card)\n+{\n+\t/* if everything is turned off, VNICC is not active */\n+\tif (!card->options.vnicc.cur_chars)\n+\t\treturn false;\n+\t/* default values are only OK if rx_bcast was not enabled by user\n+\t * or the card is offline.\n+\t */\n+\tif (card->options.vnicc.cur_chars == QETH_VNICC_DEFAULT) {\n+\t\tif (!card->options.vnicc.rx_bcast_enabled ||\n+\t\t !qeth_card_hw_is_reachable(card))\n+\t\t\treturn false;\n+\t}\n+\treturn true;\n+}\n+\n+/* recover user characteristic setting */\n+static bool qeth_l2_vnicc_recover_char(struct qeth_card *card, u32 vnicc,\n+\t\t\t\t bool enable)\n+{\n+\tu32 cmd = enable ? IPA_VNICC_ENABLE : IPA_VNICC_DISABLE;\n+\n+\tif (card->options.vnicc.sup_chars & vnicc &&\n+\t card->options.vnicc.set_char_sup & vnicc &&\n+\t !qeth_l2_vnicc_set_char(card, vnicc, cmd))\n+\t\treturn false;\n+\tcard->options.vnicc.wanted_chars &= ~vnicc;\n+\tcard->options.vnicc.wanted_chars |= QETH_VNICC_DEFAULT & vnicc;\n+\treturn true;\n+}\n+\n /* (re-)initialize VNICC */\n static void qeth_l2_vnicc_init(struct qeth_card *card)\n {\n+\tunsigned int chars_len, i;\n+\tunsigned long chars_tmp;\n+\tu32 sup_cmds, vnicc;\n+\tbool enable, error;\n+\n \tQETH_CARD_TEXT(card, 2, \"vniccini\");\n+\t/* reset rx_bcast */\n+\tcard->options.vnicc.rx_bcast_enabled = 0;\n \t/* initial query and storage of VNIC characteristics */\n \tif (qeth_l2_vnicc_query_chars(card)) {\n+\t\tif (card->options.vnicc.wanted_chars != QETH_VNICC_DEFAULT)\n+\t\t\tdev_err(&card->gdev->dev, \"Configuring the VNIC characteristics failed\\n\");\n+\t\t/* fail quietly if user didn't change the default config */\n \t\tcard->options.vnicc.sup_chars = 0;\n \t\tcard->options.vnicc.cur_chars = 0;\n+\t\tcard->options.vnicc.wanted_chars = QETH_VNICC_DEFAULT;\n+\t\treturn;\n \t}\n+\t/* get supported commands for each supported characteristic */\n+\tchars_tmp = card->options.vnicc.sup_chars;\n+\tchars_len = sizeof(card->options.vnicc.sup_chars) * BITS_PER_BYTE;\n+\tfor_each_set_bit(i, &chars_tmp, chars_len) {\n+\t\tvnicc = BIT(i);\n+\t\tqeth_l2_vnicc_query_cmds(card, vnicc, &sup_cmds);\n+\t\tif (!(sup_cmds & IPA_VNICC_ENABLE) ||\n+\t\t !(sup_cmds & IPA_VNICC_DISABLE))\n+\t\t\tcard->options.vnicc.set_char_sup &= ~vnicc;\n+\t}\n+\t/* enforce assumed default values and recover settings, if changed */\n+\terror = false;\n+\tchars_tmp = card->options.vnicc.wanted_chars ^ QETH_VNICC_DEFAULT;\n+\tchars_tmp |= QETH_VNICC_BRIDGE_INVISIBLE;\n+\tchars_len = sizeof(card->options.vnicc.wanted_chars) * BITS_PER_BYTE;\n+\tfor_each_set_bit(i, &chars_tmp, chars_len) {\n+\t\tvnicc = BIT(i);\n+\t\tenable = card->options.vnicc.wanted_chars & vnicc;\n+\t\terror |= qeth_l2_vnicc_recover_char(card, vnicc, enable);\n+\t}\n+\tif (error)\n+\t\tdev_err(&card->gdev->dev, \"Configuring the VNIC characteristics failed\\n\");\n+}\n+\n+/* configure default values of VNIC characteristics */\n+static void qeth_l2_vnicc_set_defaults(struct qeth_card *card)\n+{\n+\t/* characteristics values */\n+\tcard->options.vnicc.sup_chars = QETH_VNICC_ALL;\n+\tcard->options.vnicc.cur_chars = QETH_VNICC_DEFAULT;\n+\t/* supported commands */\n+\tcard->options.vnicc.set_char_sup = QETH_VNICC_ALL;\n+\t/* settings wanted by users */\n+\tcard->options.vnicc.wanted_chars = QETH_VNICC_DEFAULT;\n }\n \n module_init(qeth_l2_init);\ndiff --git a/drivers/s390/net/qeth_l2_sys.c b/drivers/s390/net/qeth_l2_sys.c\nindex 9696baa49e2d..01936f7dbe7e 100644\n--- a/drivers/s390/net/qeth_l2_sys.c\n+++ b/drivers/s390/net/qeth_l2_sys.c\n@@ -20,6 +20,9 @@ static ssize_t qeth_bridge_port_role_state_show(struct device *dev,\n \tif (!card)\n \t\treturn -EINVAL;\n \n+\tif (qeth_l2_vnicc_is_in_use(card))\n+\t\treturn sprintf(buf, \"n/a (VNIC characteristics)\\n\");\n+\n \tif (qeth_card_hw_is_reachable(card) &&\n \t\t\t\t\tcard->options.sbp.supported_funcs)\n \t\trc = qeth_bridgeport_query_ports(card,\n@@ -60,6 +63,11 @@ static ssize_t qeth_bridge_port_role_state_show(struct device *dev,\n static ssize_t qeth_bridge_port_role_show(struct device *dev,\n \t\t\t\tstruct device_attribute *attr, char *buf)\n {\n+\tstruct qeth_card *card = dev_get_drvdata(dev);\n+\n+\tif (qeth_l2_vnicc_is_in_use(card))\n+\t\treturn sprintf(buf, \"n/a (VNIC characteristics)\\n\");\n+\n \treturn qeth_bridge_port_role_state_show(dev, attr, buf, 0);\n }\n \n@@ -83,7 +91,10 @@ static ssize_t qeth_bridge_port_role_store(struct device *dev,\n \n \tmutex_lock(&card->conf_mutex);\n \n-\tif (card->options.sbp.reflect_promisc) /* Forbid direct manipulation */\n+\tif (qeth_l2_vnicc_is_in_use(card))\n+\t\trc = -EBUSY;\n+\telse if (card->options.sbp.reflect_promisc)\n+\t\t/* Forbid direct manipulation */\n \t\trc = -EPERM;\n \telse if (qeth_card_hw_is_reachable(card)) {\n \t\trc = qeth_bridgeport_setrole(card, role);\n@@ -103,6 +114,11 @@ static DEVICE_ATTR(bridge_role, 0644, qeth_bridge_port_role_show,\n static ssize_t qeth_bridge_port_state_show(struct device *dev,\n \t\t\t\tstruct device_attribute *attr, char *buf)\n {\n+\tstruct qeth_card *card = dev_get_drvdata(dev);\n+\n+\tif (qeth_l2_vnicc_is_in_use(card))\n+\t\treturn sprintf(buf, \"n/a (VNIC characteristics)\\n\");\n+\n \treturn qeth_bridge_port_role_state_show(dev, attr, buf, 1);\n }\n \n@@ -118,6 +134,9 @@ static ssize_t qeth_bridgeport_hostnotification_show(struct device *dev,\n \tif (!card)\n \t\treturn -EINVAL;\n \n+\tif (qeth_l2_vnicc_is_in_use(card))\n+\t\treturn sprintf(buf, \"n/a (VNIC characteristics)\\n\");\n+\n \tenabled = card->options.sbp.hostnotification;\n \n \treturn sprintf(buf, \"%d\\n\", enabled);\n@@ -142,7 +161,9 @@ static ssize_t qeth_bridgeport_hostnotification_store(struct device *dev,\n \n \tmutex_lock(&card->conf_mutex);\n \n-\tif (qeth_card_hw_is_reachable(card)) {\n+\tif (qeth_l2_vnicc_is_in_use(card))\n+\t\trc = -EBUSY;\n+\telse if (qeth_card_hw_is_reachable(card)) {\n \t\trc = qeth_bridgeport_an_set(card, enable);\n \t\tif (!rc)\n \t\t\tcard->options.sbp.hostnotification = enable;\n@@ -167,6 +188,9 @@ static ssize_t qeth_bridgeport_reflect_show(struct device *dev,\n \tif (!card)\n \t\treturn -EINVAL;\n \n+\tif (qeth_l2_vnicc_is_in_use(card))\n+\t\treturn sprintf(buf, \"n/a (VNIC characteristics)\\n\");\n+\n \tif (card->options.sbp.reflect_promisc) {\n \t\tif (card->options.sbp.reflect_promisc_primary)\n \t\t\tstate = \"primary\";\n@@ -202,7 +226,9 @@ static ssize_t qeth_bridgeport_reflect_store(struct device *dev,\n \n \tmutex_lock(&card->conf_mutex);\n \n-\tif (card->options.sbp.role != QETH_SBP_ROLE_NONE)\n+\tif (qeth_l2_vnicc_is_in_use(card))\n+\t\trc = -EBUSY;\n+\telse if (card->options.sbp.role != QETH_SBP_ROLE_NONE)\n \t\trc = -EPERM;\n \telse {\n \t\tcard->options.sbp.reflect_promisc = enable;\n@@ -231,16 +257,6 @@ static struct attribute_group qeth_l2_bridgeport_attr_group = {\n \t.attrs = qeth_l2_bridgeport_attrs,\n };\n \n-int qeth_l2_create_device_attributes(struct device *dev)\n-{\n-\treturn sysfs_create_group(&dev->kobj, &qeth_l2_bridgeport_attr_group);\n-}\n-\n-void qeth_l2_remove_device_attributes(struct device *dev)\n-{\n-\tsysfs_remove_group(&dev->kobj, &qeth_l2_bridgeport_attr_group);\n-}\n-\n /**\n * qeth_l2_setup_bridgeport_attrs() - set/restore attrs when turning online.\n * @card:\t\t\t qeth_card structure pointer\n@@ -270,10 +286,124 @@ void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)\n \t\tqeth_bridgeport_an_set(card, 0);\n }\n \n+/* VNIC CHARS support */\n+\n+/* convert sysfs attr name to VNIC characteristic */\n+static u32 qeth_l2_vnicc_sysfs_attr_to_char(const char *attr_name)\n+{\n+\tif (sysfs_streq(attr_name, \"flooding\"))\n+\t\treturn QETH_VNICC_FLOODING;\n+\telse if (sysfs_streq(attr_name, \"mcast_flooding\"))\n+\t\treturn QETH_VNICC_MCAST_FLOODING;\n+\telse if (sysfs_streq(attr_name, \"learning\"))\n+\t\treturn QETH_VNICC_LEARNING;\n+\telse if (sysfs_streq(attr_name, \"takeover_setvmac\"))\n+\t\treturn QETH_VNICC_TAKEOVER_SETVMAC;\n+\telse if (sysfs_streq(attr_name, \"takeover_learning\"))\n+\t\treturn QETH_VNICC_TAKEOVER_LEARNING;\n+\telse if (sysfs_streq(attr_name, \"bridge_invisible\"))\n+\t\treturn QETH_VNICC_BRIDGE_INVISIBLE;\n+\telse if (sysfs_streq(attr_name, \"rx_bcast\"))\n+\t\treturn QETH_VNICC_RX_BCAST;\n+\n+\treturn 0;\n+}\n+\n+/* get current setting of characteristic */\n+static ssize_t qeth_vnicc_char_show(struct device *dev,\n+\t\t\t\t struct device_attribute *attr, char *buf)\n+{\n+\tstruct qeth_card *card = dev_get_drvdata(dev);\n+\tbool state;\n+\tu32 vnicc;\n+\tint rc;\n+\n+\tif (!card)\n+\t\treturn -EINVAL;\n+\n+\tvnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);\n+\trc = qeth_l2_vnicc_get_state(card, vnicc, &state);\n+\n+\tif (rc == -EBUSY)\n+\t\treturn sprintf(buf, \"n/a (BridgePort)\\n\");\n+\tif (rc == -EOPNOTSUPP)\n+\t\treturn sprintf(buf, \"n/a\\n\");\n+\treturn rc ? rc : sprintf(buf, \"%d\\n\", state);\n+}\n+\n+/* change setting of characteristic */\n+static ssize_t qeth_vnicc_char_store(struct device *dev,\n+\t\t\t\t struct device_attribute *attr,\n+\t\t\t\t const char *buf, size_t count)\n+{\n+\tstruct qeth_card *card = dev_get_drvdata(dev);\n+\tbool state;\n+\tu32 vnicc;\n+\tint rc;\n+\n+\tif (!card)\n+\t\treturn -EINVAL;\n+\n+\tif (kstrtobool(buf, &state))\n+\t\treturn -EINVAL;\n+\n+\tvnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);\n+\tmutex_lock(&card->conf_mutex);\n+\trc = qeth_l2_vnicc_set_state(card, vnicc, state);\n+\tmutex_unlock(&card->conf_mutex);\n+\n+\treturn rc ? rc : count;\n+}\n+\n+static DEVICE_ATTR(flooding, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);\n+static DEVICE_ATTR(mcast_flooding, 0644, qeth_vnicc_char_show,\n+\t\t qeth_vnicc_char_store);\n+static DEVICE_ATTR(learning, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);\n+static DEVICE_ATTR(takeover_setvmac, 0644, qeth_vnicc_char_show,\n+\t\t qeth_vnicc_char_store);\n+static DEVICE_ATTR(takeover_learning, 0644, qeth_vnicc_char_show,\n+\t\t qeth_vnicc_char_store);\n+static DEVICE_ATTR(bridge_invisible, 0644, qeth_vnicc_char_show,\n+\t\t qeth_vnicc_char_store);\n+static DEVICE_ATTR(rx_bcast, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);\n+\n+static struct attribute *qeth_l2_vnicc_attrs[] = {\n+\t&dev_attr_flooding.attr,\n+\t&dev_attr_mcast_flooding.attr,\n+\t&dev_attr_learning.attr,\n+\t&dev_attr_takeover_setvmac.attr,\n+\t&dev_attr_takeover_learning.attr,\n+\t&dev_attr_bridge_invisible.attr,\n+\t&dev_attr_rx_bcast.attr,\n+\tNULL,\n+};\n+\n+static struct attribute_group qeth_l2_vnicc_attr_group = {\n+\t.attrs = qeth_l2_vnicc_attrs,\n+\t.name = \"vnicc\",\n+};\n+\n+static const struct attribute_group *qeth_l2_only_attr_groups[] = {\n+\t&qeth_l2_bridgeport_attr_group,\n+\t&qeth_l2_vnicc_attr_group,\n+\tNULL,\n+};\n+\n+int qeth_l2_create_device_attributes(struct device *dev)\n+{\n+\treturn sysfs_create_groups(&dev->kobj, qeth_l2_only_attr_groups);\n+}\n+\n+void qeth_l2_remove_device_attributes(struct device *dev)\n+{\n+\tsysfs_remove_groups(&dev->kobj, qeth_l2_only_attr_groups);\n+}\n+\n const struct attribute_group *qeth_l2_attr_groups[] = {\n \t&qeth_device_attr_group,\n \t&qeth_device_blkt_group,\n-\t/* l2 specific, see l2_{create,remove}_device_attributes(): */\n+\t/* l2 specific, see qeth_l2_only_attr_groups: */\n \t&qeth_l2_bridgeport_attr_group,\n+\t&qeth_l2_vnicc_attr_group,\n \tNULL,\n };\n", "prefixes": [ "net-next", "2/9" ] }