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
;
21 if (!qeth_bridgeport_allowed(card
))
22 return sprintf(buf
, "n/a (VNIC characteristics)\n");
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
);
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;
42 switch (card
->options
.sbp
.role
) {
43 case QETH_SBP_ROLE_NONE
:
45 case QETH_SBP_ROLE_PRIMARY
:
46 word
= "primary"; break;
47 case QETH_SBP_ROLE_SECONDARY
:
48 word
= "secondary"; break;
53 QETH_CARD_TEXT_(card
, 2, "SBP%02x:%02x",
54 card
->options
.sbp
.role
, state
);
56 rc
= sprintf(buf
, "%s\n", word
);
58 mutex_unlock(&card
->sbp_lock
);
63 static ssize_t
qeth_bridge_port_role_show(struct device
*dev
,
64 struct device_attribute
*attr
, char *buf
)
66 struct qeth_card
*card
= dev_get_drvdata(dev
);
68 if (!qeth_bridgeport_allowed(card
))
69 return sprintf(buf
, "n/a (VNIC characteristics)\n");
71 return qeth_bridge_port_role_state_show(dev
, attr
, buf
, 0);
74 static ssize_t
qeth_bridge_port_role_store(struct device
*dev
,
75 struct device_attribute
*attr
, const char *buf
, size_t count
)
77 struct qeth_card
*card
= dev_get_drvdata(dev
);
79 enum qeth_sbp_roles role
;
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
;
90 mutex_lock(&card
->conf_mutex
);
91 mutex_lock(&card
->sbp_lock
);
93 if (!qeth_bridgeport_allowed(card
))
95 else if (card
->options
.sbp
.reflect_promisc
)
96 /* Forbid direct manipulation */
98 else if (qeth_card_hw_is_reachable(card
)) {
99 rc
= qeth_bridgeport_setrole(card
, role
);
101 card
->options
.sbp
.role
= role
;
103 card
->options
.sbp
.role
= role
;
105 mutex_unlock(&card
->sbp_lock
);
106 mutex_unlock(&card
->conf_mutex
);
108 return rc
? rc
: count
;
111 static DEVICE_ATTR(bridge_role
, 0644, qeth_bridge_port_role_show
,
112 qeth_bridge_port_role_store
);
114 static ssize_t
qeth_bridge_port_state_show(struct device
*dev
,
115 struct device_attribute
*attr
, char *buf
)
117 struct qeth_card
*card
= dev_get_drvdata(dev
);
119 if (!qeth_bridgeport_allowed(card
))
120 return sprintf(buf
, "n/a (VNIC characteristics)\n");
122 return qeth_bridge_port_role_state_show(dev
, attr
, buf
, 1);
125 static DEVICE_ATTR(bridge_state
, 0444, qeth_bridge_port_state_show
,
128 static ssize_t
qeth_bridgeport_hostnotification_show(struct device
*dev
,
129 struct device_attribute
*attr
, char *buf
)
131 struct qeth_card
*card
= dev_get_drvdata(dev
);
134 if (!qeth_bridgeport_allowed(card
))
135 return sprintf(buf
, "n/a (VNIC characteristics)\n");
137 enabled
= card
->options
.sbp
.hostnotification
;
139 return sprintf(buf
, "%d\n", enabled
);
142 static ssize_t
qeth_bridgeport_hostnotification_store(struct device
*dev
,
143 struct device_attribute
*attr
, const char *buf
, size_t count
)
145 struct qeth_card
*card
= dev_get_drvdata(dev
);
149 rc
= kstrtobool(buf
, &enable
);
153 mutex_lock(&card
->conf_mutex
);
154 mutex_lock(&card
->sbp_lock
);
156 if (!qeth_bridgeport_allowed(card
))
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 */
162 card
->options
.sbp
.hostnotification
= enable
;
164 card
->options
.sbp
.hostnotification
= enable
;
166 mutex_unlock(&card
->sbp_lock
);
167 mutex_unlock(&card
->conf_mutex
);
169 return rc
? rc
: count
;
172 static DEVICE_ATTR(bridge_hostnotify
, 0644,
173 qeth_bridgeport_hostnotification_show
,
174 qeth_bridgeport_hostnotification_store
);
176 static ssize_t
qeth_bridgeport_reflect_show(struct device
*dev
,
177 struct device_attribute
*attr
, char *buf
)
179 struct qeth_card
*card
= dev_get_drvdata(dev
);
182 if (!qeth_bridgeport_allowed(card
))
183 return sprintf(buf
, "n/a (VNIC characteristics)\n");
185 if (card
->options
.sbp
.reflect_promisc
) {
186 if (card
->options
.sbp
.reflect_promisc_primary
)
193 return sprintf(buf
, "%s\n", state
);
196 static ssize_t
qeth_bridgeport_reflect_store(struct device
*dev
,
197 struct device_attribute
*attr
, const char *buf
, size_t count
)
199 struct qeth_card
*card
= dev_get_drvdata(dev
);
203 if (sysfs_streq(buf
, "none")) {
206 } else if (sysfs_streq(buf
, "primary")) {
209 } else if (sysfs_streq(buf
, "secondary")) {
215 mutex_lock(&card
->conf_mutex
);
216 mutex_lock(&card
->sbp_lock
);
218 if (!qeth_bridgeport_allowed(card
))
220 else if (card
->options
.sbp
.role
!= QETH_SBP_ROLE_NONE
)
223 card
->options
.sbp
.reflect_promisc
= enable
;
224 card
->options
.sbp
.reflect_promisc_primary
= primary
;
228 mutex_unlock(&card
->sbp_lock
);
229 mutex_unlock(&card
->conf_mutex
);
231 return rc
? rc
: count
;
234 static DEVICE_ATTR(bridge_reflect_promisc
, 0644,
235 qeth_bridgeport_reflect_show
,
236 qeth_bridgeport_reflect_store
);
238 static 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
,
246 static struct attribute_group qeth_l2_bridgeport_attr_group
= {
247 .attrs
= qeth_l2_bridgeport_attrs
,
250 /* VNIC CHARS support */
252 /* convert sysfs attr name to VNIC characteristic */
253 static u32
qeth_l2_vnicc_sysfs_attr_to_char(const char *attr_name
)
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
;
273 /* get current timeout setting */
274 static ssize_t
qeth_vnicc_timeout_show(struct device
*dev
,
275 struct device_attribute
*attr
, char *buf
)
277 struct qeth_card
*card
= dev_get_drvdata(dev
);
281 rc
= qeth_l2_vnicc_get_timeout(card
, &timeout
);
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
);
289 /* change timeout setting */
290 static ssize_t
qeth_vnicc_timeout_store(struct device
*dev
,
291 struct device_attribute
*attr
,
292 const char *buf
, size_t count
)
294 struct qeth_card
*card
= dev_get_drvdata(dev
);
298 rc
= kstrtou32(buf
, 10, &timeout
);
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
;
308 /* get current setting of characteristic */
309 static ssize_t
qeth_vnicc_char_show(struct device
*dev
,
310 struct device_attribute
*attr
, char *buf
)
312 struct qeth_card
*card
= dev_get_drvdata(dev
);
317 vnicc
= qeth_l2_vnicc_sysfs_attr_to_char(attr
->attr
.name
);
318 rc
= qeth_l2_vnicc_get_state(card
, vnicc
, &state
);
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
);
327 /* change setting of characteristic */
328 static ssize_t
qeth_vnicc_char_store(struct device
*dev
,
329 struct device_attribute
*attr
,
330 const char *buf
, size_t count
)
332 struct qeth_card
*card
= dev_get_drvdata(dev
);
337 if (kstrtobool(buf
, &state
))
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
);
345 return rc
? rc
: count
;
348 static DEVICE_ATTR(flooding
, 0644, qeth_vnicc_char_show
, qeth_vnicc_char_store
);
349 static DEVICE_ATTR(mcast_flooding
, 0644, qeth_vnicc_char_show
,
350 qeth_vnicc_char_store
);
351 static DEVICE_ATTR(learning
, 0644, qeth_vnicc_char_show
, qeth_vnicc_char_store
);
352 static DEVICE_ATTR(learning_timeout
, 0644, qeth_vnicc_timeout_show
,
353 qeth_vnicc_timeout_store
);
354 static DEVICE_ATTR(takeover_setvmac
, 0644, qeth_vnicc_char_show
,
355 qeth_vnicc_char_store
);
356 static DEVICE_ATTR(takeover_learning
, 0644, qeth_vnicc_char_show
,
357 qeth_vnicc_char_store
);
358 static DEVICE_ATTR(bridge_invisible
, 0644, qeth_vnicc_char_show
,
359 qeth_vnicc_char_store
);
360 static DEVICE_ATTR(rx_bcast
, 0644, qeth_vnicc_char_show
, qeth_vnicc_char_store
);
362 static 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
,
374 static struct attribute_group qeth_l2_vnicc_attr_group
= {
375 .attrs
= qeth_l2_vnicc_attrs
,
379 const struct attribute_group
*qeth_l2_attr_groups
[] = {
380 &qeth_l2_bridgeport_attr_group
,
381 &qeth_l2_vnicc_attr_group
,