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 = strict_strtoul(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        for (i = 0; i < 8; i++)
 319                card->options.hsuid[i] = ' ';
 320        card->options.hsuid[8] = '\0';
 321        strncpy(card->options.hsuid, tmp, strlen(tmp));
 322        ASCEBC(card->options.hsuid, 8);
 323        if (card->dev)
 324                memcpy(card->dev->perm_addr, card->options.hsuid, 9);
 325
 326        addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
 327        if (addr != NULL) {
 328                addr->u.a6.addr.s6_addr32[0] = 0xfe800000;
 329                addr->u.a6.addr.s6_addr32[1] = 0x00000000;
 330                for (i = 8; i < 16; i++)
 331                        addr->u.a6.addr.s6_addr[i] = card->options.hsuid[i - 8];
 332                addr->u.a6.pfxlen = 0;
 333                addr->type = QETH_IP_TYPE_NORMAL;
 334        } else
 335                return -ENOMEM;
 336        if (!qeth_l3_add_ip(card, addr))
 337                kfree(addr);
 338        qeth_l3_set_ip_addr_list(card);
 339
 340        return count;
 341}
 342
 343static DEVICE_ATTR(hsuid, 0644, qeth_l3_dev_hsuid_show,
 344                   qeth_l3_dev_hsuid_store);
 345
 346
 347static struct attribute *qeth_l3_device_attrs[] = {
 348        &dev_attr_route4.attr,
 349        &dev_attr_route6.attr,
 350        &dev_attr_fake_broadcast.attr,
 351        &dev_attr_sniffer.attr,
 352        &dev_attr_hsuid.attr,
 353        NULL,
 354};
 355
 356static struct attribute_group qeth_l3_device_attr_group = {
 357        .attrs = qeth_l3_device_attrs,
 358};
 359
 360static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
 361                        struct device_attribute *attr, char *buf)
 362{
 363        struct qeth_card *card = dev_get_drvdata(dev);
 364
 365        if (!card)
 366                return -EINVAL;
 367
 368        return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
 369}
 370
 371static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
 372                struct device_attribute *attr, const char *buf, size_t count)
 373{
 374        struct qeth_card *card = dev_get_drvdata(dev);
 375        struct qeth_ipaddr *tmpipa, *t;
 376        char *tmp;
 377        int rc = 0;
 378
 379        if (!card)
 380                return -EINVAL;
 381
 382        mutex_lock(&card->conf_mutex);
 383        if ((card->state != CARD_STATE_DOWN) &&
 384            (card->state != CARD_STATE_RECOVER)) {
 385                rc = -EPERM;
 386                goto out;
 387        }
 388
 389        tmp = strsep((char **) &buf, "\n");
 390        if (!strcmp(tmp, "toggle")) {
 391                card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
 392        } else if (!strcmp(tmp, "1")) {
 393                card->ipato.enabled = 1;
 394                list_for_each_entry_safe(tmpipa, t, card->ip_tbd_list, entry) {
 395                        if ((tmpipa->type == QETH_IP_TYPE_NORMAL) &&
 396                                qeth_l3_is_addr_covered_by_ipato(card, tmpipa))
 397                                tmpipa->set_flags |=
 398                                        QETH_IPA_SETIP_TAKEOVER_FLAG;
 399                }
 400
 401        } else if (!strcmp(tmp, "0")) {
 402                card->ipato.enabled = 0;
 403                list_for_each_entry_safe(tmpipa, t, card->ip_tbd_list, entry) {
 404                        if (tmpipa->set_flags &
 405                                QETH_IPA_SETIP_TAKEOVER_FLAG)
 406                                tmpipa->set_flags &=
 407                                        ~QETH_IPA_SETIP_TAKEOVER_FLAG;
 408                }
 409        } else
 410                rc = -EINVAL;
 411out:
 412        mutex_unlock(&card->conf_mutex);
 413        return rc ? rc : count;
 414}
 415
 416static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
 417                        qeth_l3_dev_ipato_enable_show,
 418                        qeth_l3_dev_ipato_enable_store);
 419
 420static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
 421                                struct device_attribute *attr, char *buf)
 422{
 423        struct qeth_card *card = dev_get_drvdata(dev);
 424
 425        if (!card)
 426                return -EINVAL;
 427
 428        return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
 429}
 430
 431static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
 432                                struct device_attribute *attr,
 433                                const char *buf, size_t count)
 434{
 435        struct qeth_card *card = dev_get_drvdata(dev);
 436        char *tmp;
 437        int rc = 0;
 438
 439        if (!card)
 440                return -EINVAL;
 441
 442        mutex_lock(&card->conf_mutex);
 443        tmp = strsep((char **) &buf, "\n");
 444        if (!strcmp(tmp, "toggle")) {
 445                card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
 446        } else if (!strcmp(tmp, "1")) {
 447                card->ipato.invert4 = 1;
 448        } else if (!strcmp(tmp, "0")) {
 449                card->ipato.invert4 = 0;
 450        } else
 451                rc = -EINVAL;
 452        mutex_unlock(&card->conf_mutex);
 453        return rc ? rc : count;
 454}
 455
 456static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
 457                        qeth_l3_dev_ipato_invert4_show,
 458                        qeth_l3_dev_ipato_invert4_store);
 459
 460static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
 461                        enum qeth_prot_versions proto)
 462{
 463        struct qeth_ipato_entry *ipatoe;
 464        unsigned long flags;
 465        char addr_str[40];
 466        int entry_len; /* length of 1 entry string, differs between v4 and v6 */
 467        int i = 0;
 468
 469        entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
 470        /* add strlen for "/<mask>\n" */
 471        entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
 472        spin_lock_irqsave(&card->ip_lock, flags);
 473        list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
 474                if (ipatoe->proto != proto)
 475                        continue;
 476                /* String must not be longer than PAGE_SIZE. So we check if
 477                 * string length gets near PAGE_SIZE. Then we can savely display
 478                 * the next IPv6 address (worst case, compared to IPv4) */
 479                if ((PAGE_SIZE - i) <= entry_len)
 480                        break;
 481                qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
 482                i += snprintf(buf + i, PAGE_SIZE - i,
 483                              "%s/%i\n", addr_str, ipatoe->mask_bits);
 484        }
 485        spin_unlock_irqrestore(&card->ip_lock, flags);
 486        i += snprintf(buf + i, PAGE_SIZE - i, "\n");
 487
 488        return i;
 489}
 490
 491static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
 492                                struct device_attribute *attr, char *buf)
 493{
 494        struct qeth_card *card = dev_get_drvdata(dev);
 495
 496        if (!card)
 497                return -EINVAL;
 498
 499        return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
 500}
 501
 502static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
 503                  u8 *addr, int *mask_bits)
 504{
 505        const char *start, *end;
 506        char *tmp;
 507        char buffer[40] = {0, };
 508
 509        start = buf;
 510        /* get address string */
 511        end = strchr(start, '/');
 512        if (!end || (end - start >= 40)) {
 513                return -EINVAL;
 514        }
 515        strncpy(buffer, start, end - start);
 516        if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
 517                return -EINVAL;
 518        }
 519        start = end + 1;
 520        *mask_bits = simple_strtoul(start, &tmp, 10);
 521        if (!strlen(start) ||
 522            (tmp == start) ||
 523            (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
 524                return -EINVAL;
 525        }
 526        return 0;
 527}
 528
 529static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
 530                         struct qeth_card *card, enum qeth_prot_versions proto)
 531{
 532        struct qeth_ipato_entry *ipatoe;
 533        u8 addr[16];
 534        int mask_bits;
 535        int rc = 0;
 536
 537        mutex_lock(&card->conf_mutex);
 538        rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
 539        if (rc)
 540                goto out;
 541
 542        ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
 543        if (!ipatoe) {
 544                rc = -ENOMEM;
 545                goto out;
 546        }
 547        ipatoe->proto = proto;
 548        memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
 549        ipatoe->mask_bits = mask_bits;
 550
 551        rc = qeth_l3_add_ipato_entry(card, ipatoe);
 552        if (rc)
 553                kfree(ipatoe);
 554out:
 555        mutex_unlock(&card->conf_mutex);
 556        return rc ? rc : count;
 557}
 558
 559static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
 560                struct device_attribute *attr, const char *buf, size_t count)
 561{
 562        struct qeth_card *card = dev_get_drvdata(dev);
 563
 564        if (!card)
 565                return -EINVAL;
 566
 567        return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
 568}
 569
 570static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
 571                        qeth_l3_dev_ipato_add4_show,
 572                        qeth_l3_dev_ipato_add4_store);
 573
 574static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
 575                         struct qeth_card *card, enum qeth_prot_versions proto)
 576{
 577        u8 addr[16];
 578        int mask_bits;
 579        int rc = 0;
 580
 581        mutex_lock(&card->conf_mutex);
 582        rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
 583        if (!rc)
 584                qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
 585        mutex_unlock(&card->conf_mutex);
 586        return rc ? rc : count;
 587}
 588
 589static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
 590                struct device_attribute *attr, const char *buf, size_t count)
 591{
 592        struct qeth_card *card = dev_get_drvdata(dev);
 593
 594        if (!card)
 595                return -EINVAL;
 596
 597        return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
 598}
 599
 600static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
 601                        qeth_l3_dev_ipato_del4_store);
 602
 603static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
 604                struct device_attribute *attr, char *buf)
 605{
 606        struct qeth_card *card = dev_get_drvdata(dev);
 607
 608        if (!card)
 609                return -EINVAL;
 610
 611        return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
 612}
 613
 614static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
 615                struct device_attribute *attr, const char *buf, size_t count)
 616{
 617        struct qeth_card *card = dev_get_drvdata(dev);
 618        char *tmp;
 619        int rc = 0;
 620
 621        if (!card)
 622                return -EINVAL;
 623
 624        mutex_lock(&card->conf_mutex);
 625        tmp = strsep((char **) &buf, "\n");
 626        if (!strcmp(tmp, "toggle")) {
 627                card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
 628        } else if (!strcmp(tmp, "1")) {
 629                card->ipato.invert6 = 1;
 630        } else if (!strcmp(tmp, "0")) {
 631                card->ipato.invert6 = 0;
 632        } else
 633                rc = -EINVAL;
 634        mutex_unlock(&card->conf_mutex);
 635        return rc ? rc : count;
 636}
 637
 638static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
 639                        qeth_l3_dev_ipato_invert6_show,
 640                        qeth_l3_dev_ipato_invert6_store);
 641
 642
 643static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
 644                                struct device_attribute *attr, char *buf)
 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_show(buf, card, QETH_PROT_IPV6);
 652}
 653
 654static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
 655                struct device_attribute *attr, const char *buf, size_t count)
 656{
 657        struct qeth_card *card = dev_get_drvdata(dev);
 658
 659        if (!card)
 660                return -EINVAL;
 661
 662        return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
 663}
 664
 665static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
 666                        qeth_l3_dev_ipato_add6_show,
 667                        qeth_l3_dev_ipato_add6_store);
 668
 669static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
 670                struct device_attribute *attr, const char *buf, size_t count)
 671{
 672        struct qeth_card *card = dev_get_drvdata(dev);
 673
 674        if (!card)
 675                return -EINVAL;
 676
 677        return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
 678}
 679
 680static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
 681                        qeth_l3_dev_ipato_del6_store);
 682
 683static struct attribute *qeth_ipato_device_attrs[] = {
 684        &dev_attr_ipato_enable.attr,
 685        &dev_attr_ipato_invert4.attr,
 686        &dev_attr_ipato_add4.attr,
 687        &dev_attr_ipato_del4.attr,
 688        &dev_attr_ipato_invert6.attr,
 689        &dev_attr_ipato_add6.attr,
 690        &dev_attr_ipato_del6.attr,
 691        NULL,
 692};
 693
 694static struct attribute_group qeth_device_ipato_group = {
 695        .name = "ipa_takeover",
 696        .attrs = qeth_ipato_device_attrs,
 697};
 698
 699static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
 700                        enum qeth_prot_versions proto)
 701{
 702        struct qeth_ipaddr *ipaddr;
 703        char addr_str[40];
 704        int entry_len; /* length of 1 entry string, differs between v4 and v6 */
 705        unsigned long flags;
 706        int i = 0;
 707
 708        entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
 709        entry_len += 2; /* \n + terminator */
 710        spin_lock_irqsave(&card->ip_lock, flags);
 711        list_for_each_entry(ipaddr, &card->ip_list, entry) {
 712                if (ipaddr->proto != proto)
 713                        continue;
 714                if (ipaddr->type != QETH_IP_TYPE_VIPA)
 715                        continue;
 716                /* String must not be longer than PAGE_SIZE. So we check if
 717                 * string length gets near PAGE_SIZE. Then we can savely display
 718                 * the next IPv6 address (worst case, compared to IPv4) */
 719                if ((PAGE_SIZE - i) <= entry_len)
 720                        break;
 721                qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
 722                        addr_str);
 723                i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
 724        }
 725        spin_unlock_irqrestore(&card->ip_lock, flags);
 726        i += snprintf(buf + i, PAGE_SIZE - i, "\n");
 727
 728        return i;
 729}
 730
 731static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
 732                        struct device_attribute *attr, char *buf)
 733{
 734        struct qeth_card *card = dev_get_drvdata(dev);
 735
 736        if (!card)
 737                return -EINVAL;
 738
 739        return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
 740}
 741
 742static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
 743                 u8 *addr)
 744{
 745        if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
 746                return -EINVAL;
 747        }
 748        return 0;
 749}
 750
 751static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
 752                        struct qeth_card *card, enum qeth_prot_versions proto)
 753{
 754        u8 addr[16] = {0, };
 755        int rc;
 756
 757        mutex_lock(&card->conf_mutex);
 758        rc = qeth_l3_parse_vipae(buf, proto, addr);
 759        if (!rc)
 760                rc = qeth_l3_add_vipa(card, proto, addr);
 761        mutex_unlock(&card->conf_mutex);
 762        return rc ? rc : count;
 763}
 764
 765static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
 766                struct device_attribute *attr, const char *buf, size_t count)
 767{
 768        struct qeth_card *card = dev_get_drvdata(dev);
 769
 770        if (!card)
 771                return -EINVAL;
 772
 773        return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
 774}
 775
 776static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
 777                        qeth_l3_dev_vipa_add4_show,
 778                        qeth_l3_dev_vipa_add4_store);
 779
 780static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
 781                         struct qeth_card *card, enum qeth_prot_versions proto)
 782{
 783        u8 addr[16];
 784        int rc;
 785
 786        mutex_lock(&card->conf_mutex);
 787        rc = qeth_l3_parse_vipae(buf, proto, addr);
 788        if (!rc)
 789                qeth_l3_del_vipa(card, proto, addr);
 790        mutex_unlock(&card->conf_mutex);
 791        return rc ? rc : count;
 792}
 793
 794static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
 795                struct device_attribute *attr, const char *buf, size_t count)
 796{
 797        struct qeth_card *card = dev_get_drvdata(dev);
 798
 799        if (!card)
 800                return -EINVAL;
 801
 802        return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
 803}
 804
 805static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
 806                        qeth_l3_dev_vipa_del4_store);
 807
 808static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
 809                                struct device_attribute *attr, char *buf)
 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_show(buf, card, QETH_PROT_IPV6);
 817}
 818
 819static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
 820                struct device_attribute *attr, const char *buf, size_t count)
 821{
 822        struct qeth_card *card = dev_get_drvdata(dev);
 823
 824        if (!card)
 825                return -EINVAL;
 826
 827        return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
 828}
 829
 830static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
 831                        qeth_l3_dev_vipa_add6_show,
 832                        qeth_l3_dev_vipa_add6_store);
 833
 834static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
 835                struct device_attribute *attr, const char *buf, size_t count)
 836{
 837        struct qeth_card *card = dev_get_drvdata(dev);
 838
 839        if (!card)
 840                return -EINVAL;
 841
 842        return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
 843}
 844
 845static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
 846                        qeth_l3_dev_vipa_del6_store);
 847
 848static struct attribute *qeth_vipa_device_attrs[] = {
 849        &dev_attr_vipa_add4.attr,
 850        &dev_attr_vipa_del4.attr,
 851        &dev_attr_vipa_add6.attr,
 852        &dev_attr_vipa_del6.attr,
 853        NULL,
 854};
 855
 856static struct attribute_group qeth_device_vipa_group = {
 857        .name = "vipa",
 858        .attrs = qeth_vipa_device_attrs,
 859};
 860
 861static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
 862                       enum qeth_prot_versions proto)
 863{
 864        struct qeth_ipaddr *ipaddr;
 865        char addr_str[40];
 866        int entry_len; /* length of 1 entry string, differs between v4 and v6 */
 867        unsigned long flags;
 868        int i = 0;
 869
 870        entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
 871        entry_len += 2; /* \n + terminator */
 872        spin_lock_irqsave(&card->ip_lock, flags);
 873        list_for_each_entry(ipaddr, &card->ip_list, entry) {
 874                if (ipaddr->proto != proto)
 875                        continue;
 876                if (ipaddr->type != QETH_IP_TYPE_RXIP)
 877                        continue;
 878                /* String must not be longer than PAGE_SIZE. So we check if
 879                 * string length gets near PAGE_SIZE. Then we can savely display
 880                 * the next IPv6 address (worst case, compared to IPv4) */
 881                if ((PAGE_SIZE - i) <= entry_len)
 882                        break;
 883                qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
 884                        addr_str);
 885                i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
 886        }
 887        spin_unlock_irqrestore(&card->ip_lock, flags);
 888        i += snprintf(buf + i, PAGE_SIZE - i, "\n");
 889
 890        return i;
 891}
 892
 893static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
 894                        struct device_attribute *attr, char *buf)
 895{
 896        struct qeth_card *card = dev_get_drvdata(dev);
 897
 898        if (!card)
 899                return -EINVAL;
 900
 901        return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
 902}
 903
 904static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
 905                 u8 *addr)
 906{
 907        if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
 908                return -EINVAL;
 909        }
 910        return 0;
 911}
 912
 913static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
 914                        struct qeth_card *card, enum qeth_prot_versions proto)
 915{
 916        u8 addr[16] = {0, };
 917        int rc;
 918
 919        mutex_lock(&card->conf_mutex);
 920        rc = qeth_l3_parse_rxipe(buf, proto, addr);
 921        if (!rc)
 922                rc = qeth_l3_add_rxip(card, proto, addr);
 923        mutex_unlock(&card->conf_mutex);
 924        return rc ? rc : count;
 925}
 926
 927static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
 928                struct device_attribute *attr, const char *buf, size_t count)
 929{
 930        struct qeth_card *card = dev_get_drvdata(dev);
 931
 932        if (!card)
 933                return -EINVAL;
 934
 935        return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
 936}
 937
 938static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
 939                        qeth_l3_dev_rxip_add4_show,
 940                        qeth_l3_dev_rxip_add4_store);
 941
 942static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
 943                        struct qeth_card *card, enum qeth_prot_versions proto)
 944{
 945        u8 addr[16];
 946        int rc;
 947
 948        mutex_lock(&card->conf_mutex);
 949        rc = qeth_l3_parse_rxipe(buf, proto, addr);
 950        if (!rc)
 951                qeth_l3_del_rxip(card, proto, addr);
 952        mutex_unlock(&card->conf_mutex);
 953        return rc ? rc : count;
 954}
 955
 956static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
 957                struct device_attribute *attr, const char *buf, size_t count)
 958{
 959        struct qeth_card *card = dev_get_drvdata(dev);
 960
 961        if (!card)
 962                return -EINVAL;
 963
 964        return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
 965}
 966
 967static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
 968                        qeth_l3_dev_rxip_del4_store);
 969
 970static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
 971                struct device_attribute *attr, char *buf)
 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_show(buf, card, QETH_PROT_IPV6);
 979}
 980
 981static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
 982                struct device_attribute *attr, const char *buf, size_t count)
 983{
 984        struct qeth_card *card = dev_get_drvdata(dev);
 985
 986        if (!card)
 987                return -EINVAL;
 988
 989        return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
 990}
 991
 992static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
 993                        qeth_l3_dev_rxip_add6_show,
 994                        qeth_l3_dev_rxip_add6_store);
 995
 996static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
 997                struct device_attribute *attr, const char *buf, size_t count)
 998{
 999        struct qeth_card *card = dev_get_drvdata(dev);
1000
1001        if (!card)
1002                return -EINVAL;
1003
1004        return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
1005}
1006
1007static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
1008                        qeth_l3_dev_rxip_del6_store);
1009
1010static struct attribute *qeth_rxip_device_attrs[] = {
1011        &dev_attr_rxip_add4.attr,
1012        &dev_attr_rxip_del4.attr,
1013        &dev_attr_rxip_add6.attr,
1014        &dev_attr_rxip_del6.attr,
1015        NULL,
1016};
1017
1018static struct attribute_group qeth_device_rxip_group = {
1019        .name = "rxip",
1020        .attrs = qeth_rxip_device_attrs,
1021};
1022
1023int qeth_l3_create_device_attributes(struct device *dev)
1024{
1025        int ret;
1026
1027        ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1028        if (ret)
1029                return ret;
1030
1031        ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1032        if (ret) {
1033                sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1034                return ret;
1035        }
1036
1037        ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1038        if (ret) {
1039                sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1040                sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1041                return ret;
1042        }
1043
1044        ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1045        if (ret) {
1046                sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1047                sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1048                sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1049                return ret;
1050        }
1051        return 0;
1052}
1053
1054void qeth_l3_remove_device_attributes(struct device *dev)
1055{
1056        sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1057        sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1058        sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1059        sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
1060}
1061