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 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
12 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
14 static ssize_t
qeth_bridge_port_role_state_show(struct device
*dev
,
15 struct device_attribute
*attr
, char *buf
,
18 struct qeth_card
*card
= dev_get_drvdata(dev
);
19 enum qeth_sbp_states state
= QETH_SBP_STATE_INACTIVE
;
26 if (qeth_card_hw_is_reachable(card
) &&
27 card
->options
.sbp
.supported_funcs
)
28 rc
= qeth_bridgeport_query_ports(card
,
29 &card
->options
.sbp
.role
, &state
);
33 case QETH_SBP_STATE_INACTIVE
:
34 word
= "inactive"; break;
35 case QETH_SBP_STATE_STANDBY
:
36 word
= "standby"; break;
37 case QETH_SBP_STATE_ACTIVE
:
38 word
= "active"; break;
43 switch (card
->options
.sbp
.role
) {
44 case QETH_SBP_ROLE_NONE
:
46 case QETH_SBP_ROLE_PRIMARY
:
47 word
= "primary"; break;
48 case QETH_SBP_ROLE_SECONDARY
:
49 word
= "secondary"; break;
54 QETH_CARD_TEXT_(card
, 2, "SBP%02x:%02x",
55 card
->options
.sbp
.role
, state
);
57 rc
= sprintf(buf
, "%s\n", word
);
63 static ssize_t
qeth_bridge_port_role_show(struct device
*dev
,
64 struct device_attribute
*attr
, char *buf
)
66 return qeth_bridge_port_role_state_show(dev
, attr
, buf
, 0);
69 static ssize_t
qeth_bridge_port_role_store(struct device
*dev
,
70 struct device_attribute
*attr
, const char *buf
, size_t count
)
72 struct qeth_card
*card
= dev_get_drvdata(dev
);
74 enum qeth_sbp_roles role
;
78 if (sysfs_streq(buf
, "primary"))
79 role
= QETH_SBP_ROLE_PRIMARY
;
80 else if (sysfs_streq(buf
, "secondary"))
81 role
= QETH_SBP_ROLE_SECONDARY
;
82 else if (sysfs_streq(buf
, "none"))
83 role
= QETH_SBP_ROLE_NONE
;
87 mutex_lock(&card
->conf_mutex
);
89 if (card
->options
.sbp
.reflect_promisc
) /* Forbid direct manipulation */
91 else if (qeth_card_hw_is_reachable(card
)) {
92 rc
= qeth_bridgeport_setrole(card
, role
);
94 card
->options
.sbp
.role
= role
;
96 card
->options
.sbp
.role
= role
;
98 mutex_unlock(&card
->conf_mutex
);
100 return rc
? rc
: count
;
103 static DEVICE_ATTR(bridge_role
, 0644, qeth_bridge_port_role_show
,
104 qeth_bridge_port_role_store
);
106 static ssize_t
qeth_bridge_port_state_show(struct device
*dev
,
107 struct device_attribute
*attr
, char *buf
)
109 return qeth_bridge_port_role_state_show(dev
, attr
, buf
, 1);
112 static DEVICE_ATTR(bridge_state
, 0644, qeth_bridge_port_state_show
,
115 static ssize_t
qeth_bridgeport_hostnotification_show(struct device
*dev
,
116 struct device_attribute
*attr
, char *buf
)
118 struct qeth_card
*card
= dev_get_drvdata(dev
);
124 enabled
= card
->options
.sbp
.hostnotification
;
126 return sprintf(buf
, "%d\n", enabled
);
129 static ssize_t
qeth_bridgeport_hostnotification_store(struct device
*dev
,
130 struct device_attribute
*attr
, const char *buf
, size_t count
)
132 struct qeth_card
*card
= dev_get_drvdata(dev
);
139 if (sysfs_streq(buf
, "0"))
141 else if (sysfs_streq(buf
, "1"))
146 mutex_lock(&card
->conf_mutex
);
148 if (qeth_card_hw_is_reachable(card
)) {
149 rc
= qeth_bridgeport_an_set(card
, enable
);
151 card
->options
.sbp
.hostnotification
= enable
;
153 card
->options
.sbp
.hostnotification
= enable
;
155 mutex_unlock(&card
->conf_mutex
);
157 return rc
? rc
: count
;
160 static DEVICE_ATTR(bridge_hostnotify
, 0644,
161 qeth_bridgeport_hostnotification_show
,
162 qeth_bridgeport_hostnotification_store
);
164 static ssize_t
qeth_bridgeport_reflect_show(struct device
*dev
,
165 struct device_attribute
*attr
, char *buf
)
167 struct qeth_card
*card
= dev_get_drvdata(dev
);
173 if (card
->options
.sbp
.reflect_promisc
) {
174 if (card
->options
.sbp
.reflect_promisc_primary
)
181 return sprintf(buf
, "%s\n", state
);
184 static ssize_t
qeth_bridgeport_reflect_store(struct device
*dev
,
185 struct device_attribute
*attr
, const char *buf
, size_t count
)
187 struct qeth_card
*card
= dev_get_drvdata(dev
);
194 if (sysfs_streq(buf
, "none")) {
197 } else if (sysfs_streq(buf
, "primary")) {
200 } else if (sysfs_streq(buf
, "secondary")) {
206 mutex_lock(&card
->conf_mutex
);
208 if (card
->options
.sbp
.role
!= QETH_SBP_ROLE_NONE
)
211 card
->options
.sbp
.reflect_promisc
= enable
;
212 card
->options
.sbp
.reflect_promisc_primary
= primary
;
216 mutex_unlock(&card
->conf_mutex
);
218 return rc
? rc
: count
;
221 static DEVICE_ATTR(bridge_reflect_promisc
, 0644,
222 qeth_bridgeport_reflect_show
,
223 qeth_bridgeport_reflect_store
);
225 static struct attribute
*qeth_l2_bridgeport_attrs
[] = {
226 &dev_attr_bridge_role
.attr
,
227 &dev_attr_bridge_state
.attr
,
228 &dev_attr_bridge_hostnotify
.attr
,
229 &dev_attr_bridge_reflect_promisc
.attr
,
233 static struct attribute_group qeth_l2_bridgeport_attr_group
= {
234 .attrs
= qeth_l2_bridgeport_attrs
,
237 int qeth_l2_create_device_attributes(struct device
*dev
)
239 return sysfs_create_group(&dev
->kobj
, &qeth_l2_bridgeport_attr_group
);
242 void qeth_l2_remove_device_attributes(struct device
*dev
)
244 sysfs_remove_group(&dev
->kobj
, &qeth_l2_bridgeport_attr_group
);
248 * qeth_l2_setup_bridgeport_attrs() - set/restore attrs when turning online.
249 * @card: qeth_card structure pointer
251 * Note: this function is called with conf_mutex held by the caller
253 void qeth_l2_setup_bridgeport_attrs(struct qeth_card
*card
)
259 if (!card
->options
.sbp
.supported_funcs
)
261 if (card
->options
.sbp
.role
!= QETH_SBP_ROLE_NONE
) {
262 /* Conditional to avoid spurious error messages */
263 qeth_bridgeport_setrole(card
, card
->options
.sbp
.role
);
264 /* Let the callback function refresh the stored role value. */
265 qeth_bridgeport_query_ports(card
,
266 &card
->options
.sbp
.role
, NULL
);
268 if (card
->options
.sbp
.hostnotification
) {
269 rc
= qeth_bridgeport_an_set(card
, 1);
271 card
->options
.sbp
.hostnotification
= 0;
273 qeth_bridgeport_an_set(card
, 0);