cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qeth_l2_sys.c (10156B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *    Copyright IBM Corp. 2013
      4 *    Author(s): Eugene Crosser <eugene.crosser@ru.ibm.com>
      5 */
      6
      7#include <linux/slab.h>
      8#include <asm/ebcdic.h>
      9#include "qeth_core.h"
     10#include "qeth_l2.h"
     11
     12static ssize_t qeth_bridge_port_role_state_show(struct device *dev,
     13				struct device_attribute *attr, char *buf,
     14				int show_state)
     15{
     16	struct qeth_card *card = dev_get_drvdata(dev);
     17	enum qeth_sbp_states state = QETH_SBP_STATE_INACTIVE;
     18	int rc = 0;
     19	char *word;
     20
     21	if (!qeth_bridgeport_allowed(card))
     22		return sprintf(buf, "n/a (VNIC characteristics)\n");
     23
     24	mutex_lock(&card->sbp_lock);
     25	if (qeth_card_hw_is_reachable(card) &&
     26					card->options.sbp.supported_funcs)
     27		rc = qeth_bridgeport_query_ports(card,
     28			&card->options.sbp.role, &state);
     29	if (!rc) {
     30		if (show_state)
     31			switch (state) {
     32			case QETH_SBP_STATE_INACTIVE:
     33				word = "inactive"; break;
     34			case QETH_SBP_STATE_STANDBY:
     35				word = "standby"; break;
     36			case QETH_SBP_STATE_ACTIVE:
     37				word = "active"; break;
     38			default:
     39				rc = -EIO;
     40			}
     41		else
     42			switch (card->options.sbp.role) {
     43			case QETH_SBP_ROLE_NONE:
     44				word = "none"; break;
     45			case QETH_SBP_ROLE_PRIMARY:
     46				word = "primary"; break;
     47			case QETH_SBP_ROLE_SECONDARY:
     48				word = "secondary"; break;
     49			default:
     50				rc = -EIO;
     51			}
     52		if (rc)
     53			QETH_CARD_TEXT_(card, 2, "SBP%02x:%02x",
     54				card->options.sbp.role, state);
     55		else
     56			rc = sprintf(buf, "%s\n", word);
     57	}
     58	mutex_unlock(&card->sbp_lock);
     59
     60	return rc;
     61}
     62
     63static ssize_t qeth_bridge_port_role_show(struct device *dev,
     64				struct device_attribute *attr, char *buf)
     65{
     66	struct qeth_card *card = dev_get_drvdata(dev);
     67
     68	if (!qeth_bridgeport_allowed(card))
     69		return sprintf(buf, "n/a (VNIC characteristics)\n");
     70
     71	return qeth_bridge_port_role_state_show(dev, attr, buf, 0);
     72}
     73
     74static ssize_t qeth_bridge_port_role_store(struct device *dev,
     75		struct device_attribute *attr, const char *buf, size_t count)
     76{
     77	struct qeth_card *card = dev_get_drvdata(dev);
     78	int rc = 0;
     79	enum qeth_sbp_roles role;
     80
     81	if (sysfs_streq(buf, "primary"))
     82		role = QETH_SBP_ROLE_PRIMARY;
     83	else if (sysfs_streq(buf, "secondary"))
     84		role = QETH_SBP_ROLE_SECONDARY;
     85	else if (sysfs_streq(buf, "none"))
     86		role = QETH_SBP_ROLE_NONE;
     87	else
     88		return -EINVAL;
     89
     90	mutex_lock(&card->conf_mutex);
     91	mutex_lock(&card->sbp_lock);
     92
     93	if (!qeth_bridgeport_allowed(card))
     94		rc = -EBUSY;
     95	else if (card->options.sbp.reflect_promisc)
     96		/* Forbid direct manipulation */
     97		rc = -EPERM;
     98	else if (qeth_card_hw_is_reachable(card)) {
     99		rc = qeth_bridgeport_setrole(card, role);
    100		if (!rc)
    101			card->options.sbp.role = role;
    102	} else
    103		card->options.sbp.role = role;
    104
    105	mutex_unlock(&card->sbp_lock);
    106	mutex_unlock(&card->conf_mutex);
    107
    108	return rc ? rc : count;
    109}
    110
    111static DEVICE_ATTR(bridge_role, 0644, qeth_bridge_port_role_show,
    112		   qeth_bridge_port_role_store);
    113
    114static ssize_t qeth_bridge_port_state_show(struct device *dev,
    115				struct device_attribute *attr, char *buf)
    116{
    117	struct qeth_card *card = dev_get_drvdata(dev);
    118
    119	if (!qeth_bridgeport_allowed(card))
    120		return sprintf(buf, "n/a (VNIC characteristics)\n");
    121
    122	return qeth_bridge_port_role_state_show(dev, attr, buf, 1);
    123}
    124
    125static DEVICE_ATTR(bridge_state, 0444, qeth_bridge_port_state_show,
    126		   NULL);
    127
    128static ssize_t qeth_bridgeport_hostnotification_show(struct device *dev,
    129				struct device_attribute *attr, char *buf)
    130{
    131	struct qeth_card *card = dev_get_drvdata(dev);
    132	int enabled;
    133
    134	if (!qeth_bridgeport_allowed(card))
    135		return sprintf(buf, "n/a (VNIC characteristics)\n");
    136
    137	enabled = card->options.sbp.hostnotification;
    138
    139	return sprintf(buf, "%d\n", enabled);
    140}
    141
    142static ssize_t qeth_bridgeport_hostnotification_store(struct device *dev,
    143		struct device_attribute *attr, const char *buf, size_t count)
    144{
    145	struct qeth_card *card = dev_get_drvdata(dev);
    146	bool enable;
    147	int rc;
    148
    149	rc = kstrtobool(buf, &enable);
    150	if (rc)
    151		return rc;
    152
    153	mutex_lock(&card->conf_mutex);
    154	mutex_lock(&card->sbp_lock);
    155
    156	if (!qeth_bridgeport_allowed(card))
    157		rc = -EBUSY;
    158	else if (qeth_card_hw_is_reachable(card)) {
    159		rc = qeth_bridgeport_an_set(card, enable);
    160		/* sbp_lock ensures ordering vs notifications-stopped events */
    161		if (!rc)
    162			card->options.sbp.hostnotification = enable;
    163	} else
    164		card->options.sbp.hostnotification = enable;
    165
    166	mutex_unlock(&card->sbp_lock);
    167	mutex_unlock(&card->conf_mutex);
    168
    169	return rc ? rc : count;
    170}
    171
    172static DEVICE_ATTR(bridge_hostnotify, 0644,
    173			qeth_bridgeport_hostnotification_show,
    174			qeth_bridgeport_hostnotification_store);
    175
    176static ssize_t qeth_bridgeport_reflect_show(struct device *dev,
    177				struct device_attribute *attr, char *buf)
    178{
    179	struct qeth_card *card = dev_get_drvdata(dev);
    180	char *state;
    181
    182	if (!qeth_bridgeport_allowed(card))
    183		return sprintf(buf, "n/a (VNIC characteristics)\n");
    184
    185	if (card->options.sbp.reflect_promisc) {
    186		if (card->options.sbp.reflect_promisc_primary)
    187			state = "primary";
    188		else
    189			state = "secondary";
    190	} else
    191		state = "none";
    192
    193	return sprintf(buf, "%s\n", state);
    194}
    195
    196static ssize_t qeth_bridgeport_reflect_store(struct device *dev,
    197		struct device_attribute *attr, const char *buf, size_t count)
    198{
    199	struct qeth_card *card = dev_get_drvdata(dev);
    200	int enable, primary;
    201	int rc = 0;
    202
    203	if (sysfs_streq(buf, "none")) {
    204		enable = 0;
    205		primary = 0;
    206	} else if (sysfs_streq(buf, "primary")) {
    207		enable = 1;
    208		primary = 1;
    209	} else if (sysfs_streq(buf, "secondary")) {
    210		enable = 1;
    211		primary = 0;
    212	} else
    213		return -EINVAL;
    214
    215	mutex_lock(&card->conf_mutex);
    216	mutex_lock(&card->sbp_lock);
    217
    218	if (!qeth_bridgeport_allowed(card))
    219		rc = -EBUSY;
    220	else if (card->options.sbp.role != QETH_SBP_ROLE_NONE)
    221		rc = -EPERM;
    222	else {
    223		card->options.sbp.reflect_promisc = enable;
    224		card->options.sbp.reflect_promisc_primary = primary;
    225		rc = 0;
    226	}
    227
    228	mutex_unlock(&card->sbp_lock);
    229	mutex_unlock(&card->conf_mutex);
    230
    231	return rc ? rc : count;
    232}
    233
    234static DEVICE_ATTR(bridge_reflect_promisc, 0644,
    235			qeth_bridgeport_reflect_show,
    236			qeth_bridgeport_reflect_store);
    237
    238static struct attribute *qeth_l2_bridgeport_attrs[] = {
    239	&dev_attr_bridge_role.attr,
    240	&dev_attr_bridge_state.attr,
    241	&dev_attr_bridge_hostnotify.attr,
    242	&dev_attr_bridge_reflect_promisc.attr,
    243	NULL,
    244};
    245
    246static struct attribute_group qeth_l2_bridgeport_attr_group = {
    247	.attrs = qeth_l2_bridgeport_attrs,
    248};
    249
    250/* VNIC CHARS support */
    251
    252/* convert sysfs attr name to VNIC characteristic */
    253static u32 qeth_l2_vnicc_sysfs_attr_to_char(const char *attr_name)
    254{
    255	if (sysfs_streq(attr_name, "flooding"))
    256		return QETH_VNICC_FLOODING;
    257	else if (sysfs_streq(attr_name, "mcast_flooding"))
    258		return QETH_VNICC_MCAST_FLOODING;
    259	else if (sysfs_streq(attr_name, "learning"))
    260		return QETH_VNICC_LEARNING;
    261	else if (sysfs_streq(attr_name, "takeover_setvmac"))
    262		return QETH_VNICC_TAKEOVER_SETVMAC;
    263	else if (sysfs_streq(attr_name, "takeover_learning"))
    264		return QETH_VNICC_TAKEOVER_LEARNING;
    265	else if (sysfs_streq(attr_name, "bridge_invisible"))
    266		return QETH_VNICC_BRIDGE_INVISIBLE;
    267	else if (sysfs_streq(attr_name, "rx_bcast"))
    268		return QETH_VNICC_RX_BCAST;
    269
    270	return 0;
    271}
    272
    273/* get current timeout setting */
    274static ssize_t qeth_vnicc_timeout_show(struct device *dev,
    275				       struct device_attribute *attr, char *buf)
    276{
    277	struct qeth_card *card = dev_get_drvdata(dev);
    278	u32 timeout;
    279	int rc;
    280
    281	rc = qeth_l2_vnicc_get_timeout(card, &timeout);
    282	if (rc == -EBUSY)
    283		return sprintf(buf, "n/a (BridgePort)\n");
    284	if (rc == -EOPNOTSUPP)
    285		return sprintf(buf, "n/a\n");
    286	return rc ? rc : sprintf(buf, "%d\n", timeout);
    287}
    288
    289/* change timeout setting */
    290static ssize_t qeth_vnicc_timeout_store(struct device *dev,
    291					struct device_attribute *attr,
    292					const char *buf, size_t count)
    293{
    294	struct qeth_card *card = dev_get_drvdata(dev);
    295	u32 timeout;
    296	int rc;
    297
    298	rc = kstrtou32(buf, 10, &timeout);
    299	if (rc)
    300		return rc;
    301
    302	mutex_lock(&card->conf_mutex);
    303	rc = qeth_l2_vnicc_set_timeout(card, timeout);
    304	mutex_unlock(&card->conf_mutex);
    305	return rc ? rc : count;
    306}
    307
    308/* get current setting of characteristic */
    309static ssize_t qeth_vnicc_char_show(struct device *dev,
    310				    struct device_attribute *attr, char *buf)
    311{
    312	struct qeth_card *card = dev_get_drvdata(dev);
    313	bool state;
    314	u32 vnicc;
    315	int rc;
    316
    317	vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
    318	rc = qeth_l2_vnicc_get_state(card, vnicc, &state);
    319
    320	if (rc == -EBUSY)
    321		return sprintf(buf, "n/a (BridgePort)\n");
    322	if (rc == -EOPNOTSUPP)
    323		return sprintf(buf, "n/a\n");
    324	return rc ? rc : sprintf(buf, "%d\n", state);
    325}
    326
    327/* change setting of characteristic */
    328static ssize_t qeth_vnicc_char_store(struct device *dev,
    329				     struct device_attribute *attr,
    330				     const char *buf, size_t count)
    331{
    332	struct qeth_card *card = dev_get_drvdata(dev);
    333	bool state;
    334	u32 vnicc;
    335	int rc;
    336
    337	if (kstrtobool(buf, &state))
    338		return -EINVAL;
    339
    340	vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
    341	mutex_lock(&card->conf_mutex);
    342	rc = qeth_l2_vnicc_set_state(card, vnicc, state);
    343	mutex_unlock(&card->conf_mutex);
    344
    345	return rc ? rc : count;
    346}
    347
    348static DEVICE_ATTR(flooding, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
    349static DEVICE_ATTR(mcast_flooding, 0644, qeth_vnicc_char_show,
    350		   qeth_vnicc_char_store);
    351static DEVICE_ATTR(learning, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
    352static DEVICE_ATTR(learning_timeout, 0644, qeth_vnicc_timeout_show,
    353		   qeth_vnicc_timeout_store);
    354static DEVICE_ATTR(takeover_setvmac, 0644, qeth_vnicc_char_show,
    355		   qeth_vnicc_char_store);
    356static DEVICE_ATTR(takeover_learning, 0644, qeth_vnicc_char_show,
    357		   qeth_vnicc_char_store);
    358static DEVICE_ATTR(bridge_invisible, 0644, qeth_vnicc_char_show,
    359		   qeth_vnicc_char_store);
    360static DEVICE_ATTR(rx_bcast, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
    361
    362static struct attribute *qeth_l2_vnicc_attrs[] = {
    363	&dev_attr_flooding.attr,
    364	&dev_attr_mcast_flooding.attr,
    365	&dev_attr_learning.attr,
    366	&dev_attr_learning_timeout.attr,
    367	&dev_attr_takeover_setvmac.attr,
    368	&dev_attr_takeover_learning.attr,
    369	&dev_attr_bridge_invisible.attr,
    370	&dev_attr_rx_bcast.attr,
    371	NULL,
    372};
    373
    374static struct attribute_group qeth_l2_vnicc_attr_group = {
    375	.attrs = qeth_l2_vnicc_attrs,
    376	.name = "vnicc",
    377};
    378
    379const struct attribute_group *qeth_l2_attr_groups[] = {
    380	&qeth_l2_bridgeport_attr_group,
    381	&qeth_l2_vnicc_attr_group,
    382	NULL,
    383};