GNU Linux-libre 5.4.200-gnu1
[releases.git] / drivers / s390 / net / qeth_l2_sys.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *    Copyright IBM Corp. 2013
4  *    Author(s): Eugene Crosser <eugene.crosser@ru.ibm.com>
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                 /* Forbid direct manipulation */
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  * qeth_l2_setup_bridgeport_attrs() - set/restore attrs when turning online.
268  * @card:                             qeth_card structure pointer
269  *
270  * Note: this function is called with conf_mutex held by the caller
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                 /* Conditional to avoid spurious error messages */
285                 qeth_bridgeport_setrole(card, card->options.sbp.role);
286                 /* Let the callback function refresh the stored role value. */
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 /* VNIC CHARS support */
301
302 /* convert sysfs attr name to VNIC characteristic */
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 /* get current timeout setting */
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 /* change timeout setting */
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 /* get current setting of characteristic */
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 /* change setting of characteristic */
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         /* l2 specific, see qeth_l2_only_attr_groups: */
461         &qeth_l2_bridgeport_attr_group,
462         &qeth_l2_vnicc_attr_group,
463         NULL,
464 };