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
,