1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright IBM Corp. 2013
4 * Author(s): Eugene Crosser <eugene.crosser@ru.ibm.com>
7 #include <linux/slab.h>
8 #include <asm/ebcdic.h>
12 static ssize_t qeth_bridge_port_role_state_show(struct device *dev,
13 struct device_attribute *attr, char *buf,
16 struct qeth_card *card = dev_get_drvdata(dev);
17 enum qeth_sbp_states state = QETH_SBP_STATE_INACTIVE;
24 if (qeth_l2_vnicc_is_in_use(card))
25 return sprintf(buf, "n/a (VNIC characteristics)\n");
27 if (qeth_card_hw_is_reachable(card) &&
28 card->options.sbp.supported_funcs)
29 rc = qeth_bridgeport_query_ports(card,
30 &card->options.sbp.role, &state);
34 case QETH_SBP_STATE_INACTIVE:
35 word = "inactive"; break;
36 case QETH_SBP_STATE_STANDBY:
37 word = "standby"; break;
38 case QETH_SBP_STATE_ACTIVE:
39 word = "active"; break;
44 switch (card->options.sbp.role) {
45 case QETH_SBP_ROLE_NONE:
47 case QETH_SBP_ROLE_PRIMARY:
48 word = "primary"; break;
49 case QETH_SBP_ROLE_SECONDARY:
50 word = "secondary"; break;
55 QETH_CARD_TEXT_(card, 2, "SBP%02x:%02x",
56 card->options.sbp.role, state);
58 rc = sprintf(buf, "%s\n", word);
64 static ssize_t qeth_bridge_port_role_show(struct device *dev,
65 struct device_attribute *attr, char *buf)
67 struct qeth_card *card = dev_get_drvdata(dev);
69 if (qeth_l2_vnicc_is_in_use(card))
70 return sprintf(buf, "n/a (VNIC characteristics)\n");
72 return qeth_bridge_port_role_state_show(dev, attr, buf, 0);
75 static ssize_t qeth_bridge_port_role_store(struct device *dev,
76 struct device_attribute *attr, const char *buf, size_t count)
78 struct qeth_card *card = dev_get_drvdata(dev);
80 enum qeth_sbp_roles role;
84 if (sysfs_streq(buf, "primary"))
85 role = QETH_SBP_ROLE_PRIMARY;
86 else if (sysfs_streq(buf, "secondary"))
87 role = QETH_SBP_ROLE_SECONDARY;
88 else if (sysfs_streq(buf, "none"))
89 role = QETH_SBP_ROLE_NONE;
93 mutex_lock(&card->conf_mutex);
95 if (qeth_l2_vnicc_is_in_use(card))
97 else if (card->options.sbp.reflect_promisc)
98 /* Forbid direct manipulation */
100 else if (qeth_card_hw_is_reachable(card)) {
101 rc = qeth_bridgeport_setrole(card, role);
103 card->options.sbp.role = role;
105 card->options.sbp.role = role;
107 mutex_unlock(&card->conf_mutex);
109 return rc ? rc : count;
112 static DEVICE_ATTR(bridge_role, 0644, qeth_bridge_port_role_show,
113 qeth_bridge_port_role_store);
115 static ssize_t qeth_bridge_port_state_show(struct device *dev,
116 struct device_attribute *attr, char *buf)
118 struct qeth_card *card = dev_get_drvdata(dev);
120 if (qeth_l2_vnicc_is_in_use(card))
121 return sprintf(buf, "n/a (VNIC characteristics)\n");
123 return qeth_bridge_port_role_state_show(dev, attr, buf, 1);
126 static DEVICE_ATTR(bridge_state, 0444, qeth_bridge_port_state_show,
129 static ssize_t qeth_bridgeport_hostnotification_show(struct device *dev,
130 struct device_attribute *attr, char *buf)
132 struct qeth_card *card = dev_get_drvdata(dev);
138 if (qeth_l2_vnicc_is_in_use(card))
139 return sprintf(buf, "n/a (VNIC characteristics)\n");
141 enabled = card->options.sbp.hostnotification;
143 return sprintf(buf, "%d\n", enabled);
146 static ssize_t qeth_bridgeport_hostnotification_store(struct device *dev,
147 struct device_attribute *attr, const char *buf, size_t count)
149 struct qeth_card *card = dev_get_drvdata(dev);
156 rc = kstrtobool(buf, &enable);
160 mutex_lock(&card->conf_mutex);
162 if (qeth_l2_vnicc_is_in_use(card))
164 else if (qeth_card_hw_is_reachable(card)) {
165 rc = qeth_bridgeport_an_set(card, enable);
167 card->options.sbp.hostnotification = enable;
169 card->options.sbp.hostnotification = enable;
171 mutex_unlock(&card->conf_mutex);
173 return rc ? rc : count;
176 static DEVICE_ATTR(bridge_hostnotify, 0644,
177 qeth_bridgeport_hostnotification_show,
178 qeth_bridgeport_hostnotification_store);
180 static ssize_t qeth_bridgeport_reflect_show(struct device *dev,
181 struct device_attribute *attr, char *buf)
183 struct qeth_card *card = dev_get_drvdata(dev);
189 if (qeth_l2_vnicc_is_in_use(card))
190 return sprintf(buf, "n/a (VNIC characteristics)\n");
192 if (card->options.sbp.reflect_promisc) {
193 if (card->options.sbp.reflect_promisc_primary)
200 return sprintf(buf, "%s\n", state);
203 static ssize_t qeth_bridgeport_reflect_store(struct device *dev,
204 struct device_attribute *attr, const char *buf, size_t count)
206 struct qeth_card *card = dev_get_drvdata(dev);
213 if (sysfs_streq(buf, "none")) {
216 } else if (sysfs_streq(buf, "primary")) {
219 } else if (sysfs_streq(buf, "secondary")) {
225 mutex_lock(&card->conf_mutex);
227 if (qeth_l2_vnicc_is_in_use(card))
229 else if (card->options.sbp.role != QETH_SBP_ROLE_NONE)
232 card->options.sbp.reflect_promisc = enable;
233 card->options.sbp.reflect_promisc_primary = primary;
237 mutex_unlock(&card->conf_mutex);
239 return rc ? rc : count;
242 static DEVICE_ATTR(bridge_reflect_promisc, 0644,
243 qeth_bridgeport_reflect_show,
244 qeth_bridgeport_reflect_store);
246 static struct attribute *qeth_l2_bridgeport_attrs[] = {
247 &dev_attr_bridge_role.attr,
248 &dev_attr_bridge_state.attr,
249 &dev_attr_bridge_hostnotify.attr,
250 &dev_attr_bridge_reflect_promisc.attr,
254 static struct attribute_group qeth_l2_bridgeport_attr_group = {
255 .attrs = qeth_l2_bridgeport_attrs,
259 * qeth_l2_setup_bridgeport_attrs() - set/restore attrs when turning online.
260 * @card: qeth_card structure pointer
262 * Note: this function is called with conf_mutex held by the caller
264 void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)
270 if (!card->options.sbp.supported_funcs)
272 if (card->options.sbp.role != QETH_SBP_ROLE_NONE) {
273 /* Conditional to avoid spurious error messages */
274 qeth_bridgeport_setrole(card, card->options.sbp.role);
275 /* Let the callback function refresh the stored role value. */
276 qeth_bridgeport_query_ports(card,
277 &card->options.sbp.role, NULL);
279 if (card->options.sbp.hostnotification) {
280 rc = qeth_bridgeport_an_set(card, 1);
282 card->options.sbp.hostnotification = 0;
284 qeth_bridgeport_an_set(card, 0);
287 /* VNIC CHARS support */
289 /* convert sysfs attr name to VNIC characteristic */
290 static u32 qeth_l2_vnicc_sysfs_attr_to_char(const char *attr_name)
292 if (sysfs_streq(attr_name, "flooding"))
293 return QETH_VNICC_FLOODING;
294 else if (sysfs_streq(attr_name, "mcast_flooding"))
295 return QETH_VNICC_MCAST_FLOODING;
296 else if (sysfs_streq(attr_name, "learning"))
297 return QETH_VNICC_LEARNING;
298 else if (sysfs_streq(attr_name, "takeover_setvmac"))
299 return QETH_VNICC_TAKEOVER_SETVMAC;
300 else if (sysfs_streq(attr_name, "takeover_learning"))
301 return QETH_VNICC_TAKEOVER_LEARNING;
302 else if (sysfs_streq(attr_name, "bridge_invisible"))
303 return QETH_VNICC_BRIDGE_INVISIBLE;
304 else if (sysfs_streq(attr_name, "rx_bcast"))
305 return QETH_VNICC_RX_BCAST;
310 /* get current timeout setting */
311 static ssize_t qeth_vnicc_timeout_show(struct device *dev,
312 struct device_attribute *attr, char *buf)
314 struct qeth_card *card = dev_get_drvdata(dev);
321 rc = qeth_l2_vnicc_get_timeout(card, &timeout);
323 return sprintf(buf, "n/a (BridgePort)\n");
324 if (rc == -EOPNOTSUPP)
325 return sprintf(buf, "n/a\n");
326 return rc ? rc : sprintf(buf, "%d\n", timeout);
329 /* change timeout setting */
330 static ssize_t qeth_vnicc_timeout_store(struct device *dev,
331 struct device_attribute *attr,
332 const char *buf, size_t count)
334 struct qeth_card *card = dev_get_drvdata(dev);
341 rc = kstrtou32(buf, 10, &timeout);
345 mutex_lock(&card->conf_mutex);
346 rc = qeth_l2_vnicc_set_timeout(card, timeout);
347 mutex_unlock(&card->conf_mutex);
348 return rc ? rc : count;
351 /* get current setting of characteristic */
352 static ssize_t qeth_vnicc_char_show(struct device *dev,
353 struct device_attribute *attr, char *buf)
355 struct qeth_card *card = dev_get_drvdata(dev);
363 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
364 rc = qeth_l2_vnicc_get_state(card, vnicc, &state);
367 return sprintf(buf, "n/a (BridgePort)\n");
368 if (rc == -EOPNOTSUPP)
369 return sprintf(buf, "n/a\n");
370 return rc ? rc : sprintf(buf, "%d\n", state);
373 /* change setting of characteristic */
374 static ssize_t qeth_vnicc_char_store(struct device *dev,
375 struct device_attribute *attr,
376 const char *buf, size_t count)
378 struct qeth_card *card = dev_get_drvdata(dev);
386 if (kstrtobool(buf, &state))
389 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
390 mutex_lock(&card->conf_mutex);
391 rc = qeth_l2_vnicc_set_state(card, vnicc, state);
392 mutex_unlock(&card->conf_mutex);
394 return rc ? rc : count;
397 static DEVICE_ATTR(flooding, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
398 static DEVICE_ATTR(mcast_flooding, 0644, qeth_vnicc_char_show,
399 qeth_vnicc_char_store);
400 static DEVICE_ATTR(learning, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
401 static DEVICE_ATTR(learning_timeout, 0644, qeth_vnicc_timeout_show,
402 qeth_vnicc_timeout_store);
403 static DEVICE_ATTR(takeover_setvmac, 0644, qeth_vnicc_char_show,
404 qeth_vnicc_char_store);
405 static DEVICE_ATTR(takeover_learning, 0644, qeth_vnicc_char_show,
406 qeth_vnicc_char_store);
407 static DEVICE_ATTR(bridge_invisible, 0644, qeth_vnicc_char_show,
408 qeth_vnicc_char_store);
409 static DEVICE_ATTR(rx_bcast, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
411 static struct attribute *qeth_l2_vnicc_attrs[] = {
412 &dev_attr_flooding.attr,
413 &dev_attr_mcast_flooding.attr,
414 &dev_attr_learning.attr,
415 &dev_attr_learning_timeout.attr,
416 &dev_attr_takeover_setvmac.attr,
417 &dev_attr_takeover_learning.attr,
418 &dev_attr_bridge_invisible.attr,
419 &dev_attr_rx_bcast.attr,
423 static struct attribute_group qeth_l2_vnicc_attr_group = {
424 .attrs = qeth_l2_vnicc_attrs,
428 static const struct attribute_group *qeth_l2_only_attr_groups[] = {
429 &qeth_l2_bridgeport_attr_group,
430 &qeth_l2_vnicc_attr_group,
434 int qeth_l2_create_device_attributes(struct device *dev)
436 return sysfs_create_groups(&dev->kobj, qeth_l2_only_attr_groups);
439 void qeth_l2_remove_device_attributes(struct device *dev)
441 sysfs_remove_groups(&dev->kobj, qeth_l2_only_attr_groups);
444 const struct attribute_group *qeth_l2_attr_groups[] = {
445 &qeth_device_attr_group,
446 &qeth_device_blkt_group,
447 /* l2 specific, see qeth_l2_only_attr_groups: */
448 &qeth_l2_bridgeport_attr_group,
449 &qeth_l2_vnicc_attr_group,