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 mutex_lock(&card
->conf_mutex
);
28 if (qeth_card_hw_is_reachable(card
) &&
29 card
->options
.sbp
.supported_funcs
)
30 rc
= qeth_bridgeport_query_ports(card
,
31 &card
->options
.sbp
.role
, &state
);
35 case QETH_SBP_STATE_INACTIVE
:
36 word
= "inactive"; break;
37 case QETH_SBP_STATE_STANDBY
:
38 word
= "standby"; break;
39 case QETH_SBP_STATE_ACTIVE
:
40 word
= "active"; break;
45 switch (card
->options
.sbp
.role
) {
46 case QETH_SBP_ROLE_NONE
:
48 case QETH_SBP_ROLE_PRIMARY
:
49 word
= "primary"; break;
50 case QETH_SBP_ROLE_SECONDARY
:
51 word
= "secondary"; break;
56 QETH_CARD_TEXT_(card
, 2, "SBP%02x:%02x",
57 card
->options
.sbp
.role
, state
);
59 rc
= sprintf(buf
, "%s\n", word
);
62 mutex_unlock(&card
->conf_mutex
);
67 static ssize_t
qeth_bridge_port_role_show(struct device
*dev
,
68 struct device_attribute
*attr
, char *buf
)
70 return qeth_bridge_port_role_state_show(dev
, attr
, buf
, 0);
73 static ssize_t
qeth_bridge_port_role_store(struct device
*dev
,
74 struct device_attribute
*attr
, const char *buf
, size_t count
)
76 struct qeth_card
*card
= dev_get_drvdata(dev
);
78 enum qeth_sbp_roles role
;
82 if (sysfs_streq(buf
, "primary"))
83 role
= QETH_SBP_ROLE_PRIMARY
;
84 else if (sysfs_streq(buf
, "secondary"))
85 role
= QETH_SBP_ROLE_SECONDARY
;
86 else if (sysfs_streq(buf
, "none"))
87 role
= QETH_SBP_ROLE_NONE
;
91 mutex_lock(&card
->conf_mutex
);
93 if (qeth_card_hw_is_reachable(card
)) {
94 rc
= qeth_bridgeport_setrole(card
, role
);
96 card
->options
.sbp
.role
= role
;
98 card
->options
.sbp
.role
= role
;
100 mutex_unlock(&card
->conf_mutex
);
102 return rc
? rc
: count
;
105 static DEVICE_ATTR(bridge_role
, 0644, qeth_bridge_port_role_show
,
106 qeth_bridge_port_role_store
);
108 static ssize_t
qeth_bridge_port_state_show(struct device
*dev
,
109 struct device_attribute
*attr
, char *buf
)
111 return qeth_bridge_port_role_state_show(dev
, attr
, buf
, 1);
114 static DEVICE_ATTR(bridge_state
, 0644, qeth_bridge_port_state_show
,
117 static ssize_t
qeth_bridgeport_hostnotification_show(struct device
*dev
,
118 struct device_attribute
*attr
, char *buf
)
120 struct qeth_card
*card
= dev_get_drvdata(dev
);
126 mutex_lock(&card
->conf_mutex
);
128 enabled
= card
->options
.sbp
.hostnotification
;
130 mutex_unlock(&card
->conf_mutex
);
132 return sprintf(buf
, "%d\n", enabled
);
135 static ssize_t
qeth_bridgeport_hostnotification_store(struct device
*dev
,
136 struct device_attribute
*attr
, const char *buf
, size_t count
)
138 struct qeth_card
*card
= dev_get_drvdata(dev
);
145 if (sysfs_streq(buf
, "0"))
147 else if (sysfs_streq(buf
, "1"))
152 mutex_lock(&card
->conf_mutex
);
154 if (qeth_card_hw_is_reachable(card
)) {
155 rc
= qeth_bridgeport_an_set(card
, enable
);
157 card
->options
.sbp
.hostnotification
= enable
;
159 card
->options
.sbp
.hostnotification
= enable
;
161 mutex_unlock(&card
->conf_mutex
);
163 return rc
? rc
: count
;
166 static DEVICE_ATTR(bridge_hostnotify
, 0644,
167 qeth_bridgeport_hostnotification_show
,
168 qeth_bridgeport_hostnotification_store
);
170 static struct attribute
*qeth_l2_bridgeport_attrs
[] = {
171 &dev_attr_bridge_role
.attr
,
172 &dev_attr_bridge_state
.attr
,
173 &dev_attr_bridge_hostnotify
.attr
,
177 static struct attribute_group qeth_l2_bridgeport_attr_group
= {
178 .attrs
= qeth_l2_bridgeport_attrs
,
181 int qeth_l2_create_device_attributes(struct device
*dev
)
183 return sysfs_create_group(&dev
->kobj
, &qeth_l2_bridgeport_attr_group
);
186 void qeth_l2_remove_device_attributes(struct device
*dev
)
188 sysfs_remove_group(&dev
->kobj
, &qeth_l2_bridgeport_attr_group
);
192 * qeth_l2_setup_bridgeport_attrs() - set/restore attrs when turning online.
193 * @card: qeth_card structure pointer
195 * Note: this function is called with conf_mutex held by the caller
197 void qeth_l2_setup_bridgeport_attrs(struct qeth_card
*card
)
203 if (!card
->options
.sbp
.supported_funcs
)
205 if (card
->options
.sbp
.role
!= QETH_SBP_ROLE_NONE
) {
206 /* Conditional to avoid spurious error messages */
207 qeth_bridgeport_setrole(card
, card
->options
.sbp
.role
);
208 /* Let the callback function refresh the stored role value. */
209 qeth_bridgeport_query_ports(card
,
210 &card
->options
.sbp
.role
, NULL
);
212 if (card
->options
.sbp
.hostnotification
) {
213 rc
= qeth_bridgeport_an_set(card
, 1);
215 card
->options
.sbp
.hostnotification
= 0;
217 qeth_bridgeport_an_set(card
, 0);