Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
qeth_l3_sys.c
Go to the documentation of this file.
1 /*
2  * Copyright IBM Corp. 2007
3  * Author(s): Utz Bacher <[email protected]>,
4  * Frank Pavlic <[email protected]>,
5  * Thomas Spatzier <[email protected]>,
6  * Frank Blaschka <[email protected]>
7  */
8 
9 #include <linux/slab.h>
10 #include <asm/ebcdic.h>
11 #include "qeth_l3.h"
12 
13 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
14 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
15 
16 static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
17  struct qeth_routing_info *route, char *buf)
18 {
19  switch (route->type) {
20  case PRIMARY_ROUTER:
21  return sprintf(buf, "%s\n", "primary router");
22  case SECONDARY_ROUTER:
23  return sprintf(buf, "%s\n", "secondary router");
24  case MULTICAST_ROUTER:
25  if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
26  return sprintf(buf, "%s\n", "multicast router+");
27  else
28  return sprintf(buf, "%s\n", "multicast router");
29  case PRIMARY_CONNECTOR:
30  if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
31  return sprintf(buf, "%s\n", "primary connector+");
32  else
33  return sprintf(buf, "%s\n", "primary connector");
35  if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
36  return sprintf(buf, "%s\n", "secondary connector+");
37  else
38  return sprintf(buf, "%s\n", "secondary connector");
39  default:
40  return sprintf(buf, "%s\n", "no");
41  }
42 }
43 
44 static ssize_t qeth_l3_dev_route4_show(struct device *dev,
45  struct device_attribute *attr, char *buf)
46 {
47  struct qeth_card *card = dev_get_drvdata(dev);
48 
49  if (!card)
50  return -EINVAL;
51 
52  return qeth_l3_dev_route_show(card, &card->options.route4, buf);
53 }
54 
55 static ssize_t qeth_l3_dev_route_store(struct qeth_card *card,
56  struct qeth_routing_info *route, enum qeth_prot_versions prot,
57  const char *buf, size_t count)
58 {
59  enum qeth_routing_types old_route_type = route->type;
60  char *tmp;
61  int rc = 0;
62 
63  tmp = strsep((char **) &buf, "\n");
64  mutex_lock(&card->conf_mutex);
65  if (!strcmp(tmp, "no_router")) {
66  route->type = NO_ROUTER;
67  } else if (!strcmp(tmp, "primary_connector")) {
68  route->type = PRIMARY_CONNECTOR;
69  } else if (!strcmp(tmp, "secondary_connector")) {
70  route->type = SECONDARY_CONNECTOR;
71  } else if (!strcmp(tmp, "primary_router")) {
72  route->type = PRIMARY_ROUTER;
73  } else if (!strcmp(tmp, "secondary_router")) {
74  route->type = SECONDARY_ROUTER;
75  } else if (!strcmp(tmp, "multicast_router")) {
76  route->type = MULTICAST_ROUTER;
77  } else {
78  rc = -EINVAL;
79  goto out;
80  }
81  if (((card->state == CARD_STATE_SOFTSETUP) ||
82  (card->state == CARD_STATE_UP)) &&
83  (old_route_type != route->type)) {
84  if (prot == QETH_PROT_IPV4)
85  rc = qeth_l3_setrouting_v4(card);
86  else if (prot == QETH_PROT_IPV6)
87  rc = qeth_l3_setrouting_v6(card);
88  }
89 out:
90  mutex_unlock(&card->conf_mutex);
91  return rc ? rc : count;
92 }
93 
94 static ssize_t qeth_l3_dev_route4_store(struct device *dev,
95  struct device_attribute *attr, const char *buf, size_t count)
96 {
97  struct qeth_card *card = dev_get_drvdata(dev);
98 
99  if (!card)
100  return -EINVAL;
101 
102  return qeth_l3_dev_route_store(card, &card->options.route4,
103  QETH_PROT_IPV4, buf, count);
104 }
105 
106 static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show,
107  qeth_l3_dev_route4_store);
108 
109 static ssize_t qeth_l3_dev_route6_show(struct device *dev,
110  struct device_attribute *attr, char *buf)
111 {
112  struct qeth_card *card = dev_get_drvdata(dev);
113 
114  if (!card)
115  return -EINVAL;
116 
117  return qeth_l3_dev_route_show(card, &card->options.route6, buf);
118 }
119 
120 static ssize_t qeth_l3_dev_route6_store(struct device *dev,
121  struct device_attribute *attr, const char *buf, size_t count)
122 {
123  struct qeth_card *card = dev_get_drvdata(dev);
124 
125  if (!card)
126  return -EINVAL;
127 
128  return qeth_l3_dev_route_store(card, &card->options.route6,
129  QETH_PROT_IPV6, buf, count);
130 }
131 
132 static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
133  qeth_l3_dev_route6_store);
134 
135 static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
136  struct device_attribute *attr, char *buf)
137 {
138  struct qeth_card *card = dev_get_drvdata(dev);
139 
140  if (!card)
141  return -EINVAL;
142 
143  return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
144 }
145 
146 static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev,
147  struct device_attribute *attr, const char *buf, size_t count)
148 {
149  struct qeth_card *card = dev_get_drvdata(dev);
150  char *tmp;
151  int i, rc = 0;
152 
153  if (!card)
154  return -EINVAL;
155 
156  mutex_lock(&card->conf_mutex);
157  if ((card->state != CARD_STATE_DOWN) &&
158  (card->state != CARD_STATE_RECOVER)) {
159  rc = -EPERM;
160  goto out;
161  }
162 
163  i = simple_strtoul(buf, &tmp, 16);
164  if ((i == 0) || (i == 1))
165  card->options.fake_broadcast = i;
166  else
167  rc = -EINVAL;
168 out:
169  mutex_unlock(&card->conf_mutex);
170  return rc ? rc : count;
171 }
172 
173 static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
174  qeth_l3_dev_fake_broadcast_store);
175 
176 static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
177  struct device_attribute *attr, char *buf)
178 {
179  struct qeth_card *card = dev_get_drvdata(dev);
180 
181  if (!card)
182  return -EINVAL;
183 
184  return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
185 }
186 
187 static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
188  struct device_attribute *attr, const char *buf, size_t count)
189 {
190  struct qeth_card *card = dev_get_drvdata(dev);
191  int rc = 0;
192  unsigned long i;
193 
194  if (!card)
195  return -EINVAL;
196 
197  if (card->info.type != QETH_CARD_TYPE_IQD)
198  return -EPERM;
199  if (card->options.cq == QETH_CQ_ENABLED)
200  return -EPERM;
201 
202  mutex_lock(&card->conf_mutex);
203  if ((card->state != CARD_STATE_DOWN) &&
204  (card->state != CARD_STATE_RECOVER)) {
205  rc = -EPERM;
206  goto out;
207  }
208 
209  rc = strict_strtoul(buf, 16, &i);
210  if (rc) {
211  rc = -EINVAL;
212  goto out;
213  }
214  switch (i) {
215  case 0:
216  card->options.sniffer = i;
217  break;
218  case 1:
219  qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
220  if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
221  card->options.sniffer = i;
222  if (card->qdio.init_pool.buf_count !=
226  } else
227  rc = -EPERM;
228  break;
229  default:
230  rc = -EINVAL;
231  }
232 out:
233  mutex_unlock(&card->conf_mutex);
234  return rc ? rc : count;
235 }
236 
237 static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
238  qeth_l3_dev_sniffer_store);
239 
240 
241 static ssize_t qeth_l3_dev_hsuid_show(struct device *dev,
242  struct device_attribute *attr, char *buf)
243 {
244  struct qeth_card *card = dev_get_drvdata(dev);
245  char tmp_hsuid[9];
246 
247  if (!card)
248  return -EINVAL;
249 
250  if (card->info.type != QETH_CARD_TYPE_IQD)
251  return -EPERM;
252 
253  if (card->state == CARD_STATE_DOWN)
254  return -EPERM;
255 
256  memcpy(tmp_hsuid, card->options.hsuid, sizeof(tmp_hsuid));
257  EBCASC(tmp_hsuid, 8);
258  return sprintf(buf, "%s\n", tmp_hsuid);
259 }
260 
261 static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
262  struct device_attribute *attr, const char *buf, size_t count)
263 {
264  struct qeth_card *card = dev_get_drvdata(dev);
265  struct qeth_ipaddr *addr;
266  char *tmp;
267  int i;
268 
269  if (!card)
270  return -EINVAL;
271 
272  if (card->info.type != QETH_CARD_TYPE_IQD)
273  return -EPERM;
274  if (card->state != CARD_STATE_DOWN &&
275  card->state != CARD_STATE_RECOVER)
276  return -EPERM;
277  if (card->options.sniffer)
278  return -EPERM;
279  if (card->options.cq == QETH_CQ_NOTAVAILABLE)
280  return -EPERM;
281 
282  tmp = strsep((char **)&buf, "\n");
283  if (strlen(tmp) > 8)
284  return -EINVAL;
285 
286  if (card->options.hsuid[0]) {
287  /* delete old ip address */
289  if (addr != NULL) {
290  addr->u.a6.addr.s6_addr32[0] = 0xfe800000;
291  addr->u.a6.addr.s6_addr32[1] = 0x00000000;
292  for (i = 8; i < 16; i++)
293  addr->u.a6.addr.s6_addr[i] =
294  card->options.hsuid[i - 8];
295  addr->u.a6.pfxlen = 0;
296  addr->type = QETH_IP_TYPE_NORMAL;
297  } else
298  return -ENOMEM;
299  if (!qeth_l3_delete_ip(card, addr))
300  kfree(addr);
302  }
303 
304  if (strlen(tmp) == 0) {
305  /* delete ip address only */
306  card->options.hsuid[0] = '\0';
307  if (card->dev)
308  memcpy(card->dev->perm_addr, card->options.hsuid, 9);
310  return count;
311  }
312 
314  return -EPERM;
315 
316  for (i = 0; i < 8; i++)
317  card->options.hsuid[i] = ' ';
318  card->options.hsuid[8] = '\0';
319  strncpy(card->options.hsuid, tmp, strlen(tmp));
320  ASCEBC(card->options.hsuid, 8);
321  if (card->dev)
322  memcpy(card->dev->perm_addr, card->options.hsuid, 9);
323 
325  if (addr != NULL) {
326  addr->u.a6.addr.s6_addr32[0] = 0xfe800000;
327  addr->u.a6.addr.s6_addr32[1] = 0x00000000;
328  for (i = 8; i < 16; i++)
329  addr->u.a6.addr.s6_addr[i] = card->options.hsuid[i - 8];
330  addr->u.a6.pfxlen = 0;
331  addr->type = QETH_IP_TYPE_NORMAL;
332  } else
333  return -ENOMEM;
334  if (!qeth_l3_add_ip(card, addr))
335  kfree(addr);
337 
338  return count;
339 }
340 
341 static DEVICE_ATTR(hsuid, 0644, qeth_l3_dev_hsuid_show,
342  qeth_l3_dev_hsuid_store);
343 
344 
345 static struct attribute *qeth_l3_device_attrs[] = {
346  &dev_attr_route4.attr,
347  &dev_attr_route6.attr,
348  &dev_attr_fake_broadcast.attr,
349  &dev_attr_sniffer.attr,
350  &dev_attr_hsuid.attr,
351  NULL,
352 };
353 
354 static struct attribute_group qeth_l3_device_attr_group = {
355  .attrs = qeth_l3_device_attrs,
356 };
357 
358 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
359  struct device_attribute *attr, char *buf)
360 {
361  struct qeth_card *card = dev_get_drvdata(dev);
362 
363  if (!card)
364  return -EINVAL;
365 
366  return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
367 }
368 
369 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
370  struct device_attribute *attr, const char *buf, size_t count)
371 {
372  struct qeth_card *card = dev_get_drvdata(dev);
373  struct qeth_ipaddr *tmpipa, *t;
374  char *tmp;
375  int rc = 0;
376 
377  if (!card)
378  return -EINVAL;
379 
380  mutex_lock(&card->conf_mutex);
381  if ((card->state != CARD_STATE_DOWN) &&
382  (card->state != CARD_STATE_RECOVER)) {
383  rc = -EPERM;
384  goto out;
385  }
386 
387  tmp = strsep((char **) &buf, "\n");
388  if (!strcmp(tmp, "toggle")) {
389  card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
390  } else if (!strcmp(tmp, "1")) {
391  card->ipato.enabled = 1;
392  list_for_each_entry_safe(tmpipa, t, card->ip_tbd_list, entry) {
393  if ((tmpipa->type == QETH_IP_TYPE_NORMAL) &&
394  qeth_l3_is_addr_covered_by_ipato(card, tmpipa))
395  tmpipa->set_flags |=
397  }
398 
399  } else if (!strcmp(tmp, "0")) {
400  card->ipato.enabled = 0;
401  list_for_each_entry_safe(tmpipa, t, card->ip_tbd_list, entry) {
402  if (tmpipa->set_flags &
404  tmpipa->set_flags &=
406  }
407  } else
408  rc = -EINVAL;
409 out:
410  mutex_unlock(&card->conf_mutex);
411  return rc ? rc : count;
412 }
413 
414 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
415  qeth_l3_dev_ipato_enable_show,
416  qeth_l3_dev_ipato_enable_store);
417 
418 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
419  struct device_attribute *attr, char *buf)
420 {
421  struct qeth_card *card = dev_get_drvdata(dev);
422 
423  if (!card)
424  return -EINVAL;
425 
426  return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
427 }
428 
429 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
430  struct device_attribute *attr,
431  const char *buf, size_t count)
432 {
433  struct qeth_card *card = dev_get_drvdata(dev);
434  char *tmp;
435  int rc = 0;
436 
437  if (!card)
438  return -EINVAL;
439 
440  mutex_lock(&card->conf_mutex);
441  tmp = strsep((char **) &buf, "\n");
442  if (!strcmp(tmp, "toggle")) {
443  card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
444  } else if (!strcmp(tmp, "1")) {
445  card->ipato.invert4 = 1;
446  } else if (!strcmp(tmp, "0")) {
447  card->ipato.invert4 = 0;
448  } else
449  rc = -EINVAL;
450  mutex_unlock(&card->conf_mutex);
451  return rc ? rc : count;
452 }
453 
454 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
455  qeth_l3_dev_ipato_invert4_show,
456  qeth_l3_dev_ipato_invert4_store);
457 
458 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
460 {
461  struct qeth_ipato_entry *ipatoe;
462  unsigned long flags;
463  char addr_str[40];
464  int entry_len; /* length of 1 entry string, differs between v4 and v6 */
465  int i = 0;
466 
467  entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
468  /* add strlen for "/<mask>\n" */
469  entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
470  spin_lock_irqsave(&card->ip_lock, flags);
471  list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
472  if (ipatoe->proto != proto)
473  continue;
474  /* String must not be longer than PAGE_SIZE. So we check if
475  * string length gets near PAGE_SIZE. Then we can savely display
476  * the next IPv6 address (worst case, compared to IPv4) */
477  if ((PAGE_SIZE - i) <= entry_len)
478  break;
479  qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
480  i += snprintf(buf + i, PAGE_SIZE - i,
481  "%s/%i\n", addr_str, ipatoe->mask_bits);
482  }
483  spin_unlock_irqrestore(&card->ip_lock, flags);
484  i += snprintf(buf + i, PAGE_SIZE - i, "\n");
485 
486  return i;
487 }
488 
489 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
490  struct device_attribute *attr, char *buf)
491 {
492  struct qeth_card *card = dev_get_drvdata(dev);
493 
494  if (!card)
495  return -EINVAL;
496 
497  return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
498 }
499 
500 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
501  u8 *addr, int *mask_bits)
502 {
503  const char *start, *end;
504  char *tmp;
505  char buffer[40] = {0, };
506 
507  start = buf;
508  /* get address string */
509  end = strchr(start, '/');
510  if (!end || (end - start >= 40)) {
511  return -EINVAL;
512  }
513  strncpy(buffer, start, end - start);
514  if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
515  return -EINVAL;
516  }
517  start = end + 1;
518  *mask_bits = simple_strtoul(start, &tmp, 10);
519  if (!strlen(start) ||
520  (tmp == start) ||
521  (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
522  return -EINVAL;
523  }
524  return 0;
525 }
526 
527 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
528  struct qeth_card *card, enum qeth_prot_versions proto)
529 {
530  struct qeth_ipato_entry *ipatoe;
531  u8 addr[16];
532  int mask_bits;
533  int rc = 0;
534 
535  mutex_lock(&card->conf_mutex);
536  rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
537  if (rc)
538  goto out;
539 
540  ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
541  if (!ipatoe) {
542  rc = -ENOMEM;
543  goto out;
544  }
545  ipatoe->proto = proto;
546  memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
547  ipatoe->mask_bits = mask_bits;
548 
549  rc = qeth_l3_add_ipato_entry(card, ipatoe);
550  if (rc)
551  kfree(ipatoe);
552 out:
553  mutex_unlock(&card->conf_mutex);
554  return rc ? rc : count;
555 }
556 
557 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
558  struct device_attribute *attr, const char *buf, size_t count)
559 {
560  struct qeth_card *card = dev_get_drvdata(dev);
561 
562  if (!card)
563  return -EINVAL;
564 
565  return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
566 }
567 
568 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
569  qeth_l3_dev_ipato_add4_show,
570  qeth_l3_dev_ipato_add4_store);
571 
572 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
573  struct qeth_card *card, enum qeth_prot_versions proto)
574 {
575  u8 addr[16];
576  int mask_bits;
577  int rc = 0;
578 
579  mutex_lock(&card->conf_mutex);
580  rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
581  if (!rc)
582  qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
583  mutex_unlock(&card->conf_mutex);
584  return rc ? rc : count;
585 }
586 
587 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
588  struct device_attribute *attr, const char *buf, size_t count)
589 {
590  struct qeth_card *card = dev_get_drvdata(dev);
591 
592  if (!card)
593  return -EINVAL;
594 
595  return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
596 }
597 
598 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
599  qeth_l3_dev_ipato_del4_store);
600 
601 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
602  struct device_attribute *attr, char *buf)
603 {
604  struct qeth_card *card = dev_get_drvdata(dev);
605 
606  if (!card)
607  return -EINVAL;
608 
609  return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
610 }
611 
612 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
613  struct device_attribute *attr, const char *buf, size_t count)
614 {
615  struct qeth_card *card = dev_get_drvdata(dev);
616  char *tmp;
617  int rc = 0;
618 
619  if (!card)
620  return -EINVAL;
621 
622  mutex_lock(&card->conf_mutex);
623  tmp = strsep((char **) &buf, "\n");
624  if (!strcmp(tmp, "toggle")) {
625  card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
626  } else if (!strcmp(tmp, "1")) {
627  card->ipato.invert6 = 1;
628  } else if (!strcmp(tmp, "0")) {
629  card->ipato.invert6 = 0;
630  } else
631  rc = -EINVAL;
632  mutex_unlock(&card->conf_mutex);
633  return rc ? rc : count;
634 }
635 
636 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
637  qeth_l3_dev_ipato_invert6_show,
638  qeth_l3_dev_ipato_invert6_store);
639 
640 
641 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
642  struct device_attribute *attr, char *buf)
643 {
644  struct qeth_card *card = dev_get_drvdata(dev);
645 
646  if (!card)
647  return -EINVAL;
648 
649  return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
650 }
651 
652 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
653  struct device_attribute *attr, const char *buf, size_t count)
654 {
655  struct qeth_card *card = dev_get_drvdata(dev);
656 
657  if (!card)
658  return -EINVAL;
659 
660  return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
661 }
662 
663 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
664  qeth_l3_dev_ipato_add6_show,
665  qeth_l3_dev_ipato_add6_store);
666 
667 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
668  struct device_attribute *attr, const char *buf, size_t count)
669 {
670  struct qeth_card *card = dev_get_drvdata(dev);
671 
672  if (!card)
673  return -EINVAL;
674 
675  return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
676 }
677 
678 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
679  qeth_l3_dev_ipato_del6_store);
680 
681 static struct attribute *qeth_ipato_device_attrs[] = {
682  &dev_attr_ipato_enable.attr,
683  &dev_attr_ipato_invert4.attr,
684  &dev_attr_ipato_add4.attr,
685  &dev_attr_ipato_del4.attr,
686  &dev_attr_ipato_invert6.attr,
687  &dev_attr_ipato_add6.attr,
688  &dev_attr_ipato_del6.attr,
689  NULL,
690 };
691 
692 static struct attribute_group qeth_device_ipato_group = {
693  .name = "ipa_takeover",
694  .attrs = qeth_ipato_device_attrs,
695 };
696 
697 static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
698  enum qeth_prot_versions proto)
699 {
700  struct qeth_ipaddr *ipaddr;
701  char addr_str[40];
702  int entry_len; /* length of 1 entry string, differs between v4 and v6 */
703  unsigned long flags;
704  int i = 0;
705 
706  entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
707  entry_len += 2; /* \n + terminator */
708  spin_lock_irqsave(&card->ip_lock, flags);
709  list_for_each_entry(ipaddr, &card->ip_list, entry) {
710  if (ipaddr->proto != proto)
711  continue;
712  if (ipaddr->type != QETH_IP_TYPE_VIPA)
713  continue;
714  /* String must not be longer than PAGE_SIZE. So we check if
715  * string length gets near PAGE_SIZE. Then we can savely display
716  * the next IPv6 address (worst case, compared to IPv4) */
717  if ((PAGE_SIZE - i) <= entry_len)
718  break;
719  qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
720  addr_str);
721  i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
722  }
723  spin_unlock_irqrestore(&card->ip_lock, flags);
724  i += snprintf(buf + i, PAGE_SIZE - i, "\n");
725 
726  return i;
727 }
728 
729 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
730  struct device_attribute *attr, char *buf)
731 {
732  struct qeth_card *card = dev_get_drvdata(dev);
733 
734  if (!card)
735  return -EINVAL;
736 
737  return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
738 }
739 
740 static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
741  u8 *addr)
742 {
743  if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
744  return -EINVAL;
745  }
746  return 0;
747 }
748 
749 static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
750  struct qeth_card *card, enum qeth_prot_versions proto)
751 {
752  u8 addr[16] = {0, };
753  int rc;
754 
755  mutex_lock(&card->conf_mutex);
756  rc = qeth_l3_parse_vipae(buf, proto, addr);
757  if (!rc)
758  rc = qeth_l3_add_vipa(card, proto, addr);
759  mutex_unlock(&card->conf_mutex);
760  return rc ? rc : count;
761 }
762 
763 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
764  struct device_attribute *attr, const char *buf, size_t count)
765 {
766  struct qeth_card *card = dev_get_drvdata(dev);
767 
768  if (!card)
769  return -EINVAL;
770 
771  return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
772 }
773 
774 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
775  qeth_l3_dev_vipa_add4_show,
776  qeth_l3_dev_vipa_add4_store);
777 
778 static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
779  struct qeth_card *card, enum qeth_prot_versions proto)
780 {
781  u8 addr[16];
782  int rc;
783 
784  mutex_lock(&card->conf_mutex);
785  rc = qeth_l3_parse_vipae(buf, proto, addr);
786  if (!rc)
787  qeth_l3_del_vipa(card, proto, addr);
788  mutex_unlock(&card->conf_mutex);
789  return rc ? rc : count;
790 }
791 
792 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
793  struct device_attribute *attr, const char *buf, size_t count)
794 {
795  struct qeth_card *card = dev_get_drvdata(dev);
796 
797  if (!card)
798  return -EINVAL;
799 
800  return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
801 }
802 
803 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
804  qeth_l3_dev_vipa_del4_store);
805 
806 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
807  struct device_attribute *attr, char *buf)
808 {
809  struct qeth_card *card = dev_get_drvdata(dev);
810 
811  if (!card)
812  return -EINVAL;
813 
814  return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
815 }
816 
817 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
818  struct device_attribute *attr, const char *buf, size_t count)
819 {
820  struct qeth_card *card = dev_get_drvdata(dev);
821 
822  if (!card)
823  return -EINVAL;
824 
825  return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
826 }
827 
828 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
829  qeth_l3_dev_vipa_add6_show,
830  qeth_l3_dev_vipa_add6_store);
831 
832 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
833  struct device_attribute *attr, const char *buf, size_t count)
834 {
835  struct qeth_card *card = dev_get_drvdata(dev);
836 
837  if (!card)
838  return -EINVAL;
839 
840  return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
841 }
842 
843 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
844  qeth_l3_dev_vipa_del6_store);
845 
846 static struct attribute *qeth_vipa_device_attrs[] = {
847  &dev_attr_vipa_add4.attr,
848  &dev_attr_vipa_del4.attr,
849  &dev_attr_vipa_add6.attr,
850  &dev_attr_vipa_del6.attr,
851  NULL,
852 };
853 
854 static struct attribute_group qeth_device_vipa_group = {
855  .name = "vipa",
856  .attrs = qeth_vipa_device_attrs,
857 };
858 
859 static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
860  enum qeth_prot_versions proto)
861 {
862  struct qeth_ipaddr *ipaddr;
863  char addr_str[40];
864  int entry_len; /* length of 1 entry string, differs between v4 and v6 */
865  unsigned long flags;
866  int i = 0;
867 
868  entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
869  entry_len += 2; /* \n + terminator */
870  spin_lock_irqsave(&card->ip_lock, flags);
871  list_for_each_entry(ipaddr, &card->ip_list, entry) {
872  if (ipaddr->proto != proto)
873  continue;
874  if (ipaddr->type != QETH_IP_TYPE_RXIP)
875  continue;
876  /* String must not be longer than PAGE_SIZE. So we check if
877  * string length gets near PAGE_SIZE. Then we can savely display
878  * the next IPv6 address (worst case, compared to IPv4) */
879  if ((PAGE_SIZE - i) <= entry_len)
880  break;
881  qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
882  addr_str);
883  i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
884  }
885  spin_unlock_irqrestore(&card->ip_lock, flags);
886  i += snprintf(buf + i, PAGE_SIZE - i, "\n");
887 
888  return i;
889 }
890 
891 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
892  struct device_attribute *attr, char *buf)
893 {
894  struct qeth_card *card = dev_get_drvdata(dev);
895 
896  if (!card)
897  return -EINVAL;
898 
899  return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
900 }
901 
902 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
903  u8 *addr)
904 {
905  if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
906  return -EINVAL;
907  }
908  return 0;
909 }
910 
911 static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
912  struct qeth_card *card, enum qeth_prot_versions proto)
913 {
914  u8 addr[16] = {0, };
915  int rc;
916 
917  mutex_lock(&card->conf_mutex);
918  rc = qeth_l3_parse_rxipe(buf, proto, addr);
919  if (!rc)
920  rc = qeth_l3_add_rxip(card, proto, addr);
921  mutex_unlock(&card->conf_mutex);
922  return rc ? rc : count;
923 }
924 
925 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
926  struct device_attribute *attr, const char *buf, size_t count)
927 {
928  struct qeth_card *card = dev_get_drvdata(dev);
929 
930  if (!card)
931  return -EINVAL;
932 
933  return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
934 }
935 
936 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
937  qeth_l3_dev_rxip_add4_show,
938  qeth_l3_dev_rxip_add4_store);
939 
940 static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
941  struct qeth_card *card, enum qeth_prot_versions proto)
942 {
943  u8 addr[16];
944  int rc;
945 
946  mutex_lock(&card->conf_mutex);
947  rc = qeth_l3_parse_rxipe(buf, proto, addr);
948  if (!rc)
949  qeth_l3_del_rxip(card, proto, addr);
950  mutex_unlock(&card->conf_mutex);
951  return rc ? rc : count;
952 }
953 
954 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
955  struct device_attribute *attr, const char *buf, size_t count)
956 {
957  struct qeth_card *card = dev_get_drvdata(dev);
958 
959  if (!card)
960  return -EINVAL;
961 
962  return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
963 }
964 
965 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
966  qeth_l3_dev_rxip_del4_store);
967 
968 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
969  struct device_attribute *attr, char *buf)
970 {
971  struct qeth_card *card = dev_get_drvdata(dev);
972 
973  if (!card)
974  return -EINVAL;
975 
976  return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
977 }
978 
979 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
980  struct device_attribute *attr, const char *buf, size_t count)
981 {
982  struct qeth_card *card = dev_get_drvdata(dev);
983 
984  if (!card)
985  return -EINVAL;
986 
987  return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
988 }
989 
990 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
991  qeth_l3_dev_rxip_add6_show,
992  qeth_l3_dev_rxip_add6_store);
993 
994 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
995  struct device_attribute *attr, const char *buf, size_t count)
996 {
997  struct qeth_card *card = dev_get_drvdata(dev);
998 
999  if (!card)
1000  return -EINVAL;
1001 
1002  return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
1003 }
1004 
1005 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
1006  qeth_l3_dev_rxip_del6_store);
1007 
1008 static struct attribute *qeth_rxip_device_attrs[] = {
1009  &dev_attr_rxip_add4.attr,
1010  &dev_attr_rxip_del4.attr,
1011  &dev_attr_rxip_add6.attr,
1012  &dev_attr_rxip_del6.attr,
1013  NULL,
1014 };
1015 
1016 static struct attribute_group qeth_device_rxip_group = {
1017  .name = "rxip",
1018  .attrs = qeth_rxip_device_attrs,
1019 };
1020 
1022 {
1023  int ret;
1024 
1025  ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1026  if (ret)
1027  return ret;
1028 
1029  ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1030  if (ret) {
1031  sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1032  return ret;
1033  }
1034 
1035  ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1036  if (ret) {
1037  sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1038  sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1039  return ret;
1040  }
1041 
1042  ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1043  if (ret) {
1044  sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1045  sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1046  sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1047  return ret;
1048  }
1049  return 0;
1050 }
1051 
1053 {
1054  sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1055  sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1056  sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1057  sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
1058 }