2 * Copyright IBM Corp. 2013
3 * Author(s): Eugene Crosser <eugene.crosser@ru.ibm.com>
6 #include <linux/slab.h>
7 #include <asm/ebcdic.h>
11 static ssize_t
qeth_bridge_port_role_state_show(struct device
*dev
,
12 struct device_attribute
*attr
, char *buf
,
15 struct qeth_card
*card
= dev_get_drvdata(dev
);
16 enum qeth_sbp_states state
= QETH_SBP_STATE_INACTIVE
;
23 if (qeth_card_hw_is_reachable(card
) &&
24 card
->options
.sbp
.supported_funcs
)
25 rc
= qeth_bridgeport_query_ports(card
,
26 &card
->options
.sbp
.role
, &state
);
30 case QETH_SBP_STATE_INACTIVE
:
31 word
= "inactive"; break;
32 case QETH_SBP_STATE_STANDBY
:
33 word
= "standby"; break;
34 case QETH_SBP_STATE_ACTIVE
:
35 word
= "active"; break;
40 switch (card
->options
.sbp
.role
) {
41 case QETH_SBP_ROLE_NONE
:
43 case QETH_SBP_ROLE_PRIMARY
:
44 word
= "primary"; break;
45 case QETH_SBP_ROLE_SECONDARY
:
46 word
= "secondary"; break;
51 QETH_CARD_TEXT_(card
, 2, "SBP%02x:%02x",
52 card
->options
.sbp
.role
, state
);
54 rc
= sprintf(buf
, "%s\n", word
);
60 static ssize_t
qeth_bridge_port_role_show(struct device
*dev
,
61 struct device_attribute
*attr
, char *buf
)
63 return qeth_bridge_port_role_state_show(dev
, attr
, buf
, 0);
66 static ssize_t
qeth_bridge_port_role_store(struct device
*dev
,
67 struct device_attribute
*attr
, const char *buf
, size_t count
)
69 struct qeth_card
*card
= dev_get_drvdata(dev
);
71 enum qeth_sbp_roles role
;
75 if (sysfs_streq(buf
, "primary"))
76 role
= QETH_SBP_ROLE_PRIMARY
;
77 else if (sysfs_streq(buf
, "secondary"))
78 role
= QETH_SBP_ROLE_SECONDARY
;
79 else if (sysfs_streq(buf
, "none"))
80 role
= QETH_SBP_ROLE_NONE
;
84 mutex_lock(&card
->conf_mutex
);
86 if (card
->options
.sbp
.reflect_promisc
) /* Forbid direct manipulation */
88 else if (qeth_card_hw_is_reachable(card
)) {
89 rc
= qeth_bridgeport_setrole(card
, role
);
91 card
->options
.sbp
.role
= role
;
93 card
->options
.sbp
.role
= role
;
95 mutex_unlock(&card
->conf_mutex
);
97 return rc
? rc
: count
;
100 static DEVICE_ATTR(bridge_role
, 0644, qeth_bridge_port_role_show
,
101 qeth_bridge_port_role_store
);
103 static ssize_t
qeth_bridge_port_state_show(struct device
*dev
,
104 struct device_attribute
*attr
, char *buf
)
106 return qeth_bridge_port_role_state_show(dev
, attr
, buf
, 1);
109 static DEVICE_ATTR(bridge_state
, 0444, qeth_bridge_port_state_show
,
112 static ssize_t
qeth_bridgeport_hostnotification_show(struct device
*dev
,
113 struct device_attribute
*attr
, char *buf
)
115 struct qeth_card
*card
= dev_get_drvdata(dev
);
121 enabled
= card
->options
.sbp
.hostnotification
;
123 return sprintf(buf
, "%d\n", enabled
);
126 static ssize_t
qeth_bridgeport_hostnotification_store(struct device
*dev
,
127 struct device_attribute
*attr
, const char *buf
, size_t count
)
129 struct qeth_card
*card
= dev_get_drvdata(dev
);
136 if (sysfs_streq(buf
, "0"))
138 else if (sysfs_streq(buf
, "1"))
143 mutex_lock(&card
->conf_mutex
);
145 if (qeth_card_hw_is_reachable(card
)) {
146 rc
= qeth_bridgeport_an_set(card
, enable
);
148 card
->options
.sbp
.hostnotification
= enable
;
150 card
->options
.sbp
.hostnotification
= enable
;
152 mutex_unlock(&card
->conf_mutex
);
154 return rc
? rc
: count
;
157 static DEVICE_ATTR(bridge_hostnotify
, 0644,
158 qeth_bridgeport_hostnotification_show
,
159 qeth_bridgeport_hostnotification_store
);
161 static ssize_t
qeth_bridgeport_reflect_show(struct device
*dev
,
162 struct device_attribute
*attr
, char *buf
)
164 struct qeth_card
*card
= dev_get_drvdata(dev
);
170 if (card
->options
.sbp
.reflect_promisc
) {
171 if (card
->options
.sbp
.reflect_promisc_primary
)
178 return sprintf(buf
, "%s\n", state
);
181 static ssize_t
qeth_bridgeport_reflect_store(struct device
*dev
,
182 struct device_attribute
*attr
, const char *buf
, size_t count
)
184 struct qeth_card
*card
= dev_get_drvdata(dev
);
191 if (sysfs_streq(buf
, "none")) {
194 } else if (sysfs_streq(buf
, "primary")) {
197 } else if (sysfs_streq(buf
, "secondary")) {
203 mutex_lock(&card
->conf_mutex
);
205 if (card
->options
.sbp
.role
!= QETH_SBP_ROLE_NONE
)
208 card
->options
.sbp
.reflect_promisc
= enable
;
209 card
->options
.sbp
.reflect_promisc_primary
= primary
;
213 mutex_unlock(&card
->conf_mutex
);
215 return rc
? rc
: count
;
218 static DEVICE_ATTR(bridge_reflect_promisc
, 0644,
219 qeth_bridgeport_reflect_show
,
220 qeth_bridgeport_reflect_store
);
222 static struct attribute
*qeth_l2_bridgeport_attrs
[] = {
223 &dev_attr_bridge_role
.attr
,
224 &dev_attr_bridge_state
.attr
,
225 &dev_attr_bridge_hostnotify
.attr
,
226 &dev_attr_bridge_reflect_promisc
.attr
,
230 static struct attribute_group qeth_l2_bridgeport_attr_group
= {
231 .attrs
= qeth_l2_bridgeport_attrs
,
234 int qeth_l2_create_device_attributes(struct device
*dev
)
236 return sysfs_create_group(&dev
->kobj
, &qeth_l2_bridgeport_attr_group
);
239 void qeth_l2_remove_device_attributes(struct device
*dev
)
241 sysfs_remove_group(&dev
->kobj
, &qeth_l2_bridgeport_attr_group
);
245 * qeth_l2_setup_bridgeport_attrs() - set/restore attrs when turning online.
246 * @card: qeth_card structure pointer
248 * Note: this function is called with conf_mutex held by the caller
250 void qeth_l2_setup_bridgeport_attrs(struct qeth_card
*card
)
256 if (!card
->options
.sbp
.supported_funcs
)
258 if (card
->options
.sbp
.role
!= QETH_SBP_ROLE_NONE
) {
259 /* Conditional to avoid spurious error messages */
260 qeth_bridgeport_setrole(card
, card
->options
.sbp
.role
);
261 /* Let the callback function refresh the stored role value. */
262 qeth_bridgeport_query_ports(card
,
263 &card
->options
.sbp
.role
, NULL
);
265 if (card
->options
.sbp
.hostnotification
) {
266 rc
= qeth_bridgeport_an_set(card
, 1);
268 card
->options
.sbp
.hostnotification
= 0;
270 qeth_bridgeport_an_set(card
, 0);
273 const struct attribute_group
*qeth_l2_attr_groups
[] = {
274 &qeth_device_attr_group
,
275 &qeth_device_blkt_group
,
276 /* l2 specific, see l2_{create,remove}_device_attributes(): */
277 &qeth_l2_bridgeport_attr_group
,