static void tb_test_credit_alloc_dma_multiple()

in test.c [2112:2207]


static void tb_test_credit_alloc_dma_multiple(struct kunit *test)
{
	struct tb_tunnel *tunnel1, *tunnel2, *tunnel3;
	struct tb_switch *host, *dev;
	struct tb_port *nhi, *port;
	struct tb_path *path;

	host = alloc_host_usb4(test);
	dev = alloc_dev_usb4(test, host, 0x1, true);

	nhi = &host->ports[7];
	port = &dev->ports[3];

	/*
	 * Create three DMA tunnels through the same ports. With the
	 * default buffers we should be able to create two and the last
	 * one fails.
	 *
	 * For default host we have following buffers for DMA:
	 *
	 *   120 - (2 + 2 * (1 + 0) + 32 + 64 + spare) = 20
	 *
	 * For device we have following:
	 *
	 *  120 - (2 + 2 * (1 + 18) + 14 + 32 + spare) = 34
	 *
	 * spare = 14 + 1 = 15
	 *
	 * So on host the first tunnel gets 14 and the second gets the
	 * remaining 1 and then we run out of buffers.
	 */
	tunnel1 = tb_tunnel_alloc_dma(NULL, nhi, port, 8, 1, 8, 1);
	KUNIT_ASSERT_TRUE(test, tunnel1 != NULL);
	KUNIT_ASSERT_EQ(test, tunnel1->npaths, (size_t)2);

	path = tunnel1->paths[0];
	KUNIT_ASSERT_EQ(test, path->path_length, 2);
	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 14U);
	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);

	path = tunnel1->paths[1];
	KUNIT_ASSERT_EQ(test, path->path_length, 2);
	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);

	tunnel2 = tb_tunnel_alloc_dma(NULL, nhi, port, 9, 2, 9, 2);
	KUNIT_ASSERT_TRUE(test, tunnel2 != NULL);
	KUNIT_ASSERT_EQ(test, tunnel2->npaths, (size_t)2);

	path = tunnel2->paths[0];
	KUNIT_ASSERT_EQ(test, path->path_length, 2);
	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 14U);
	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);

	path = tunnel2->paths[1];
	KUNIT_ASSERT_EQ(test, path->path_length, 2);
	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);

	tunnel3 = tb_tunnel_alloc_dma(NULL, nhi, port, 10, 3, 10, 3);
	KUNIT_ASSERT_TRUE(test, tunnel3 == NULL);

	/*
	 * Release the first DMA tunnel. That should make 14 buffers
	 * available for the next tunnel.
	 */
	tb_tunnel_free(tunnel1);

	tunnel3 = tb_tunnel_alloc_dma(NULL, nhi, port, 10, 3, 10, 3);
	KUNIT_ASSERT_TRUE(test, tunnel3 != NULL);

	path = tunnel3->paths[0];
	KUNIT_ASSERT_EQ(test, path->path_length, 2);
	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 14U);
	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);

	path = tunnel3->paths[1];
	KUNIT_ASSERT_EQ(test, path->path_length, 2);
	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);
	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);

	tb_tunnel_free(tunnel3);
	tb_tunnel_free(tunnel2);
}