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