thunderbolt: Move nfc_credits field to struct tb_path_hop
authorMika Westerberg <mika.westerberg@linux.intel.com>
Thu, 10 Dec 2020 14:07:59 +0000 (16:07 +0200)
committerMika Westerberg <mika.westerberg@linux.intel.com>
Tue, 1 Jun 2021 07:48:59 +0000 (10:48 +0300)
With the USB4 buffer allocation the number of credits (and non-flow
credits) may be different depending on the router buffer allocation
preferences. To allow this move the nfc_credits field to struct
tb_path_hop.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
drivers/thunderbolt/path.c
drivers/thunderbolt/tb.h
drivers/thunderbolt/tunnel.c

index f63e205..564e2f4 100644 (file)
@@ -367,7 +367,7 @@ static void __tb_path_deallocate_nfc(struct tb_path *path, int first_hop)
        int i, res;
        for (i = first_hop; i < path->path_length; i++) {
                res = tb_port_add_nfc_credits(path->hops[i].in_port,
-                                             -path->nfc_credits);
+                                             -path->hops[i].nfc_credits);
                if (res)
                        tb_port_warn(path->hops[i].in_port,
                                     "nfc credits deallocation failed for hop %d\n",
@@ -502,7 +502,7 @@ int tb_path_activate(struct tb_path *path)
        /* Add non flow controlled credits. */
        for (i = path->path_length - 1; i >= 0; i--) {
                res = tb_port_add_nfc_credits(path->hops[i].in_port,
-                                             path->nfc_credits);
+                                             path->hops[i].nfc_credits);
                if (res) {
                        __tb_path_deallocate_nfc(path, i);
                        goto err;
index 60a987c..b4bc25b 100644 (file)
@@ -256,6 +256,8 @@ struct tb_retimer {
  * @next_hop_index: HopID of the packet when it is routed out from @out_port
  * @initial_credits: Number of initial flow control credits allocated for
  *                  the path
+ * @nfc_credits: Number of non-flow controlled buffers allocated for the
+ *              @in_port.
  *
  * Hop configuration is always done on the IN port of a switch.
  * in_port and out_port have to be on the same switch. Packets arriving on
@@ -275,6 +277,7 @@ struct tb_path_hop {
        int in_counter_index;
        int next_hop_index;
        unsigned int initial_credits;
+       unsigned int nfc_credits;
 };
 
 /**
@@ -297,7 +300,6 @@ enum tb_path_port {
  * struct tb_path - a unidirectional path between two ports
  * @tb: Pointer to the domain structure
  * @name: Name of the path (used for debugging)
- * @nfc_credits: Number of non flow controlled credits allocated for the path
  * @ingress_shared_buffer: Shared buffering used for ingress ports on the path
  * @egress_shared_buffer: Shared buffering used for egress ports on the path
  * @ingress_fc_enable: Flow control for ingress ports on the path
@@ -318,7 +320,6 @@ enum tb_path_port {
 struct tb_path {
        struct tb *tb;
        const char *name;
-       int nfc_credits;
        enum tb_path_port ingress_shared_buffer;
        enum tb_path_port egress_shared_buffer;
        enum tb_path_port ingress_fc_enable;
index e1979be..5be0f31 100644 (file)
@@ -119,7 +119,6 @@ static void tb_pci_init_path(struct tb_path *path)
        path->priority = 3;
        path->weight = 1;
        path->drop_packages = 0;
-       path->nfc_credits = 0;
        path->hops[0].initial_credits = 7;
        if (path->path_length > 1)
                path->hops[1].initial_credits =
@@ -616,7 +615,7 @@ static void tb_dp_init_aux_path(struct tb_path *path)
 
 static void tb_dp_init_video_path(struct tb_path *path, bool discover)
 {
-       u32 nfc_credits = path->hops[0].in_port->config.nfc_credits;
+       int i;
 
        path->egress_fc_enable = TB_PATH_NONE;
        path->egress_shared_buffer = TB_PATH_NONE;
@@ -625,15 +624,20 @@ static void tb_dp_init_video_path(struct tb_path *path, bool discover)
        path->priority = 1;
        path->weight = 1;
 
-       if (discover) {
-               path->nfc_credits = nfc_credits & ADP_CS_4_NFC_BUFFERS_MASK;
-       } else {
-               u32 max_credits;
+       for (i = 0; i < path->path_length; i++) {
+               u32 nfc_credits = path->hops[i].in_port->config.nfc_credits;
 
-               max_credits = (nfc_credits & ADP_CS_4_TOTAL_BUFFERS_MASK) >>
-                       ADP_CS_4_TOTAL_BUFFERS_SHIFT;
-               /* Leave some credits for AUX path */
-               path->nfc_credits = min(max_credits - 2, 12U);
+               if (discover) {
+                       path->hops[i].nfc_credits =
+                               nfc_credits & ADP_CS_4_NFC_BUFFERS_MASK;
+               } else {
+                       u32 max_credits;
+
+                       max_credits = (nfc_credits & ADP_CS_4_TOTAL_BUFFERS_MASK) >>
+                               ADP_CS_4_TOTAL_BUFFERS_SHIFT;
+                       /* Leave some credits for AUX path */
+                       path->hops[i].nfc_credits = min(max_credits - 2, 12U);
+               }
        }
 }
 
@@ -1076,7 +1080,6 @@ static void tb_usb3_init_path(struct tb_path *path)
        path->priority = 3;
        path->weight = 3;
        path->drop_packages = 0;
-       path->nfc_credits = 0;
        path->hops[0].initial_credits = 7;
        if (path->path_length > 1)
                path->hops[1].initial_credits =