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,