summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/nhi.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-12-08 15:41:45 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-12-08 15:41:45 +0300
commit3d411378019425a891901f3c2c96674ea0c3f18b (patch)
treea0d78235f5ca1dff0a6a8c194fa9a0bb1263c826 /drivers/thunderbolt/nhi.c
parent08a02f954b0def3ada8ed6d4b2c7bcb67e885e9c (diff)
parentdb0746e3399ee87ee5f957880811da16faa89fb8 (diff)
downloadlinux-3d411378019425a891901f3c2c96674ea0c3f18b.tar.xz
Merge tag 'thunderbolt-for-v5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-next
Mika writes: thunderbolt: Changes for v5.11 merge window This includes following Thunderbolt/USB4 changes for v5.11 merge window: * DMA traffic test driver * USB4 router NVM upgrade improvements * USB4 router operations proxy implementation available in the recent Intel Connection Manager firmwares * Support for Intel Maple Ridge discrete Thunderbolt 4 controller * A couple of cleanups and minor improvements. * tag 'thunderbolt-for-v5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: (22 commits) thunderbolt: Add support for Intel Maple Ridge thunderbolt: Add USB4 router operation proxy for firmware connection manager thunderbolt: Move constants for USB4 router operations to tb_regs.h thunderbolt: Add connection manager specific hooks for USB4 router operations thunderbolt: Pass TX and RX data directly to usb4_switch_op() thunderbolt: Pass metadata directly to usb4_switch_op() thunderbolt: Perform USB4 router NVM upgrade in two phases thunderbolt: Return -ENOTCONN when ERR_CONN is received thunderbolt: Keep the parent runtime resumed for a while on device disconnect thunderbolt: Log adapter numbers in decimal in path activation/deactivation thunderbolt: Log which connection manager implementation is used thunderbolt: Move max_boot_acl field to correct place in struct icm MAINTAINERS: Add Isaac as maintainer of Thunderbolt DMA traffic test driver thunderbolt: Add DMA traffic test driver thunderbolt: Add support for end-to-end flow control thunderbolt: Make it possible to allocate one directional DMA tunnel thunderbolt: Create debugfs directory automatically for services thunderbolt: Add functions for enabling and disabling lane bonding on XDomain thunderbolt: Add link_speed and link_width to XDomain thunderbolt: Create XDomain devices for loops back to the host ...
Diffstat (limited to 'drivers/thunderbolt/nhi.c')
-rw-r--r--drivers/thunderbolt/nhi.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index db80dc5dfeba..cfc622da4f83 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -494,7 +494,7 @@ err_unlock:
static struct tb_ring *tb_ring_alloc(struct tb_nhi *nhi, u32 hop, int size,
bool transmit, unsigned int flags,
- u16 sof_mask, u16 eof_mask,
+ int e2e_tx_hop, u16 sof_mask, u16 eof_mask,
void (*start_poll)(void *),
void *poll_data)
{
@@ -517,6 +517,7 @@ static struct tb_ring *tb_ring_alloc(struct tb_nhi *nhi, u32 hop, int size,
ring->is_tx = transmit;
ring->size = size;
ring->flags = flags;
+ ring->e2e_tx_hop = e2e_tx_hop;
ring->sof_mask = sof_mask;
ring->eof_mask = eof_mask;
ring->head = 0;
@@ -561,7 +562,7 @@ err_free_ring:
struct tb_ring *tb_ring_alloc_tx(struct tb_nhi *nhi, int hop, int size,
unsigned int flags)
{
- return tb_ring_alloc(nhi, hop, size, true, flags, 0, 0, NULL, NULL);
+ return tb_ring_alloc(nhi, hop, size, true, flags, 0, 0, 0, NULL, NULL);
}
EXPORT_SYMBOL_GPL(tb_ring_alloc_tx);
@@ -571,6 +572,7 @@ EXPORT_SYMBOL_GPL(tb_ring_alloc_tx);
* @hop: HopID (ring) to allocate. Pass %-1 for automatic allocation.
* @size: Number of entries in the ring
* @flags: Flags for the ring
+ * @e2e_tx_hop: Transmit HopID when E2E is enabled in @flags
* @sof_mask: Mask of PDF values that start a frame
* @eof_mask: Mask of PDF values that end a frame
* @start_poll: If not %NULL the ring will call this function when an
@@ -579,10 +581,11 @@ EXPORT_SYMBOL_GPL(tb_ring_alloc_tx);
* @poll_data: Optional data passed to @start_poll
*/
struct tb_ring *tb_ring_alloc_rx(struct tb_nhi *nhi, int hop, int size,
- unsigned int flags, u16 sof_mask, u16 eof_mask,
+ unsigned int flags, int e2e_tx_hop,
+ u16 sof_mask, u16 eof_mask,
void (*start_poll)(void *), void *poll_data)
{
- return tb_ring_alloc(nhi, hop, size, false, flags, sof_mask, eof_mask,
+ return tb_ring_alloc(nhi, hop, size, false, flags, e2e_tx_hop, sof_mask, eof_mask,
start_poll, poll_data);
}
EXPORT_SYMBOL_GPL(tb_ring_alloc_rx);
@@ -629,6 +632,31 @@ void tb_ring_start(struct tb_ring *ring)
ring_iowrite32options(ring, sof_eof_mask, 4);
ring_iowrite32options(ring, flags, 0);
}
+
+ /*
+ * Now that the ring valid bit is set we can configure E2E if
+ * enabled for the ring.
+ */
+ if (ring->flags & RING_FLAG_E2E) {
+ if (!ring->is_tx) {
+ u32 hop;
+
+ hop = ring->e2e_tx_hop << REG_RX_OPTIONS_E2E_HOP_SHIFT;
+ hop &= REG_RX_OPTIONS_E2E_HOP_MASK;
+ flags |= hop;
+
+ dev_dbg(&ring->nhi->pdev->dev,
+ "enabling E2E for %s %d with TX HopID %d\n",
+ RING_TYPE(ring), ring->hop, ring->e2e_tx_hop);
+ } else {
+ dev_dbg(&ring->nhi->pdev->dev, "enabling E2E for %s %d\n",
+ RING_TYPE(ring), ring->hop);
+ }
+
+ flags |= RING_FLAG_E2E_FLOW_CONTROL;
+ ring_iowrite32options(ring, flags, 0);
+ }
+
ring_interrupt_active(ring, true);
ring->running = true;
err: