linux/drivers/misc/ocxl/config.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2// Copyright 2017 IBM Corp.
   3#include <linux/pci.h>
   4#include <asm/pnv-ocxl.h>
   5#include <misc/ocxl.h>
   6#include <misc/ocxl-config.h>
   7
   8#define EXTRACT_BIT(val, bit) (!!(val & BIT(bit)))
   9#define EXTRACT_BITS(val, s, e) ((val & GENMASK(e, s)) >> s)
  10
  11#define OCXL_DVSEC_AFU_IDX_MASK              GENMASK(5, 0)
  12#define OCXL_DVSEC_ACTAG_MASK                GENMASK(11, 0)
  13#define OCXL_DVSEC_PASID_MASK                GENMASK(19, 0)
  14#define OCXL_DVSEC_PASID_LOG_MASK            GENMASK(4, 0)
  15
  16#define OCXL_DVSEC_TEMPL_VERSION         0x0
  17#define OCXL_DVSEC_TEMPL_NAME            0x4
  18#define OCXL_DVSEC_TEMPL_AFU_VERSION     0x1C
  19#define OCXL_DVSEC_TEMPL_MMIO_GLOBAL     0x20
  20#define OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ  0x28
  21#define OCXL_DVSEC_TEMPL_MMIO_PP         0x30
  22#define OCXL_DVSEC_TEMPL_MMIO_PP_SZ      0x38
  23#define OCXL_DVSEC_TEMPL_MEM_SZ          0x3C
  24#define OCXL_DVSEC_TEMPL_WWID            0x40
  25
  26#define OCXL_MAX_AFU_PER_FUNCTION 64
  27#define OCXL_TEMPL_LEN            0x58
  28#define OCXL_TEMPL_NAME_LEN       24
  29#define OCXL_CFG_TIMEOUT     3
  30
  31static int find_dvsec(struct pci_dev *dev, int dvsec_id)
  32{
  33        int vsec = 0;
  34        u16 vendor, id;
  35
  36        while ((vsec = pci_find_next_ext_capability(dev, vsec,
  37                                                    OCXL_EXT_CAP_ID_DVSEC))) {
  38                pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
  39                                &vendor);
  40                pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
  41                if (vendor == PCI_VENDOR_ID_IBM && id == dvsec_id)
  42                        return vsec;
  43        }
  44        return 0;
  45}
  46
  47static int find_dvsec_afu_ctrl(struct pci_dev *dev, u8 afu_idx)
  48{
  49        int vsec = 0;
  50        u16 vendor, id;
  51        u8 idx;
  52
  53        while ((vsec = pci_find_next_ext_capability(dev, vsec,
  54                                                    OCXL_EXT_CAP_ID_DVSEC))) {
  55                pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
  56                                &vendor);
  57                pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
  58
  59                if (vendor == PCI_VENDOR_ID_IBM &&
  60                        id == OCXL_DVSEC_AFU_CTRL_ID) {
  61                        pci_read_config_byte(dev,
  62                                        vsec + OCXL_DVSEC_AFU_CTRL_AFU_IDX,
  63                                        &idx);
  64                        if (idx == afu_idx)
  65                                return vsec;
  66                }
  67        }
  68        return 0;
  69}
  70
  71static int read_pasid(struct pci_dev *dev, struct ocxl_fn_config *fn)
  72{
  73        u16 val;
  74        int pos;
  75
  76        pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PASID);
  77        if (!pos) {
  78                /*
  79                 * PASID capability is not mandatory, but there
  80                 * shouldn't be any AFU
  81                 */
  82                dev_dbg(&dev->dev, "Function doesn't require any PASID\n");
  83                fn->max_pasid_log = -1;
  84                goto out;
  85        }
  86        pci_read_config_word(dev, pos + PCI_PASID_CAP, &val);
  87        fn->max_pasid_log = EXTRACT_BITS(val, 8, 12);
  88
  89out:
  90        dev_dbg(&dev->dev, "PASID capability:\n");
  91        dev_dbg(&dev->dev, "  Max PASID log = %d\n", fn->max_pasid_log);
  92        return 0;
  93}
  94
  95static int read_dvsec_tl(struct pci_dev *dev, struct ocxl_fn_config *fn)
  96{
  97        int pos;
  98
  99        pos = find_dvsec(dev, OCXL_DVSEC_TL_ID);
 100        if (!pos && PCI_FUNC(dev->devfn) == 0) {
 101                dev_err(&dev->dev, "Can't find TL DVSEC\n");
 102                return -ENODEV;
 103        }
 104        if (pos && PCI_FUNC(dev->devfn) != 0) {
 105                dev_err(&dev->dev, "TL DVSEC is only allowed on function 0\n");
 106                return -ENODEV;
 107        }
 108        fn->dvsec_tl_pos = pos;
 109        return 0;
 110}
 111
 112static int read_dvsec_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
 113{
 114        int pos, afu_present;
 115        u32 val;
 116
 117        pos = find_dvsec(dev, OCXL_DVSEC_FUNC_ID);
 118        if (!pos) {
 119                dev_err(&dev->dev, "Can't find function DVSEC\n");
 120                return -ENODEV;
 121        }
 122        fn->dvsec_function_pos = pos;
 123
 124        pci_read_config_dword(dev, pos + OCXL_DVSEC_FUNC_OFF_INDEX, &val);
 125        afu_present = EXTRACT_BIT(val, 31);
 126        if (!afu_present) {
 127                fn->max_afu_index = -1;
 128                dev_dbg(&dev->dev, "Function doesn't define any AFU\n");
 129                goto out;
 130        }
 131        fn->max_afu_index = EXTRACT_BITS(val, 24, 29);
 132
 133out:
 134        dev_dbg(&dev->dev, "Function DVSEC:\n");
 135        dev_dbg(&dev->dev, "  Max AFU index = %d\n", fn->max_afu_index);
 136        return 0;
 137}
 138
 139static int read_dvsec_afu_info(struct pci_dev *dev, struct ocxl_fn_config *fn)
 140{
 141        int pos;
 142
 143        if (fn->max_afu_index < 0) {
 144                fn->dvsec_afu_info_pos = -1;
 145                return 0;
 146        }
 147
 148        pos = find_dvsec(dev, OCXL_DVSEC_AFU_INFO_ID);
 149        if (!pos) {
 150                dev_err(&dev->dev, "Can't find AFU information DVSEC\n");
 151                return -ENODEV;
 152        }
 153        fn->dvsec_afu_info_pos = pos;
 154        return 0;
 155}
 156
 157static int read_dvsec_vendor(struct pci_dev *dev)
 158{
 159        int pos;
 160        u32 cfg, tlx, dlx;
 161
 162        /*
 163         * vendor specific DVSEC is optional
 164         *
 165         * It's currently only used on function 0 to specify the
 166         * version of some logic blocks. Some older images may not
 167         * even have it so we ignore any errors
 168         */
 169        if (PCI_FUNC(dev->devfn) != 0)
 170                return 0;
 171
 172        pos = find_dvsec(dev, OCXL_DVSEC_VENDOR_ID);
 173        if (!pos)
 174                return 0;
 175
 176        pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_CFG_VERS, &cfg);
 177        pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_TLX_VERS, &tlx);
 178        pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_DLX_VERS, &dlx);
 179
 180        dev_dbg(&dev->dev, "Vendor specific DVSEC:\n");
 181        dev_dbg(&dev->dev, "  CFG version = 0x%x\n", cfg);
 182        dev_dbg(&dev->dev, "  TLX version = 0x%x\n", tlx);
 183        dev_dbg(&dev->dev, "  DLX version = 0x%x\n", dlx);
 184        return 0;
 185}
 186
 187static int validate_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
 188{
 189        if (fn->max_pasid_log == -1 && fn->max_afu_index >= 0) {
 190                dev_err(&dev->dev,
 191                        "AFUs are defined but no PASIDs are requested\n");
 192                return -EINVAL;
 193        }
 194
 195        if (fn->max_afu_index > OCXL_MAX_AFU_PER_FUNCTION) {
 196                dev_err(&dev->dev,
 197                        "Max AFU index out of architectural limit (%d vs %d)\n",
 198                        fn->max_afu_index, OCXL_MAX_AFU_PER_FUNCTION);
 199                return -EINVAL;
 200        }
 201        return 0;
 202}
 203
 204int ocxl_config_read_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
 205{
 206        int rc;
 207
 208        rc = read_pasid(dev, fn);
 209        if (rc) {
 210                dev_err(&dev->dev, "Invalid PASID configuration: %d\n", rc);
 211                return -ENODEV;
 212        }
 213
 214        rc = read_dvsec_tl(dev, fn);
 215        if (rc) {
 216                dev_err(&dev->dev,
 217                        "Invalid Transaction Layer DVSEC configuration: %d\n",
 218                        rc);
 219                return -ENODEV;
 220        }
 221
 222        rc = read_dvsec_function(dev, fn);
 223        if (rc) {
 224                dev_err(&dev->dev,
 225                        "Invalid Function DVSEC configuration: %d\n", rc);
 226                return -ENODEV;
 227        }
 228
 229        rc = read_dvsec_afu_info(dev, fn);
 230        if (rc) {
 231                dev_err(&dev->dev, "Invalid AFU configuration: %d\n", rc);
 232                return -ENODEV;
 233        }
 234
 235        rc = read_dvsec_vendor(dev);
 236        if (rc) {
 237                dev_err(&dev->dev,
 238                        "Invalid vendor specific DVSEC configuration: %d\n",
 239                        rc);
 240                return -ENODEV;
 241        }
 242
 243        rc = validate_function(dev, fn);
 244        return rc;
 245}
 246EXPORT_SYMBOL_GPL(ocxl_config_read_function);
 247
 248static int read_afu_info(struct pci_dev *dev, struct ocxl_fn_config *fn,
 249                        int offset, u32 *data)
 250{
 251        u32 val;
 252        unsigned long timeout = jiffies + (HZ * OCXL_CFG_TIMEOUT);
 253        int pos = fn->dvsec_afu_info_pos;
 254
 255        /* Protect 'data valid' bit */
 256        if (EXTRACT_BIT(offset, 31)) {
 257                dev_err(&dev->dev, "Invalid offset in AFU info DVSEC\n");
 258                return -EINVAL;
 259        }
 260
 261        pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_OFF, offset);
 262        pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_OFF, &val);
 263        while (!EXTRACT_BIT(val, 31)) {
 264                if (time_after_eq(jiffies, timeout)) {
 265                        dev_err(&dev->dev,
 266                                "Timeout while reading AFU info DVSEC (offset=%d)\n",
 267                                offset);
 268                        return -EBUSY;
 269                }
 270                cpu_relax();
 271                pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_OFF, &val);
 272        }
 273        pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_DATA, data);
 274        return 0;
 275}
 276
 277int ocxl_config_check_afu_index(struct pci_dev *dev,
 278                                struct ocxl_fn_config *fn, int afu_idx)
 279{
 280        u32 val;
 281        int rc, templ_major, templ_minor, len;
 282
 283        pci_write_config_word(dev, fn->dvsec_afu_info_pos, afu_idx);
 284        rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_VERSION, &val);
 285        if (rc)
 286                return rc;
 287
 288        /* AFU index map can have holes */
 289        if (!val)
 290                return 0;
 291
 292        templ_major = EXTRACT_BITS(val, 8, 15);
 293        templ_minor = EXTRACT_BITS(val, 0, 7);
 294        dev_dbg(&dev->dev, "AFU descriptor template version %d.%d\n",
 295                templ_major, templ_minor);
 296
 297        len = EXTRACT_BITS(val, 16, 31);
 298        if (len != OCXL_TEMPL_LEN) {
 299                dev_warn(&dev->dev,
 300                        "Unexpected template length in AFU information (%#x)\n",
 301                        len);
 302        }
 303        return 1;
 304}
 305EXPORT_SYMBOL_GPL(ocxl_config_check_afu_index);
 306
 307static int read_afu_name(struct pci_dev *dev, struct ocxl_fn_config *fn,
 308                        struct ocxl_afu_config *afu)
 309{
 310        int i, rc;
 311        u32 val, *ptr;
 312
 313        BUILD_BUG_ON(OCXL_AFU_NAME_SZ < OCXL_TEMPL_NAME_LEN);
 314        for (i = 0; i < OCXL_TEMPL_NAME_LEN; i += 4) {
 315                rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_NAME + i, &val);
 316                if (rc)
 317                        return rc;
 318                ptr = (u32 *) &afu->name[i];
 319                *ptr = val;
 320        }
 321        afu->name[OCXL_AFU_NAME_SZ - 1] = '\0'; /* play safe */
 322        return 0;
 323}
 324
 325static int read_afu_mmio(struct pci_dev *dev, struct ocxl_fn_config *fn,
 326                        struct ocxl_afu_config *afu)
 327{
 328        int rc;
 329        u32 val;
 330
 331        /*
 332         * Global MMIO
 333         */
 334        rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL, &val);
 335        if (rc)
 336                return rc;
 337        afu->global_mmio_bar = EXTRACT_BITS(val, 0, 2);
 338        afu->global_mmio_offset = EXTRACT_BITS(val, 16, 31) << 16;
 339
 340        rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL + 4, &val);
 341        if (rc)
 342                return rc;
 343        afu->global_mmio_offset += (u64) val << 32;
 344
 345        rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ, &val);
 346        if (rc)
 347                return rc;
 348        afu->global_mmio_size = val;
 349
 350        /*
 351         * Per-process MMIO
 352         */
 353        rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP, &val);
 354        if (rc)
 355                return rc;
 356        afu->pp_mmio_bar = EXTRACT_BITS(val, 0, 2);
 357        afu->pp_mmio_offset = EXTRACT_BITS(val, 16, 31) << 16;
 358
 359        rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP + 4, &val);
 360        if (rc)
 361                return rc;
 362        afu->pp_mmio_offset += (u64) val << 32;
 363
 364        rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP_SZ, &val);
 365        if (rc)
 366                return rc;
 367        afu->pp_mmio_stride = val;
 368
 369        return 0;
 370}
 371
 372static int read_afu_control(struct pci_dev *dev, struct ocxl_afu_config *afu)
 373{
 374        int pos;
 375        u8 val8;
 376        u16 val16;
 377
 378        pos = find_dvsec_afu_ctrl(dev, afu->idx);
 379        if (!pos) {
 380                dev_err(&dev->dev, "Can't find AFU control DVSEC for AFU %d\n",
 381                        afu->idx);
 382                return -ENODEV;
 383        }
 384        afu->dvsec_afu_control_pos = pos;
 385
 386        pci_read_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_SUP, &val8);
 387        afu->pasid_supported_log = EXTRACT_BITS(val8, 0, 4);
 388
 389        pci_read_config_word(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_SUP, &val16);
 390        afu->actag_supported = EXTRACT_BITS(val16, 0, 11);
 391        return 0;
 392}
 393
 394static bool char_allowed(int c)
 395{
 396        /*
 397         * Permitted Characters : Alphanumeric, hyphen, underscore, comma
 398         */
 399        if ((c >= 0x30 && c <= 0x39) /* digits */ ||
 400                (c >= 0x41 && c <= 0x5A) /* upper case */ ||
 401                (c >= 0x61 && c <= 0x7A) /* lower case */ ||
 402                c == 0 /* NULL */ ||
 403                c == 0x2D /* - */ ||
 404                c == 0x5F /* _ */ ||
 405                c == 0x2C /* , */)
 406                return true;
 407        return false;
 408}
 409
 410static int validate_afu(struct pci_dev *dev, struct ocxl_afu_config *afu)
 411{
 412        int i;
 413
 414        if (!afu->name[0]) {
 415                dev_err(&dev->dev, "Empty AFU name\n");
 416                return -EINVAL;
 417        }
 418        for (i = 0; i < OCXL_TEMPL_NAME_LEN; i++) {
 419                if (!char_allowed(afu->name[i])) {
 420                        dev_err(&dev->dev,
 421                                "Invalid character in AFU name\n");
 422                        return -EINVAL;
 423                }
 424        }
 425
 426        if (afu->global_mmio_bar != 0 &&
 427                afu->global_mmio_bar != 2 &&
 428                afu->global_mmio_bar != 4) {
 429                dev_err(&dev->dev, "Invalid global MMIO bar number\n");
 430                return -EINVAL;
 431        }
 432        if (afu->pp_mmio_bar != 0 &&
 433                afu->pp_mmio_bar != 2 &&
 434                afu->pp_mmio_bar != 4) {
 435                dev_err(&dev->dev, "Invalid per-process MMIO bar number\n");
 436                return -EINVAL;
 437        }
 438        return 0;
 439}
 440
 441int ocxl_config_read_afu(struct pci_dev *dev, struct ocxl_fn_config *fn,
 442                        struct ocxl_afu_config *afu, u8 afu_idx)
 443{
 444        int rc;
 445        u32 val32;
 446
 447        /*
 448         * First, we need to write the AFU idx for the AFU we want to
 449         * access.
 450         */
 451        WARN_ON((afu_idx & OCXL_DVSEC_AFU_IDX_MASK) != afu_idx);
 452        afu->idx = afu_idx;
 453        pci_write_config_byte(dev,
 454                        fn->dvsec_afu_info_pos + OCXL_DVSEC_AFU_INFO_AFU_IDX,
 455                        afu->idx);
 456
 457        rc = read_afu_name(dev, fn, afu);
 458        if (rc)
 459                return rc;
 460
 461        rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_AFU_VERSION, &val32);
 462        if (rc)
 463                return rc;
 464        afu->version_major = EXTRACT_BITS(val32, 24, 31);
 465        afu->version_minor = EXTRACT_BITS(val32, 16, 23);
 466        afu->afuc_type = EXTRACT_BITS(val32, 14, 15);
 467        afu->afum_type = EXTRACT_BITS(val32, 12, 13);
 468        afu->profile = EXTRACT_BITS(val32, 0, 7);
 469
 470        rc = read_afu_mmio(dev, fn, afu);
 471        if (rc)
 472                return rc;
 473
 474        rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MEM_SZ, &val32);
 475        if (rc)
 476                return rc;
 477        afu->log_mem_size = EXTRACT_BITS(val32, 0, 7);
 478
 479        rc = read_afu_control(dev, afu);
 480        if (rc)
 481                return rc;
 482
 483        dev_dbg(&dev->dev, "AFU configuration:\n");
 484        dev_dbg(&dev->dev, "  name = %s\n", afu->name);
 485        dev_dbg(&dev->dev, "  version = %d.%d\n", afu->version_major,
 486                afu->version_minor);
 487        dev_dbg(&dev->dev, "  global mmio bar = %hhu\n", afu->global_mmio_bar);
 488        dev_dbg(&dev->dev, "  global mmio offset = %#llx\n",
 489                afu->global_mmio_offset);
 490        dev_dbg(&dev->dev, "  global mmio size = %#x\n", afu->global_mmio_size);
 491        dev_dbg(&dev->dev, "  pp mmio bar = %hhu\n", afu->pp_mmio_bar);
 492        dev_dbg(&dev->dev, "  pp mmio offset = %#llx\n", afu->pp_mmio_offset);
 493        dev_dbg(&dev->dev, "  pp mmio stride = %#x\n", afu->pp_mmio_stride);
 494        dev_dbg(&dev->dev, "  mem size (log) = %hhu\n", afu->log_mem_size);
 495        dev_dbg(&dev->dev, "  pasid supported (log) = %u\n",
 496                afu->pasid_supported_log);
 497        dev_dbg(&dev->dev, "  actag supported = %u\n",
 498                afu->actag_supported);
 499
 500        rc = validate_afu(dev, afu);
 501        return rc;
 502}
 503EXPORT_SYMBOL_GPL(ocxl_config_read_afu);
 504
 505int ocxl_config_get_actag_info(struct pci_dev *dev, u16 *base, u16 *enabled,
 506                        u16 *supported)
 507{
 508        int rc;
 509
 510        /*
 511         * This is really a simple wrapper for the kernel API, to
 512         * avoid an external driver using ocxl as a library to call
 513         * platform-dependent code
 514         */
 515        rc = pnv_ocxl_get_actag(dev, base, enabled, supported);
 516        if (rc) {
 517                dev_err(&dev->dev, "Can't get actag for device: %d\n", rc);
 518                return rc;
 519        }
 520        return 0;
 521}
 522EXPORT_SYMBOL_GPL(ocxl_config_get_actag_info);
 523
 524void ocxl_config_set_afu_actag(struct pci_dev *dev, int pos, int actag_base,
 525                        int actag_count)
 526{
 527        u16 val;
 528
 529        val = actag_count & OCXL_DVSEC_ACTAG_MASK;
 530        pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_EN, val);
 531
 532        val = actag_base & OCXL_DVSEC_ACTAG_MASK;
 533        pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_BASE, val);
 534}
 535EXPORT_SYMBOL_GPL(ocxl_config_set_afu_actag);
 536
 537int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count)
 538{
 539        return pnv_ocxl_get_pasid_count(dev, count);
 540}
 541EXPORT_SYMBOL_GPL(ocxl_config_get_pasid_info);
 542
 543void ocxl_config_set_afu_pasid(struct pci_dev *dev, int pos, int pasid_base,
 544                        u32 pasid_count_log)
 545{
 546        u8 val8;
 547        u32 val32;
 548
 549        val8 = pasid_count_log & OCXL_DVSEC_PASID_LOG_MASK;
 550        pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_EN, val8);
 551
 552        pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_BASE,
 553                        &val32);
 554        val32 &= ~OCXL_DVSEC_PASID_MASK;
 555        val32 |= pasid_base & OCXL_DVSEC_PASID_MASK;
 556        pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_BASE,
 557                        val32);
 558}
 559EXPORT_SYMBOL_GPL(ocxl_config_set_afu_pasid);
 560
 561void ocxl_config_set_afu_state(struct pci_dev *dev, int pos, int enable)
 562{
 563        u8 val;
 564
 565        pci_read_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ENABLE, &val);
 566        if (enable)
 567                val |= 1;
 568        else
 569                val &= 0xFE;
 570        pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ENABLE, val);
 571}
 572EXPORT_SYMBOL_GPL(ocxl_config_set_afu_state);
 573
 574int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec)
 575{
 576        u32 val;
 577        __be32 *be32ptr;
 578        u8 timers;
 579        int i, rc;
 580        long recv_cap;
 581        char *recv_rate;
 582
 583        /*
 584         * Skip on function != 0, as the TL can only be defined on 0
 585         */
 586        if (PCI_FUNC(dev->devfn) != 0)
 587                return 0;
 588
 589        recv_rate = kzalloc(PNV_OCXL_TL_RATE_BUF_SIZE, GFP_KERNEL);
 590        if (!recv_rate)
 591                return -ENOMEM;
 592        /*
 593         * The spec defines 64 templates for messages in the
 594         * Transaction Layer (TL).
 595         *
 596         * The host and device each support a subset, so we need to
 597         * configure the transmitters on each side to send only
 598         * templates the receiver understands, at a rate the receiver
 599         * can process.  Per the spec, template 0 must be supported by
 600         * everybody. That's the template which has been used by the
 601         * host and device so far.
 602         *
 603         * The sending rate limit must be set before the template is
 604         * enabled.
 605         */
 606
 607        /*
 608         * Device -> host
 609         */
 610        rc = pnv_ocxl_get_tl_cap(dev, &recv_cap, recv_rate,
 611                                PNV_OCXL_TL_RATE_BUF_SIZE);
 612        if (rc)
 613                goto out;
 614
 615        for (i = 0; i < PNV_OCXL_TL_RATE_BUF_SIZE; i += 4) {
 616                be32ptr = (__be32 *) &recv_rate[i];
 617                pci_write_config_dword(dev,
 618                                tl_dvsec + OCXL_DVSEC_TL_SEND_RATE + i,
 619                                be32_to_cpu(*be32ptr));
 620        }
 621        val = recv_cap >> 32;
 622        pci_write_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_SEND_CAP, val);
 623        val = recv_cap & GENMASK(31, 0);
 624        pci_write_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_SEND_CAP + 4, val);
 625
 626        /*
 627         * Host -> device
 628         */
 629        for (i = 0; i < PNV_OCXL_TL_RATE_BUF_SIZE; i += 4) {
 630                pci_read_config_dword(dev,
 631                                tl_dvsec + OCXL_DVSEC_TL_RECV_RATE + i,
 632                                &val);
 633                be32ptr = (__be32 *) &recv_rate[i];
 634                *be32ptr = cpu_to_be32(val);
 635        }
 636        pci_read_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_RECV_CAP, &val);
 637        recv_cap = (long) val << 32;
 638        pci_read_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_RECV_CAP + 4, &val);
 639        recv_cap |= val;
 640
 641        rc = pnv_ocxl_set_tl_conf(dev, recv_cap, __pa(recv_rate),
 642                                PNV_OCXL_TL_RATE_BUF_SIZE);
 643        if (rc)
 644                goto out;
 645
 646        /*
 647         * Opencapi commands needing to be retried are classified per
 648         * the TL in 2 groups: short and long commands.
 649         *
 650         * The short back off timer it not used for now. It will be
 651         * for opencapi 4.0.
 652         *
 653         * The long back off timer is typically used when an AFU hits
 654         * a page fault but the NPU is already processing one. So the
 655         * AFU needs to wait before it can resubmit. Having a value
 656         * too low doesn't break anything, but can generate extra
 657         * traffic on the link.
 658         * We set it to 1.6 us for now. It's shorter than, but in the
 659         * same order of magnitude as the time spent to process a page
 660         * fault.
 661         */
 662        timers = 0x2 << 4; /* long timer = 1.6 us */
 663        pci_write_config_byte(dev, tl_dvsec + OCXL_DVSEC_TL_BACKOFF_TIMERS,
 664                        timers);
 665
 666        rc = 0;
 667out:
 668        kfree(recv_rate);
 669        return rc;
 670}
 671EXPORT_SYMBOL_GPL(ocxl_config_set_TL);
 672
 673int ocxl_config_terminate_pasid(struct pci_dev *dev, int afu_control, int pasid)
 674{
 675        u32 val;
 676        unsigned long timeout;
 677
 678        pci_read_config_dword(dev, afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
 679                        &val);
 680        if (EXTRACT_BIT(val, 20)) {
 681                dev_err(&dev->dev,
 682                        "Can't terminate PASID %#x, previous termination didn't complete\n",
 683                        pasid);
 684                return -EBUSY;
 685        }
 686
 687        val &= ~OCXL_DVSEC_PASID_MASK;
 688        val |= pasid & OCXL_DVSEC_PASID_MASK;
 689        val |= BIT(20);
 690        pci_write_config_dword(dev,
 691                        afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
 692                        val);
 693
 694        timeout = jiffies + (HZ * OCXL_CFG_TIMEOUT);
 695        pci_read_config_dword(dev, afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
 696                        &val);
 697        while (EXTRACT_BIT(val, 20)) {
 698                if (time_after_eq(jiffies, timeout)) {
 699                        dev_err(&dev->dev,
 700                                "Timeout while waiting for AFU to terminate PASID %#x\n",
 701                                pasid);
 702                        return -EBUSY;
 703                }
 704                cpu_relax();
 705                pci_read_config_dword(dev,
 706                                afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
 707                                &val);
 708        }
 709        return 0;
 710}
 711EXPORT_SYMBOL_GPL(ocxl_config_terminate_pasid);
 712
 713void ocxl_config_set_actag(struct pci_dev *dev, int func_dvsec, u32 tag_first,
 714                        u32 tag_count)
 715{
 716        u32 val;
 717
 718        val = (tag_first & OCXL_DVSEC_ACTAG_MASK) << 16;
 719        val |= tag_count & OCXL_DVSEC_ACTAG_MASK;
 720        pci_write_config_dword(dev, func_dvsec + OCXL_DVSEC_FUNC_OFF_ACTAG,
 721                        val);
 722}
 723EXPORT_SYMBOL_GPL(ocxl_config_set_actag);
 724