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 mutex_lock(&card->sbp_lock);
28 if (qeth_card_hw_is_reachable(card) &&
29 card->options.sbp.supported_funcs)
30 rc = qeth_bridgeport_query_ports(card,
31 &card->options.sbp.role, &state);
35 case QETH_SBP_STATE_INACTIVE:
36 word = "inactive"; break;
37 case QETH_SBP_STATE_STANDBY:
38 word = "standby"; break;
39 case QETH_SBP_STATE_ACTIVE:
40 word = "active"; break;
45 switch (card->options.sbp.role) {
46 case QETH_SBP_ROLE_NONE:
48 case QETH_SBP_ROLE_PRIMARY:
49 word = "primary"; break;
50 case QETH_SBP_ROLE_SECONDARY:
51 word = "secondary"; break;
56 QETH_CARD_TEXT_(card, 2, "SBP%02x:%02x",
57 card->options.sbp.role, state);
59 rc = sprintf(buf, "%s\n", word);
61 mutex_unlock(&card->sbp_lock);
66 static ssize_t qeth_bridge_port_role_show(struct device *dev,
67 struct device_attribute *attr, char *buf)
69 struct qeth_card *card = dev_get_drvdata(dev);
71 if (qeth_l2_vnicc_is_in_use(card))
72 return sprintf(buf, "n/a (VNIC characteristics)\n");
74 return qeth_bridge_port_role_state_show(dev, attr, buf, 0);
77 static ssize_t qeth_bridge_port_role_store(struct device *dev,
78 struct device_attribute *attr, const char *buf, size_t count)
80 struct qeth_card *card = dev_get_drvdata(dev);
82 enum qeth_sbp_roles role;
86 if (sysfs_streq(buf, "primary"))
87 role = QETH_SBP_ROLE_PRIMARY;
88 else if (sysfs_streq(buf, "secondary"))
89 role = QETH_SBP_ROLE_SECONDARY;
90 else if (sysfs_streq(buf, "none"))
91 role = QETH_SBP_ROLE_NONE;
95 mutex_lock(&card->conf_mutex);
96 mutex_lock(&card->sbp_lock);
98 if (qeth_l2_vnicc_is_in_use(card))
100 else if (card->options.sbp.reflect_promisc)
101 /* Forbid direct manipulation */
103 else if (qeth_card_hw_is_reachable(card)) {
104 rc = qeth_bridgeport_setrole(card, role);
106 card->options.sbp.role = role;
108 card->options.sbp.role = role;
110 mutex_unlock(&card->sbp_lock);
111 mutex_unlock(&card->conf_mutex);
113 return rc ? rc : count;
116 static DEVICE_ATTR(bridge_role, 0644, qeth_bridge_port_role_show,
117 qeth_bridge_port_role_store);
119 static ssize_t qeth_bridge_port_state_show(struct device *dev,
120 struct device_attribute *attr, char *buf)
122 struct qeth_card *card = dev_get_drvdata(dev);
124 if (qeth_l2_vnicc_is_in_use(card))
125 return sprintf(buf, "n/a (VNIC characteristics)\n");
127 return qeth_bridge_port_role_state_show(dev, attr, buf, 1);
130 static DEVICE_ATTR(bridge_state, 0444, qeth_bridge_port_state_show,
133 static ssize_t qeth_bridgeport_hostnotification_show(struct device *dev,
134 struct device_attribute *attr, char *buf)
136 struct qeth_card *card = dev_get_drvdata(dev);
142 if (qeth_l2_vnicc_is_in_use(card))
143 return sprintf(buf, "n/a (VNIC characteristics)\n");
145 enabled = card->options.sbp.hostnotification;
147 return sprintf(buf, "%d\n", enabled);
150 static ssize_t qeth_bridgeport_hostnotification_store(struct device *dev,
151 struct device_attribute *attr, const char *buf, size_t count)
153 struct qeth_card *card = dev_get_drvdata(dev);
160 rc = kstrtobool(buf, &enable);
164 mutex_lock(&card->conf_mutex);
165 mutex_lock(&card->sbp_lock);
167 if (qeth_l2_vnicc_is_in_use(card))
169 else if (qeth_card_hw_is_reachable(card)) {
170 rc = qeth_bridgeport_an_set(card, enable);
172 card->options.sbp.hostnotification = enable;
174 card->options.sbp.hostnotification = enable;
176 mutex_unlock(&card->sbp_lock);
177 mutex_unlock(&card->conf_mutex);
179 return rc ? rc : count;
182 static DEVICE_ATTR(bridge_hostnotify, 0644,
183 qeth_bridgeport_hostnotification_show,
184 qeth_bridgeport_hostnotification_store);
186 static ssize_t qeth_bridgeport_reflect_show(struct device *dev,
187 struct device_attribute *attr, char *buf)
189 struct qeth_card *card = dev_get_drvdata(dev);
195 if (qeth_l2_vnicc_is_in_use(card))
196 return sprintf(buf, "n/a (VNIC characteristics)\n");
198 if (card->options.sbp.reflect_promisc) {
199 if (card->options.sbp.reflect_promisc_primary)
206 return sprintf(buf, "%s\n", state);
209 static ssize_t qeth_bridgeport_reflect_store(struct device *dev,
210 struct device_attribute *attr, const char *buf, size_t count)
212 struct qeth_card *card = dev_get_drvdata(dev);
219 if (sysfs_streq(buf, "none")) {
222 } else if (sysfs_streq(buf, "primary")) {
225 } else if (sysfs_streq(buf, "secondary")) {
231 mutex_lock(&card->conf_mutex);
232 mutex_lock(&card->sbp_lock);
234 if (qeth_l2_vnicc_is_in_use(card))
236 else if (card->options.sbp.role != QETH_SBP_ROLE_NONE)
239 card->options.sbp.reflect_promisc = enable;
240 card->options.sbp.reflect_promisc_primary = primary;
244 mutex_unlock(&card->sbp_lock);
245 mutex_unlock(&card->conf_mutex);
247 return rc ? rc : count;
250 static DEVICE_ATTR(bridge_reflect_promisc, 0644,
251 qeth_bridgeport_reflect_show,
252 qeth_bridgeport_reflect_store);
254 static struct attribute *qeth_l2_bridgeport_attrs[] = {
255 &dev_attr_bridge_role.attr,
256 &dev_attr_bridge_state.attr,
257 &dev_attr_bridge_hostnotify.attr,
258 &dev_attr_bridge_reflect_promisc.attr,
262 static struct attribute_group qeth_l2_bridgeport_attr_group = {
263 .attrs = qeth_l2_bridgeport_attrs,
267 * qeth_l2_setup_bridgeport_attrs() - set/restore attrs when turning online.
268 * @card: qeth_card structure pointer
270 * Note: this function is called with conf_mutex held by the caller
272 void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)
278 if (!card->options.sbp.supported_funcs)
281 mutex_lock(&card->sbp_lock);
282 if (!card->options.sbp.reflect_promisc &&
283 card->options.sbp.role != QETH_SBP_ROLE_NONE) {
284 /* Conditional to avoid spurious error messages */
285 qeth_bridgeport_setrole(card, card->options.sbp.role);
286 /* Let the callback function refresh the stored role value. */
287 qeth_bridgeport_query_ports(card,
288 &card->options.sbp.role, NULL);
290 if (card->options.sbp.hostnotification) {
291 rc = qeth_bridgeport_an_set(card, 1);
293 card->options.sbp.hostnotification = 0;
295 qeth_bridgeport_an_set(card, 0);
297 mutex_unlock(&card->sbp_lock);
300 /* VNIC CHARS support */
302 /* convert sysfs attr name to VNIC characteristic */
303 static u32 qeth_l2_vnicc_sysfs_attr_to_char(const char *attr_name)
305 if (sysfs_streq(attr_name, "flooding"))
306 return QETH_VNICC_FLOODING;
307 else if (sysfs_streq(attr_name, "mcast_flooding"))
308 return QETH_VNICC_MCAST_FLOODING;
309 else if (sysfs_streq(attr_name, "learning"))
310 return QETH_VNICC_LEARNING;
311 else if (sysfs_streq(attr_name, "takeover_setvmac"))
312 return QETH_VNICC_TAKEOVER_SETVMAC;
313 else if (sysfs_streq(attr_name, "takeover_learning"))
314 return QETH_VNICC_TAKEOVER_LEARNING;
315 else if (sysfs_streq(attr_name, "bridge_invisible"))
316 return QETH_VNICC_BRIDGE_INVISIBLE;
317 else if (sysfs_streq(attr_name, "rx_bcast"))
318 return QETH_VNICC_RX_BCAST;
323 /* get current timeout setting */
324 static ssize_t qeth_vnicc_timeout_show(struct device *dev,
325 struct device_attribute *attr, char *buf)
327 struct qeth_card *card = dev_get_drvdata(dev);
334 rc = qeth_l2_vnicc_get_timeout(card, &timeout);
336 return sprintf(buf, "n/a (BridgePort)\n");
337 if (rc == -EOPNOTSUPP)
338 return sprintf(buf, "n/a\n");
339 return rc ? rc : sprintf(buf, "%d\n", timeout);
342 /* change timeout setting */
343 static ssize_t qeth_vnicc_timeout_store(struct device *dev,
344 struct device_attribute *attr,
345 const char *buf, size_t count)
347 struct qeth_card *card = dev_get_drvdata(dev);
354 rc = kstrtou32(buf, 10, &timeout);
358 mutex_lock(&card->conf_mutex);
359 rc = qeth_l2_vnicc_set_timeout(card, timeout);
360 mutex_unlock(&card->conf_mutex);
361 return rc ? rc : count;
364 /* get current setting of characteristic */
365 static ssize_t qeth_vnicc_char_show(struct device *dev,
366 struct device_attribute *attr, char *buf)
368 struct qeth_card *card = dev_get_drvdata(dev);
376 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
377 rc = qeth_l2_vnicc_get_state(card, vnicc, &state);
380 return sprintf(buf, "n/a (BridgePort)\n");
381 if (rc == -EOPNOTSUPP)
382 return sprintf(buf, "n/a\n");
383 return rc ? rc : sprintf(buf, "%d\n", state);
386 /* change setting of characteristic */
387 static ssize_t qeth_vnicc_char_store(struct device *dev,
388 struct device_attribute *attr,
389 const char *buf, size_t count)
391 struct qeth_card *card = dev_get_drvdata(dev);
399 if (kstrtobool(buf, &state))
402 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
403 mutex_lock(&card->conf_mutex);
404 rc = qeth_l2_vnicc_set_state(card, vnicc, state);
405 mutex_unlock(&card->conf_mutex);
407 return rc ? rc : count;
410 static DEVICE_ATTR(flooding, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
411 static DEVICE_ATTR(mcast_flooding, 0644, qeth_vnicc_char_show,
412 qeth_vnicc_char_store);
413 static DEVICE_ATTR(learning, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
414 static DEVICE_ATTR(learning_timeout, 0644, qeth_vnicc_timeout_show,
415 qeth_vnicc_timeout_store);
416 static DEVICE_ATTR(takeover_setvmac, 0644, qeth_vnicc_char_show,
417 qeth_vnicc_char_store);
418 static DEVICE_ATTR(takeover_learning, 0644, qeth_vnicc_char_show,
419 qeth_vnicc_char_store);
420 static DEVICE_ATTR(bridge_invisible, 0644, qeth_vnicc_char_show,
421 qeth_vnicc_char_store);
422 static DEVICE_ATTR(rx_bcast, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
424 static struct attribute *qeth_l2_vnicc_attrs[] = {
425 &dev_attr_flooding.attr,
426 &dev_attr_mcast_flooding.attr,
427 &dev_attr_learning.attr,
428 &dev_attr_learning_timeout.attr,
429 &dev_attr_takeover_setvmac.attr,
430 &dev_attr_takeover_learning.attr,
431 &dev_attr_bridge_invisible.attr,
432 &dev_attr_rx_bcast.attr,
436 static struct attribute_group qeth_l2_vnicc_attr_group = {
437 .attrs = qeth_l2_vnicc_attrs,
441 static const struct attribute_group *qeth_l2_only_attr_groups[] = {
442 &qeth_l2_bridgeport_attr_group,
443 &qeth_l2_vnicc_attr_group,
447 int qeth_l2_create_device_attributes(struct device *dev)
449 return sysfs_create_groups(&dev->kobj, qeth_l2_only_attr_groups);
452 void qeth_l2_remove_device_attributes(struct device *dev)
454 sysfs_remove_groups(&dev->kobj, qeth_l2_only_attr_groups);
457 const struct attribute_group *qeth_l2_attr_groups[] = {
458 &qeth_device_attr_group,
459 &qeth_device_blkt_group,
460 /* l2 specific, see qeth_l2_only_attr_groups: */
461 &qeth_l2_bridgeport_attr_group,
462 &qeth_l2_vnicc_attr_group,