.. | .. |
---|
58 | 58 | |
---|
59 | 59 | #include <linux/completion.h> |
---|
60 | 60 | #include <linux/device.h> |
---|
| 61 | +#include <linux/interrupt.h> |
---|
61 | 62 | |
---|
62 | 63 | struct ntb_client; |
---|
63 | 64 | struct ntb_dev; |
---|
| 65 | +struct ntb_msi; |
---|
64 | 66 | struct pci_dev; |
---|
65 | 67 | |
---|
66 | 68 | /** |
---|
.. | .. |
---|
205 | 207 | } |
---|
206 | 208 | |
---|
207 | 209 | /** |
---|
208 | | - * struct ntb_ctx_ops - ntb device operations |
---|
| 210 | + * struct ntb_dev_ops - ntb device operations |
---|
209 | 211 | * @port_number: See ntb_port_number(). |
---|
210 | 212 | * @peer_port_count: See ntb_peer_port_count(). |
---|
211 | 213 | * @peer_port_number: See ntb_peer_port_number(). |
---|
.. | .. |
---|
296 | 298 | int (*db_clear_mask)(struct ntb_dev *ntb, u64 db_bits); |
---|
297 | 299 | |
---|
298 | 300 | int (*peer_db_addr)(struct ntb_dev *ntb, |
---|
299 | | - phys_addr_t *db_addr, resource_size_t *db_size); |
---|
| 301 | + phys_addr_t *db_addr, resource_size_t *db_size, |
---|
| 302 | + u64 *db_data, int db_bit); |
---|
300 | 303 | u64 (*peer_db_read)(struct ntb_dev *ntb); |
---|
301 | 304 | int (*peer_db_set)(struct ntb_dev *ntb, u64 db_bits); |
---|
302 | 305 | int (*peer_db_clear)(struct ntb_dev *ntb, u64 db_bits); |
---|
.. | .. |
---|
403 | 406 | #define drv_ntb_client(__drv) container_of((__drv), struct ntb_client, drv) |
---|
404 | 407 | |
---|
405 | 408 | /** |
---|
406 | | - * struct ntb_device - ntb device |
---|
| 409 | + * struct ntb_dev - ntb device |
---|
407 | 410 | * @dev: Linux device object. |
---|
408 | 411 | * @pdev: PCI device entry of the ntb. |
---|
409 | 412 | * @topo: Detected topology of the ntb. |
---|
.. | .. |
---|
425 | 428 | spinlock_t ctx_lock; |
---|
426 | 429 | /* block unregister until device is fully released */ |
---|
427 | 430 | struct completion released; |
---|
| 431 | + |
---|
| 432 | +#ifdef CONFIG_NTB_MSI |
---|
| 433 | + struct ntb_msi *msi; |
---|
| 434 | +#endif |
---|
428 | 435 | }; |
---|
429 | 436 | #define dev_ntb(__dev) container_of((__dev), struct ntb_dev, dev) |
---|
430 | 437 | |
---|
.. | .. |
---|
471 | 478 | int ntb_register_device(struct ntb_dev *ntb); |
---|
472 | 479 | |
---|
473 | 480 | /** |
---|
474 | | - * ntb_register_device() - unregister a ntb device |
---|
| 481 | + * ntb_unregister_device() - unregister a ntb device |
---|
475 | 482 | * @ntb: NTB device context. |
---|
476 | 483 | * |
---|
477 | 484 | * The device will be removed from the list of ntb devices. If the ntb device |
---|
.. | .. |
---|
615 | 622 | |
---|
616 | 623 | return ntb->ops->port_number(ntb); |
---|
617 | 624 | } |
---|
618 | | - |
---|
619 | 625 | /** |
---|
620 | 626 | * ntb_peer_port_count() - get the number of peer device ports |
---|
621 | 627 | * @ntb: NTB device context. |
---|
.. | .. |
---|
650 | 656 | return ntb_default_peer_port_number(ntb, pidx); |
---|
651 | 657 | |
---|
652 | 658 | return ntb->ops->peer_port_number(ntb, pidx); |
---|
| 659 | +} |
---|
| 660 | + |
---|
| 661 | +/** |
---|
| 662 | + * ntb_logical_port_number() - get the logical port number of the local port |
---|
| 663 | + * @ntb: NTB device context. |
---|
| 664 | + * |
---|
| 665 | + * The Logical Port Number is defined to be a unique number for each |
---|
| 666 | + * port starting from zero through to the number of ports minus one. |
---|
| 667 | + * This is in contrast to the Port Number where each port can be assigned |
---|
| 668 | + * any unique physical number by the hardware. |
---|
| 669 | + * |
---|
| 670 | + * The logical port number is useful for calculating the resource indexes |
---|
| 671 | + * used by peers. |
---|
| 672 | + * |
---|
| 673 | + * Return: the logical port number or negative value indicating an error |
---|
| 674 | + */ |
---|
| 675 | +static inline int ntb_logical_port_number(struct ntb_dev *ntb) |
---|
| 676 | +{ |
---|
| 677 | + int lport = ntb_port_number(ntb); |
---|
| 678 | + int pidx; |
---|
| 679 | + |
---|
| 680 | + if (lport < 0) |
---|
| 681 | + return lport; |
---|
| 682 | + |
---|
| 683 | + for (pidx = 0; pidx < ntb_peer_port_count(ntb); pidx++) |
---|
| 684 | + if (lport <= ntb_peer_port_number(ntb, pidx)) |
---|
| 685 | + return pidx; |
---|
| 686 | + |
---|
| 687 | + return pidx; |
---|
| 688 | +} |
---|
| 689 | + |
---|
| 690 | +/** |
---|
| 691 | + * ntb_peer_logical_port_number() - get the logical peer port by given index |
---|
| 692 | + * @ntb: NTB device context. |
---|
| 693 | + * @pidx: Peer port index. |
---|
| 694 | + * |
---|
| 695 | + * The Logical Port Number is defined to be a unique number for each |
---|
| 696 | + * port starting from zero through to the number of ports minus one. |
---|
| 697 | + * This is in contrast to the Port Number where each port can be assigned |
---|
| 698 | + * any unique physical number by the hardware. |
---|
| 699 | + * |
---|
| 700 | + * The logical port number is useful for calculating the resource indexes |
---|
| 701 | + * used by peers. |
---|
| 702 | + * |
---|
| 703 | + * Return: the peer's logical port number or negative value indicating an error |
---|
| 704 | + */ |
---|
| 705 | +static inline int ntb_peer_logical_port_number(struct ntb_dev *ntb, int pidx) |
---|
| 706 | +{ |
---|
| 707 | + if (ntb_peer_port_number(ntb, pidx) < ntb_port_number(ntb)) |
---|
| 708 | + return pidx; |
---|
| 709 | + else |
---|
| 710 | + return pidx + 1; |
---|
653 | 711 | } |
---|
654 | 712 | |
---|
655 | 713 | /** |
---|
.. | .. |
---|
1078 | 1136 | * @ntb: NTB device context. |
---|
1079 | 1137 | * @db_addr: OUT - The address of the peer doorbell register. |
---|
1080 | 1138 | * @db_size: OUT - The number of bytes to write the peer doorbell register. |
---|
| 1139 | + * @db_data: OUT - The data of peer doorbell register |
---|
| 1140 | + * @db_bit: door bell bit number |
---|
1081 | 1141 | * |
---|
1082 | 1142 | * Return the address of the peer doorbell register. This may be used, for |
---|
1083 | 1143 | * example, by drivers that offload memory copy operations to a dma engine. |
---|
.. | .. |
---|
1091 | 1151 | */ |
---|
1092 | 1152 | static inline int ntb_peer_db_addr(struct ntb_dev *ntb, |
---|
1093 | 1153 | phys_addr_t *db_addr, |
---|
1094 | | - resource_size_t *db_size) |
---|
| 1154 | + resource_size_t *db_size, |
---|
| 1155 | + u64 *db_data, int db_bit) |
---|
1095 | 1156 | { |
---|
1096 | 1157 | if (!ntb->ops->peer_db_addr) |
---|
1097 | 1158 | return -EINVAL; |
---|
1098 | 1159 | |
---|
1099 | | - return ntb->ops->peer_db_addr(ntb, db_addr, db_size); |
---|
| 1160 | + return ntb->ops->peer_db_addr(ntb, db_addr, db_size, db_data, db_bit); |
---|
1100 | 1161 | } |
---|
1101 | 1162 | |
---|
1102 | 1163 | /** |
---|
.. | .. |
---|
1290 | 1351 | * @sidx: Scratchpad index. |
---|
1291 | 1352 | * @spad_addr: OUT - The address of the peer scratchpad register. |
---|
1292 | 1353 | * |
---|
1293 | | - * Return the address of the peer doorbell register. This may be used, for |
---|
| 1354 | + * Return the address of the peer scratchpad register. This may be used, for |
---|
1294 | 1355 | * example, by drivers that offload memory copy operations to a dma engine. |
---|
1295 | 1356 | * |
---|
1296 | 1357 | * Return: Zero on success, otherwise an error number. |
---|
.. | .. |
---|
1312 | 1373 | * |
---|
1313 | 1374 | * Read the peer scratchpad register, and return the value. |
---|
1314 | 1375 | * |
---|
1315 | | - * Return: The value of the local scratchpad register. |
---|
| 1376 | + * Return: The value of the peer scratchpad register. |
---|
1316 | 1377 | */ |
---|
1317 | 1378 | static inline u32 ntb_peer_spad_read(struct ntb_dev *ntb, int pidx, int sidx) |
---|
1318 | 1379 | { |
---|
.. | .. |
---|
1502 | 1563 | return ntb->ops->peer_msg_write(ntb, pidx, midx, msg); |
---|
1503 | 1564 | } |
---|
1504 | 1565 | |
---|
| 1566 | +/** |
---|
| 1567 | + * ntb_peer_resource_idx() - get a resource index for a given peer idx |
---|
| 1568 | + * @ntb: NTB device context. |
---|
| 1569 | + * @pidx: Peer port index. |
---|
| 1570 | + * |
---|
| 1571 | + * When constructing a graph of peers, each remote peer must use a different |
---|
| 1572 | + * resource index (mw, doorbell, etc) to communicate with each other |
---|
| 1573 | + * peer. |
---|
| 1574 | + * |
---|
| 1575 | + * In a two peer system, this function should always return 0 such that |
---|
| 1576 | + * resource 0 points to the remote peer on both ports. |
---|
| 1577 | + * |
---|
| 1578 | + * In a 5 peer system, this function will return the following matrix |
---|
| 1579 | + * |
---|
| 1580 | + * pidx \ port 0 1 2 3 4 |
---|
| 1581 | + * 0 0 0 1 2 3 |
---|
| 1582 | + * 1 0 1 1 2 3 |
---|
| 1583 | + * 2 0 1 2 2 3 |
---|
| 1584 | + * 3 0 1 2 3 3 |
---|
| 1585 | + * |
---|
| 1586 | + * For example, if this function is used to program peer's memory |
---|
| 1587 | + * windows, port 0 will program MW 0 on all it's peers to point to itself. |
---|
| 1588 | + * port 1 will program MW 0 in port 0 to point to itself and MW 1 on all |
---|
| 1589 | + * other ports. etc. |
---|
| 1590 | + * |
---|
| 1591 | + * For the legacy two host case, ntb_port_number() and ntb_peer_port_number() |
---|
| 1592 | + * both return zero and therefore this function will always return zero. |
---|
| 1593 | + * So MW 0 on each host would be programmed to point to the other host. |
---|
| 1594 | + * |
---|
| 1595 | + * Return: the resource index to use for that peer. |
---|
| 1596 | + */ |
---|
| 1597 | +static inline int ntb_peer_resource_idx(struct ntb_dev *ntb, int pidx) |
---|
| 1598 | +{ |
---|
| 1599 | + int local_port, peer_port; |
---|
| 1600 | + |
---|
| 1601 | + if (pidx >= ntb_peer_port_count(ntb)) |
---|
| 1602 | + return -EINVAL; |
---|
| 1603 | + |
---|
| 1604 | + local_port = ntb_logical_port_number(ntb); |
---|
| 1605 | + peer_port = ntb_peer_logical_port_number(ntb, pidx); |
---|
| 1606 | + |
---|
| 1607 | + if (peer_port < local_port) |
---|
| 1608 | + return local_port - 1; |
---|
| 1609 | + else |
---|
| 1610 | + return local_port; |
---|
| 1611 | +} |
---|
| 1612 | + |
---|
| 1613 | +/** |
---|
| 1614 | + * ntb_peer_highest_mw_idx() - get a memory window index for a given peer idx |
---|
| 1615 | + * using the highest index memory windows first |
---|
| 1616 | + * |
---|
| 1617 | + * @ntb: NTB device context. |
---|
| 1618 | + * @pidx: Peer port index. |
---|
| 1619 | + * |
---|
| 1620 | + * Like ntb_peer_resource_idx(), except it returns indexes starting with |
---|
| 1621 | + * last memory window index. |
---|
| 1622 | + * |
---|
| 1623 | + * Return: the resource index to use for that peer. |
---|
| 1624 | + */ |
---|
| 1625 | +static inline int ntb_peer_highest_mw_idx(struct ntb_dev *ntb, int pidx) |
---|
| 1626 | +{ |
---|
| 1627 | + int ret; |
---|
| 1628 | + |
---|
| 1629 | + ret = ntb_peer_resource_idx(ntb, pidx); |
---|
| 1630 | + if (ret < 0) |
---|
| 1631 | + return ret; |
---|
| 1632 | + |
---|
| 1633 | + return ntb_mw_count(ntb, pidx) - ret - 1; |
---|
| 1634 | +} |
---|
| 1635 | + |
---|
| 1636 | +struct ntb_msi_desc { |
---|
| 1637 | + u32 addr_offset; |
---|
| 1638 | + u32 data; |
---|
| 1639 | +}; |
---|
| 1640 | + |
---|
| 1641 | +#ifdef CONFIG_NTB_MSI |
---|
| 1642 | + |
---|
| 1643 | +int ntb_msi_init(struct ntb_dev *ntb, void (*desc_changed)(void *ctx)); |
---|
| 1644 | +int ntb_msi_setup_mws(struct ntb_dev *ntb); |
---|
| 1645 | +void ntb_msi_clear_mws(struct ntb_dev *ntb); |
---|
| 1646 | +int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler, |
---|
| 1647 | + irq_handler_t thread_fn, |
---|
| 1648 | + const char *name, void *dev_id, |
---|
| 1649 | + struct ntb_msi_desc *msi_desc); |
---|
| 1650 | +void ntbm_msi_free_irq(struct ntb_dev *ntb, unsigned int irq, void *dev_id); |
---|
| 1651 | +int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer, |
---|
| 1652 | + struct ntb_msi_desc *desc); |
---|
| 1653 | +int ntb_msi_peer_addr(struct ntb_dev *ntb, int peer, |
---|
| 1654 | + struct ntb_msi_desc *desc, |
---|
| 1655 | + phys_addr_t *msi_addr); |
---|
| 1656 | + |
---|
| 1657 | +#else /* not CONFIG_NTB_MSI */ |
---|
| 1658 | + |
---|
| 1659 | +static inline int ntb_msi_init(struct ntb_dev *ntb, |
---|
| 1660 | + void (*desc_changed)(void *ctx)) |
---|
| 1661 | +{ |
---|
| 1662 | + return -EOPNOTSUPP; |
---|
| 1663 | +} |
---|
| 1664 | +static inline int ntb_msi_setup_mws(struct ntb_dev *ntb) |
---|
| 1665 | +{ |
---|
| 1666 | + return -EOPNOTSUPP; |
---|
| 1667 | +} |
---|
| 1668 | +static inline void ntb_msi_clear_mws(struct ntb_dev *ntb) {} |
---|
| 1669 | +static inline int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, |
---|
| 1670 | + irq_handler_t handler, |
---|
| 1671 | + irq_handler_t thread_fn, |
---|
| 1672 | + const char *name, void *dev_id, |
---|
| 1673 | + struct ntb_msi_desc *msi_desc) |
---|
| 1674 | +{ |
---|
| 1675 | + return -EOPNOTSUPP; |
---|
| 1676 | +} |
---|
| 1677 | +static inline void ntbm_msi_free_irq(struct ntb_dev *ntb, unsigned int irq, |
---|
| 1678 | + void *dev_id) {} |
---|
| 1679 | +static inline int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer, |
---|
| 1680 | + struct ntb_msi_desc *desc) |
---|
| 1681 | +{ |
---|
| 1682 | + return -EOPNOTSUPP; |
---|
| 1683 | +} |
---|
| 1684 | +static inline int ntb_msi_peer_addr(struct ntb_dev *ntb, int peer, |
---|
| 1685 | + struct ntb_msi_desc *desc, |
---|
| 1686 | + phys_addr_t *msi_addr) |
---|
| 1687 | +{ |
---|
| 1688 | + return -EOPNOTSUPP; |
---|
| 1689 | + |
---|
| 1690 | +} |
---|
| 1691 | + |
---|
| 1692 | +#endif /* CONFIG_NTB_MSI */ |
---|
| 1693 | + |
---|
| 1694 | +static inline int ntbm_msi_request_irq(struct ntb_dev *ntb, |
---|
| 1695 | + irq_handler_t handler, |
---|
| 1696 | + const char *name, void *dev_id, |
---|
| 1697 | + struct ntb_msi_desc *msi_desc) |
---|
| 1698 | +{ |
---|
| 1699 | + return ntbm_msi_request_threaded_irq(ntb, handler, NULL, name, |
---|
| 1700 | + dev_id, msi_desc); |
---|
| 1701 | +} |
---|
| 1702 | + |
---|
1505 | 1703 | #endif |
---|