linux/drivers/s390/net/qeth_l3_sys.c
<<
>>
Prefs
   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