]> www.infradead.org Git - users/willy/xarray.git/commitdiff
igc: remove I226 Qbv BaseTime restriction
authorMuhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
Wed, 14 Dec 2022 16:29:07 +0000 (00:29 +0800)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Tue, 3 Jan 2023 17:35:37 +0000 (09:35 -0800)
Remove the Qbv BaseTime restriction for I226 so that the BaseTime can be
scheduled to the future time. A new register bit of Tx Qav Control
(Bit-7: FutScdDis) was introduced to allow I226 scheduling future time as
Qbv BaseTime and not having the Tx hang timeout issue.

Besides, according to datasheet section 7.5.2.9.3.3, FutScdDis bit has to
be configured first before the cycle time and base time.

Indeed the FutScdDis bit is only active on re-configuration, thus we have
to set the BASET_L to zero and then only set it to the desired value.

Please also note that the Qbv configuration flow is moved around based on
the Qbv programming guideline that is documented in the latest datasheet.

Co-developed-by: Tan Tee Min <tee.min.tan@linux.intel.com>
Signed-off-by: Tan Tee Min <tee.min.tan@linux.intel.com>
Signed-off-by: Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>
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_base.c
drivers/net/ethernet/intel/igc/igc_base.h
drivers/net/ethernet/intel/igc/igc_defines.h
drivers/net/ethernet/intel/igc/igc_main.c
drivers/net/ethernet/intel/igc/igc_tsn.c

index a15927e77272036f65ad6ed67e3d642c2abf2f97..a1d815af507d90cff0f1ce297784148e2c836f2a 100644 (file)
@@ -396,6 +396,35 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw)
        rd32(IGC_MPC);
 }
 
+bool igc_is_device_id_i225(struct igc_hw *hw)
+{
+       switch (hw->device_id) {
+       case IGC_DEV_ID_I225_LM:
+       case IGC_DEV_ID_I225_V:
+       case IGC_DEV_ID_I225_I:
+       case IGC_DEV_ID_I225_K:
+       case IGC_DEV_ID_I225_K2:
+       case IGC_DEV_ID_I225_LMVP:
+       case IGC_DEV_ID_I225_IT:
+               return true;
+       default:
+               return false;
+       }
+}
+
+bool igc_is_device_id_i226(struct igc_hw *hw)
+{
+       switch (hw->device_id) {
+       case IGC_DEV_ID_I226_LM:
+       case IGC_DEV_ID_I226_V:
+       case IGC_DEV_ID_I226_K:
+       case IGC_DEV_ID_I226_IT:
+               return true;
+       default:
+               return false;
+       }
+}
+
 static struct igc_mac_operations igc_mac_ops_base = {
        .init_hw                = igc_init_hw_base,
        .check_for_link         = igc_check_for_copper_link,
index ce530f5fd7bdad08663a9e766c02f163f309dcf4..7a992befca249cf039dc17163736b282cdacf029 100644 (file)
@@ -7,6 +7,8 @@
 /* forward declaration */
 void igc_rx_fifo_flush_base(struct igc_hw *hw);
 void igc_power_down_phy_copper_base(struct igc_hw *hw);
+bool igc_is_device_id_i225(struct igc_hw *hw);
+bool igc_is_device_id_i226(struct igc_hw *hw);
 
 /* Transmit Descriptor - Advanced */
 union igc_adv_tx_desc {
index a7b22639cfcd9b6b5c94865b5029d0bf66fcd6af..0e23f6244ffb9e1a186e1450869db26b9411bcff 100644 (file)
 /* Transmit Scheduling */
 #define IGC_TQAVCTRL_TRANSMIT_MODE_TSN 0x00000001
 #define IGC_TQAVCTRL_ENHANCED_QAV      0x00000008
+#define IGC_TQAVCTRL_FUTSCDDIS         0x00000080
 
 #define IGC_TXQCTL_QUEUE_MODE_LAUNCHT  0x00000001
 #define IGC_TXQCTL_STRICT_CYCLE                0x00000002
index 44b1740dc09834888b2946793057e250c76313bc..988131d7acd7232e499239d37bfd2a563f87bd7f 100644 (file)
@@ -5958,6 +5958,7 @@ static bool validate_schedule(struct igc_adapter *adapter,
                              const struct tc_taprio_qopt_offload *qopt)
 {
        int queue_uses[IGC_MAX_TX_QUEUES] = { };
+       struct igc_hw *hw = &adapter->hw;
        struct timespec64 now;
        size_t n;
 
@@ -5970,8 +5971,10 @@ static bool validate_schedule(struct igc_adapter *adapter,
         * in the future, it will hold all the packets until that
         * time, causing a lot of TX Hangs, so to avoid that, we
         * reject schedules that would start in the future.
+        * Note: Limitation above is no longer in i226.
         */
-       if (!is_base_time_past(qopt->base_time, &now))
+       if (!is_base_time_past(qopt->base_time, &now) &&
+           igc_is_device_id_i225(hw))
                return false;
 
        for (n = 0; n < qopt->num_entries; n++) {
index bb10d7b65232a68dfb729ff28ca084a3e5e43373..28325dc4fc5b0c79b387327389bf2e721940a2bf 100644 (file)
@@ -2,6 +2,7 @@
 /* Copyright (c)  2019 Intel Corporation */
 
 #include "igc.h"
+#include "igc_hw.h"
 #include "igc_tsn.h"
 
 static bool is_any_launchtime(struct igc_adapter *adapter)
@@ -92,7 +93,8 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter)
 
        tqavctrl = rd32(IGC_TQAVCTRL);
        tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
-                     IGC_TQAVCTRL_ENHANCED_QAV);
+                     IGC_TQAVCTRL_ENHANCED_QAV | IGC_TQAVCTRL_FUTSCDDIS);
+
        wr32(IGC_TQAVCTRL, tqavctrl);
 
        for (i = 0; i < adapter->num_tx_queues; i++) {
@@ -117,20 +119,10 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
        ktime_t base_time, systim;
        int i;
 
-       cycle = adapter->cycle_time;
-       base_time = adapter->base_time;
-
        wr32(IGC_TSAUXC, 0);
        wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
        wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN);
 
-       tqavctrl = rd32(IGC_TQAVCTRL);
-       tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;
-       wr32(IGC_TQAVCTRL, tqavctrl);
-
-       wr32(IGC_QBVCYCLET_S, cycle);
-       wr32(IGC_QBVCYCLET, cycle);
-
        for (i = 0; i < adapter->num_tx_queues; i++) {
                struct igc_ring *ring = adapter->tx_ring[i];
                u32 txqctl = 0;
@@ -233,21 +225,43 @@ skip_cbs:
                wr32(IGC_TXQCTL(i), txqctl);
        }
 
+       tqavctrl = rd32(IGC_TQAVCTRL);
+       tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;
+
+       cycle = adapter->cycle_time;
+       base_time = adapter->base_time;
+
        nsec = rd32(IGC_SYSTIML);
        sec = rd32(IGC_SYSTIMH);
 
        systim = ktime_set(sec, nsec);
-
        if (ktime_compare(systim, base_time) > 0) {
-               s64 n;
+               s64 n = div64_s64(ktime_sub_ns(systim, base_time), cycle);
 
-               n = div64_s64(ktime_sub_ns(systim, base_time), cycle);
                base_time = ktime_add_ns(base_time, (n + 1) * cycle);
+       } else {
+               /* According to datasheet section 7.5.2.9.3.3, FutScdDis bit
+                * has to be configured before the cycle time and base time.
+                */
+               if (igc_is_device_id_i226(hw))
+                       tqavctrl |= IGC_TQAVCTRL_FUTSCDDIS;
        }
 
-       baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l);
+       wr32(IGC_TQAVCTRL, tqavctrl);
+
+       wr32(IGC_QBVCYCLET_S, cycle);
+       wr32(IGC_QBVCYCLET, cycle);
 
+       baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l);
        wr32(IGC_BASET_H, baset_h);
+
+       /* In i226, Future base time is only supported when FutScdDis bit
+        * is enabled and only active for re-configuration.
+        * In this case, initialize the base time with zero to create
+        * "re-configuration" scenario then only set the desired base time.
+        */
+       if (tqavctrl & IGC_TQAVCTRL_FUTSCDDIS)
+               wr32(IGC_BASET_L, 0);
        wr32(IGC_BASET_L, baset_l);
 
        return 0;