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