Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: endpoint: Support NTB transfer between RC and EP

Add NTB function driver and virtual PCI Bus and Virtual NTB driver
to implement communication between PCIe Root Port and PCIe EP devices

┌────────────┐ ┌─────────────────────────────────────┐
│ │ │ │
├────────────┤ │ ┌──────────────┤
│ NTB │ │ │ NTB │
│ NetDev │ │ │ NetDev │
├────────────┤ │ ├──────────────┤
│ NTB │ │ │ NTB │
│ Transfer │ │ │ Transfer │
├────────────┤ │ ├──────────────┤
│ │ │ │ │
│ PCI NTB │ │ │ │
│ EPF │ │ │ │
│ Driver │ │ │ PCI Virtual │
│ │ ├───────────────┐ │ NTB Driver │
│ │ │ PCI EP NTB │◄────►│ │
│ │ │ FN Driver │ │ │
├────────────┤ ├───────────────┤ ├──────────────┤
│ │ │ │ │ │
│ PCI Bus │ ◄─────► │ PCI EP Bus │ │ Virtual PCI │
│ │ PCI │ │ │ Bus │
└────────────┘ └───────────────┴──────┴──────────────┘
PCIe Root Port PCI EP

This driver includes 3 parts:
1 PCI EP NTB function driver
2 Virtual PCI bus
3 PCI virtual NTB driver, which is loaded only by above virtual PCI bus

Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Jon Mason <jdmason@kudzu.us>

authored by

Frank Li and committed by
Jon Mason
e35f56bb e75d5ae8

+1436
+11
drivers/pci/endpoint/functions/Kconfig
··· 25 25 device tree. 26 26 27 27 If in doubt, say "N" to disable Endpoint NTB driver. 28 + 29 + config PCI_EPF_VNTB 30 + tristate "PCI Endpoint NTB driver" 31 + depends on PCI_ENDPOINT 32 + select CONFIGFS_FS 33 + help 34 + Select this configuration option to enable the Non-Transparent 35 + Bridge (NTB) driver for PCIe Endpoint. NTB driver implements NTB 36 + between PCI Root Port and PCIe Endpoint. 37 + 38 + If in doubt, say "N" to disable Endpoint NTB driver.
+1
drivers/pci/endpoint/functions/Makefile
··· 5 5 6 6 obj-$(CONFIG_PCI_EPF_TEST) += pci-epf-test.o 7 7 obj-$(CONFIG_PCI_EPF_NTB) += pci-epf-ntb.o 8 + obj-$(CONFIG_PCI_EPF_VNTB) += pci-epf-vntb.o
+1424
drivers/pci/endpoint/functions/pci-epf-vntb.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Endpoint Function Driver to implement Non-Transparent Bridge functionality 4 + * Between PCI RC and EP 5 + * 6 + * Copyright (C) 2020 Texas Instruments 7 + * Copyright (C) 2022 NXP 8 + * 9 + * Based on pci-epf-ntb.c 10 + * Author: Frank Li <Frank.Li@nxp.com> 11 + * Author: Kishon Vijay Abraham I <kishon@ti.com> 12 + */ 13 + 14 + /** 15 + * +------------+ +---------------------------------------+ 16 + * | | | | 17 + * +------------+ | +--------------+ 18 + * | NTB | | | NTB | 19 + * | NetDev | | | NetDev | 20 + * +------------+ | +--------------+ 21 + * | NTB | | | NTB | 22 + * | Transfer | | | Transfer | 23 + * +------------+ | +--------------+ 24 + * | | | | | 25 + * | PCI NTB | | | | 26 + * | EPF | | | | 27 + * | Driver | | | PCI Virtual | 28 + * | | +---------------+ | NTB Driver | 29 + * | | | PCI EP NTB |<------>| | 30 + * | | | FN Driver | | | 31 + * +------------+ +---------------+ +--------------+ 32 + * | | | | | | 33 + * | PCI Bus | <-----> | PCI EP Bus | | Virtual PCI | 34 + * | | PCI | | | Bus | 35 + * +------------+ +---------------+--------+--------------+ 36 + * PCIe Root Port PCI EP 37 + */ 38 + 39 + #include <linux/delay.h> 40 + #include <linux/io.h> 41 + #include <linux/module.h> 42 + #include <linux/slab.h> 43 + 44 + #include <linux/pci-epc.h> 45 + #include <linux/pci-epf.h> 46 + #include <linux/ntb.h> 47 + 48 + static struct workqueue_struct *kpcintb_workqueue; 49 + 50 + #define COMMAND_CONFIGURE_DOORBELL 1 51 + #define COMMAND_TEARDOWN_DOORBELL 2 52 + #define COMMAND_CONFIGURE_MW 3 53 + #define COMMAND_TEARDOWN_MW 4 54 + #define COMMAND_LINK_UP 5 55 + #define COMMAND_LINK_DOWN 6 56 + 57 + #define COMMAND_STATUS_OK 1 58 + #define COMMAND_STATUS_ERROR 2 59 + 60 + #define LINK_STATUS_UP BIT(0) 61 + 62 + #define SPAD_COUNT 64 63 + #define DB_COUNT 4 64 + #define NTB_MW_OFFSET 2 65 + #define DB_COUNT_MASK GENMASK(15, 0) 66 + #define MSIX_ENABLE BIT(16) 67 + #define MAX_DB_COUNT 32 68 + #define MAX_MW 4 69 + 70 + enum epf_ntb_bar { 71 + BAR_CONFIG, 72 + BAR_DB, 73 + BAR_MW0, 74 + BAR_MW1, 75 + BAR_MW2, 76 + }; 77 + 78 + /* 79 + * +--------------------------------------------------+ Base 80 + * | | 81 + * | | 82 + * | | 83 + * | Common Control Register | 84 + * | | 85 + * | | 86 + * | | 87 + * +-----------------------+--------------------------+ Base+span_offset 88 + * | | | 89 + * | Peer Span Space | Span Space | 90 + * | | | 91 + * | | | 92 + * +-----------------------+--------------------------+ Base+span_offset 93 + * | | | +span_count * 4 94 + * | | | 95 + * | Span Space | Peer Span Space | 96 + * | | | 97 + * +-----------------------+--------------------------+ 98 + * Virtual PCI PCIe Endpoint 99 + * NTB Driver NTB Driver 100 + */ 101 + struct epf_ntb_ctrl { 102 + u32 command; 103 + u32 argument; 104 + u16 command_status; 105 + u16 link_status; 106 + u32 topology; 107 + u64 addr; 108 + u64 size; 109 + u32 num_mws; 110 + u32 reserved; 111 + u32 spad_offset; 112 + u32 spad_count; 113 + u32 db_entry_size; 114 + u32 db_data[MAX_DB_COUNT]; 115 + u32 db_offset[MAX_DB_COUNT]; 116 + } __packed; 117 + 118 + struct epf_ntb { 119 + struct ntb_dev ntb; 120 + struct pci_epf *epf; 121 + struct config_group group; 122 + 123 + u32 num_mws; 124 + u32 db_count; 125 + u32 spad_count; 126 + u64 mws_size[MAX_MW]; 127 + u64 db; 128 + u32 vbus_number; 129 + u16 vntb_pid; 130 + u16 vntb_vid; 131 + 132 + bool linkup; 133 + u32 spad_size; 134 + 135 + enum pci_barno epf_ntb_bar[6]; 136 + 137 + struct epf_ntb_ctrl *reg; 138 + 139 + phys_addr_t epf_db_phy; 140 + void __iomem *epf_db; 141 + 142 + phys_addr_t vpci_mw_phy[MAX_MW]; 143 + void __iomem *vpci_mw_addr[MAX_MW]; 144 + 145 + struct delayed_work cmd_handler; 146 + }; 147 + 148 + #define to_epf_ntb(epf_group) container_of((epf_group), struct epf_ntb, group) 149 + #define ntb_ndev(__ntb) container_of(__ntb, struct epf_ntb, ntb) 150 + 151 + static struct pci_epf_header epf_ntb_header = { 152 + .vendorid = PCI_ANY_ID, 153 + .deviceid = PCI_ANY_ID, 154 + .baseclass_code = PCI_BASE_CLASS_MEMORY, 155 + .interrupt_pin = PCI_INTERRUPT_INTA, 156 + }; 157 + 158 + /** 159 + * epf_ntb_link_up() - Raise link_up interrupt to Virtual Host 160 + * @ntb: NTB device that facilitates communication between HOST and VHOST 161 + * @link_up: true or false indicating Link is UP or Down 162 + * 163 + * Once NTB function in HOST invoke ntb_link_enable(), 164 + * this NTB function driver will trigger a link event to vhost. 165 + */ 166 + static int epf_ntb_link_up(struct epf_ntb *ntb, bool link_up) 167 + { 168 + if (link_up) 169 + ntb->reg->link_status |= LINK_STATUS_UP; 170 + else 171 + ntb->reg->link_status &= ~LINK_STATUS_UP; 172 + 173 + ntb_link_event(&ntb->ntb); 174 + return 0; 175 + } 176 + 177 + /** 178 + * epf_ntb_configure_mw() - Configure the Outbound Address Space for vhost 179 + * to access the memory window of host 180 + * @ntb: NTB device that facilitates communication between host and vhost 181 + * @mw: Index of the memory window (either 0, 1, 2 or 3) 182 + * 183 + * EP Outbound Window 184 + * +--------+ +-----------+ 185 + * | | | | 186 + * | | | | 187 + * | | | | 188 + * | | | | 189 + * | | +-----------+ 190 + * | Virtual| | Memory Win| 191 + * | NTB | -----------> | | 192 + * | Driver | | | 193 + * | | +-----------+ 194 + * | | | | 195 + * | | | | 196 + * +--------+ +-----------+ 197 + * VHost PCI EP 198 + */ 199 + static int epf_ntb_configure_mw(struct epf_ntb *ntb, u32 mw) 200 + { 201 + phys_addr_t phys_addr; 202 + u8 func_no, vfunc_no; 203 + u64 addr, size; 204 + int ret = 0; 205 + 206 + phys_addr = ntb->vpci_mw_phy[mw]; 207 + addr = ntb->reg->addr; 208 + size = ntb->reg->size; 209 + 210 + func_no = ntb->epf->func_no; 211 + vfunc_no = ntb->epf->vfunc_no; 212 + 213 + ret = pci_epc_map_addr(ntb->epf->epc, func_no, vfunc_no, phys_addr, addr, size); 214 + if (ret) 215 + dev_err(&ntb->epf->epc->dev, 216 + "Failed to map memory window %d address\n", mw); 217 + return ret; 218 + } 219 + 220 + /** 221 + * epf_ntb_teardown_mw() - Teardown the configured OB ATU 222 + * @ntb: NTB device that facilitates communication between HOST and vHOST 223 + * @mw: Index of the memory window (either 0, 1, 2 or 3) 224 + * 225 + * Teardown the configured OB ATU configured in epf_ntb_configure_mw() using 226 + * pci_epc_unmap_addr() 227 + */ 228 + static void epf_ntb_teardown_mw(struct epf_ntb *ntb, u32 mw) 229 + { 230 + pci_epc_unmap_addr(ntb->epf->epc, 231 + ntb->epf->func_no, 232 + ntb->epf->vfunc_no, 233 + ntb->vpci_mw_phy[mw]); 234 + } 235 + 236 + /** 237 + * epf_ntb_cmd_handler() - Handle commands provided by the NTB Host 238 + * @work: work_struct for the epf_ntb_epc 239 + * 240 + * Workqueue function that gets invoked for the two epf_ntb_epc 241 + * periodically (once every 5ms) to see if it has received any commands 242 + * from NTB host. The host can send commands to configure doorbell or 243 + * configure memory window or to update link status. 244 + */ 245 + static void epf_ntb_cmd_handler(struct work_struct *work) 246 + { 247 + struct epf_ntb_ctrl *ctrl; 248 + u32 command, argument; 249 + struct epf_ntb *ntb; 250 + struct device *dev; 251 + int ret; 252 + int i; 253 + 254 + ntb = container_of(work, struct epf_ntb, cmd_handler.work); 255 + 256 + for (i = 1; i < ntb->db_count; i++) { 257 + if (readl(ntb->epf_db + i * 4)) { 258 + if (readl(ntb->epf_db + i * 4)) 259 + ntb->db |= 1 << (i - 1); 260 + 261 + ntb_db_event(&ntb->ntb, i); 262 + writel(0, ntb->epf_db + i * 4); 263 + } 264 + } 265 + 266 + ctrl = ntb->reg; 267 + command = ctrl->command; 268 + if (!command) 269 + goto reset_handler; 270 + argument = ctrl->argument; 271 + 272 + ctrl->command = 0; 273 + ctrl->argument = 0; 274 + 275 + ctrl = ntb->reg; 276 + dev = &ntb->epf->dev; 277 + 278 + switch (command) { 279 + case COMMAND_CONFIGURE_DOORBELL: 280 + ctrl->command_status = COMMAND_STATUS_OK; 281 + break; 282 + case COMMAND_TEARDOWN_DOORBELL: 283 + ctrl->command_status = COMMAND_STATUS_OK; 284 + break; 285 + case COMMAND_CONFIGURE_MW: 286 + ret = epf_ntb_configure_mw(ntb, argument); 287 + if (ret < 0) 288 + ctrl->command_status = COMMAND_STATUS_ERROR; 289 + else 290 + ctrl->command_status = COMMAND_STATUS_OK; 291 + break; 292 + case COMMAND_TEARDOWN_MW: 293 + epf_ntb_teardown_mw(ntb, argument); 294 + ctrl->command_status = COMMAND_STATUS_OK; 295 + break; 296 + case COMMAND_LINK_UP: 297 + ntb->linkup = true; 298 + ret = epf_ntb_link_up(ntb, true); 299 + if (ret < 0) 300 + ctrl->command_status = COMMAND_STATUS_ERROR; 301 + else 302 + ctrl->command_status = COMMAND_STATUS_OK; 303 + goto reset_handler; 304 + case COMMAND_LINK_DOWN: 305 + ntb->linkup = false; 306 + ret = epf_ntb_link_up(ntb, false); 307 + if (ret < 0) 308 + ctrl->command_status = COMMAND_STATUS_ERROR; 309 + else 310 + ctrl->command_status = COMMAND_STATUS_OK; 311 + break; 312 + default: 313 + dev_err(dev, "UNKNOWN command: %d\n", command); 314 + break; 315 + } 316 + 317 + reset_handler: 318 + queue_delayed_work(kpcintb_workqueue, &ntb->cmd_handler, 319 + msecs_to_jiffies(5)); 320 + } 321 + 322 + /** 323 + * epf_ntb_config_sspad_bar_clear() - Clear Config + Self scratchpad BAR 324 + * @ntb_epc: EPC associated with one of the HOST which holds peer's outbound 325 + * address. 326 + * 327 + * Clear BAR0 of EP CONTROLLER 1 which contains the HOST1's config and 328 + * self scratchpad region (removes inbound ATU configuration). While BAR0 is 329 + * the default self scratchpad BAR, an NTB could have other BARs for self 330 + * scratchpad (because of reserved BARs). This function can get the exact BAR 331 + * used for self scratchpad from epf_ntb_bar[BAR_CONFIG]. 332 + * 333 + * Please note the self scratchpad region and config region is combined to 334 + * a single region and mapped using the same BAR. Also note HOST2's peer 335 + * scratchpad is HOST1's self scratchpad. 336 + */ 337 + static void epf_ntb_config_sspad_bar_clear(struct epf_ntb *ntb) 338 + { 339 + struct pci_epf_bar *epf_bar; 340 + enum pci_barno barno; 341 + 342 + barno = ntb->epf_ntb_bar[BAR_CONFIG]; 343 + epf_bar = &ntb->epf->bar[barno]; 344 + 345 + pci_epc_clear_bar(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no, epf_bar); 346 + } 347 + 348 + /** 349 + * epf_ntb_config_sspad_bar_set() - Set Config + Self scratchpad BAR 350 + * @ntb: NTB device that facilitates communication between HOST and vHOST 351 + * 352 + * Map BAR0 of EP CONTROLLER 1 which contains the HOST1's config and 353 + * self scratchpad region. 354 + * 355 + * Please note the self scratchpad region and config region is combined to 356 + * a single region and mapped using the same BAR. 357 + */ 358 + static int epf_ntb_config_sspad_bar_set(struct epf_ntb *ntb) 359 + { 360 + struct pci_epf_bar *epf_bar; 361 + enum pci_barno barno; 362 + u8 func_no, vfunc_no; 363 + struct device *dev; 364 + int ret; 365 + 366 + dev = &ntb->epf->dev; 367 + func_no = ntb->epf->func_no; 368 + vfunc_no = ntb->epf->vfunc_no; 369 + barno = ntb->epf_ntb_bar[BAR_CONFIG]; 370 + epf_bar = &ntb->epf->bar[barno]; 371 + 372 + ret = pci_epc_set_bar(ntb->epf->epc, func_no, vfunc_no, epf_bar); 373 + if (ret) { 374 + dev_err(dev, "inft: Config/Status/SPAD BAR set failed\n"); 375 + return ret; 376 + } 377 + return 0; 378 + } 379 + 380 + /** 381 + * epf_ntb_config_spad_bar_free() - Free the physical memory associated with 382 + * config + scratchpad region 383 + * @ntb: NTB device that facilitates communication between HOST and vHOST 384 + */ 385 + static void epf_ntb_config_spad_bar_free(struct epf_ntb *ntb) 386 + { 387 + enum pci_barno barno; 388 + 389 + barno = ntb->epf_ntb_bar[BAR_CONFIG]; 390 + pci_epf_free_space(ntb->epf, ntb->reg, barno, 0); 391 + } 392 + 393 + /** 394 + * epf_ntb_config_spad_bar_alloc() - Allocate memory for config + scratchpad 395 + * region 396 + * @ntb: NTB device that facilitates communication between HOST1 and HOST2 397 + * 398 + * Allocate the Local Memory mentioned in the above diagram. The size of 399 + * CONFIG REGION is sizeof(struct epf_ntb_ctrl) and size of SCRATCHPAD REGION 400 + * is obtained from "spad-count" configfs entry. 401 + */ 402 + static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb) 403 + { 404 + size_t align; 405 + enum pci_barno barno; 406 + struct epf_ntb_ctrl *ctrl; 407 + u32 spad_size, ctrl_size; 408 + u64 size; 409 + struct pci_epf *epf = ntb->epf; 410 + struct device *dev = &epf->dev; 411 + u32 spad_count; 412 + void *base; 413 + int i; 414 + const struct pci_epc_features *epc_features = pci_epc_get_features(epf->epc, 415 + epf->func_no, 416 + epf->vfunc_no); 417 + barno = ntb->epf_ntb_bar[BAR_CONFIG]; 418 + size = epc_features->bar_fixed_size[barno]; 419 + align = epc_features->align; 420 + 421 + if ((!IS_ALIGNED(size, align))) 422 + return -EINVAL; 423 + 424 + spad_count = ntb->spad_count; 425 + 426 + ctrl_size = sizeof(struct epf_ntb_ctrl); 427 + spad_size = 2 * spad_count * 4; 428 + 429 + if (!align) { 430 + ctrl_size = roundup_pow_of_two(ctrl_size); 431 + spad_size = roundup_pow_of_two(spad_size); 432 + } else { 433 + ctrl_size = ALIGN(ctrl_size, align); 434 + spad_size = ALIGN(spad_size, align); 435 + } 436 + 437 + if (!size) 438 + size = ctrl_size + spad_size; 439 + else if (size < ctrl_size + spad_size) 440 + return -EINVAL; 441 + 442 + base = pci_epf_alloc_space(epf, size, barno, align, 0); 443 + if (!base) { 444 + dev_err(dev, "Config/Status/SPAD alloc region fail\n"); 445 + return -ENOMEM; 446 + } 447 + 448 + ntb->reg = base; 449 + 450 + ctrl = ntb->reg; 451 + ctrl->spad_offset = ctrl_size; 452 + 453 + ctrl->spad_count = spad_count; 454 + ctrl->num_mws = ntb->num_mws; 455 + ntb->spad_size = spad_size; 456 + 457 + ctrl->db_entry_size = 4; 458 + 459 + for (i = 0; i < ntb->db_count; i++) { 460 + ntb->reg->db_data[i] = 1 + i; 461 + ntb->reg->db_offset[i] = 0; 462 + } 463 + 464 + return 0; 465 + } 466 + 467 + /** 468 + * epf_ntb_configure_interrupt() - Configure MSI/MSI-X capaiblity 469 + * @ntb: NTB device that facilitates communication between HOST and vHOST 470 + * 471 + * Configure MSI/MSI-X capability for each interface with number of 472 + * interrupts equal to "db_count" configfs entry. 473 + */ 474 + static int epf_ntb_configure_interrupt(struct epf_ntb *ntb) 475 + { 476 + const struct pci_epc_features *epc_features; 477 + struct device *dev; 478 + u32 db_count; 479 + int ret; 480 + 481 + dev = &ntb->epf->dev; 482 + 483 + epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no); 484 + 485 + if (!(epc_features->msix_capable || epc_features->msi_capable)) { 486 + dev_err(dev, "MSI or MSI-X is required for doorbell\n"); 487 + return -EINVAL; 488 + } 489 + 490 + db_count = ntb->db_count; 491 + if (db_count > MAX_DB_COUNT) { 492 + dev_err(dev, "DB count cannot be more than %d\n", MAX_DB_COUNT); 493 + return -EINVAL; 494 + } 495 + 496 + ntb->db_count = db_count; 497 + 498 + if (epc_features->msi_capable) { 499 + ret = pci_epc_set_msi(ntb->epf->epc, 500 + ntb->epf->func_no, 501 + ntb->epf->vfunc_no, 502 + 16); 503 + if (ret) { 504 + dev_err(dev, "MSI configuration failed\n"); 505 + return ret; 506 + } 507 + } 508 + 509 + return 0; 510 + } 511 + 512 + /** 513 + * epf_ntb_db_bar_init() - Configure Doorbell window BARs 514 + * @ntb: NTB device that facilitates communication between HOST and vHOST 515 + */ 516 + static int epf_ntb_db_bar_init(struct epf_ntb *ntb) 517 + { 518 + const struct pci_epc_features *epc_features; 519 + u32 align; 520 + struct device *dev = &ntb->epf->dev; 521 + int ret; 522 + struct pci_epf_bar *epf_bar; 523 + void __iomem *mw_addr; 524 + enum pci_barno barno; 525 + size_t size = 4 * ntb->db_count; 526 + 527 + epc_features = pci_epc_get_features(ntb->epf->epc, 528 + ntb->epf->func_no, 529 + ntb->epf->vfunc_no); 530 + align = epc_features->align; 531 + 532 + if (size < 128) 533 + size = 128; 534 + 535 + if (align) 536 + size = ALIGN(size, align); 537 + else 538 + size = roundup_pow_of_two(size); 539 + 540 + barno = ntb->epf_ntb_bar[BAR_DB]; 541 + 542 + mw_addr = pci_epf_alloc_space(ntb->epf, size, barno, align, 0); 543 + if (!mw_addr) { 544 + dev_err(dev, "Failed to allocate OB address\n"); 545 + return -ENOMEM; 546 + } 547 + 548 + ntb->epf_db = mw_addr; 549 + 550 + epf_bar = &ntb->epf->bar[barno]; 551 + 552 + ret = pci_epc_set_bar(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no, epf_bar); 553 + if (ret) { 554 + dev_err(dev, "Doorbell BAR set failed\n"); 555 + goto err_alloc_peer_mem; 556 + } 557 + return ret; 558 + 559 + err_alloc_peer_mem: 560 + pci_epc_mem_free_addr(ntb->epf->epc, epf_bar->phys_addr, mw_addr, epf_bar->size); 561 + return -1; 562 + } 563 + 564 + /** 565 + * epf_ntb_db_bar_clear() - Clear doorbell BAR and free memory 566 + * allocated in peer's outbound address space 567 + * @ntb: NTB device that facilitates communication between HOST and vHOST 568 + */ 569 + static void epf_ntb_db_bar_clear(struct epf_ntb *ntb) 570 + { 571 + enum pci_barno barno; 572 + 573 + barno = ntb->epf_ntb_bar[BAR_DB]; 574 + pci_epf_free_space(ntb->epf, ntb->epf_db, barno, 0); 575 + pci_epc_clear_bar(ntb->epf->epc, 576 + ntb->epf->func_no, 577 + ntb->epf->vfunc_no, 578 + &ntb->epf->bar[barno]); 579 + } 580 + 581 + /** 582 + * epf_ntb_mw_bar_init() - Configure Memory window BARs 583 + * @ntb: NTB device that facilitates communication between HOST and vHOST 584 + * 585 + */ 586 + static int epf_ntb_mw_bar_init(struct epf_ntb *ntb) 587 + { 588 + int ret = 0; 589 + int i; 590 + u64 size; 591 + enum pci_barno barno; 592 + struct device *dev = &ntb->epf->dev; 593 + 594 + for (i = 0; i < ntb->num_mws; i++) { 595 + size = ntb->mws_size[i]; 596 + barno = ntb->epf_ntb_bar[BAR_MW0 + i]; 597 + 598 + ntb->epf->bar[barno].barno = barno; 599 + ntb->epf->bar[barno].size = size; 600 + ntb->epf->bar[barno].addr = 0; 601 + ntb->epf->bar[barno].phys_addr = 0; 602 + ntb->epf->bar[barno].flags |= upper_32_bits(size) ? 603 + PCI_BASE_ADDRESS_MEM_TYPE_64 : 604 + PCI_BASE_ADDRESS_MEM_TYPE_32; 605 + 606 + ret = pci_epc_set_bar(ntb->epf->epc, 607 + ntb->epf->func_no, 608 + ntb->epf->vfunc_no, 609 + &ntb->epf->bar[barno]); 610 + if (ret) { 611 + dev_err(dev, "MW set failed\n"); 612 + goto err_alloc_mem; 613 + } 614 + 615 + /* Allocate EPC outbound memory windows to vpci vntb device */ 616 + ntb->vpci_mw_addr[i] = pci_epc_mem_alloc_addr(ntb->epf->epc, 617 + &ntb->vpci_mw_phy[i], 618 + size); 619 + if (!ntb->vpci_mw_addr[i]) { 620 + dev_err(dev, "Failed to allocate source address\n"); 621 + goto err_alloc_mem; 622 + } 623 + } 624 + 625 + return ret; 626 + err_alloc_mem: 627 + return ret; 628 + } 629 + 630 + /** 631 + * epf_ntb_mw_bar_clear() - Clear Memory window BARs 632 + * @ntb: NTB device that facilitates communication between HOST and vHOST 633 + */ 634 + static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb) 635 + { 636 + enum pci_barno barno; 637 + int i; 638 + 639 + for (i = 0; i < ntb->num_mws; i++) { 640 + barno = ntb->epf_ntb_bar[BAR_MW0 + i]; 641 + pci_epc_clear_bar(ntb->epf->epc, 642 + ntb->epf->func_no, 643 + ntb->epf->vfunc_no, 644 + &ntb->epf->bar[barno]); 645 + 646 + pci_epc_mem_free_addr(ntb->epf->epc, 647 + ntb->vpci_mw_phy[i], 648 + ntb->vpci_mw_addr[i], 649 + ntb->mws_size[i]); 650 + } 651 + } 652 + 653 + /** 654 + * epf_ntb_epc_destroy() - Cleanup NTB EPC interface 655 + * @ntb: NTB device that facilitates communication between HOST and vHOST 656 + * 657 + * Wrapper for epf_ntb_epc_destroy_interface() to cleanup all the NTB interfaces 658 + */ 659 + static void epf_ntb_epc_destroy(struct epf_ntb *ntb) 660 + { 661 + pci_epc_remove_epf(ntb->epf->epc, ntb->epf, 0); 662 + pci_epc_put(ntb->epf->epc); 663 + } 664 + 665 + /** 666 + * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB 667 + * constructs (scratchpad region, doorbell, memorywindow) 668 + * @ntb: NTB device that facilitates communication between HOST and vHOST 669 + */ 670 + static int epf_ntb_init_epc_bar(struct epf_ntb *ntb) 671 + { 672 + const struct pci_epc_features *epc_features; 673 + enum pci_barno barno; 674 + enum epf_ntb_bar bar; 675 + struct device *dev; 676 + u32 num_mws; 677 + int i; 678 + 679 + barno = BAR_0; 680 + num_mws = ntb->num_mws; 681 + dev = &ntb->epf->dev; 682 + epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no); 683 + 684 + /* These are required BARs which are mandatory for NTB functionality */ 685 + for (bar = BAR_CONFIG; bar <= BAR_MW0; bar++, barno++) { 686 + barno = pci_epc_get_next_free_bar(epc_features, barno); 687 + if (barno < 0) { 688 + dev_err(dev, "Fail to get NTB function BAR\n"); 689 + return barno; 690 + } 691 + ntb->epf_ntb_bar[bar] = barno; 692 + } 693 + 694 + /* These are optional BARs which don't impact NTB functionality */ 695 + for (bar = BAR_MW1, i = 1; i < num_mws; bar++, barno++, i++) { 696 + barno = pci_epc_get_next_free_bar(epc_features, barno); 697 + if (barno < 0) { 698 + ntb->num_mws = i; 699 + dev_dbg(dev, "BAR not available for > MW%d\n", i + 1); 700 + } 701 + ntb->epf_ntb_bar[bar] = barno; 702 + } 703 + 704 + return 0; 705 + } 706 + 707 + /** 708 + * epf_ntb_epc_init() - Initialize NTB interface 709 + * @ntb: NTB device that facilitates communication between HOST and vHOST2 710 + * 711 + * Wrapper to initialize a particular EPC interface and start the workqueue 712 + * to check for commands from host. This function will write to the 713 + * EP controller HW for configuring it. 714 + */ 715 + static int epf_ntb_epc_init(struct epf_ntb *ntb) 716 + { 717 + u8 func_no, vfunc_no; 718 + struct pci_epc *epc; 719 + struct pci_epf *epf; 720 + struct device *dev; 721 + int ret; 722 + 723 + epf = ntb->epf; 724 + dev = &epf->dev; 725 + epc = epf->epc; 726 + func_no = ntb->epf->func_no; 727 + vfunc_no = ntb->epf->vfunc_no; 728 + 729 + ret = epf_ntb_config_sspad_bar_set(ntb); 730 + if (ret) { 731 + dev_err(dev, "Config/self SPAD BAR init failed"); 732 + return ret; 733 + } 734 + 735 + ret = epf_ntb_configure_interrupt(ntb); 736 + if (ret) { 737 + dev_err(dev, "Interrupt configuration failed\n"); 738 + goto err_config_interrupt; 739 + } 740 + 741 + ret = epf_ntb_db_bar_init(ntb); 742 + if (ret) { 743 + dev_err(dev, "DB BAR init failed\n"); 744 + goto err_db_bar_init; 745 + } 746 + 747 + ret = epf_ntb_mw_bar_init(ntb); 748 + if (ret) { 749 + dev_err(dev, "MW BAR init failed\n"); 750 + goto err_mw_bar_init; 751 + } 752 + 753 + if (vfunc_no <= 1) { 754 + ret = pci_epc_write_header(epc, func_no, vfunc_no, epf->header); 755 + if (ret) { 756 + dev_err(dev, "Configuration header write failed\n"); 757 + goto err_write_header; 758 + } 759 + } 760 + 761 + INIT_DELAYED_WORK(&ntb->cmd_handler, epf_ntb_cmd_handler); 762 + queue_work(kpcintb_workqueue, &ntb->cmd_handler.work); 763 + 764 + return 0; 765 + 766 + err_write_header: 767 + epf_ntb_mw_bar_clear(ntb); 768 + err_mw_bar_init: 769 + epf_ntb_db_bar_clear(ntb); 770 + err_db_bar_init: 771 + err_config_interrupt: 772 + epf_ntb_config_sspad_bar_clear(ntb); 773 + 774 + return ret; 775 + } 776 + 777 + 778 + /** 779 + * epf_ntb_epc_cleanup() - Cleanup all NTB interfaces 780 + * @ntb: NTB device that facilitates communication between HOST1 and HOST2 781 + * 782 + * Wrapper to cleanup all NTB interfaces. 783 + */ 784 + static void epf_ntb_epc_cleanup(struct epf_ntb *ntb) 785 + { 786 + epf_ntb_db_bar_clear(ntb); 787 + epf_ntb_mw_bar_clear(ntb); 788 + } 789 + 790 + #define EPF_NTB_R(_name) \ 791 + static ssize_t epf_ntb_##_name##_show(struct config_item *item, \ 792 + char *page) \ 793 + { \ 794 + struct config_group *group = to_config_group(item); \ 795 + struct epf_ntb *ntb = to_epf_ntb(group); \ 796 + \ 797 + return sprintf(page, "%d\n", ntb->_name); \ 798 + } 799 + 800 + #define EPF_NTB_W(_name) \ 801 + static ssize_t epf_ntb_##_name##_store(struct config_item *item, \ 802 + const char *page, size_t len) \ 803 + { \ 804 + struct config_group *group = to_config_group(item); \ 805 + struct epf_ntb *ntb = to_epf_ntb(group); \ 806 + u32 val; \ 807 + int ret; \ 808 + \ 809 + ret = kstrtou32(page, 0, &val); \ 810 + if (ret) \ 811 + return ret; \ 812 + \ 813 + ntb->_name = val; \ 814 + \ 815 + return len; \ 816 + } 817 + 818 + #define EPF_NTB_MW_R(_name) \ 819 + static ssize_t epf_ntb_##_name##_show(struct config_item *item, \ 820 + char *page) \ 821 + { \ 822 + struct config_group *group = to_config_group(item); \ 823 + struct epf_ntb *ntb = to_epf_ntb(group); \ 824 + int win_no; \ 825 + \ 826 + sscanf(#_name, "mw%d", &win_no); \ 827 + \ 828 + return sprintf(page, "%lld\n", ntb->mws_size[win_no - 1]); \ 829 + } 830 + 831 + #define EPF_NTB_MW_W(_name) \ 832 + static ssize_t epf_ntb_##_name##_store(struct config_item *item, \ 833 + const char *page, size_t len) \ 834 + { \ 835 + struct config_group *group = to_config_group(item); \ 836 + struct epf_ntb *ntb = to_epf_ntb(group); \ 837 + struct device *dev = &ntb->epf->dev; \ 838 + int win_no; \ 839 + u64 val; \ 840 + int ret; \ 841 + \ 842 + ret = kstrtou64(page, 0, &val); \ 843 + if (ret) \ 844 + return ret; \ 845 + \ 846 + if (sscanf(#_name, "mw%d", &win_no) != 1) \ 847 + return -EINVAL; \ 848 + \ 849 + if (ntb->num_mws < win_no) { \ 850 + dev_err(dev, "Invalid num_nws: %d value\n", ntb->num_mws); \ 851 + return -EINVAL; \ 852 + } \ 853 + \ 854 + ntb->mws_size[win_no - 1] = val; \ 855 + \ 856 + return len; \ 857 + } 858 + 859 + static ssize_t epf_ntb_num_mws_store(struct config_item *item, 860 + const char *page, size_t len) 861 + { 862 + struct config_group *group = to_config_group(item); 863 + struct epf_ntb *ntb = to_epf_ntb(group); 864 + u32 val; 865 + int ret; 866 + 867 + ret = kstrtou32(page, 0, &val); 868 + if (ret) 869 + return ret; 870 + 871 + if (val > MAX_MW) 872 + return -EINVAL; 873 + 874 + ntb->num_mws = val; 875 + 876 + return len; 877 + } 878 + 879 + EPF_NTB_R(spad_count) 880 + EPF_NTB_W(spad_count) 881 + EPF_NTB_R(db_count) 882 + EPF_NTB_W(db_count) 883 + EPF_NTB_R(num_mws) 884 + EPF_NTB_R(vbus_number) 885 + EPF_NTB_W(vbus_number) 886 + EPF_NTB_R(vntb_pid) 887 + EPF_NTB_W(vntb_pid) 888 + EPF_NTB_R(vntb_vid) 889 + EPF_NTB_W(vntb_vid) 890 + EPF_NTB_MW_R(mw1) 891 + EPF_NTB_MW_W(mw1) 892 + EPF_NTB_MW_R(mw2) 893 + EPF_NTB_MW_W(mw2) 894 + EPF_NTB_MW_R(mw3) 895 + EPF_NTB_MW_W(mw3) 896 + EPF_NTB_MW_R(mw4) 897 + EPF_NTB_MW_W(mw4) 898 + 899 + CONFIGFS_ATTR(epf_ntb_, spad_count); 900 + CONFIGFS_ATTR(epf_ntb_, db_count); 901 + CONFIGFS_ATTR(epf_ntb_, num_mws); 902 + CONFIGFS_ATTR(epf_ntb_, mw1); 903 + CONFIGFS_ATTR(epf_ntb_, mw2); 904 + CONFIGFS_ATTR(epf_ntb_, mw3); 905 + CONFIGFS_ATTR(epf_ntb_, mw4); 906 + CONFIGFS_ATTR(epf_ntb_, vbus_number); 907 + CONFIGFS_ATTR(epf_ntb_, vntb_pid); 908 + CONFIGFS_ATTR(epf_ntb_, vntb_vid); 909 + 910 + static struct configfs_attribute *epf_ntb_attrs[] = { 911 + &epf_ntb_attr_spad_count, 912 + &epf_ntb_attr_db_count, 913 + &epf_ntb_attr_num_mws, 914 + &epf_ntb_attr_mw1, 915 + &epf_ntb_attr_mw2, 916 + &epf_ntb_attr_mw3, 917 + &epf_ntb_attr_mw4, 918 + &epf_ntb_attr_vbus_number, 919 + &epf_ntb_attr_vntb_pid, 920 + &epf_ntb_attr_vntb_vid, 921 + NULL, 922 + }; 923 + 924 + static const struct config_item_type ntb_group_type = { 925 + .ct_attrs = epf_ntb_attrs, 926 + .ct_owner = THIS_MODULE, 927 + }; 928 + 929 + /** 930 + * epf_ntb_add_cfs() - Add configfs directory specific to NTB 931 + * @epf: NTB endpoint function device 932 + * @group: A pointer to the config_group structure referencing a group of 933 + * config_items of a specific type that belong to a specific sub-system. 934 + * 935 + * Add configfs directory specific to NTB. This directory will hold 936 + * NTB specific properties like db_count, spad_count, num_mws etc., 937 + */ 938 + static struct config_group *epf_ntb_add_cfs(struct pci_epf *epf, 939 + struct config_group *group) 940 + { 941 + struct epf_ntb *ntb = epf_get_drvdata(epf); 942 + struct config_group *ntb_group = &ntb->group; 943 + struct device *dev = &epf->dev; 944 + 945 + config_group_init_type_name(ntb_group, dev_name(dev), &ntb_group_type); 946 + 947 + return ntb_group; 948 + } 949 + 950 + /*==== virtual PCI bus driver, which only load virtual NTB PCI driver ====*/ 951 + 952 + static u32 pci_space[] = { 953 + 0xffffffff, /*DeviceID, Vendor ID*/ 954 + 0, /*Status, Command*/ 955 + 0xffffffff, /*Class code, subclass, prog if, revision id*/ 956 + 0x40, /*bist, header type, latency Timer, cache line size*/ 957 + 0, /*BAR 0*/ 958 + 0, /*BAR 1*/ 959 + 0, /*BAR 2*/ 960 + 0, /*BAR 3*/ 961 + 0, /*BAR 4*/ 962 + 0, /*BAR 5*/ 963 + 0, /*Cardbus cis point*/ 964 + 0, /*Subsystem ID Subystem vendor id*/ 965 + 0, /*ROM Base Address*/ 966 + 0, /*Reserved, Cap. Point*/ 967 + 0, /*Reserved,*/ 968 + 0, /*Max Lat, Min Gnt, interrupt pin, interrupt line*/ 969 + }; 970 + 971 + int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) 972 + { 973 + if (devfn == 0) { 974 + memcpy(val, ((u8 *)pci_space) + where, size); 975 + return PCIBIOS_SUCCESSFUL; 976 + } 977 + return PCIBIOS_DEVICE_NOT_FOUND; 978 + } 979 + 980 + int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) 981 + { 982 + return 0; 983 + } 984 + 985 + struct pci_ops vpci_ops = { 986 + .read = pci_read, 987 + .write = pci_write, 988 + }; 989 + 990 + static int vpci_scan_bus(void *sysdata) 991 + { 992 + struct pci_bus *vpci_bus; 993 + struct epf_ntb *ndev = sysdata; 994 + 995 + vpci_bus = pci_scan_bus(ndev->vbus_number, &vpci_ops, sysdata); 996 + if (vpci_bus) 997 + pr_err("create pci bus\n"); 998 + 999 + pci_bus_add_devices(vpci_bus); 1000 + 1001 + return 0; 1002 + } 1003 + 1004 + /*==================== Virtual PCIe NTB driver ==========================*/ 1005 + 1006 + static int vntb_epf_mw_count(struct ntb_dev *ntb, int pidx) 1007 + { 1008 + struct epf_ntb *ndev = ntb_ndev(ntb); 1009 + 1010 + return ndev->num_mws; 1011 + } 1012 + 1013 + static int vntb_epf_spad_count(struct ntb_dev *ntb) 1014 + { 1015 + return ntb_ndev(ntb)->spad_count; 1016 + } 1017 + 1018 + static int vntb_epf_peer_mw_count(struct ntb_dev *ntb) 1019 + { 1020 + return ntb_ndev(ntb)->num_mws; 1021 + } 1022 + 1023 + static u64 vntb_epf_db_valid_mask(struct ntb_dev *ntb) 1024 + { 1025 + return BIT_ULL(ntb_ndev(ntb)->db_count) - 1; 1026 + } 1027 + 1028 + static int vntb_epf_db_set_mask(struct ntb_dev *ntb, u64 db_bits) 1029 + { 1030 + return 0; 1031 + } 1032 + 1033 + static int vntb_epf_mw_set_trans(struct ntb_dev *ndev, int pidx, int idx, 1034 + dma_addr_t addr, resource_size_t size) 1035 + { 1036 + struct epf_ntb *ntb = ntb_ndev(ndev); 1037 + struct pci_epf_bar *epf_bar; 1038 + enum pci_barno barno; 1039 + int ret; 1040 + struct device *dev; 1041 + 1042 + dev = &ntb->ntb.dev; 1043 + barno = ntb->epf_ntb_bar[BAR_MW0 + idx]; 1044 + epf_bar = &ntb->epf->bar[barno]; 1045 + epf_bar->phys_addr = addr; 1046 + epf_bar->barno = barno; 1047 + epf_bar->size = size; 1048 + 1049 + ret = pci_epc_set_bar(ntb->epf->epc, 0, 0, epf_bar); 1050 + if (ret) { 1051 + dev_err(dev, "failure set mw trans\n"); 1052 + return ret; 1053 + } 1054 + return 0; 1055 + } 1056 + 1057 + static int vntb_epf_mw_clear_trans(struct ntb_dev *ntb, int pidx, int idx) 1058 + { 1059 + return 0; 1060 + } 1061 + 1062 + static int vntb_epf_peer_mw_get_addr(struct ntb_dev *ndev, int idx, 1063 + phys_addr_t *base, resource_size_t *size) 1064 + { 1065 + 1066 + struct epf_ntb *ntb = ntb_ndev(ndev); 1067 + 1068 + if (base) 1069 + *base = ntb->vpci_mw_phy[idx]; 1070 + 1071 + if (size) 1072 + *size = ntb->mws_size[idx]; 1073 + 1074 + return 0; 1075 + } 1076 + 1077 + static int vntb_epf_link_enable(struct ntb_dev *ntb, 1078 + enum ntb_speed max_speed, 1079 + enum ntb_width max_width) 1080 + { 1081 + return 0; 1082 + } 1083 + 1084 + static u32 vntb_epf_spad_read(struct ntb_dev *ndev, int idx) 1085 + { 1086 + struct epf_ntb *ntb = ntb_ndev(ndev); 1087 + int off = ntb->reg->spad_offset, ct = ntb->reg->spad_count * 4; 1088 + u32 val; 1089 + void __iomem *base = ntb->reg; 1090 + 1091 + val = readl(base + off + ct + idx * 4); 1092 + return val; 1093 + } 1094 + 1095 + static int vntb_epf_spad_write(struct ntb_dev *ndev, int idx, u32 val) 1096 + { 1097 + struct epf_ntb *ntb = ntb_ndev(ndev); 1098 + struct epf_ntb_ctrl *ctrl = ntb->reg; 1099 + int off = ctrl->spad_offset, ct = ctrl->spad_count * 4; 1100 + void __iomem *base = ntb->reg; 1101 + 1102 + writel(val, base + off + ct + idx * 4); 1103 + return 0; 1104 + } 1105 + 1106 + static u32 vntb_epf_peer_spad_read(struct ntb_dev *ndev, int pidx, int idx) 1107 + { 1108 + struct epf_ntb *ntb = ntb_ndev(ndev); 1109 + struct epf_ntb_ctrl *ctrl = ntb->reg; 1110 + int off = ctrl->spad_offset; 1111 + void __iomem *base = ntb->reg; 1112 + u32 val; 1113 + 1114 + val = readl(base + off + idx * 4); 1115 + return val; 1116 + } 1117 + 1118 + static int vntb_epf_peer_spad_write(struct ntb_dev *ndev, int pidx, int idx, u32 val) 1119 + { 1120 + struct epf_ntb *ntb = ntb_ndev(ndev); 1121 + struct epf_ntb_ctrl *ctrl = ntb->reg; 1122 + int off = ctrl->spad_offset; 1123 + void __iomem *base = ntb->reg; 1124 + 1125 + writel(val, base + off + idx * 4); 1126 + return 0; 1127 + } 1128 + 1129 + static int vntb_epf_peer_db_set(struct ntb_dev *ndev, u64 db_bits) 1130 + { 1131 + u32 interrupt_num = ffs(db_bits) + 1; 1132 + struct epf_ntb *ntb = ntb_ndev(ndev); 1133 + u8 func_no, vfunc_no; 1134 + int ret; 1135 + 1136 + func_no = ntb->epf->func_no; 1137 + vfunc_no = ntb->epf->vfunc_no; 1138 + 1139 + ret = pci_epc_raise_irq(ntb->epf->epc, 1140 + func_no, 1141 + vfunc_no, 1142 + PCI_EPC_IRQ_MSI, 1143 + interrupt_num + 1); 1144 + if (ret) 1145 + dev_err(&ntb->ntb.dev, "Failed to raise IRQ\n"); 1146 + 1147 + return ret; 1148 + } 1149 + 1150 + static u64 vntb_epf_db_read(struct ntb_dev *ndev) 1151 + { 1152 + struct epf_ntb *ntb = ntb_ndev(ndev); 1153 + 1154 + return ntb->db; 1155 + } 1156 + 1157 + static int vntb_epf_mw_get_align(struct ntb_dev *ndev, int pidx, int idx, 1158 + resource_size_t *addr_align, 1159 + resource_size_t *size_align, 1160 + resource_size_t *size_max) 1161 + { 1162 + struct epf_ntb *ntb = ntb_ndev(ndev); 1163 + 1164 + if (addr_align) 1165 + *addr_align = SZ_4K; 1166 + 1167 + if (size_align) 1168 + *size_align = 1; 1169 + 1170 + if (size_max) 1171 + *size_max = ntb->mws_size[idx]; 1172 + 1173 + return 0; 1174 + } 1175 + 1176 + static u64 vntb_epf_link_is_up(struct ntb_dev *ndev, 1177 + enum ntb_speed *speed, 1178 + enum ntb_width *width) 1179 + { 1180 + struct epf_ntb *ntb = ntb_ndev(ndev); 1181 + 1182 + return ntb->reg->link_status; 1183 + } 1184 + 1185 + static int vntb_epf_db_clear_mask(struct ntb_dev *ndev, u64 db_bits) 1186 + { 1187 + return 0; 1188 + } 1189 + 1190 + static int vntb_epf_db_clear(struct ntb_dev *ndev, u64 db_bits) 1191 + { 1192 + struct epf_ntb *ntb = ntb_ndev(ndev); 1193 + 1194 + ntb->db &= ~db_bits; 1195 + return 0; 1196 + } 1197 + 1198 + static int vntb_epf_link_disable(struct ntb_dev *ntb) 1199 + { 1200 + return 0; 1201 + } 1202 + 1203 + static const struct ntb_dev_ops vntb_epf_ops = { 1204 + .mw_count = vntb_epf_mw_count, 1205 + .spad_count = vntb_epf_spad_count, 1206 + .peer_mw_count = vntb_epf_peer_mw_count, 1207 + .db_valid_mask = vntb_epf_db_valid_mask, 1208 + .db_set_mask = vntb_epf_db_set_mask, 1209 + .mw_set_trans = vntb_epf_mw_set_trans, 1210 + .mw_clear_trans = vntb_epf_mw_clear_trans, 1211 + .peer_mw_get_addr = vntb_epf_peer_mw_get_addr, 1212 + .link_enable = vntb_epf_link_enable, 1213 + .spad_read = vntb_epf_spad_read, 1214 + .spad_write = vntb_epf_spad_write, 1215 + .peer_spad_read = vntb_epf_peer_spad_read, 1216 + .peer_spad_write = vntb_epf_peer_spad_write, 1217 + .peer_db_set = vntb_epf_peer_db_set, 1218 + .db_read = vntb_epf_db_read, 1219 + .mw_get_align = vntb_epf_mw_get_align, 1220 + .link_is_up = vntb_epf_link_is_up, 1221 + .db_clear_mask = vntb_epf_db_clear_mask, 1222 + .db_clear = vntb_epf_db_clear, 1223 + .link_disable = vntb_epf_link_disable, 1224 + }; 1225 + 1226 + static int pci_vntb_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1227 + { 1228 + int ret; 1229 + struct epf_ntb *ndev = (struct epf_ntb *)pdev->sysdata; 1230 + struct device *dev = &pdev->dev; 1231 + 1232 + ndev->ntb.pdev = pdev; 1233 + ndev->ntb.topo = NTB_TOPO_NONE; 1234 + ndev->ntb.ops = &vntb_epf_ops; 1235 + 1236 + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 1237 + if (ret) { 1238 + dev_err(dev, "Cannot set DMA mask\n"); 1239 + return -EINVAL; 1240 + } 1241 + 1242 + ret = ntb_register_device(&ndev->ntb); 1243 + if (ret) { 1244 + dev_err(dev, "Failed to register NTB device\n"); 1245 + goto err_register_dev; 1246 + } 1247 + 1248 + dev_dbg(dev, "PCI Virtual NTB driver loaded\n"); 1249 + return 0; 1250 + 1251 + err_register_dev: 1252 + return -EINVAL; 1253 + } 1254 + 1255 + static struct pci_device_id pci_vntb_table[] = { 1256 + { 1257 + PCI_DEVICE(0xffff, 0xffff), 1258 + }, 1259 + {}, 1260 + }; 1261 + 1262 + static struct pci_driver vntb_pci_driver = { 1263 + .name = "pci-vntb", 1264 + .id_table = pci_vntb_table, 1265 + .probe = pci_vntb_probe, 1266 + }; 1267 + 1268 + /* ============ PCIe EPF Driver Bind ====================*/ 1269 + 1270 + /** 1271 + * epf_ntb_bind() - Initialize endpoint controller to provide NTB functionality 1272 + * @epf: NTB endpoint function device 1273 + * 1274 + * Initialize both the endpoint controllers associated with NTB function device. 1275 + * Invoked when a primary interface or secondary interface is bound to EPC 1276 + * device. This function will succeed only when EPC is bound to both the 1277 + * interfaces. 1278 + */ 1279 + static int epf_ntb_bind(struct pci_epf *epf) 1280 + { 1281 + struct epf_ntb *ntb = epf_get_drvdata(epf); 1282 + struct device *dev = &epf->dev; 1283 + int ret; 1284 + 1285 + if (!epf->epc) { 1286 + dev_dbg(dev, "PRIMARY EPC interface not yet bound\n"); 1287 + return 0; 1288 + } 1289 + 1290 + ret = epf_ntb_init_epc_bar(ntb); 1291 + if (ret) { 1292 + dev_err(dev, "Failed to create NTB EPC\n"); 1293 + goto err_bar_init; 1294 + } 1295 + 1296 + ret = epf_ntb_config_spad_bar_alloc(ntb); 1297 + if (ret) { 1298 + dev_err(dev, "Failed to allocate BAR memory\n"); 1299 + goto err_bar_alloc; 1300 + } 1301 + 1302 + ret = epf_ntb_epc_init(ntb); 1303 + if (ret) { 1304 + dev_err(dev, "Failed to initialize EPC\n"); 1305 + goto err_bar_alloc; 1306 + } 1307 + 1308 + epf_set_drvdata(epf, ntb); 1309 + 1310 + pci_space[0] = (ntb->vntb_pid << 16) | ntb->vntb_vid; 1311 + pci_vntb_table[0].vendor = ntb->vntb_vid; 1312 + pci_vntb_table[0].device = ntb->vntb_pid; 1313 + 1314 + if (pci_register_driver(&vntb_pci_driver)) { 1315 + dev_err(dev, "failure register vntb pci driver\n"); 1316 + goto err_bar_alloc; 1317 + } 1318 + 1319 + vpci_scan_bus(ntb); 1320 + 1321 + return 0; 1322 + 1323 + err_bar_alloc: 1324 + epf_ntb_config_spad_bar_free(ntb); 1325 + 1326 + err_bar_init: 1327 + epf_ntb_epc_destroy(ntb); 1328 + 1329 + return ret; 1330 + } 1331 + 1332 + /** 1333 + * epf_ntb_unbind() - Cleanup the initialization from epf_ntb_bind() 1334 + * @epf: NTB endpoint function device 1335 + * 1336 + * Cleanup the initialization from epf_ntb_bind() 1337 + */ 1338 + static void epf_ntb_unbind(struct pci_epf *epf) 1339 + { 1340 + struct epf_ntb *ntb = epf_get_drvdata(epf); 1341 + 1342 + epf_ntb_epc_cleanup(ntb); 1343 + epf_ntb_config_spad_bar_free(ntb); 1344 + epf_ntb_epc_destroy(ntb); 1345 + 1346 + pci_unregister_driver(&vntb_pci_driver); 1347 + } 1348 + 1349 + // EPF driver probe 1350 + static struct pci_epf_ops epf_ntb_ops = { 1351 + .bind = epf_ntb_bind, 1352 + .unbind = epf_ntb_unbind, 1353 + .add_cfs = epf_ntb_add_cfs, 1354 + }; 1355 + 1356 + /** 1357 + * epf_ntb_probe() - Probe NTB function driver 1358 + * @epf: NTB endpoint function device 1359 + * 1360 + * Probe NTB function driver when endpoint function bus detects a NTB 1361 + * endpoint function. 1362 + */ 1363 + static int epf_ntb_probe(struct pci_epf *epf) 1364 + { 1365 + struct epf_ntb *ntb; 1366 + struct device *dev; 1367 + 1368 + dev = &epf->dev; 1369 + 1370 + ntb = devm_kzalloc(dev, sizeof(*ntb), GFP_KERNEL); 1371 + if (!ntb) 1372 + return -ENOMEM; 1373 + 1374 + epf->header = &epf_ntb_header; 1375 + ntb->epf = epf; 1376 + ntb->vbus_number = 0xff; 1377 + epf_set_drvdata(epf, ntb); 1378 + 1379 + dev_info(dev, "pci-ep epf driver loaded\n"); 1380 + return 0; 1381 + } 1382 + 1383 + static const struct pci_epf_device_id epf_ntb_ids[] = { 1384 + { 1385 + .name = "pci_epf_vntb", 1386 + }, 1387 + {}, 1388 + }; 1389 + 1390 + static struct pci_epf_driver epf_ntb_driver = { 1391 + .driver.name = "pci_epf_vntb", 1392 + .probe = epf_ntb_probe, 1393 + .id_table = epf_ntb_ids, 1394 + .ops = &epf_ntb_ops, 1395 + .owner = THIS_MODULE, 1396 + }; 1397 + 1398 + static int __init epf_ntb_init(void) 1399 + { 1400 + int ret; 1401 + 1402 + kpcintb_workqueue = alloc_workqueue("kpcintb", WQ_MEM_RECLAIM | 1403 + WQ_HIGHPRI, 0); 1404 + ret = pci_epf_register_driver(&epf_ntb_driver); 1405 + if (ret) { 1406 + destroy_workqueue(kpcintb_workqueue); 1407 + pr_err("Failed to register pci epf ntb driver --> %d\n", ret); 1408 + return ret; 1409 + } 1410 + 1411 + return 0; 1412 + } 1413 + module_init(epf_ntb_init); 1414 + 1415 + static void __exit epf_ntb_exit(void) 1416 + { 1417 + pci_epf_unregister_driver(&epf_ntb_driver); 1418 + destroy_workqueue(kpcintb_workqueue); 1419 + } 1420 + module_exit(epf_ntb_exit); 1421 + 1422 + MODULE_DESCRIPTION("PCI EPF NTB DRIVER"); 1423 + MODULE_AUTHOR("Frank Li <Frank.li@nxp.com>"); 1424 + MODULE_LICENSE("GPL v2");