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