1/* 2 * Copyright IBM Corp. 2007 3 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>, 4 * Frank Pavlic <fpavlic@de.ibm.com>, 5 * Thomas Spatzier <tspat@de.ibm.com>, 6 * Frank Blaschka <frank.blaschka@de.ibm.com> 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) \ 14struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store) 15 16static 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"); 34 case SECONDARY_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 44static 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 55static 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 } 89out: 90 if (rc) 91 route->type = old_route_type; 92 mutex_unlock(&card->conf_mutex); 93 return rc ? rc : count; 94} 95 96static ssize_t qeth_l3_dev_route4_store(struct device *dev, 97 struct device_attribute *attr, const char *buf, size_t count) 98{ 99 struct qeth_card *card = dev_get_drvdata(dev); 100 101 if (!card) 102 return -EINVAL; 103 104 return qeth_l3_dev_route_store(card, &card->options.route4, 105 QETH_PROT_IPV4, buf, count); 106} 107 108static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show, 109 qeth_l3_dev_route4_store); 110 111static ssize_t qeth_l3_dev_route6_show(struct device *dev, 112 struct device_attribute *attr, char *buf) 113{ 114 struct qeth_card *card = dev_get_drvdata(dev); 115 116 if (!card) 117 return -EINVAL; 118 119 return qeth_l3_dev_route_show(card, &card->options.route6, buf); 120} 121 122static ssize_t qeth_l3_dev_route6_store(struct device *dev, 123 struct device_attribute *attr, const char *buf, size_t count) 124{ 125 struct qeth_card *card = dev_get_drvdata(dev); 126 127 if (!card) 128 return -EINVAL; 129 130 return qeth_l3_dev_route_store(card, &card->options.route6, 131 QETH_PROT_IPV6, buf, count); 132} 133 134static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show, 135 qeth_l3_dev_route6_store); 136 137static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev, 138 struct device_attribute *attr, char *buf) 139{ 140 struct qeth_card *card = dev_get_drvdata(dev); 141 142 if (!card) 143 return -EINVAL; 144 145 return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0); 146} 147 148static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev, 149 struct device_attribute *attr, const char *buf, size_t count) 150{ 151 struct qeth_card *card = dev_get_drvdata(dev); 152 char *tmp; 153 int i, rc = 0; 154 155 if (!card) 156 return -EINVAL; 157 158 mutex_lock(&card->conf_mutex); 159 if ((card->state != CARD_STATE_DOWN) && 160 (card->state != CARD_STATE_RECOVER)) { 161 rc = -EPERM; 162 goto out; 163 } 164 165 i = simple_strtoul(buf, &tmp, 16); 166 if ((i == 0) || (i == 1)) 167 card->options.fake_broadcast = i; 168 else 169 rc = -EINVAL; 170out: 171 mutex_unlock(&card->conf_mutex); 172 return rc ? rc : count; 173} 174 175static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show, 176 qeth_l3_dev_fake_broadcast_store); 177 178static ssize_t qeth_l3_dev_sniffer_show(struct device *dev, 179 struct device_attribute *attr, char *buf) 180{ 181 struct qeth_card *card = dev_get_drvdata(dev); 182 183 if (!card) 184 return -EINVAL; 185 186 return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0); 187} 188 189static ssize_t qeth_l3_dev_sniffer_store(struct device *dev, 190 struct device_attribute *attr, const char *buf, size_t count) 191{ 192 struct qeth_card *card = dev_get_drvdata(dev); 193 int rc = 0; 194 unsigned long i; 195 196 if (!card) 197 return -EINVAL; 198 199 if (card->info.type != QETH_CARD_TYPE_IQD) 200 return -EPERM; 201 if (card->options.cq == QETH_CQ_ENABLED) 202 return -EPERM; 203 204 mutex_lock(&card->conf_mutex); 205 if ((card->state != CARD_STATE_DOWN) && 206 (card->state != CARD_STATE_RECOVER)) { 207 rc = -EPERM; 208 goto out; 209 } 210 211 rc = kstrtoul(buf, 16, &i); 212 if (rc) { 213 rc = -EINVAL; 214 goto out; 215 } 216 switch (i) { 217 case 0: 218 card->options.sniffer = i; 219 break; 220 case 1: 221 qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd); 222 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) { 223 card->options.sniffer = i; 224 if (card->qdio.init_pool.buf_count != 225 QETH_IN_BUF_COUNT_MAX) 226 qeth_realloc_buffer_pool(card, 227 QETH_IN_BUF_COUNT_MAX); 228 } else 229 rc = -EPERM; 230 break; 231 default: 232 rc = -EINVAL; 233 } 234out: 235 mutex_unlock(&card->conf_mutex); 236 return rc ? rc : count; 237} 238 239static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show, 240 qeth_l3_dev_sniffer_store); 241 242 243static ssize_t qeth_l3_dev_hsuid_show(struct device *dev, 244 struct device_attribute *attr, char *buf) 245{ 246 struct qeth_card *card = dev_get_drvdata(dev); 247 char tmp_hsuid[9]; 248 249 if (!card) 250 return -EINVAL; 251 252 if (card->info.type != QETH_CARD_TYPE_IQD) 253 return -EPERM; 254 255 if (card->state == CARD_STATE_DOWN) 256 return -EPERM; 257 258 memcpy(tmp_hsuid, card->options.hsuid, sizeof(tmp_hsuid)); 259 EBCASC(tmp_hsuid, 8); 260 return sprintf(buf, "%s\n", tmp_hsuid); 261} 262 263static ssize_t qeth_l3_dev_hsuid_store(struct device *dev, 264 struct device_attribute *attr, const char *buf, size_t count) 265{ 266 struct qeth_card *card = dev_get_drvdata(dev); 267 struct qeth_ipaddr *addr; 268 char *tmp; 269 int i; 270 271 if (!card) 272 return -EINVAL; 273 274 if (card->info.type != QETH_CARD_TYPE_IQD) 275 return -EPERM; 276 if (card->state != CARD_STATE_DOWN && 277 card->state != CARD_STATE_RECOVER) 278 return -EPERM; 279 if (card->options.sniffer) 280 return -EPERM; 281 if (card->options.cq == QETH_CQ_NOTAVAILABLE) 282 return -EPERM; 283 284 tmp = strsep((char **)&buf, "\n"); 285 if (strlen(tmp) > 8) 286 return -EINVAL; 287 288 if (card->options.hsuid[0]) { 289 /* delete old ip address */ 290 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6); 291 if (addr != NULL) { 292 addr->u.a6.addr.s6_addr32[0] = 0xfe800000; 293 addr->u.a6.addr.s6_addr32[1] = 0x00000000; 294 for (i = 8; i < 16; i++) 295 addr->u.a6.addr.s6_addr[i] = 296 card->options.hsuid[i - 8]; 297 addr->u.a6.pfxlen = 0; 298 addr->type = QETH_IP_TYPE_NORMAL; 299 } else 300 return -ENOMEM; 301 if (!qeth_l3_delete_ip(card, addr)) 302 kfree(addr); 303 qeth_l3_set_ip_addr_list(card); 304 } 305 306 if (strlen(tmp) == 0) { 307 /* delete ip address only */ 308 card->options.hsuid[0] = '\0'; 309 if (card->dev) 310 memcpy(card->dev->perm_addr, card->options.hsuid, 9); 311 qeth_configure_cq(card, QETH_CQ_DISABLED); 312 return count; 313 } 314 315 if (qeth_configure_cq(card, QETH_CQ_ENABLED)) 316 return -EPERM; 317 318 snprintf(card->options.hsuid, sizeof(card->options.hsuid), 319 "%-8s", tmp); 320 ASCEBC(card->options.hsuid, 8); 321 if (card->dev) 322 memcpy(card->dev->perm_addr, card->options.hsuid, 9); 323 324 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6); 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); 336 qeth_l3_set_ip_addr_list(card); 337 338 return count; 339} 340 341static DEVICE_ATTR(hsuid, 0644, qeth_l3_dev_hsuid_show, 342 qeth_l3_dev_hsuid_store); 343 344 345static 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 354static struct attribute_group qeth_l3_device_attr_group = { 355 .attrs = qeth_l3_device_attrs, 356}; 357 358static 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 369static 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 |= 396 QETH_IPA_SETIP_TAKEOVER_FLAG; 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 & 403 QETH_IPA_SETIP_TAKEOVER_FLAG) 404 tmpipa->set_flags &= 405 ~QETH_IPA_SETIP_TAKEOVER_FLAG; 406 } 407 } else 408 rc = -EINVAL; 409out: 410 mutex_unlock(&card->conf_mutex); 411 return rc ? rc : count; 412} 413 414static QETH_DEVICE_ATTR(ipato_enable, enable, 0644, 415 qeth_l3_dev_ipato_enable_show, 416 qeth_l3_dev_ipato_enable_store); 417 418static 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 429static 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 454static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644, 455 qeth_l3_dev_ipato_invert4_show, 456 qeth_l3_dev_ipato_invert4_store); 457 458static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card, 459 enum qeth_prot_versions proto) 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 489static 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 500static 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 527static 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); 552out: 553 mutex_unlock(&card->conf_mutex); 554 return rc ? rc : count; 555} 556 557static 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 568static QETH_DEVICE_ATTR(ipato_add4, add4, 0644, 569 qeth_l3_dev_ipato_add4_show, 570 qeth_l3_dev_ipato_add4_store); 571 572static 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 587static 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 598static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL, 599 qeth_l3_dev_ipato_del4_store); 600 601static 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 612static 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 636static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644, 637 qeth_l3_dev_ipato_invert6_show, 638 qeth_l3_dev_ipato_invert6_store); 639 640 641static 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 652static 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 663static QETH_DEVICE_ATTR(ipato_add6, add6, 0644, 664 qeth_l3_dev_ipato_add6_show, 665 qeth_l3_dev_ipato_add6_store); 666 667static 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 678static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL, 679 qeth_l3_dev_ipato_del6_store); 680 681static 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 692static struct attribute_group qeth_device_ipato_group = { 693 .name = "ipa_takeover", 694 .attrs = qeth_ipato_device_attrs, 695}; 696 697static 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 729static 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 740static 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 749static 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 763static 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 774static QETH_DEVICE_ATTR(vipa_add4, add4, 0644, 775 qeth_l3_dev_vipa_add4_show, 776 qeth_l3_dev_vipa_add4_store); 777 778static 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 792static 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 803static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL, 804 qeth_l3_dev_vipa_del4_store); 805 806static 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 817static 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 828static QETH_DEVICE_ATTR(vipa_add6, add6, 0644, 829 qeth_l3_dev_vipa_add6_show, 830 qeth_l3_dev_vipa_add6_store); 831 832static 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 843static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL, 844 qeth_l3_dev_vipa_del6_store); 845 846static 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 854static struct attribute_group qeth_device_vipa_group = { 855 .name = "vipa", 856 .attrs = qeth_vipa_device_attrs, 857}; 858 859static 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 891static 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 902static 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 911static 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 925static 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 936static QETH_DEVICE_ATTR(rxip_add4, add4, 0644, 937 qeth_l3_dev_rxip_add4_show, 938 qeth_l3_dev_rxip_add4_store); 939 940static 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 954static 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 965static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL, 966 qeth_l3_dev_rxip_del4_store); 967 968static 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 979static 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 990static QETH_DEVICE_ATTR(rxip_add6, add6, 0644, 991 qeth_l3_dev_rxip_add6_show, 992 qeth_l3_dev_rxip_add6_store); 993 994static 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 1005static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL, 1006 qeth_l3_dev_rxip_del6_store); 1007 1008static 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 1016static struct attribute_group qeth_device_rxip_group = { 1017 .name = "rxip", 1018 .attrs = qeth_rxip_device_attrs, 1019}; 1020 1021int qeth_l3_create_device_attributes(struct device *dev) 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 1052void qeth_l3_remove_device_attributes(struct device *dev) 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} 1059