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_card_hw_is_reachable(card
) &&
25 card
->options
.sbp
.supported_funcs
)
26 rc
= qeth_bridgeport_query_ports(card
,
27 &card
->options
.sbp
.role
, &state
);
31 case QETH_SBP_STATE_INACTIVE
:
32 word
= "inactive"; break;
33 case QETH_SBP_STATE_STANDBY
:
34 word
= "standby"; break;
35 case QETH_SBP_STATE_ACTIVE
:
36 word
= "active"; break;
41 switch (card
->options
.sbp
.role
) {
42 case QETH_SBP_ROLE_NONE
:
44 case QETH_SBP_ROLE_PRIMARY
:
45 word
= "primary"; break;
46 case QETH_SBP_ROLE_SECONDARY
:
47 word
= "secondary"; break;
52 QETH_CARD_TEXT_(card
, 2, "SBP%02x:%02x",
53 card
->options
.sbp
.role
, state
);
55 rc
= sprintf(buf
, "%s\n", word
);
61 static ssize_t
qeth_bridge_port_role_show(struct device
*dev
,
62 struct device_attribute
*attr
, char *buf
)
64 return qeth_bridge_port_role_state_show(dev
, attr
, buf
, 0);
67 static ssize_t
qeth_bridge_port_role_store(struct device
*dev
,
68 struct device_attribute
*attr
, const char *buf
, size_t count
)
70 struct qeth_card
*card
= dev_get_drvdata(dev
);
72 enum qeth_sbp_roles role
;
76 if (sysfs_streq(buf
, "primary"))
77 role
= QETH_SBP_ROLE_PRIMARY
;
78 else if (sysfs_streq(buf
, "secondary"))
79 role
= QETH_SBP_ROLE_SECONDARY
;
80 else if (sysfs_streq(buf
, "none"))
81 role
= QETH_SBP_ROLE_NONE
;
85 mutex_lock(&card
->conf_mutex
);
87 if (card
->options
.sbp
.reflect_promisc
) /* Forbid direct manipulation */
89 else if (qeth_card_hw_is_reachable(card
)) {
90 rc
= qeth_bridgeport_setrole(card
, role
);
92 card
->options
.sbp
.role
= role
;
94 card
->options
.sbp
.role
= role
;
96 mutex_unlock(&card
->conf_mutex
);
98 return rc
? rc
: count
;
101 static DEVICE_ATTR(bridge_role
, 0644, qeth_bridge_port_role_show
,
102 qeth_bridge_port_role_store
);
104 static ssize_t
qeth_bridge_port_state_show(struct device
*dev
,
105 struct device_attribute
*attr
, char *buf
)
107 return qeth_bridge_port_role_state_show(dev
, attr
, buf
, 1);
110 static DEVICE_ATTR(bridge_state
, 0444, qeth_bridge_port_state_show
,
113 static ssize_t
qeth_bridgeport_hostnotification_show(struct device
*dev
,
114 struct device_attribute
*attr
, char *buf
)
116 struct qeth_card
*card
= dev_get_drvdata(dev
);
122 enabled
= card
->options
.sbp
.hostnotification
;
124 return sprintf(buf
, "%d\n", enabled
);
127 static ssize_t
qeth_bridgeport_hostnotification_store(struct device
*dev
,
128 struct device_attribute
*attr
, const char *buf
, size_t count
)
130 struct qeth_card
*card
= dev_get_drvdata(dev
);
137 if (sysfs_streq(buf
, "0"))
139 else if (sysfs_streq(buf
, "1"))
144 mutex_lock(&card
->conf_mutex
);
146 if (qeth_card_hw_is_reachable(card
)) {
147 rc
= qeth_bridgeport_an_set(card
, enable
);
149 card
->options
.sbp
.hostnotification
= enable
;
151 card
->options
.sbp
.hostnotification
= enable
;
153 mutex_unlock(&card
->conf_mutex
);
155 return rc
? rc
: count
;
158 static DEVICE_ATTR(bridge_hostnotify
, 0644,
159 qeth_bridgeport_hostnotification_show
,
160 qeth_bridgeport_hostnotification_store
);
162 static ssize_t
qeth_bridgeport_reflect_show(struct device
*dev
,
163 struct device_attribute
*attr
, char *buf
)
165 struct qeth_card
*card
= dev_get_drvdata(dev
);
171 if (card
->options
.sbp
.reflect_promisc
) {
172 if (card
->options
.sbp
.reflect_promisc_primary
)
179 return sprintf(buf
, "%s\n", state
);
182 static ssize_t
qeth_bridgeport_reflect_store(struct device
*dev
,
183 struct device_attribute
*attr
, const char *buf
, size_t count
)
185 struct qeth_card
*card
= dev_get_drvdata(dev
);
192 if (sysfs_streq(buf
, "none")) {
195 } else if (sysfs_streq(buf
, "primary")) {
198 } else if (sysfs_streq(buf
, "secondary")) {
204 mutex_lock(&card
->conf_mutex
);
206 if (card
->options
.sbp
.role
!= QETH_SBP_ROLE_NONE
)
209 card
->options
.sbp
.reflect_promisc
= enable
;
210 card
->options
.sbp
.reflect_promisc_primary
= primary
;
214 mutex_unlock(&card
->conf_mutex
);
216 return rc
? rc
: count
;
219 static DEVICE_ATTR(bridge_reflect_promisc
, 0644,
220 qeth_bridgeport_reflect_show
,
221 qeth_bridgeport_reflect_store
);
223 static struct attribute
*qeth_l2_bridgeport_attrs
[] = {
224 &dev_attr_bridge_role
.attr
,
225 &dev_attr_bridge_state
.attr
,
226 &dev_attr_bridge_hostnotify
.attr
,
227 &dev_attr_bridge_reflect_promisc
.attr
,
231 static struct attribute_group qeth_l2_bridgeport_attr_group
= {
232 .attrs
= qeth_l2_bridgeport_attrs
,
235 int qeth_l2_create_device_attributes(struct device
*dev
)
237 return sysfs_create_group(&dev
->kobj
, &qeth_l2_bridgeport_attr_group
);
240 void qeth_l2_remove_device_attributes(struct device
*dev
)
242 sysfs_remove_group(&dev
->kobj
, &qeth_l2_bridgeport_attr_group
);
246 * qeth_l2_setup_bridgeport_attrs() - set/restore attrs when turning online.
247 * @card: qeth_card structure pointer
249 * Note: this function is called with conf_mutex held by the caller
251 void qeth_l2_setup_bridgeport_attrs(struct qeth_card
*card
)
257 if (!card
->options
.sbp
.supported_funcs
)
259 if (card
->options
.sbp
.role
!= QETH_SBP_ROLE_NONE
) {
260 /* Conditional to avoid spurious error messages */
261 qeth_bridgeport_setrole(card
, card
->options
.sbp
.role
);
262 /* Let the callback function refresh the stored role value. */
263 qeth_bridgeport_query_ports(card
,
264 &card
->options
.sbp
.role
, NULL
);
266 if (card
->options
.sbp
.hostnotification
) {
267 rc
= qeth_bridgeport_an_set(card
, 1);
269 card
->options
.sbp
.hostnotification
= 0;
271 qeth_bridgeport_an_set(card
, 0);
274 const struct attribute_group
*qeth_l2_attr_groups
[] = {
275 &qeth_device_attr_group
,
276 &qeth_device_blkt_group
,
277 /* l2 specific, see l2_{create,remove}_device_attributes(): */
278 &qeth_l2_bridgeport_attr_group
,