Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (C) 2021 Gerhard Engleder <gerhard@engleder-embedded.com> */
0003 
0004 #include "tsnep.h"
0005 
0006 #include <net/pkt_sched.h>
0007 
0008 enum tsnep_test {
0009     TSNEP_TEST_ENABLE = 0,
0010     TSNEP_TEST_TAPRIO,
0011     TSNEP_TEST_TAPRIO_CHANGE,
0012     TSNEP_TEST_TAPRIO_EXTENSION,
0013 };
0014 
0015 static const char tsnep_test_strings[][ETH_GSTRING_LEN] = {
0016     "Enable timeout        (offline)",
0017     "TAPRIO                (offline)",
0018     "TAPRIO change         (offline)",
0019     "TAPRIO extension      (offline)",
0020 };
0021 
0022 #define TSNEP_TEST_COUNT (sizeof(tsnep_test_strings) / ETH_GSTRING_LEN)
0023 
0024 static bool enable_gc_timeout(struct tsnep_adapter *adapter)
0025 {
0026     iowrite8(TSNEP_GC_ENABLE_TIMEOUT, adapter->addr + TSNEP_GC);
0027     if (!(ioread32(adapter->addr + TSNEP_GC) & TSNEP_GC_TIMEOUT_ACTIVE))
0028         return false;
0029 
0030     return true;
0031 }
0032 
0033 static bool gc_timeout_signaled(struct tsnep_adapter *adapter)
0034 {
0035     if (ioread32(adapter->addr + TSNEP_GC) & TSNEP_GC_TIMEOUT_SIGNAL)
0036         return true;
0037 
0038     return false;
0039 }
0040 
0041 static bool ack_gc_timeout(struct tsnep_adapter *adapter)
0042 {
0043     iowrite8(TSNEP_GC_ENABLE_TIMEOUT, adapter->addr + TSNEP_GC);
0044     if (ioread32(adapter->addr + TSNEP_GC) &
0045         (TSNEP_GC_TIMEOUT_ACTIVE | TSNEP_GC_TIMEOUT_SIGNAL))
0046         return false;
0047     return true;
0048 }
0049 
0050 static bool enable_gc(struct tsnep_adapter *adapter, bool a)
0051 {
0052     u8 enable;
0053     u8 active;
0054 
0055     if (a) {
0056         enable = TSNEP_GC_ENABLE_A;
0057         active = TSNEP_GC_ACTIVE_A;
0058     } else {
0059         enable = TSNEP_GC_ENABLE_B;
0060         active = TSNEP_GC_ACTIVE_B;
0061     }
0062 
0063     iowrite8(enable, adapter->addr + TSNEP_GC);
0064     if (!(ioread32(adapter->addr + TSNEP_GC) & active))
0065         return false;
0066 
0067     return true;
0068 }
0069 
0070 static bool disable_gc(struct tsnep_adapter *adapter)
0071 {
0072     iowrite8(TSNEP_GC_DISABLE, adapter->addr + TSNEP_GC);
0073     if (ioread32(adapter->addr + TSNEP_GC) &
0074         (TSNEP_GC_ACTIVE_A | TSNEP_GC_ACTIVE_B))
0075         return false;
0076 
0077     return true;
0078 }
0079 
0080 static bool gc_delayed_enable(struct tsnep_adapter *adapter, bool a, int delay)
0081 {
0082     u64 before, after;
0083     u32 time;
0084     bool enabled;
0085 
0086     if (!disable_gc(adapter))
0087         return false;
0088 
0089     before = ktime_get_ns();
0090 
0091     if (!enable_gc_timeout(adapter))
0092         return false;
0093 
0094     /* for start time after timeout, the timeout can guarantee, that enable
0095      * is blocked if too late
0096      */
0097     time = ioread32(adapter->addr + ECM_SYSTEM_TIME_LOW);
0098     time += TSNEP_GC_TIMEOUT;
0099     iowrite32(time, adapter->addr + TSNEP_GC_TIME);
0100 
0101     ndelay(delay);
0102 
0103     enabled = enable_gc(adapter, a);
0104     after = ktime_get_ns();
0105 
0106     if (delay > TSNEP_GC_TIMEOUT) {
0107         /* timeout must have blocked enable */
0108         if (enabled)
0109             return false;
0110     } else if ((after - before) < TSNEP_GC_TIMEOUT * 14 / 16) {
0111         /* timeout must not have blocked enable */
0112         if (!enabled)
0113             return false;
0114     }
0115 
0116     if (enabled) {
0117         if (gc_timeout_signaled(adapter))
0118             return false;
0119     } else {
0120         if (!gc_timeout_signaled(adapter))
0121             return false;
0122         if (!ack_gc_timeout(adapter))
0123             return false;
0124     }
0125 
0126     if (!disable_gc(adapter))
0127         return false;
0128 
0129     return true;
0130 }
0131 
0132 static bool tsnep_test_gc_enable(struct tsnep_adapter *adapter)
0133 {
0134     int i;
0135 
0136     iowrite32(0x80000001, adapter->addr + TSNEP_GCL_A + 0);
0137     iowrite32(100000, adapter->addr + TSNEP_GCL_A + 4);
0138 
0139     for (i = 0; i < 200000; i += 100) {
0140         if (!gc_delayed_enable(adapter, true, i))
0141             return false;
0142     }
0143 
0144     iowrite32(0x80000001, adapter->addr + TSNEP_GCL_B + 0);
0145     iowrite32(100000, adapter->addr + TSNEP_GCL_B + 4);
0146 
0147     for (i = 0; i < 200000; i += 100) {
0148         if (!gc_delayed_enable(adapter, false, i))
0149             return false;
0150     }
0151 
0152     return true;
0153 }
0154 
0155 static void delay_base_time(struct tsnep_adapter *adapter,
0156                 struct tc_taprio_qopt_offload *qopt, s64 ms)
0157 {
0158     u64 system_time;
0159     u64 base_time = ktime_to_ns(qopt->base_time);
0160     u64 n;
0161 
0162     tsnep_get_system_time(adapter, &system_time);
0163     system_time += ms * 1000000;
0164     n = div64_u64(system_time - base_time, qopt->cycle_time);
0165 
0166     qopt->base_time = ktime_add_ns(qopt->base_time,
0167                        (n + 1) * qopt->cycle_time);
0168 }
0169 
0170 static void get_gate_state(struct tsnep_adapter *adapter, u32 *gc, u32 *gc_time,
0171                u64 *system_time)
0172 {
0173     u32 time_high_before;
0174     u32 time_low;
0175     u32 time_high;
0176     u32 gc_time_before;
0177 
0178     time_high = ioread32(adapter->addr + ECM_SYSTEM_TIME_HIGH);
0179     *gc_time = ioread32(adapter->addr + TSNEP_GC_TIME);
0180     do {
0181         time_low = ioread32(adapter->addr + ECM_SYSTEM_TIME_LOW);
0182         *gc = ioread32(adapter->addr + TSNEP_GC);
0183 
0184         gc_time_before = *gc_time;
0185         *gc_time = ioread32(adapter->addr + TSNEP_GC_TIME);
0186         time_high_before = time_high;
0187         time_high = ioread32(adapter->addr + ECM_SYSTEM_TIME_HIGH);
0188     } while ((time_high != time_high_before) ||
0189          (*gc_time != gc_time_before));
0190 
0191     *system_time = (((u64)time_high) << 32) | ((u64)time_low);
0192 }
0193 
0194 static int get_operation(struct tsnep_gcl *gcl, u64 system_time, u64 *next)
0195 {
0196     u64 n = div64_u64(system_time - gcl->base_time, gcl->cycle_time);
0197     u64 cycle_start = gcl->base_time + gcl->cycle_time * n;
0198     int i;
0199 
0200     *next = cycle_start;
0201     for (i = 0; i < gcl->count; i++) {
0202         *next += gcl->operation[i].interval;
0203         if (*next > system_time)
0204             break;
0205     }
0206 
0207     return i;
0208 }
0209 
0210 static bool check_gate(struct tsnep_adapter *adapter)
0211 {
0212     u32 gc_time;
0213     u32 gc;
0214     u64 system_time;
0215     struct tsnep_gcl *curr;
0216     struct tsnep_gcl *prev;
0217     u64 next_time;
0218     u8 gate_open;
0219     u8 next_gate_open;
0220 
0221     get_gate_state(adapter, &gc, &gc_time, &system_time);
0222 
0223     if (gc & TSNEP_GC_ACTIVE_A) {
0224         curr = &adapter->gcl[0];
0225         prev = &adapter->gcl[1];
0226     } else if (gc & TSNEP_GC_ACTIVE_B) {
0227         curr = &adapter->gcl[1];
0228         prev = &adapter->gcl[0];
0229     } else {
0230         return false;
0231     }
0232     if (curr->start_time <= system_time) {
0233         /* GCL is already active */
0234         int index;
0235 
0236         index = get_operation(curr, system_time, &next_time);
0237         gate_open = curr->operation[index].properties & TSNEP_GCL_MASK;
0238         if (index == curr->count - 1)
0239             index = 0;
0240         else
0241             index++;
0242         next_gate_open =
0243             curr->operation[index].properties & TSNEP_GCL_MASK;
0244     } else if (curr->change) {
0245         /* operation of previous GCL is active */
0246         int index;
0247         u64 start_before;
0248         u64 n;
0249 
0250         index = get_operation(prev, system_time, &next_time);
0251         next_time = curr->start_time;
0252         start_before = prev->base_time;
0253         n = div64_u64(curr->start_time - start_before,
0254                   prev->cycle_time);
0255         start_before += n * prev->cycle_time;
0256         if (curr->start_time == start_before)
0257             start_before -= prev->cycle_time;
0258         if (((start_before + prev->cycle_time_extension) >=
0259              curr->start_time) &&
0260             (curr->start_time - prev->cycle_time_extension <=
0261              system_time)) {
0262             /* extend */
0263             index = prev->count - 1;
0264         }
0265         gate_open = prev->operation[index].properties & TSNEP_GCL_MASK;
0266         next_gate_open =
0267             curr->operation[0].properties & TSNEP_GCL_MASK;
0268     } else {
0269         /* GCL is waiting for start */
0270         next_time = curr->start_time;
0271         gate_open = 0xFF;
0272         next_gate_open = curr->operation[0].properties & TSNEP_GCL_MASK;
0273     }
0274 
0275     if (gc_time != (next_time & 0xFFFFFFFF)) {
0276         dev_err(&adapter->pdev->dev, "gate control time 0x%x!=0x%llx\n",
0277             gc_time, next_time);
0278         return false;
0279     }
0280     if (((gc & TSNEP_GC_OPEN) >> TSNEP_GC_OPEN_SHIFT) != gate_open) {
0281         dev_err(&adapter->pdev->dev,
0282             "gate control open 0x%02x!=0x%02x\n",
0283             ((gc & TSNEP_GC_OPEN) >> TSNEP_GC_OPEN_SHIFT),
0284             gate_open);
0285         return false;
0286     }
0287     if (((gc & TSNEP_GC_NEXT_OPEN) >> TSNEP_GC_NEXT_OPEN_SHIFT) !=
0288         next_gate_open) {
0289         dev_err(&adapter->pdev->dev,
0290             "gate control next open 0x%02x!=0x%02x\n",
0291             ((gc & TSNEP_GC_NEXT_OPEN) >> TSNEP_GC_NEXT_OPEN_SHIFT),
0292             next_gate_open);
0293         return false;
0294     }
0295 
0296     return true;
0297 }
0298 
0299 static bool check_gate_duration(struct tsnep_adapter *adapter, s64 ms)
0300 {
0301     ktime_t start = ktime_get();
0302 
0303     do {
0304         if (!check_gate(adapter))
0305             return false;
0306     } while (ktime_ms_delta(ktime_get(), start) < ms);
0307 
0308     return true;
0309 }
0310 
0311 static bool enable_check_taprio(struct tsnep_adapter *adapter,
0312                 struct tc_taprio_qopt_offload *qopt, s64 ms)
0313 {
0314     int retval;
0315 
0316     retval = tsnep_tc_setup(adapter->netdev, TC_SETUP_QDISC_TAPRIO, qopt);
0317     if (retval)
0318         return false;
0319 
0320     if (!check_gate_duration(adapter, ms))
0321         return false;
0322 
0323     return true;
0324 }
0325 
0326 static bool disable_taprio(struct tsnep_adapter *adapter)
0327 {
0328     struct tc_taprio_qopt_offload qopt;
0329     int retval;
0330 
0331     memset(&qopt, 0, sizeof(qopt));
0332     qopt.enable = 0;
0333     retval = tsnep_tc_setup(adapter->netdev, TC_SETUP_QDISC_TAPRIO, &qopt);
0334     if (retval)
0335         return false;
0336 
0337     return true;
0338 }
0339 
0340 static bool run_taprio(struct tsnep_adapter *adapter,
0341                struct tc_taprio_qopt_offload *qopt, s64 ms)
0342 {
0343     if (!enable_check_taprio(adapter, qopt, ms))
0344         return false;
0345 
0346     if (!disable_taprio(adapter))
0347         return false;
0348 
0349     return true;
0350 }
0351 
0352 static bool tsnep_test_taprio(struct tsnep_adapter *adapter)
0353 {
0354     struct tc_taprio_qopt_offload *qopt;
0355     int i;
0356 
0357     qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL);
0358     if (!qopt)
0359         return false;
0360     for (i = 0; i < 255; i++)
0361         qopt->entries[i].command = TC_TAPRIO_CMD_SET_GATES;
0362 
0363     qopt->enable = 1;
0364     qopt->base_time = ktime_set(0, 0);
0365     qopt->cycle_time = 1500000;
0366     qopt->cycle_time_extension = 0;
0367     qopt->entries[0].gate_mask = 0x02;
0368     qopt->entries[0].interval = 200000;
0369     qopt->entries[1].gate_mask = 0x03;
0370     qopt->entries[1].interval = 800000;
0371     qopt->entries[2].gate_mask = 0x07;
0372     qopt->entries[2].interval = 240000;
0373     qopt->entries[3].gate_mask = 0x01;
0374     qopt->entries[3].interval = 80000;
0375     qopt->entries[4].gate_mask = 0x04;
0376     qopt->entries[4].interval = 70000;
0377     qopt->entries[5].gate_mask = 0x06;
0378     qopt->entries[5].interval = 60000;
0379     qopt->entries[6].gate_mask = 0x0F;
0380     qopt->entries[6].interval = 50000;
0381     qopt->num_entries = 7;
0382     if (!run_taprio(adapter, qopt, 100))
0383         goto failed;
0384 
0385     qopt->enable = 1;
0386     qopt->base_time = ktime_set(0, 0);
0387     qopt->cycle_time = 411854;
0388     qopt->cycle_time_extension = 0;
0389     qopt->entries[0].gate_mask = 0x17;
0390     qopt->entries[0].interval = 23842;
0391     qopt->entries[1].gate_mask = 0x16;
0392     qopt->entries[1].interval = 13482;
0393     qopt->entries[2].gate_mask = 0x15;
0394     qopt->entries[2].interval = 49428;
0395     qopt->entries[3].gate_mask = 0x14;
0396     qopt->entries[3].interval = 38189;
0397     qopt->entries[4].gate_mask = 0x13;
0398     qopt->entries[4].interval = 92321;
0399     qopt->entries[5].gate_mask = 0x12;
0400     qopt->entries[5].interval = 71239;
0401     qopt->entries[6].gate_mask = 0x11;
0402     qopt->entries[6].interval = 69932;
0403     qopt->entries[7].gate_mask = 0x10;
0404     qopt->entries[7].interval = 53421;
0405     qopt->num_entries = 8;
0406     if (!run_taprio(adapter, qopt, 100))
0407         goto failed;
0408 
0409     qopt->enable = 1;
0410     qopt->base_time = ktime_set(0, 0);
0411     delay_base_time(adapter, qopt, 12);
0412     qopt->cycle_time = 125000;
0413     qopt->cycle_time_extension = 0;
0414     qopt->entries[0].gate_mask = 0x27;
0415     qopt->entries[0].interval = 15000;
0416     qopt->entries[1].gate_mask = 0x26;
0417     qopt->entries[1].interval = 15000;
0418     qopt->entries[2].gate_mask = 0x25;
0419     qopt->entries[2].interval = 12500;
0420     qopt->entries[3].gate_mask = 0x24;
0421     qopt->entries[3].interval = 17500;
0422     qopt->entries[4].gate_mask = 0x23;
0423     qopt->entries[4].interval = 10000;
0424     qopt->entries[5].gate_mask = 0x22;
0425     qopt->entries[5].interval = 11000;
0426     qopt->entries[6].gate_mask = 0x21;
0427     qopt->entries[6].interval = 9000;
0428     qopt->entries[7].gate_mask = 0x20;
0429     qopt->entries[7].interval = 10000;
0430     qopt->entries[8].gate_mask = 0x20;
0431     qopt->entries[8].interval = 12500;
0432     qopt->entries[9].gate_mask = 0x20;
0433     qopt->entries[9].interval = 12500;
0434     qopt->num_entries = 10;
0435     if (!run_taprio(adapter, qopt, 100))
0436         goto failed;
0437 
0438     kfree(qopt);
0439 
0440     return true;
0441 
0442 failed:
0443     disable_taprio(adapter);
0444     kfree(qopt);
0445 
0446     return false;
0447 }
0448 
0449 static bool tsnep_test_taprio_change(struct tsnep_adapter *adapter)
0450 {
0451     struct tc_taprio_qopt_offload *qopt;
0452     int i;
0453 
0454     qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL);
0455     if (!qopt)
0456         return false;
0457     for (i = 0; i < 255; i++)
0458         qopt->entries[i].command = TC_TAPRIO_CMD_SET_GATES;
0459 
0460     qopt->enable = 1;
0461     qopt->base_time = ktime_set(0, 0);
0462     qopt->cycle_time = 100000;
0463     qopt->cycle_time_extension = 0;
0464     qopt->entries[0].gate_mask = 0x30;
0465     qopt->entries[0].interval = 20000;
0466     qopt->entries[1].gate_mask = 0x31;
0467     qopt->entries[1].interval = 80000;
0468     qopt->num_entries = 2;
0469     if (!enable_check_taprio(adapter, qopt, 100))
0470         goto failed;
0471 
0472     /* change to identical */
0473     if (!enable_check_taprio(adapter, qopt, 100))
0474         goto failed;
0475     delay_base_time(adapter, qopt, 17);
0476     if (!enable_check_taprio(adapter, qopt, 100))
0477         goto failed;
0478 
0479     /* change to same cycle time */
0480     qopt->base_time = ktime_set(0, 0);
0481     qopt->entries[0].gate_mask = 0x42;
0482     qopt->entries[1].gate_mask = 0x43;
0483     delay_base_time(adapter, qopt, 2);
0484     if (!enable_check_taprio(adapter, qopt, 100))
0485         goto failed;
0486     qopt->base_time = ktime_set(0, 0);
0487     qopt->entries[0].gate_mask = 0x54;
0488     qopt->entries[0].interval = 33333;
0489     qopt->entries[1].gate_mask = 0x55;
0490     qopt->entries[1].interval = 66667;
0491     delay_base_time(adapter, qopt, 23);
0492     if (!enable_check_taprio(adapter, qopt, 100))
0493         goto failed;
0494     qopt->base_time = ktime_set(0, 0);
0495     qopt->entries[0].gate_mask = 0x66;
0496     qopt->entries[0].interval = 50000;
0497     qopt->entries[1].gate_mask = 0x67;
0498     qopt->entries[1].interval = 25000;
0499     qopt->entries[2].gate_mask = 0x68;
0500     qopt->entries[2].interval = 25000;
0501     qopt->num_entries = 3;
0502     delay_base_time(adapter, qopt, 11);
0503     if (!enable_check_taprio(adapter, qopt, 100))
0504         goto failed;
0505 
0506     /* change to multiple of cycle time */
0507     qopt->base_time = ktime_set(0, 0);
0508     qopt->cycle_time = 200000;
0509     qopt->entries[0].gate_mask = 0x79;
0510     qopt->entries[0].interval = 50000;
0511     qopt->entries[1].gate_mask = 0x7A;
0512     qopt->entries[1].interval = 150000;
0513     qopt->num_entries = 2;
0514     delay_base_time(adapter, qopt, 11);
0515     if (!enable_check_taprio(adapter, qopt, 100))
0516         goto failed;
0517     qopt->base_time = ktime_set(0, 0);
0518     qopt->cycle_time = 1000000;
0519     qopt->entries[0].gate_mask = 0x7B;
0520     qopt->entries[0].interval = 125000;
0521     qopt->entries[1].gate_mask = 0x7C;
0522     qopt->entries[1].interval = 250000;
0523     qopt->entries[2].gate_mask = 0x7D;
0524     qopt->entries[2].interval = 375000;
0525     qopt->entries[3].gate_mask = 0x7E;
0526     qopt->entries[3].interval = 250000;
0527     qopt->num_entries = 4;
0528     delay_base_time(adapter, qopt, 3);
0529     if (!enable_check_taprio(adapter, qopt, 100))
0530         goto failed;
0531 
0532     /* change to shorter cycle time */
0533     qopt->base_time = ktime_set(0, 0);
0534     qopt->cycle_time = 333333;
0535     qopt->entries[0].gate_mask = 0x8F;
0536     qopt->entries[0].interval = 166666;
0537     qopt->entries[1].gate_mask = 0x80;
0538     qopt->entries[1].interval = 166667;
0539     qopt->num_entries = 2;
0540     delay_base_time(adapter, qopt, 11);
0541     if (!enable_check_taprio(adapter, qopt, 100))
0542         goto failed;
0543     qopt->base_time = ktime_set(0, 0);
0544     qopt->cycle_time = 62500;
0545     qopt->entries[0].gate_mask = 0x81;
0546     qopt->entries[0].interval = 31250;
0547     qopt->entries[1].gate_mask = 0x82;
0548     qopt->entries[1].interval = 15625;
0549     qopt->entries[2].gate_mask = 0x83;
0550     qopt->entries[2].interval = 15625;
0551     qopt->num_entries = 3;
0552     delay_base_time(adapter, qopt, 1);
0553     if (!enable_check_taprio(adapter, qopt, 100))
0554         goto failed;
0555 
0556     /* change to longer cycle time */
0557     qopt->base_time = ktime_set(0, 0);
0558     qopt->cycle_time = 400000;
0559     qopt->entries[0].gate_mask = 0x84;
0560     qopt->entries[0].interval = 100000;
0561     qopt->entries[1].gate_mask = 0x85;
0562     qopt->entries[1].interval = 100000;
0563     qopt->entries[2].gate_mask = 0x86;
0564     qopt->entries[2].interval = 100000;
0565     qopt->entries[3].gate_mask = 0x87;
0566     qopt->entries[3].interval = 100000;
0567     qopt->num_entries = 4;
0568     delay_base_time(adapter, qopt, 7);
0569     if (!enable_check_taprio(adapter, qopt, 100))
0570         goto failed;
0571     qopt->base_time = ktime_set(0, 0);
0572     qopt->cycle_time = 1700000;
0573     qopt->entries[0].gate_mask = 0x88;
0574     qopt->entries[0].interval = 200000;
0575     qopt->entries[1].gate_mask = 0x89;
0576     qopt->entries[1].interval = 300000;
0577     qopt->entries[2].gate_mask = 0x8A;
0578     qopt->entries[2].interval = 600000;
0579     qopt->entries[3].gate_mask = 0x8B;
0580     qopt->entries[3].interval = 100000;
0581     qopt->entries[4].gate_mask = 0x8C;
0582     qopt->entries[4].interval = 500000;
0583     qopt->num_entries = 5;
0584     delay_base_time(adapter, qopt, 6);
0585     if (!enable_check_taprio(adapter, qopt, 100))
0586         goto failed;
0587 
0588     if (!disable_taprio(adapter))
0589         goto failed;
0590 
0591     kfree(qopt);
0592 
0593     return true;
0594 
0595 failed:
0596     disable_taprio(adapter);
0597     kfree(qopt);
0598 
0599     return false;
0600 }
0601 
0602 static bool tsnep_test_taprio_extension(struct tsnep_adapter *adapter)
0603 {
0604     struct tc_taprio_qopt_offload *qopt;
0605     int i;
0606 
0607     qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL);
0608     if (!qopt)
0609         return false;
0610     for (i = 0; i < 255; i++)
0611         qopt->entries[i].command = TC_TAPRIO_CMD_SET_GATES;
0612 
0613     qopt->enable = 1;
0614     qopt->base_time = ktime_set(0, 0);
0615     qopt->cycle_time = 100000;
0616     qopt->cycle_time_extension = 50000;
0617     qopt->entries[0].gate_mask = 0x90;
0618     qopt->entries[0].interval = 20000;
0619     qopt->entries[1].gate_mask = 0x91;
0620     qopt->entries[1].interval = 80000;
0621     qopt->num_entries = 2;
0622     if (!enable_check_taprio(adapter, qopt, 100))
0623         goto failed;
0624 
0625     /* change to different phase */
0626     qopt->base_time = ktime_set(0, 50000);
0627     qopt->entries[0].gate_mask = 0x92;
0628     qopt->entries[0].interval = 33000;
0629     qopt->entries[1].gate_mask = 0x93;
0630     qopt->entries[1].interval = 67000;
0631     qopt->num_entries = 2;
0632     delay_base_time(adapter, qopt, 2);
0633     if (!enable_check_taprio(adapter, qopt, 100))
0634         goto failed;
0635 
0636     /* change to different phase and longer cycle time */
0637     qopt->base_time = ktime_set(0, 0);
0638     qopt->cycle_time = 1000000;
0639     qopt->cycle_time_extension = 700000;
0640     qopt->entries[0].gate_mask = 0x94;
0641     qopt->entries[0].interval = 400000;
0642     qopt->entries[1].gate_mask = 0x95;
0643     qopt->entries[1].interval = 600000;
0644     qopt->num_entries = 2;
0645     delay_base_time(adapter, qopt, 7);
0646     if (!enable_check_taprio(adapter, qopt, 100))
0647         goto failed;
0648     qopt->base_time = ktime_set(0, 700000);
0649     qopt->cycle_time = 2000000;
0650     qopt->cycle_time_extension = 1900000;
0651     qopt->entries[0].gate_mask = 0x96;
0652     qopt->entries[0].interval = 400000;
0653     qopt->entries[1].gate_mask = 0x97;
0654     qopt->entries[1].interval = 1600000;
0655     qopt->num_entries = 2;
0656     delay_base_time(adapter, qopt, 9);
0657     if (!enable_check_taprio(adapter, qopt, 100))
0658         goto failed;
0659 
0660     /* change to different phase and shorter cycle time */
0661     qopt->base_time = ktime_set(0, 0);
0662     qopt->cycle_time = 1500000;
0663     qopt->cycle_time_extension = 700000;
0664     qopt->entries[0].gate_mask = 0x98;
0665     qopt->entries[0].interval = 400000;
0666     qopt->entries[1].gate_mask = 0x99;
0667     qopt->entries[1].interval = 600000;
0668     qopt->entries[2].gate_mask = 0x9A;
0669     qopt->entries[2].interval = 500000;
0670     qopt->num_entries = 3;
0671     delay_base_time(adapter, qopt, 3);
0672     if (!enable_check_taprio(adapter, qopt, 100))
0673         goto failed;
0674     qopt->base_time = ktime_set(0, 100000);
0675     qopt->cycle_time = 500000;
0676     qopt->cycle_time_extension = 300000;
0677     qopt->entries[0].gate_mask = 0x9B;
0678     qopt->entries[0].interval = 150000;
0679     qopt->entries[1].gate_mask = 0x9C;
0680     qopt->entries[1].interval = 350000;
0681     qopt->num_entries = 2;
0682     delay_base_time(adapter, qopt, 9);
0683     if (!enable_check_taprio(adapter, qopt, 100))
0684         goto failed;
0685 
0686     /* change to different cycle time */
0687     qopt->base_time = ktime_set(0, 0);
0688     qopt->cycle_time = 1000000;
0689     qopt->cycle_time_extension = 700000;
0690     qopt->entries[0].gate_mask = 0xAD;
0691     qopt->entries[0].interval = 400000;
0692     qopt->entries[1].gate_mask = 0xAE;
0693     qopt->entries[1].interval = 300000;
0694     qopt->entries[2].gate_mask = 0xAF;
0695     qopt->entries[2].interval = 300000;
0696     qopt->num_entries = 3;
0697     if (!enable_check_taprio(adapter, qopt, 100))
0698         goto failed;
0699     qopt->base_time = ktime_set(0, 0);
0700     qopt->cycle_time = 400000;
0701     qopt->cycle_time_extension = 100000;
0702     qopt->entries[0].gate_mask = 0xA0;
0703     qopt->entries[0].interval = 200000;
0704     qopt->entries[1].gate_mask = 0xA1;
0705     qopt->entries[1].interval = 200000;
0706     qopt->num_entries = 2;
0707     delay_base_time(adapter, qopt, 19);
0708     if (!enable_check_taprio(adapter, qopt, 100))
0709         goto failed;
0710     qopt->base_time = ktime_set(0, 0);
0711     qopt->cycle_time = 500000;
0712     qopt->cycle_time_extension = 499999;
0713     qopt->entries[0].gate_mask = 0xB2;
0714     qopt->entries[0].interval = 100000;
0715     qopt->entries[1].gate_mask = 0xB3;
0716     qopt->entries[1].interval = 100000;
0717     qopt->entries[2].gate_mask = 0xB4;
0718     qopt->entries[2].interval = 100000;
0719     qopt->entries[3].gate_mask = 0xB5;
0720     qopt->entries[3].interval = 200000;
0721     qopt->num_entries = 4;
0722     delay_base_time(adapter, qopt, 19);
0723     if (!enable_check_taprio(adapter, qopt, 100))
0724         goto failed;
0725     qopt->base_time = ktime_set(0, 0);
0726     qopt->cycle_time = 6000000;
0727     qopt->cycle_time_extension = 5999999;
0728     qopt->entries[0].gate_mask = 0xC6;
0729     qopt->entries[0].interval = 1000000;
0730     qopt->entries[1].gate_mask = 0xC7;
0731     qopt->entries[1].interval = 1000000;
0732     qopt->entries[2].gate_mask = 0xC8;
0733     qopt->entries[2].interval = 1000000;
0734     qopt->entries[3].gate_mask = 0xC9;
0735     qopt->entries[3].interval = 1500000;
0736     qopt->entries[4].gate_mask = 0xCA;
0737     qopt->entries[4].interval = 1500000;
0738     qopt->num_entries = 5;
0739     delay_base_time(adapter, qopt, 1);
0740     if (!enable_check_taprio(adapter, qopt, 100))
0741         goto failed;
0742 
0743     if (!disable_taprio(adapter))
0744         goto failed;
0745 
0746     kfree(qopt);
0747 
0748     return true;
0749 
0750 failed:
0751     disable_taprio(adapter);
0752     kfree(qopt);
0753 
0754     return false;
0755 }
0756 
0757 int tsnep_ethtool_get_test_count(void)
0758 {
0759     return TSNEP_TEST_COUNT;
0760 }
0761 
0762 void tsnep_ethtool_get_test_strings(u8 *data)
0763 {
0764     memcpy(data, tsnep_test_strings, sizeof(tsnep_test_strings));
0765 }
0766 
0767 void tsnep_ethtool_self_test(struct net_device *netdev,
0768                  struct ethtool_test *eth_test, u64 *data)
0769 {
0770     struct tsnep_adapter *adapter = netdev_priv(netdev);
0771 
0772     eth_test->len = TSNEP_TEST_COUNT;
0773 
0774     if (eth_test->flags != ETH_TEST_FL_OFFLINE) {
0775         /* no tests are done online */
0776         data[TSNEP_TEST_ENABLE] = 0;
0777         data[TSNEP_TEST_TAPRIO] = 0;
0778         data[TSNEP_TEST_TAPRIO_CHANGE] = 0;
0779         data[TSNEP_TEST_TAPRIO_EXTENSION] = 0;
0780 
0781         return;
0782     }
0783 
0784     if (tsnep_test_gc_enable(adapter)) {
0785         data[TSNEP_TEST_ENABLE] = 0;
0786     } else {
0787         eth_test->flags |= ETH_TEST_FL_FAILED;
0788         data[TSNEP_TEST_ENABLE] = 1;
0789     }
0790 
0791     if (tsnep_test_taprio(adapter)) {
0792         data[TSNEP_TEST_TAPRIO] = 0;
0793     } else {
0794         eth_test->flags |= ETH_TEST_FL_FAILED;
0795         data[TSNEP_TEST_TAPRIO] = 1;
0796     }
0797 
0798     if (tsnep_test_taprio_change(adapter)) {
0799         data[TSNEP_TEST_TAPRIO_CHANGE] = 0;
0800     } else {
0801         eth_test->flags |= ETH_TEST_FL_FAILED;
0802         data[TSNEP_TEST_TAPRIO_CHANGE] = 1;
0803     }
0804 
0805     if (tsnep_test_taprio_extension(adapter)) {
0806         data[TSNEP_TEST_TAPRIO_EXTENSION] = 0;
0807     } else {
0808         eth_test->flags |= ETH_TEST_FL_FAILED;
0809         data[TSNEP_TEST_TAPRIO_EXTENSION] = 1;
0810     }
0811 }