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