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