igc: Correct the launchtime offset
authorMuhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
Wed, 21 Sep 2022 02:49:40 +0000 (10:49 +0800)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Wed, 2 Nov 2022 18:38:22 +0000 (11:38 -0700)
The launchtime offset should be corrected according to sections 7.5.2.6
Transmit Scheduling Latency of the Intel Ethernet I225/I226 Software
User Manual.

Software can compensate the latency between the transmission scheduling
and the time that packet is transmitted to the network by setting this
GTxOffset register. Without setting this register, there may be a
significant delay between the packet scheduling and the network point.

This patch helps to reduce the latency for each of the link speed.

Before:

10Mbps   : 11000 - 13800 nanosecond
100Mbps  : 1300 - 1700 nanosecond
1000Mbps : 190 - 600 nanosecond
2500Mbps : 1400 - 1700 nanosecond

After:

10Mbps   : less than 750 nanosecond
100Mbps  : less than 192 nanosecond
1000Mbps : less than 128 nanosecond
2500Mbps : less than 128 nanosecond

Test Setup:

Talker : Use l2_tai.c to generate the launchtime into packet payload.
Listener: Use timedump.c to compute the delta between packet arrival and
LaunchTime packet payload.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
Acked-by: Sasha Neftin <sasha.neftin@intel.com>
Acked-by: Paul Menzel <pmenzel@molgen.mpg.de>
Tested-by: Naama Meir <naamax.meir@linux.intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/igc/igc_defines.h
drivers/net/ethernet/intel/igc/igc_main.c
drivers/net/ethernet/intel/igc/igc_regs.h
drivers/net/ethernet/intel/igc/igc_tsn.c
drivers/net/ethernet/intel/igc/igc_tsn.h

index 4f9d7f0..f7311ae 100644 (file)
 #define IGC_DTXMXPKTSZ_TSN     0x19 /* 1600 bytes of max TX DMA packet size */
 #define IGC_DTXMXPKTSZ_DEFAULT 0x98 /* 9728-byte Jumbo frames */
 
+/* Transmit Scheduling Latency */
+/* Latency between transmission scheduling (LaunchTime) and the time
+ * the packet is transmitted to the network in nanosecond.
+ */
+#define IGC_TXOFFSET_SPEED_10  0x000034BC
+#define IGC_TXOFFSET_SPEED_100 0x00000578
+#define IGC_TXOFFSET_SPEED_1000        0x0000012C
+#define IGC_TXOFFSET_SPEED_2500        0x00000578
+
 /* Time Sync Interrupt Causes */
 #define IGC_TSICR_SYS_WRAP     BIT(0) /* SYSTIM Wrap around. */
 #define IGC_TSICR_TXTS         BIT(1) /* Transmit Timestamp. */
index 5d307b6..1586e1e 100644 (file)
@@ -5381,6 +5381,13 @@ static void igc_watchdog_task(struct work_struct *work)
                                break;
                        }
 
+                       /* Once the launch time has been set on the wire, there
+                        * is a delay before the link speed can be determined
+                        * based on link-up activity. Write into the register
+                        * as soon as we know the correct link speed.
+                        */
+                       igc_tsn_adjust_txtime_offset(adapter);
+
                        if (adapter->link_speed != SPEED_1000)
                                goto no_wait;
 
index c0d8214..01c86d3 100644 (file)
 /* Transmit Scheduling Registers */
 #define IGC_TQAVCTRL           0x3570
 #define IGC_TXQCTL(_n)         (0x3344 + 0x4 * (_n))
+#define IGC_GTXOFFSET          0x3310
 #define IGC_BASET_L            0x3314
 #define IGC_BASET_H            0x3318
 #define IGC_QBVCYCLET          0x331C
index 0fce22d..f975ed8 100644 (file)
@@ -48,6 +48,35 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
        return new_flags;
 }
 
+void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter)
+{
+       struct igc_hw *hw = &adapter->hw;
+       u16 txoffset;
+
+       if (!is_any_launchtime(adapter))
+               return;
+
+       switch (adapter->link_speed) {
+       case SPEED_10:
+               txoffset = IGC_TXOFFSET_SPEED_10;
+               break;
+       case SPEED_100:
+               txoffset = IGC_TXOFFSET_SPEED_100;
+               break;
+       case SPEED_1000:
+               txoffset = IGC_TXOFFSET_SPEED_1000;
+               break;
+       case SPEED_2500:
+               txoffset = IGC_TXOFFSET_SPEED_2500;
+               break;
+       default:
+               txoffset = 0;
+               break;
+       }
+
+       wr32(IGC_GTXOFFSET, txoffset);
+}
+
 /* Returns the TSN specific registers to their default values after
  * the adapter is reset.
  */
@@ -57,6 +86,7 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter)
        u32 tqavctrl;
        int i;
 
+       wr32(IGC_GTXOFFSET, 0);
        wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT);
        wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT);
 
index 1512307..b53e6af 100644 (file)
@@ -6,5 +6,6 @@
 
 int igc_tsn_offload_apply(struct igc_adapter *adapter);
 int igc_tsn_reset(struct igc_adapter *adapter);
+void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter);
 
 #endif /* _IGC_BASE_H */