This source file includes following definitions.
- qeth_bridge_port_role_state_show
- qeth_bridge_port_role_show
- qeth_bridge_port_role_store
- qeth_bridge_port_state_show
- qeth_bridgeport_hostnotification_show
- qeth_bridgeport_hostnotification_store
- qeth_bridgeport_reflect_show
- qeth_bridgeport_reflect_store
- qeth_l2_setup_bridgeport_attrs
- qeth_l2_vnicc_sysfs_attr_to_char
- qeth_vnicc_timeout_show
- qeth_vnicc_timeout_store
- qeth_vnicc_char_show
- qeth_vnicc_char_store
- qeth_l2_create_device_attributes
- qeth_l2_remove_device_attributes
1
2
3
4
5
6
7 #include <linux/slab.h>
8 #include <asm/ebcdic.h>
9 #include "qeth_core.h"
10 #include "qeth_l2.h"
11
12 static ssize_t qeth_bridge_port_role_state_show(struct device *dev,
13 struct device_attribute *attr, char *buf,
14 int show_state)
15 {
16 struct qeth_card *card = dev_get_drvdata(dev);
17 enum qeth_sbp_states state = QETH_SBP_STATE_INACTIVE;
18 int rc = 0;
19 char *word;
20
21 if (!card)
22 return -EINVAL;
23
24 if (qeth_l2_vnicc_is_in_use(card))
25 return sprintf(buf, "n/a (VNIC characteristics)\n");
26
27 mutex_lock(&card->sbp_lock);
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);
32 if (!rc) {
33 if (show_state)
34 switch (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;
41 default:
42 rc = -EIO;
43 }
44 else
45 switch (card->options.sbp.role) {
46 case QETH_SBP_ROLE_NONE:
47 word = "none"; break;
48 case QETH_SBP_ROLE_PRIMARY:
49 word = "primary"; break;
50 case QETH_SBP_ROLE_SECONDARY:
51 word = "secondary"; break;
52 default:
53 rc = -EIO;
54 }
55 if (rc)
56 QETH_CARD_TEXT_(card, 2, "SBP%02x:%02x",
57 card->options.sbp.role, state);
58 else
59 rc = sprintf(buf, "%s\n", word);
60 }
61 mutex_unlock(&card->sbp_lock);
62
63 return rc;
64 }
65
66 static ssize_t qeth_bridge_port_role_show(struct device *dev,
67 struct device_attribute *attr, char *buf)
68 {
69 struct qeth_card *card = dev_get_drvdata(dev);
70
71 if (qeth_l2_vnicc_is_in_use(card))
72 return sprintf(buf, "n/a (VNIC characteristics)\n");
73
74 return qeth_bridge_port_role_state_show(dev, attr, buf, 0);
75 }
76
77 static ssize_t qeth_bridge_port_role_store(struct device *dev,
78 struct device_attribute *attr, const char *buf, size_t count)
79 {
80 struct qeth_card *card = dev_get_drvdata(dev);
81 int rc = 0;
82 enum qeth_sbp_roles role;
83
84 if (!card)
85 return -EINVAL;
86 if (sysfs_streq(buf, "primary"))
87 role = QETH_SBP_ROLE_PRIMARY;
88 else if (sysfs_streq(buf, "secondary"))
89 role = QETH_SBP_ROLE_SECONDARY;
90 else if (sysfs_streq(buf, "none"))
91 role = QETH_SBP_ROLE_NONE;
92 else
93 return -EINVAL;
94
95 mutex_lock(&card->conf_mutex);
96 mutex_lock(&card->sbp_lock);
97
98 if (qeth_l2_vnicc_is_in_use(card))
99 rc = -EBUSY;
100 else if (card->options.sbp.reflect_promisc)
101
102 rc = -EPERM;
103 else if (qeth_card_hw_is_reachable(card)) {
104 rc = qeth_bridgeport_setrole(card, role);
105 if (!rc)
106 card->options.sbp.role = role;
107 } else
108 card->options.sbp.role = role;
109
110 mutex_unlock(&card->sbp_lock);
111 mutex_unlock(&card->conf_mutex);
112
113 return rc ? rc : count;
114 }
115
116 static DEVICE_ATTR(bridge_role, 0644, qeth_bridge_port_role_show,
117 qeth_bridge_port_role_store);
118
119 static ssize_t qeth_bridge_port_state_show(struct device *dev,
120 struct device_attribute *attr, char *buf)
121 {
122 struct qeth_card *card = dev_get_drvdata(dev);
123
124 if (qeth_l2_vnicc_is_in_use(card))
125 return sprintf(buf, "n/a (VNIC characteristics)\n");
126
127 return qeth_bridge_port_role_state_show(dev, attr, buf, 1);
128 }
129
130 static DEVICE_ATTR(bridge_state, 0444, qeth_bridge_port_state_show,
131 NULL);
132
133 static ssize_t qeth_bridgeport_hostnotification_show(struct device *dev,
134 struct device_attribute *attr, char *buf)
135 {
136 struct qeth_card *card = dev_get_drvdata(dev);
137 int enabled;
138
139 if (!card)
140 return -EINVAL;
141
142 if (qeth_l2_vnicc_is_in_use(card))
143 return sprintf(buf, "n/a (VNIC characteristics)\n");
144
145 enabled = card->options.sbp.hostnotification;
146
147 return sprintf(buf, "%d\n", enabled);
148 }
149
150 static ssize_t qeth_bridgeport_hostnotification_store(struct device *dev,
151 struct device_attribute *attr, const char *buf, size_t count)
152 {
153 struct qeth_card *card = dev_get_drvdata(dev);
154 bool enable;
155 int rc;
156
157 if (!card)
158 return -EINVAL;
159
160 rc = kstrtobool(buf, &enable);
161 if (rc)
162 return rc;
163
164 mutex_lock(&card->conf_mutex);
165 mutex_lock(&card->sbp_lock);
166
167 if (qeth_l2_vnicc_is_in_use(card))
168 rc = -EBUSY;
169 else if (qeth_card_hw_is_reachable(card)) {
170 rc = qeth_bridgeport_an_set(card, enable);
171 if (!rc)
172 card->options.sbp.hostnotification = enable;
173 } else
174 card->options.sbp.hostnotification = enable;
175
176 mutex_unlock(&card->sbp_lock);
177 mutex_unlock(&card->conf_mutex);
178
179 return rc ? rc : count;
180 }
181
182 static DEVICE_ATTR(bridge_hostnotify, 0644,
183 qeth_bridgeport_hostnotification_show,
184 qeth_bridgeport_hostnotification_store);
185
186 static ssize_t qeth_bridgeport_reflect_show(struct device *dev,
187 struct device_attribute *attr, char *buf)
188 {
189 struct qeth_card *card = dev_get_drvdata(dev);
190 char *state;
191
192 if (!card)
193 return -EINVAL;
194
195 if (qeth_l2_vnicc_is_in_use(card))
196 return sprintf(buf, "n/a (VNIC characteristics)\n");
197
198 if (card->options.sbp.reflect_promisc) {
199 if (card->options.sbp.reflect_promisc_primary)
200 state = "primary";
201 else
202 state = "secondary";
203 } else
204 state = "none";
205
206 return sprintf(buf, "%s\n", state);
207 }
208
209 static ssize_t qeth_bridgeport_reflect_store(struct device *dev,
210 struct device_attribute *attr, const char *buf, size_t count)
211 {
212 struct qeth_card *card = dev_get_drvdata(dev);
213 int enable, primary;
214 int rc = 0;
215
216 if (!card)
217 return -EINVAL;
218
219 if (sysfs_streq(buf, "none")) {
220 enable = 0;
221 primary = 0;
222 } else if (sysfs_streq(buf, "primary")) {
223 enable = 1;
224 primary = 1;
225 } else if (sysfs_streq(buf, "secondary")) {
226 enable = 1;
227 primary = 0;
228 } else
229 return -EINVAL;
230
231 mutex_lock(&card->conf_mutex);
232 mutex_lock(&card->sbp_lock);
233
234 if (qeth_l2_vnicc_is_in_use(card))
235 rc = -EBUSY;
236 else if (card->options.sbp.role != QETH_SBP_ROLE_NONE)
237 rc = -EPERM;
238 else {
239 card->options.sbp.reflect_promisc = enable;
240 card->options.sbp.reflect_promisc_primary = primary;
241 rc = 0;
242 }
243
244 mutex_unlock(&card->sbp_lock);
245 mutex_unlock(&card->conf_mutex);
246
247 return rc ? rc : count;
248 }
249
250 static DEVICE_ATTR(bridge_reflect_promisc, 0644,
251 qeth_bridgeport_reflect_show,
252 qeth_bridgeport_reflect_store);
253
254 static struct attribute *qeth_l2_bridgeport_attrs[] = {
255 &dev_attr_bridge_role.attr,
256 &dev_attr_bridge_state.attr,
257 &dev_attr_bridge_hostnotify.attr,
258 &dev_attr_bridge_reflect_promisc.attr,
259 NULL,
260 };
261
262 static struct attribute_group qeth_l2_bridgeport_attr_group = {
263 .attrs = qeth_l2_bridgeport_attrs,
264 };
265
266
267
268
269
270
271
272 void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)
273 {
274 int rc;
275
276 if (!card)
277 return;
278 if (!card->options.sbp.supported_funcs)
279 return;
280
281 mutex_lock(&card->sbp_lock);
282 if (!card->options.sbp.reflect_promisc &&
283 card->options.sbp.role != QETH_SBP_ROLE_NONE) {
284
285 qeth_bridgeport_setrole(card, card->options.sbp.role);
286
287 qeth_bridgeport_query_ports(card,
288 &card->options.sbp.role, NULL);
289 }
290 if (card->options.sbp.hostnotification) {
291 rc = qeth_bridgeport_an_set(card, 1);
292 if (rc)
293 card->options.sbp.hostnotification = 0;
294 } else {
295 qeth_bridgeport_an_set(card, 0);
296 }
297 mutex_unlock(&card->sbp_lock);
298 }
299
300
301
302
303 static u32 qeth_l2_vnicc_sysfs_attr_to_char(const char *attr_name)
304 {
305 if (sysfs_streq(attr_name, "flooding"))
306 return QETH_VNICC_FLOODING;
307 else if (sysfs_streq(attr_name, "mcast_flooding"))
308 return QETH_VNICC_MCAST_FLOODING;
309 else if (sysfs_streq(attr_name, "learning"))
310 return QETH_VNICC_LEARNING;
311 else if (sysfs_streq(attr_name, "takeover_setvmac"))
312 return QETH_VNICC_TAKEOVER_SETVMAC;
313 else if (sysfs_streq(attr_name, "takeover_learning"))
314 return QETH_VNICC_TAKEOVER_LEARNING;
315 else if (sysfs_streq(attr_name, "bridge_invisible"))
316 return QETH_VNICC_BRIDGE_INVISIBLE;
317 else if (sysfs_streq(attr_name, "rx_bcast"))
318 return QETH_VNICC_RX_BCAST;
319
320 return 0;
321 }
322
323
324 static ssize_t qeth_vnicc_timeout_show(struct device *dev,
325 struct device_attribute *attr, char *buf)
326 {
327 struct qeth_card *card = dev_get_drvdata(dev);
328 u32 timeout;
329 int rc;
330
331 if (!card)
332 return -EINVAL;
333
334 rc = qeth_l2_vnicc_get_timeout(card, &timeout);
335 if (rc == -EBUSY)
336 return sprintf(buf, "n/a (BridgePort)\n");
337 if (rc == -EOPNOTSUPP)
338 return sprintf(buf, "n/a\n");
339 return rc ? rc : sprintf(buf, "%d\n", timeout);
340 }
341
342
343 static ssize_t qeth_vnicc_timeout_store(struct device *dev,
344 struct device_attribute *attr,
345 const char *buf, size_t count)
346 {
347 struct qeth_card *card = dev_get_drvdata(dev);
348 u32 timeout;
349 int rc;
350
351 if (!card)
352 return -EINVAL;
353
354 rc = kstrtou32(buf, 10, &timeout);
355 if (rc)
356 return rc;
357
358 mutex_lock(&card->conf_mutex);
359 rc = qeth_l2_vnicc_set_timeout(card, timeout);
360 mutex_unlock(&card->conf_mutex);
361 return rc ? rc : count;
362 }
363
364
365 static ssize_t qeth_vnicc_char_show(struct device *dev,
366 struct device_attribute *attr, char *buf)
367 {
368 struct qeth_card *card = dev_get_drvdata(dev);
369 bool state;
370 u32 vnicc;
371 int rc;
372
373 if (!card)
374 return -EINVAL;
375
376 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
377 rc = qeth_l2_vnicc_get_state(card, vnicc, &state);
378
379 if (rc == -EBUSY)
380 return sprintf(buf, "n/a (BridgePort)\n");
381 if (rc == -EOPNOTSUPP)
382 return sprintf(buf, "n/a\n");
383 return rc ? rc : sprintf(buf, "%d\n", state);
384 }
385
386
387 static ssize_t qeth_vnicc_char_store(struct device *dev,
388 struct device_attribute *attr,
389 const char *buf, size_t count)
390 {
391 struct qeth_card *card = dev_get_drvdata(dev);
392 bool state;
393 u32 vnicc;
394 int rc;
395
396 if (!card)
397 return -EINVAL;
398
399 if (kstrtobool(buf, &state))
400 return -EINVAL;
401
402 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
403 mutex_lock(&card->conf_mutex);
404 rc = qeth_l2_vnicc_set_state(card, vnicc, state);
405 mutex_unlock(&card->conf_mutex);
406
407 return rc ? rc : count;
408 }
409
410 static DEVICE_ATTR(flooding, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
411 static DEVICE_ATTR(mcast_flooding, 0644, qeth_vnicc_char_show,
412 qeth_vnicc_char_store);
413 static DEVICE_ATTR(learning, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
414 static DEVICE_ATTR(learning_timeout, 0644, qeth_vnicc_timeout_show,
415 qeth_vnicc_timeout_store);
416 static DEVICE_ATTR(takeover_setvmac, 0644, qeth_vnicc_char_show,
417 qeth_vnicc_char_store);
418 static DEVICE_ATTR(takeover_learning, 0644, qeth_vnicc_char_show,
419 qeth_vnicc_char_store);
420 static DEVICE_ATTR(bridge_invisible, 0644, qeth_vnicc_char_show,
421 qeth_vnicc_char_store);
422 static DEVICE_ATTR(rx_bcast, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
423
424 static struct attribute *qeth_l2_vnicc_attrs[] = {
425 &dev_attr_flooding.attr,
426 &dev_attr_mcast_flooding.attr,
427 &dev_attr_learning.attr,
428 &dev_attr_learning_timeout.attr,
429 &dev_attr_takeover_setvmac.attr,
430 &dev_attr_takeover_learning.attr,
431 &dev_attr_bridge_invisible.attr,
432 &dev_attr_rx_bcast.attr,
433 NULL,
434 };
435
436 static struct attribute_group qeth_l2_vnicc_attr_group = {
437 .attrs = qeth_l2_vnicc_attrs,
438 .name = "vnicc",
439 };
440
441 static const struct attribute_group *qeth_l2_only_attr_groups[] = {
442 &qeth_l2_bridgeport_attr_group,
443 &qeth_l2_vnicc_attr_group,
444 NULL,
445 };
446
447 int qeth_l2_create_device_attributes(struct device *dev)
448 {
449 return sysfs_create_groups(&dev->kobj, qeth_l2_only_attr_groups);
450 }
451
452 void qeth_l2_remove_device_attributes(struct device *dev)
453 {
454 sysfs_remove_groups(&dev->kobj, qeth_l2_only_attr_groups);
455 }
456
457 const struct attribute_group *qeth_l2_attr_groups[] = {
458 &qeth_device_attr_group,
459 &qeth_device_blkt_group,
460
461 &qeth_l2_bridgeport_attr_group,
462 &qeth_l2_vnicc_attr_group,
463 NULL,
464 };