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