linux/drivers/s390/net/ism_drv.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * ISM driver for s390.
   4 *
   5 * Copyright IBM Corp. 2018
   6 */
   7#define KMSG_COMPONENT "ism"
   8#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
   9
  10#include <linux/module.h>
  11#include <linux/types.h>
  12#include <linux/interrupt.h>
  13#include <linux/device.h>
  14#include <linux/pci.h>
  15#include <linux/err.h>
  16#include <linux/ctype.h>
  17#include <linux/processor.h>
  18#include <net/smc.h>
  19
  20#include <asm/debug.h>
  21
  22#include "ism.h"
  23
  24MODULE_DESCRIPTION("ISM driver for s390");
  25MODULE_LICENSE("GPL");
  26
  27#define PCI_DEVICE_ID_IBM_ISM 0x04ED
  28#define DRV_NAME "ism"
  29
  30static const struct pci_device_id ism_device_table[] = {
  31        { PCI_VDEVICE(IBM, PCI_DEVICE_ID_IBM_ISM), 0 },
  32        { 0, }
  33};
  34MODULE_DEVICE_TABLE(pci, ism_device_table);
  35
  36static debug_info_t *ism_debug_info;
  37
  38static int ism_cmd(struct ism_dev *ism, void *cmd)
  39{
  40        struct ism_req_hdr *req = cmd;
  41        struct ism_resp_hdr *resp = cmd;
  42
  43        __ism_write_cmd(ism, req + 1, sizeof(*req), req->len - sizeof(*req));
  44        __ism_write_cmd(ism, req, 0, sizeof(*req));
  45
  46        WRITE_ONCE(resp->ret, ISM_ERROR);
  47
  48        __ism_read_cmd(ism, resp, 0, sizeof(*resp));
  49        if (resp->ret) {
  50                debug_text_event(ism_debug_info, 0, "cmd failure");
  51                debug_event(ism_debug_info, 0, resp, sizeof(*resp));
  52                goto out;
  53        }
  54        __ism_read_cmd(ism, resp + 1, sizeof(*resp), resp->len - sizeof(*resp));
  55out:
  56        return resp->ret;
  57}
  58
  59static int ism_cmd_simple(struct ism_dev *ism, u32 cmd_code)
  60{
  61        union ism_cmd_simple cmd;
  62
  63        memset(&cmd, 0, sizeof(cmd));
  64        cmd.request.hdr.cmd = cmd_code;
  65        cmd.request.hdr.len = sizeof(cmd.request);
  66
  67        return ism_cmd(ism, &cmd);
  68}
  69
  70static int query_info(struct ism_dev *ism)
  71{
  72        union ism_qi cmd;
  73
  74        memset(&cmd, 0, sizeof(cmd));
  75        cmd.request.hdr.cmd = ISM_QUERY_INFO;
  76        cmd.request.hdr.len = sizeof(cmd.request);
  77
  78        if (ism_cmd(ism, &cmd))
  79                goto out;
  80
  81        debug_text_event(ism_debug_info, 3, "query info");
  82        debug_event(ism_debug_info, 3, &cmd.response, sizeof(cmd.response));
  83out:
  84        return 0;
  85}
  86
  87static int register_sba(struct ism_dev *ism)
  88{
  89        union ism_reg_sba cmd;
  90        dma_addr_t dma_handle;
  91        struct ism_sba *sba;
  92
  93        sba = dma_alloc_coherent(&ism->pdev->dev, PAGE_SIZE, &dma_handle,
  94                                 GFP_KERNEL);
  95        if (!sba)
  96                return -ENOMEM;
  97
  98        memset(&cmd, 0, sizeof(cmd));
  99        cmd.request.hdr.cmd = ISM_REG_SBA;
 100        cmd.request.hdr.len = sizeof(cmd.request);
 101        cmd.request.sba = dma_handle;
 102
 103        if (ism_cmd(ism, &cmd)) {
 104                dma_free_coherent(&ism->pdev->dev, PAGE_SIZE, sba, dma_handle);
 105                return -EIO;
 106        }
 107
 108        ism->sba = sba;
 109        ism->sba_dma_addr = dma_handle;
 110
 111        return 0;
 112}
 113
 114static int register_ieq(struct ism_dev *ism)
 115{
 116        union ism_reg_ieq cmd;
 117        dma_addr_t dma_handle;
 118        struct ism_eq *ieq;
 119
 120        ieq = dma_alloc_coherent(&ism->pdev->dev, PAGE_SIZE, &dma_handle,
 121                                 GFP_KERNEL);
 122        if (!ieq)
 123                return -ENOMEM;
 124
 125        memset(&cmd, 0, sizeof(cmd));
 126        cmd.request.hdr.cmd = ISM_REG_IEQ;
 127        cmd.request.hdr.len = sizeof(cmd.request);
 128        cmd.request.ieq = dma_handle;
 129        cmd.request.len = sizeof(*ieq);
 130
 131        if (ism_cmd(ism, &cmd)) {
 132                dma_free_coherent(&ism->pdev->dev, PAGE_SIZE, ieq, dma_handle);
 133                return -EIO;
 134        }
 135
 136        ism->ieq = ieq;
 137        ism->ieq_idx = -1;
 138        ism->ieq_dma_addr = dma_handle;
 139
 140        return 0;
 141}
 142
 143static int unregister_sba(struct ism_dev *ism)
 144{
 145        int ret;
 146
 147        if (!ism->sba)
 148                return 0;
 149
 150        ret = ism_cmd_simple(ism, ISM_UNREG_SBA);
 151        if (ret && ret != ISM_ERROR)
 152                return -EIO;
 153
 154        dma_free_coherent(&ism->pdev->dev, PAGE_SIZE,
 155                          ism->sba, ism->sba_dma_addr);
 156
 157        ism->sba = NULL;
 158        ism->sba_dma_addr = 0;
 159
 160        return 0;
 161}
 162
 163static int unregister_ieq(struct ism_dev *ism)
 164{
 165        int ret;
 166
 167        if (!ism->ieq)
 168                return 0;
 169
 170        ret = ism_cmd_simple(ism, ISM_UNREG_IEQ);
 171        if (ret && ret != ISM_ERROR)
 172                return -EIO;
 173
 174        dma_free_coherent(&ism->pdev->dev, PAGE_SIZE,
 175                          ism->ieq, ism->ieq_dma_addr);
 176
 177        ism->ieq = NULL;
 178        ism->ieq_dma_addr = 0;
 179
 180        return 0;
 181}
 182
 183static int ism_read_local_gid(struct ism_dev *ism)
 184{
 185        union ism_read_gid cmd;
 186        int ret;
 187
 188        memset(&cmd, 0, sizeof(cmd));
 189        cmd.request.hdr.cmd = ISM_READ_GID;
 190        cmd.request.hdr.len = sizeof(cmd.request);
 191
 192        ret = ism_cmd(ism, &cmd);
 193        if (ret)
 194                goto out;
 195
 196        ism->smcd->local_gid = cmd.response.gid;
 197out:
 198        return ret;
 199}
 200
 201static int ism_query_rgid(struct smcd_dev *smcd, u64 rgid, u32 vid_valid,
 202                          u32 vid)
 203{
 204        struct ism_dev *ism = smcd->priv;
 205        union ism_query_rgid cmd;
 206
 207        memset(&cmd, 0, sizeof(cmd));
 208        cmd.request.hdr.cmd = ISM_QUERY_RGID;
 209        cmd.request.hdr.len = sizeof(cmd.request);
 210
 211        cmd.request.rgid = rgid;
 212        cmd.request.vlan_valid = vid_valid;
 213        cmd.request.vlan_id = vid;
 214
 215        return ism_cmd(ism, &cmd);
 216}
 217
 218static void ism_free_dmb(struct ism_dev *ism, struct smcd_dmb *dmb)
 219{
 220        clear_bit(dmb->sba_idx, ism->sba_bitmap);
 221        dma_free_coherent(&ism->pdev->dev, dmb->dmb_len,
 222                          dmb->cpu_addr, dmb->dma_addr);
 223}
 224
 225static int ism_alloc_dmb(struct ism_dev *ism, struct smcd_dmb *dmb)
 226{
 227        unsigned long bit;
 228
 229        if (PAGE_ALIGN(dmb->dmb_len) > dma_get_max_seg_size(&ism->pdev->dev))
 230                return -EINVAL;
 231
 232        if (!dmb->sba_idx) {
 233                bit = find_next_zero_bit(ism->sba_bitmap, ISM_NR_DMBS,
 234                                         ISM_DMB_BIT_OFFSET);
 235                if (bit == ISM_NR_DMBS)
 236                        return -ENOSPC;
 237
 238                dmb->sba_idx = bit;
 239        }
 240        if (dmb->sba_idx < ISM_DMB_BIT_OFFSET ||
 241            test_and_set_bit(dmb->sba_idx, ism->sba_bitmap))
 242                return -EINVAL;
 243
 244        dmb->cpu_addr = dma_alloc_coherent(&ism->pdev->dev, dmb->dmb_len,
 245                                           &dmb->dma_addr,
 246                                           GFP_KERNEL | __GFP_NOWARN | __GFP_NOMEMALLOC | __GFP_COMP | __GFP_NORETRY);
 247        if (!dmb->cpu_addr)
 248                clear_bit(dmb->sba_idx, ism->sba_bitmap);
 249
 250        return dmb->cpu_addr ? 0 : -ENOMEM;
 251}
 252
 253static int ism_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
 254{
 255        struct ism_dev *ism = smcd->priv;
 256        union ism_reg_dmb cmd;
 257        int ret;
 258
 259        ret = ism_alloc_dmb(ism, dmb);
 260        if (ret)
 261                goto out;
 262
 263        memset(&cmd, 0, sizeof(cmd));
 264        cmd.request.hdr.cmd = ISM_REG_DMB;
 265        cmd.request.hdr.len = sizeof(cmd.request);
 266
 267        cmd.request.dmb = dmb->dma_addr;
 268        cmd.request.dmb_len = dmb->dmb_len;
 269        cmd.request.sba_idx = dmb->sba_idx;
 270        cmd.request.vlan_valid = dmb->vlan_valid;
 271        cmd.request.vlan_id = dmb->vlan_id;
 272        cmd.request.rgid = dmb->rgid;
 273
 274        ret = ism_cmd(ism, &cmd);
 275        if (ret) {
 276                ism_free_dmb(ism, dmb);
 277                goto out;
 278        }
 279        dmb->dmb_tok = cmd.response.dmb_tok;
 280out:
 281        return ret;
 282}
 283
 284static int ism_unregister_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
 285{
 286        struct ism_dev *ism = smcd->priv;
 287        union ism_unreg_dmb cmd;
 288        int ret;
 289
 290        memset(&cmd, 0, sizeof(cmd));
 291        cmd.request.hdr.cmd = ISM_UNREG_DMB;
 292        cmd.request.hdr.len = sizeof(cmd.request);
 293
 294        cmd.request.dmb_tok = dmb->dmb_tok;
 295
 296        ret = ism_cmd(ism, &cmd);
 297        if (ret && ret != ISM_ERROR)
 298                goto out;
 299
 300        ism_free_dmb(ism, dmb);
 301out:
 302        return ret;
 303}
 304
 305static int ism_add_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
 306{
 307        struct ism_dev *ism = smcd->priv;
 308        union ism_set_vlan_id cmd;
 309
 310        memset(&cmd, 0, sizeof(cmd));
 311        cmd.request.hdr.cmd = ISM_ADD_VLAN_ID;
 312        cmd.request.hdr.len = sizeof(cmd.request);
 313
 314        cmd.request.vlan_id = vlan_id;
 315
 316        return ism_cmd(ism, &cmd);
 317}
 318
 319static int ism_del_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
 320{
 321        struct ism_dev *ism = smcd->priv;
 322        union ism_set_vlan_id cmd;
 323
 324        memset(&cmd, 0, sizeof(cmd));
 325        cmd.request.hdr.cmd = ISM_DEL_VLAN_ID;
 326        cmd.request.hdr.len = sizeof(cmd.request);
 327
 328        cmd.request.vlan_id = vlan_id;
 329
 330        return ism_cmd(ism, &cmd);
 331}
 332
 333static int ism_set_vlan_required(struct smcd_dev *smcd)
 334{
 335        return ism_cmd_simple(smcd->priv, ISM_SET_VLAN);
 336}
 337
 338static int ism_reset_vlan_required(struct smcd_dev *smcd)
 339{
 340        return ism_cmd_simple(smcd->priv, ISM_RESET_VLAN);
 341}
 342
 343static int ism_signal_ieq(struct smcd_dev *smcd, u64 rgid, u32 trigger_irq,
 344                          u32 event_code, u64 info)
 345{
 346        struct ism_dev *ism = smcd->priv;
 347        union ism_sig_ieq cmd;
 348
 349        memset(&cmd, 0, sizeof(cmd));
 350        cmd.request.hdr.cmd = ISM_SIGNAL_IEQ;
 351        cmd.request.hdr.len = sizeof(cmd.request);
 352
 353        cmd.request.rgid = rgid;
 354        cmd.request.trigger_irq = trigger_irq;
 355        cmd.request.event_code = event_code;
 356        cmd.request.info = info;
 357
 358        return ism_cmd(ism, &cmd);
 359}
 360
 361static unsigned int max_bytes(unsigned int start, unsigned int len,
 362                              unsigned int boundary)
 363{
 364        return min(boundary - (start & (boundary - 1)), len);
 365}
 366
 367static int ism_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
 368                    bool sf, unsigned int offset, void *data, unsigned int size)
 369{
 370        struct ism_dev *ism = smcd->priv;
 371        unsigned int bytes;
 372        u64 dmb_req;
 373        int ret;
 374
 375        while (size) {
 376                bytes = max_bytes(offset, size, PAGE_SIZE);
 377                dmb_req = ISM_CREATE_REQ(dmb_tok, idx, size == bytes ? sf : 0,
 378                                         offset);
 379
 380                ret = __ism_move(ism, dmb_req, data, bytes);
 381                if (ret)
 382                        return ret;
 383
 384                size -= bytes;
 385                data += bytes;
 386                offset += bytes;
 387        }
 388
 389        return 0;
 390}
 391
 392static struct ism_systemeid SYSTEM_EID = {
 393        .seid_string = "IBM-SYSZ-ISMSEID00000000",
 394        .serial_number = "0000",
 395        .type = "0000",
 396};
 397
 398static void ism_create_system_eid(void)
 399{
 400        struct cpuid id;
 401        u16 ident_tail;
 402        char tmp[5];
 403
 404        get_cpu_id(&id);
 405        ident_tail = (u16)(id.ident & ISM_IDENT_MASK);
 406        snprintf(tmp, 5, "%04X", ident_tail);
 407        memcpy(&SYSTEM_EID.serial_number, tmp, 4);
 408        snprintf(tmp, 5, "%04X", id.machine);
 409        memcpy(&SYSTEM_EID.type, tmp, 4);
 410}
 411
 412static void ism_get_system_eid(struct smcd_dev *smcd, u8 **eid)
 413{
 414        *eid = &SYSTEM_EID.seid_string[0];
 415}
 416
 417static u16 ism_get_chid(struct smcd_dev *smcd)
 418{
 419        struct ism_dev *ismdev;
 420
 421        ismdev = (struct ism_dev *)smcd->priv;
 422        if (!ismdev || !ismdev->pdev)
 423                return 0;
 424
 425        return to_zpci(ismdev->pdev)->pchid;
 426}
 427
 428static void ism_handle_event(struct ism_dev *ism)
 429{
 430        struct smcd_event *entry;
 431
 432        while ((ism->ieq_idx + 1) != READ_ONCE(ism->ieq->header.idx)) {
 433                if (++(ism->ieq_idx) == ARRAY_SIZE(ism->ieq->entry))
 434                        ism->ieq_idx = 0;
 435
 436                entry = &ism->ieq->entry[ism->ieq_idx];
 437                debug_event(ism_debug_info, 2, entry, sizeof(*entry));
 438                smcd_handle_event(ism->smcd, entry);
 439        }
 440}
 441
 442static irqreturn_t ism_handle_irq(int irq, void *data)
 443{
 444        struct ism_dev *ism = data;
 445        unsigned long bit, end;
 446        unsigned long *bv;
 447
 448        bv = (void *) &ism->sba->dmb_bits[ISM_DMB_WORD_OFFSET];
 449        end = sizeof(ism->sba->dmb_bits) * BITS_PER_BYTE - ISM_DMB_BIT_OFFSET;
 450
 451        spin_lock(&ism->lock);
 452        ism->sba->s = 0;
 453        barrier();
 454        for (bit = 0;;) {
 455                bit = find_next_bit_inv(bv, end, bit);
 456                if (bit >= end)
 457                        break;
 458
 459                clear_bit_inv(bit, bv);
 460                ism->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET] = 0;
 461                barrier();
 462                smcd_handle_irq(ism->smcd, bit + ISM_DMB_BIT_OFFSET);
 463        }
 464
 465        if (ism->sba->e) {
 466                ism->sba->e = 0;
 467                barrier();
 468                ism_handle_event(ism);
 469        }
 470        spin_unlock(&ism->lock);
 471        return IRQ_HANDLED;
 472}
 473
 474static const struct smcd_ops ism_ops = {
 475        .query_remote_gid = ism_query_rgid,
 476        .register_dmb = ism_register_dmb,
 477        .unregister_dmb = ism_unregister_dmb,
 478        .add_vlan_id = ism_add_vlan_id,
 479        .del_vlan_id = ism_del_vlan_id,
 480        .set_vlan_required = ism_set_vlan_required,
 481        .reset_vlan_required = ism_reset_vlan_required,
 482        .signal_event = ism_signal_ieq,
 483        .move_data = ism_move,
 484        .get_system_eid = ism_get_system_eid,
 485        .get_chid = ism_get_chid,
 486};
 487
 488static int ism_dev_init(struct ism_dev *ism)
 489{
 490        struct pci_dev *pdev = ism->pdev;
 491        int ret;
 492
 493        ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
 494        if (ret <= 0)
 495                goto out;
 496
 497        ret = request_irq(pci_irq_vector(pdev, 0), ism_handle_irq, 0,
 498                          pci_name(pdev), ism);
 499        if (ret)
 500                goto free_vectors;
 501
 502        ret = register_sba(ism);
 503        if (ret)
 504                goto free_irq;
 505
 506        ret = register_ieq(ism);
 507        if (ret)
 508                goto unreg_sba;
 509
 510        ret = ism_read_local_gid(ism);
 511        if (ret)
 512                goto unreg_ieq;
 513
 514        if (!ism_add_vlan_id(ism->smcd, ISM_RESERVED_VLANID))
 515                /* hardware is V2 capable */
 516                ism_create_system_eid();
 517
 518        ret = smcd_register_dev(ism->smcd);
 519        if (ret)
 520                goto unreg_ieq;
 521
 522        query_info(ism);
 523        return 0;
 524
 525unreg_ieq:
 526        unregister_ieq(ism);
 527unreg_sba:
 528        unregister_sba(ism);
 529free_irq:
 530        free_irq(pci_irq_vector(pdev, 0), ism);
 531free_vectors:
 532        pci_free_irq_vectors(pdev);
 533out:
 534        return ret;
 535}
 536
 537static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 538{
 539        struct ism_dev *ism;
 540        int ret;
 541
 542        ism = kzalloc(sizeof(*ism), GFP_KERNEL);
 543        if (!ism)
 544                return -ENOMEM;
 545
 546        spin_lock_init(&ism->lock);
 547        dev_set_drvdata(&pdev->dev, ism);
 548        ism->pdev = pdev;
 549
 550        ret = pci_enable_device_mem(pdev);
 551        if (ret)
 552                goto err;
 553
 554        ret = pci_request_mem_regions(pdev, DRV_NAME);
 555        if (ret)
 556                goto err_disable;
 557
 558        ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 559        if (ret)
 560                goto err_resource;
 561
 562        dma_set_seg_boundary(&pdev->dev, SZ_1M - 1);
 563        dma_set_max_seg_size(&pdev->dev, SZ_1M);
 564        pci_set_master(pdev);
 565
 566        ism->smcd = smcd_alloc_dev(&pdev->dev, dev_name(&pdev->dev), &ism_ops,
 567                                   ISM_NR_DMBS);
 568        if (!ism->smcd) {
 569                ret = -ENOMEM;
 570                goto err_resource;
 571        }
 572
 573        ism->smcd->priv = ism;
 574        ret = ism_dev_init(ism);
 575        if (ret)
 576                goto err_free;
 577
 578        return 0;
 579
 580err_free:
 581        smcd_free_dev(ism->smcd);
 582err_resource:
 583        pci_release_mem_regions(pdev);
 584err_disable:
 585        pci_disable_device(pdev);
 586err:
 587        kfree(ism);
 588        dev_set_drvdata(&pdev->dev, NULL);
 589        return ret;
 590}
 591
 592static void ism_dev_exit(struct ism_dev *ism)
 593{
 594        struct pci_dev *pdev = ism->pdev;
 595
 596        smcd_unregister_dev(ism->smcd);
 597        if (SYSTEM_EID.serial_number[0] != '0' ||
 598            SYSTEM_EID.type[0] != '0')
 599                ism_del_vlan_id(ism->smcd, ISM_RESERVED_VLANID);
 600        unregister_ieq(ism);
 601        unregister_sba(ism);
 602        free_irq(pci_irq_vector(pdev, 0), ism);
 603        pci_free_irq_vectors(pdev);
 604}
 605
 606static void ism_remove(struct pci_dev *pdev)
 607{
 608        struct ism_dev *ism = dev_get_drvdata(&pdev->dev);
 609
 610        ism_dev_exit(ism);
 611
 612        smcd_free_dev(ism->smcd);
 613        pci_release_mem_regions(pdev);
 614        pci_disable_device(pdev);
 615        dev_set_drvdata(&pdev->dev, NULL);
 616        kfree(ism);
 617}
 618
 619static struct pci_driver ism_driver = {
 620        .name     = DRV_NAME,
 621        .id_table = ism_device_table,
 622        .probe    = ism_probe,
 623        .remove   = ism_remove,
 624};
 625
 626static int __init ism_init(void)
 627{
 628        int ret;
 629
 630        ism_debug_info = debug_register("ism", 2, 1, 16);
 631        if (!ism_debug_info)
 632                return -ENODEV;
 633
 634        debug_register_view(ism_debug_info, &debug_hex_ascii_view);
 635        ret = pci_register_driver(&ism_driver);
 636        if (ret)
 637                debug_unregister(ism_debug_info);
 638
 639        return ret;
 640}
 641
 642static void __exit ism_exit(void)
 643{
 644        pci_unregister_driver(&ism_driver);
 645        debug_unregister(ism_debug_info);
 646}
 647
 648module_init(ism_init);
 649module_exit(ism_exit);
 650