162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright (C) 2021 Gerhard Engleder <gerhard@engleder-embedded.com> */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "tsnep.h" 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <net/pkt_sched.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_cienum tsnep_test { 962306a36Sopenharmony_ci TSNEP_TEST_ENABLE = 0, 1062306a36Sopenharmony_ci TSNEP_TEST_TAPRIO, 1162306a36Sopenharmony_ci TSNEP_TEST_TAPRIO_CHANGE, 1262306a36Sopenharmony_ci TSNEP_TEST_TAPRIO_EXTENSION, 1362306a36Sopenharmony_ci}; 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistatic const char tsnep_test_strings[][ETH_GSTRING_LEN] = { 1662306a36Sopenharmony_ci "Enable timeout (offline)", 1762306a36Sopenharmony_ci "TAPRIO (offline)", 1862306a36Sopenharmony_ci "TAPRIO change (offline)", 1962306a36Sopenharmony_ci "TAPRIO extension (offline)", 2062306a36Sopenharmony_ci}; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define TSNEP_TEST_COUNT (sizeof(tsnep_test_strings) / ETH_GSTRING_LEN) 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic bool enable_gc_timeout(struct tsnep_adapter *adapter) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci iowrite8(TSNEP_GC_ENABLE_TIMEOUT, adapter->addr + TSNEP_GC); 2762306a36Sopenharmony_ci if (!(ioread32(adapter->addr + TSNEP_GC) & TSNEP_GC_TIMEOUT_ACTIVE)) 2862306a36Sopenharmony_ci return false; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci return true; 3162306a36Sopenharmony_ci} 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistatic bool gc_timeout_signaled(struct tsnep_adapter *adapter) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci if (ioread32(adapter->addr + TSNEP_GC) & TSNEP_GC_TIMEOUT_SIGNAL) 3662306a36Sopenharmony_ci return true; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci return false; 3962306a36Sopenharmony_ci} 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic bool ack_gc_timeout(struct tsnep_adapter *adapter) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci iowrite8(TSNEP_GC_ENABLE_TIMEOUT, adapter->addr + TSNEP_GC); 4462306a36Sopenharmony_ci if (ioread32(adapter->addr + TSNEP_GC) & 4562306a36Sopenharmony_ci (TSNEP_GC_TIMEOUT_ACTIVE | TSNEP_GC_TIMEOUT_SIGNAL)) 4662306a36Sopenharmony_ci return false; 4762306a36Sopenharmony_ci return true; 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistatic bool enable_gc(struct tsnep_adapter *adapter, bool a) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci u8 enable; 5362306a36Sopenharmony_ci u8 active; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci if (a) { 5662306a36Sopenharmony_ci enable = TSNEP_GC_ENABLE_A; 5762306a36Sopenharmony_ci active = TSNEP_GC_ACTIVE_A; 5862306a36Sopenharmony_ci } else { 5962306a36Sopenharmony_ci enable = TSNEP_GC_ENABLE_B; 6062306a36Sopenharmony_ci active = TSNEP_GC_ACTIVE_B; 6162306a36Sopenharmony_ci } 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci iowrite8(enable, adapter->addr + TSNEP_GC); 6462306a36Sopenharmony_ci if (!(ioread32(adapter->addr + TSNEP_GC) & active)) 6562306a36Sopenharmony_ci return false; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci return true; 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic bool disable_gc(struct tsnep_adapter *adapter) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci iowrite8(TSNEP_GC_DISABLE, adapter->addr + TSNEP_GC); 7362306a36Sopenharmony_ci if (ioread32(adapter->addr + TSNEP_GC) & 7462306a36Sopenharmony_ci (TSNEP_GC_ACTIVE_A | TSNEP_GC_ACTIVE_B)) 7562306a36Sopenharmony_ci return false; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci return true; 7862306a36Sopenharmony_ci} 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cistatic bool gc_delayed_enable(struct tsnep_adapter *adapter, bool a, int delay) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci u64 before, after; 8362306a36Sopenharmony_ci u32 time; 8462306a36Sopenharmony_ci bool enabled; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci if (!disable_gc(adapter)) 8762306a36Sopenharmony_ci return false; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci before = ktime_get_ns(); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci if (!enable_gc_timeout(adapter)) 9262306a36Sopenharmony_ci return false; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci /* for start time after timeout, the timeout can guarantee, that enable 9562306a36Sopenharmony_ci * is blocked if too late 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_ci time = ioread32(adapter->addr + ECM_SYSTEM_TIME_LOW); 9862306a36Sopenharmony_ci time += TSNEP_GC_TIMEOUT; 9962306a36Sopenharmony_ci iowrite32(time, adapter->addr + TSNEP_GC_TIME); 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci ndelay(delay); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci enabled = enable_gc(adapter, a); 10462306a36Sopenharmony_ci after = ktime_get_ns(); 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci if (delay > TSNEP_GC_TIMEOUT) { 10762306a36Sopenharmony_ci /* timeout must have blocked enable */ 10862306a36Sopenharmony_ci if (enabled) 10962306a36Sopenharmony_ci return false; 11062306a36Sopenharmony_ci } else if ((after - before) < TSNEP_GC_TIMEOUT * 14 / 16) { 11162306a36Sopenharmony_ci /* timeout must not have blocked enable */ 11262306a36Sopenharmony_ci if (!enabled) 11362306a36Sopenharmony_ci return false; 11462306a36Sopenharmony_ci } 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci if (enabled) { 11762306a36Sopenharmony_ci if (gc_timeout_signaled(adapter)) 11862306a36Sopenharmony_ci return false; 11962306a36Sopenharmony_ci } else { 12062306a36Sopenharmony_ci if (!gc_timeout_signaled(adapter)) 12162306a36Sopenharmony_ci return false; 12262306a36Sopenharmony_ci if (!ack_gc_timeout(adapter)) 12362306a36Sopenharmony_ci return false; 12462306a36Sopenharmony_ci } 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci if (!disable_gc(adapter)) 12762306a36Sopenharmony_ci return false; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci return true; 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistatic bool tsnep_test_gc_enable(struct tsnep_adapter *adapter) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci int i; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci iowrite32(0x80000001, adapter->addr + TSNEP_GCL_A + 0); 13762306a36Sopenharmony_ci iowrite32(100000, adapter->addr + TSNEP_GCL_A + 4); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci for (i = 0; i < 200000; i += 100) { 14062306a36Sopenharmony_ci if (!gc_delayed_enable(adapter, true, i)) 14162306a36Sopenharmony_ci return false; 14262306a36Sopenharmony_ci } 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci iowrite32(0x80000001, adapter->addr + TSNEP_GCL_B + 0); 14562306a36Sopenharmony_ci iowrite32(100000, adapter->addr + TSNEP_GCL_B + 4); 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci for (i = 0; i < 200000; i += 100) { 14862306a36Sopenharmony_ci if (!gc_delayed_enable(adapter, false, i)) 14962306a36Sopenharmony_ci return false; 15062306a36Sopenharmony_ci } 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci return true; 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic void delay_base_time(struct tsnep_adapter *adapter, 15662306a36Sopenharmony_ci struct tc_taprio_qopt_offload *qopt, s64 ms) 15762306a36Sopenharmony_ci{ 15862306a36Sopenharmony_ci u64 system_time; 15962306a36Sopenharmony_ci u64 base_time = ktime_to_ns(qopt->base_time); 16062306a36Sopenharmony_ci u64 n; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci tsnep_get_system_time(adapter, &system_time); 16362306a36Sopenharmony_ci system_time += ms * 1000000; 16462306a36Sopenharmony_ci n = div64_u64(system_time - base_time, qopt->cycle_time); 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci qopt->base_time = ktime_add_ns(qopt->base_time, 16762306a36Sopenharmony_ci (n + 1) * qopt->cycle_time); 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistatic void get_gate_state(struct tsnep_adapter *adapter, u32 *gc, u32 *gc_time, 17162306a36Sopenharmony_ci u64 *system_time) 17262306a36Sopenharmony_ci{ 17362306a36Sopenharmony_ci u32 time_high_before; 17462306a36Sopenharmony_ci u32 time_low; 17562306a36Sopenharmony_ci u32 time_high; 17662306a36Sopenharmony_ci u32 gc_time_before; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci time_high = ioread32(adapter->addr + ECM_SYSTEM_TIME_HIGH); 17962306a36Sopenharmony_ci *gc_time = ioread32(adapter->addr + TSNEP_GC_TIME); 18062306a36Sopenharmony_ci do { 18162306a36Sopenharmony_ci time_low = ioread32(adapter->addr + ECM_SYSTEM_TIME_LOW); 18262306a36Sopenharmony_ci *gc = ioread32(adapter->addr + TSNEP_GC); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci gc_time_before = *gc_time; 18562306a36Sopenharmony_ci *gc_time = ioread32(adapter->addr + TSNEP_GC_TIME); 18662306a36Sopenharmony_ci time_high_before = time_high; 18762306a36Sopenharmony_ci time_high = ioread32(adapter->addr + ECM_SYSTEM_TIME_HIGH); 18862306a36Sopenharmony_ci } while ((time_high != time_high_before) || 18962306a36Sopenharmony_ci (*gc_time != gc_time_before)); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci *system_time = (((u64)time_high) << 32) | ((u64)time_low); 19262306a36Sopenharmony_ci} 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_cistatic int get_operation(struct tsnep_gcl *gcl, u64 system_time, u64 *next) 19562306a36Sopenharmony_ci{ 19662306a36Sopenharmony_ci u64 n = div64_u64(system_time - gcl->base_time, gcl->cycle_time); 19762306a36Sopenharmony_ci u64 cycle_start = gcl->base_time + gcl->cycle_time * n; 19862306a36Sopenharmony_ci int i; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci *next = cycle_start; 20162306a36Sopenharmony_ci for (i = 0; i < gcl->count; i++) { 20262306a36Sopenharmony_ci *next += gcl->operation[i].interval; 20362306a36Sopenharmony_ci if (*next > system_time) 20462306a36Sopenharmony_ci break; 20562306a36Sopenharmony_ci } 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci return i; 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cistatic bool check_gate(struct tsnep_adapter *adapter) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci u32 gc_time; 21362306a36Sopenharmony_ci u32 gc; 21462306a36Sopenharmony_ci u64 system_time; 21562306a36Sopenharmony_ci struct tsnep_gcl *curr; 21662306a36Sopenharmony_ci struct tsnep_gcl *prev; 21762306a36Sopenharmony_ci u64 next_time; 21862306a36Sopenharmony_ci u8 gate_open; 21962306a36Sopenharmony_ci u8 next_gate_open; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci get_gate_state(adapter, &gc, &gc_time, &system_time); 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci if (gc & TSNEP_GC_ACTIVE_A) { 22462306a36Sopenharmony_ci curr = &adapter->gcl[0]; 22562306a36Sopenharmony_ci prev = &adapter->gcl[1]; 22662306a36Sopenharmony_ci } else if (gc & TSNEP_GC_ACTIVE_B) { 22762306a36Sopenharmony_ci curr = &adapter->gcl[1]; 22862306a36Sopenharmony_ci prev = &adapter->gcl[0]; 22962306a36Sopenharmony_ci } else { 23062306a36Sopenharmony_ci return false; 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci if (curr->start_time <= system_time) { 23362306a36Sopenharmony_ci /* GCL is already active */ 23462306a36Sopenharmony_ci int index; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci index = get_operation(curr, system_time, &next_time); 23762306a36Sopenharmony_ci gate_open = curr->operation[index].properties & TSNEP_GCL_MASK; 23862306a36Sopenharmony_ci if (index == curr->count - 1) 23962306a36Sopenharmony_ci index = 0; 24062306a36Sopenharmony_ci else 24162306a36Sopenharmony_ci index++; 24262306a36Sopenharmony_ci next_gate_open = 24362306a36Sopenharmony_ci curr->operation[index].properties & TSNEP_GCL_MASK; 24462306a36Sopenharmony_ci } else if (curr->change) { 24562306a36Sopenharmony_ci /* operation of previous GCL is active */ 24662306a36Sopenharmony_ci int index; 24762306a36Sopenharmony_ci u64 start_before; 24862306a36Sopenharmony_ci u64 n; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci index = get_operation(prev, system_time, &next_time); 25162306a36Sopenharmony_ci next_time = curr->start_time; 25262306a36Sopenharmony_ci start_before = prev->base_time; 25362306a36Sopenharmony_ci n = div64_u64(curr->start_time - start_before, 25462306a36Sopenharmony_ci prev->cycle_time); 25562306a36Sopenharmony_ci start_before += n * prev->cycle_time; 25662306a36Sopenharmony_ci if (curr->start_time == start_before) 25762306a36Sopenharmony_ci start_before -= prev->cycle_time; 25862306a36Sopenharmony_ci if (((start_before + prev->cycle_time_extension) >= 25962306a36Sopenharmony_ci curr->start_time) && 26062306a36Sopenharmony_ci (curr->start_time - prev->cycle_time_extension <= 26162306a36Sopenharmony_ci system_time)) { 26262306a36Sopenharmony_ci /* extend */ 26362306a36Sopenharmony_ci index = prev->count - 1; 26462306a36Sopenharmony_ci } 26562306a36Sopenharmony_ci gate_open = prev->operation[index].properties & TSNEP_GCL_MASK; 26662306a36Sopenharmony_ci next_gate_open = 26762306a36Sopenharmony_ci curr->operation[0].properties & TSNEP_GCL_MASK; 26862306a36Sopenharmony_ci } else { 26962306a36Sopenharmony_ci /* GCL is waiting for start */ 27062306a36Sopenharmony_ci next_time = curr->start_time; 27162306a36Sopenharmony_ci gate_open = 0xFF; 27262306a36Sopenharmony_ci next_gate_open = curr->operation[0].properties & TSNEP_GCL_MASK; 27362306a36Sopenharmony_ci } 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci if (gc_time != (next_time & 0xFFFFFFFF)) { 27662306a36Sopenharmony_ci dev_err(&adapter->pdev->dev, "gate control time 0x%x!=0x%llx\n", 27762306a36Sopenharmony_ci gc_time, next_time); 27862306a36Sopenharmony_ci return false; 27962306a36Sopenharmony_ci } 28062306a36Sopenharmony_ci if (((gc & TSNEP_GC_OPEN) >> TSNEP_GC_OPEN_SHIFT) != gate_open) { 28162306a36Sopenharmony_ci dev_err(&adapter->pdev->dev, 28262306a36Sopenharmony_ci "gate control open 0x%02x!=0x%02x\n", 28362306a36Sopenharmony_ci ((gc & TSNEP_GC_OPEN) >> TSNEP_GC_OPEN_SHIFT), 28462306a36Sopenharmony_ci gate_open); 28562306a36Sopenharmony_ci return false; 28662306a36Sopenharmony_ci } 28762306a36Sopenharmony_ci if (((gc & TSNEP_GC_NEXT_OPEN) >> TSNEP_GC_NEXT_OPEN_SHIFT) != 28862306a36Sopenharmony_ci next_gate_open) { 28962306a36Sopenharmony_ci dev_err(&adapter->pdev->dev, 29062306a36Sopenharmony_ci "gate control next open 0x%02x!=0x%02x\n", 29162306a36Sopenharmony_ci ((gc & TSNEP_GC_NEXT_OPEN) >> TSNEP_GC_NEXT_OPEN_SHIFT), 29262306a36Sopenharmony_ci next_gate_open); 29362306a36Sopenharmony_ci return false; 29462306a36Sopenharmony_ci } 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci return true; 29762306a36Sopenharmony_ci} 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_cistatic bool check_gate_duration(struct tsnep_adapter *adapter, s64 ms) 30062306a36Sopenharmony_ci{ 30162306a36Sopenharmony_ci ktime_t start = ktime_get(); 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci do { 30462306a36Sopenharmony_ci if (!check_gate(adapter)) 30562306a36Sopenharmony_ci return false; 30662306a36Sopenharmony_ci } while (ktime_ms_delta(ktime_get(), start) < ms); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci return true; 30962306a36Sopenharmony_ci} 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_cistatic bool enable_check_taprio(struct tsnep_adapter *adapter, 31262306a36Sopenharmony_ci struct tc_taprio_qopt_offload *qopt, s64 ms) 31362306a36Sopenharmony_ci{ 31462306a36Sopenharmony_ci int retval; 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci retval = tsnep_tc_setup(adapter->netdev, TC_SETUP_QDISC_TAPRIO, qopt); 31762306a36Sopenharmony_ci if (retval) 31862306a36Sopenharmony_ci return false; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci if (!check_gate_duration(adapter, ms)) 32162306a36Sopenharmony_ci return false; 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci return true; 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_cistatic bool disable_taprio(struct tsnep_adapter *adapter) 32762306a36Sopenharmony_ci{ 32862306a36Sopenharmony_ci struct tc_taprio_qopt_offload qopt; 32962306a36Sopenharmony_ci int retval; 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci memset(&qopt, 0, sizeof(qopt)); 33262306a36Sopenharmony_ci qopt.cmd = TAPRIO_CMD_DESTROY; 33362306a36Sopenharmony_ci retval = tsnep_tc_setup(adapter->netdev, TC_SETUP_QDISC_TAPRIO, &qopt); 33462306a36Sopenharmony_ci if (retval) 33562306a36Sopenharmony_ci return false; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci return true; 33862306a36Sopenharmony_ci} 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_cistatic bool run_taprio(struct tsnep_adapter *adapter, 34162306a36Sopenharmony_ci struct tc_taprio_qopt_offload *qopt, s64 ms) 34262306a36Sopenharmony_ci{ 34362306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, ms)) 34462306a36Sopenharmony_ci return false; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci if (!disable_taprio(adapter)) 34762306a36Sopenharmony_ci return false; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci return true; 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_cistatic bool tsnep_test_taprio(struct tsnep_adapter *adapter) 35362306a36Sopenharmony_ci{ 35462306a36Sopenharmony_ci struct tc_taprio_qopt_offload *qopt; 35562306a36Sopenharmony_ci int i; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL); 35862306a36Sopenharmony_ci if (!qopt) 35962306a36Sopenharmony_ci return false; 36062306a36Sopenharmony_ci for (i = 0; i < 255; i++) 36162306a36Sopenharmony_ci qopt->entries[i].command = TC_TAPRIO_CMD_SET_GATES; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci qopt->cmd = TAPRIO_CMD_REPLACE; 36462306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 36562306a36Sopenharmony_ci qopt->cycle_time = 1500000; 36662306a36Sopenharmony_ci qopt->cycle_time_extension = 0; 36762306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x02; 36862306a36Sopenharmony_ci qopt->entries[0].interval = 200000; 36962306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x03; 37062306a36Sopenharmony_ci qopt->entries[1].interval = 800000; 37162306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0x07; 37262306a36Sopenharmony_ci qopt->entries[2].interval = 240000; 37362306a36Sopenharmony_ci qopt->entries[3].gate_mask = 0x01; 37462306a36Sopenharmony_ci qopt->entries[3].interval = 80000; 37562306a36Sopenharmony_ci qopt->entries[4].gate_mask = 0x04; 37662306a36Sopenharmony_ci qopt->entries[4].interval = 70000; 37762306a36Sopenharmony_ci qopt->entries[5].gate_mask = 0x06; 37862306a36Sopenharmony_ci qopt->entries[5].interval = 60000; 37962306a36Sopenharmony_ci qopt->entries[6].gate_mask = 0x0F; 38062306a36Sopenharmony_ci qopt->entries[6].interval = 50000; 38162306a36Sopenharmony_ci qopt->num_entries = 7; 38262306a36Sopenharmony_ci if (!run_taprio(adapter, qopt, 100)) 38362306a36Sopenharmony_ci goto failed; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci qopt->cmd = TAPRIO_CMD_REPLACE; 38662306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 38762306a36Sopenharmony_ci qopt->cycle_time = 411854; 38862306a36Sopenharmony_ci qopt->cycle_time_extension = 0; 38962306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x17; 39062306a36Sopenharmony_ci qopt->entries[0].interval = 23842; 39162306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x16; 39262306a36Sopenharmony_ci qopt->entries[1].interval = 13482; 39362306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0x15; 39462306a36Sopenharmony_ci qopt->entries[2].interval = 49428; 39562306a36Sopenharmony_ci qopt->entries[3].gate_mask = 0x14; 39662306a36Sopenharmony_ci qopt->entries[3].interval = 38189; 39762306a36Sopenharmony_ci qopt->entries[4].gate_mask = 0x13; 39862306a36Sopenharmony_ci qopt->entries[4].interval = 92321; 39962306a36Sopenharmony_ci qopt->entries[5].gate_mask = 0x12; 40062306a36Sopenharmony_ci qopt->entries[5].interval = 71239; 40162306a36Sopenharmony_ci qopt->entries[6].gate_mask = 0x11; 40262306a36Sopenharmony_ci qopt->entries[6].interval = 69932; 40362306a36Sopenharmony_ci qopt->entries[7].gate_mask = 0x10; 40462306a36Sopenharmony_ci qopt->entries[7].interval = 53421; 40562306a36Sopenharmony_ci qopt->num_entries = 8; 40662306a36Sopenharmony_ci if (!run_taprio(adapter, qopt, 100)) 40762306a36Sopenharmony_ci goto failed; 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci qopt->cmd = TAPRIO_CMD_REPLACE; 41062306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 41162306a36Sopenharmony_ci delay_base_time(adapter, qopt, 12); 41262306a36Sopenharmony_ci qopt->cycle_time = 125000; 41362306a36Sopenharmony_ci qopt->cycle_time_extension = 0; 41462306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x27; 41562306a36Sopenharmony_ci qopt->entries[0].interval = 15000; 41662306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x26; 41762306a36Sopenharmony_ci qopt->entries[1].interval = 15000; 41862306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0x25; 41962306a36Sopenharmony_ci qopt->entries[2].interval = 12500; 42062306a36Sopenharmony_ci qopt->entries[3].gate_mask = 0x24; 42162306a36Sopenharmony_ci qopt->entries[3].interval = 17500; 42262306a36Sopenharmony_ci qopt->entries[4].gate_mask = 0x23; 42362306a36Sopenharmony_ci qopt->entries[4].interval = 10000; 42462306a36Sopenharmony_ci qopt->entries[5].gate_mask = 0x22; 42562306a36Sopenharmony_ci qopt->entries[5].interval = 11000; 42662306a36Sopenharmony_ci qopt->entries[6].gate_mask = 0x21; 42762306a36Sopenharmony_ci qopt->entries[6].interval = 9000; 42862306a36Sopenharmony_ci qopt->entries[7].gate_mask = 0x20; 42962306a36Sopenharmony_ci qopt->entries[7].interval = 10000; 43062306a36Sopenharmony_ci qopt->entries[8].gate_mask = 0x20; 43162306a36Sopenharmony_ci qopt->entries[8].interval = 12500; 43262306a36Sopenharmony_ci qopt->entries[9].gate_mask = 0x20; 43362306a36Sopenharmony_ci qopt->entries[9].interval = 12500; 43462306a36Sopenharmony_ci qopt->num_entries = 10; 43562306a36Sopenharmony_ci if (!run_taprio(adapter, qopt, 100)) 43662306a36Sopenharmony_ci goto failed; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci kfree(qopt); 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci return true; 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_cifailed: 44362306a36Sopenharmony_ci disable_taprio(adapter); 44462306a36Sopenharmony_ci kfree(qopt); 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci return false; 44762306a36Sopenharmony_ci} 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_cistatic bool tsnep_test_taprio_change(struct tsnep_adapter *adapter) 45062306a36Sopenharmony_ci{ 45162306a36Sopenharmony_ci struct tc_taprio_qopt_offload *qopt; 45262306a36Sopenharmony_ci int i; 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL); 45562306a36Sopenharmony_ci if (!qopt) 45662306a36Sopenharmony_ci return false; 45762306a36Sopenharmony_ci for (i = 0; i < 255; i++) 45862306a36Sopenharmony_ci qopt->entries[i].command = TC_TAPRIO_CMD_SET_GATES; 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci qopt->cmd = TAPRIO_CMD_REPLACE; 46162306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 46262306a36Sopenharmony_ci qopt->cycle_time = 100000; 46362306a36Sopenharmony_ci qopt->cycle_time_extension = 0; 46462306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x30; 46562306a36Sopenharmony_ci qopt->entries[0].interval = 20000; 46662306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x31; 46762306a36Sopenharmony_ci qopt->entries[1].interval = 80000; 46862306a36Sopenharmony_ci qopt->num_entries = 2; 46962306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 47062306a36Sopenharmony_ci goto failed; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci /* change to identical */ 47362306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 47462306a36Sopenharmony_ci goto failed; 47562306a36Sopenharmony_ci delay_base_time(adapter, qopt, 17); 47662306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 47762306a36Sopenharmony_ci goto failed; 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci /* change to same cycle time */ 48062306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 48162306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x42; 48262306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x43; 48362306a36Sopenharmony_ci delay_base_time(adapter, qopt, 2); 48462306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 48562306a36Sopenharmony_ci goto failed; 48662306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 48762306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x54; 48862306a36Sopenharmony_ci qopt->entries[0].interval = 33333; 48962306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x55; 49062306a36Sopenharmony_ci qopt->entries[1].interval = 66667; 49162306a36Sopenharmony_ci delay_base_time(adapter, qopt, 23); 49262306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 49362306a36Sopenharmony_ci goto failed; 49462306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 49562306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x66; 49662306a36Sopenharmony_ci qopt->entries[0].interval = 50000; 49762306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x67; 49862306a36Sopenharmony_ci qopt->entries[1].interval = 25000; 49962306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0x68; 50062306a36Sopenharmony_ci qopt->entries[2].interval = 25000; 50162306a36Sopenharmony_ci qopt->num_entries = 3; 50262306a36Sopenharmony_ci delay_base_time(adapter, qopt, 11); 50362306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 50462306a36Sopenharmony_ci goto failed; 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci /* change to multiple of cycle time */ 50762306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 50862306a36Sopenharmony_ci qopt->cycle_time = 200000; 50962306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x79; 51062306a36Sopenharmony_ci qopt->entries[0].interval = 50000; 51162306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x7A; 51262306a36Sopenharmony_ci qopt->entries[1].interval = 150000; 51362306a36Sopenharmony_ci qopt->num_entries = 2; 51462306a36Sopenharmony_ci delay_base_time(adapter, qopt, 11); 51562306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 51662306a36Sopenharmony_ci goto failed; 51762306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 51862306a36Sopenharmony_ci qopt->cycle_time = 1000000; 51962306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x7B; 52062306a36Sopenharmony_ci qopt->entries[0].interval = 125000; 52162306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x7C; 52262306a36Sopenharmony_ci qopt->entries[1].interval = 250000; 52362306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0x7D; 52462306a36Sopenharmony_ci qopt->entries[2].interval = 375000; 52562306a36Sopenharmony_ci qopt->entries[3].gate_mask = 0x7E; 52662306a36Sopenharmony_ci qopt->entries[3].interval = 250000; 52762306a36Sopenharmony_ci qopt->num_entries = 4; 52862306a36Sopenharmony_ci delay_base_time(adapter, qopt, 3); 52962306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 53062306a36Sopenharmony_ci goto failed; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci /* change to shorter cycle time */ 53362306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 53462306a36Sopenharmony_ci qopt->cycle_time = 333333; 53562306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x8F; 53662306a36Sopenharmony_ci qopt->entries[0].interval = 166666; 53762306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x80; 53862306a36Sopenharmony_ci qopt->entries[1].interval = 166667; 53962306a36Sopenharmony_ci qopt->num_entries = 2; 54062306a36Sopenharmony_ci delay_base_time(adapter, qopt, 11); 54162306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 54262306a36Sopenharmony_ci goto failed; 54362306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 54462306a36Sopenharmony_ci qopt->cycle_time = 62500; 54562306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x81; 54662306a36Sopenharmony_ci qopt->entries[0].interval = 31250; 54762306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x82; 54862306a36Sopenharmony_ci qopt->entries[1].interval = 15625; 54962306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0x83; 55062306a36Sopenharmony_ci qopt->entries[2].interval = 15625; 55162306a36Sopenharmony_ci qopt->num_entries = 3; 55262306a36Sopenharmony_ci delay_base_time(adapter, qopt, 1); 55362306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 55462306a36Sopenharmony_ci goto failed; 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci /* change to longer cycle time */ 55762306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 55862306a36Sopenharmony_ci qopt->cycle_time = 400000; 55962306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x84; 56062306a36Sopenharmony_ci qopt->entries[0].interval = 100000; 56162306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x85; 56262306a36Sopenharmony_ci qopt->entries[1].interval = 100000; 56362306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0x86; 56462306a36Sopenharmony_ci qopt->entries[2].interval = 100000; 56562306a36Sopenharmony_ci qopt->entries[3].gate_mask = 0x87; 56662306a36Sopenharmony_ci qopt->entries[3].interval = 100000; 56762306a36Sopenharmony_ci qopt->num_entries = 4; 56862306a36Sopenharmony_ci delay_base_time(adapter, qopt, 7); 56962306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 57062306a36Sopenharmony_ci goto failed; 57162306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 57262306a36Sopenharmony_ci qopt->cycle_time = 1700000; 57362306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x88; 57462306a36Sopenharmony_ci qopt->entries[0].interval = 200000; 57562306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x89; 57662306a36Sopenharmony_ci qopt->entries[1].interval = 300000; 57762306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0x8A; 57862306a36Sopenharmony_ci qopt->entries[2].interval = 600000; 57962306a36Sopenharmony_ci qopt->entries[3].gate_mask = 0x8B; 58062306a36Sopenharmony_ci qopt->entries[3].interval = 100000; 58162306a36Sopenharmony_ci qopt->entries[4].gate_mask = 0x8C; 58262306a36Sopenharmony_ci qopt->entries[4].interval = 500000; 58362306a36Sopenharmony_ci qopt->num_entries = 5; 58462306a36Sopenharmony_ci delay_base_time(adapter, qopt, 6); 58562306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 58662306a36Sopenharmony_ci goto failed; 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci if (!disable_taprio(adapter)) 58962306a36Sopenharmony_ci goto failed; 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci kfree(qopt); 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci return true; 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_cifailed: 59662306a36Sopenharmony_ci disable_taprio(adapter); 59762306a36Sopenharmony_ci kfree(qopt); 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci return false; 60062306a36Sopenharmony_ci} 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_cistatic bool tsnep_test_taprio_extension(struct tsnep_adapter *adapter) 60362306a36Sopenharmony_ci{ 60462306a36Sopenharmony_ci struct tc_taprio_qopt_offload *qopt; 60562306a36Sopenharmony_ci int i; 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL); 60862306a36Sopenharmony_ci if (!qopt) 60962306a36Sopenharmony_ci return false; 61062306a36Sopenharmony_ci for (i = 0; i < 255; i++) 61162306a36Sopenharmony_ci qopt->entries[i].command = TC_TAPRIO_CMD_SET_GATES; 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci qopt->cmd = TAPRIO_CMD_REPLACE; 61462306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 61562306a36Sopenharmony_ci qopt->cycle_time = 100000; 61662306a36Sopenharmony_ci qopt->cycle_time_extension = 50000; 61762306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x90; 61862306a36Sopenharmony_ci qopt->entries[0].interval = 20000; 61962306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x91; 62062306a36Sopenharmony_ci qopt->entries[1].interval = 80000; 62162306a36Sopenharmony_ci qopt->num_entries = 2; 62262306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 62362306a36Sopenharmony_ci goto failed; 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci /* change to different phase */ 62662306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 50000); 62762306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x92; 62862306a36Sopenharmony_ci qopt->entries[0].interval = 33000; 62962306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x93; 63062306a36Sopenharmony_ci qopt->entries[1].interval = 67000; 63162306a36Sopenharmony_ci qopt->num_entries = 2; 63262306a36Sopenharmony_ci delay_base_time(adapter, qopt, 2); 63362306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 63462306a36Sopenharmony_ci goto failed; 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ci /* change to different phase and longer cycle time */ 63762306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 63862306a36Sopenharmony_ci qopt->cycle_time = 1000000; 63962306a36Sopenharmony_ci qopt->cycle_time_extension = 700000; 64062306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x94; 64162306a36Sopenharmony_ci qopt->entries[0].interval = 400000; 64262306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x95; 64362306a36Sopenharmony_ci qopt->entries[1].interval = 600000; 64462306a36Sopenharmony_ci qopt->num_entries = 2; 64562306a36Sopenharmony_ci delay_base_time(adapter, qopt, 7); 64662306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 64762306a36Sopenharmony_ci goto failed; 64862306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 700000); 64962306a36Sopenharmony_ci qopt->cycle_time = 2000000; 65062306a36Sopenharmony_ci qopt->cycle_time_extension = 1900000; 65162306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x96; 65262306a36Sopenharmony_ci qopt->entries[0].interval = 400000; 65362306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x97; 65462306a36Sopenharmony_ci qopt->entries[1].interval = 1600000; 65562306a36Sopenharmony_ci qopt->num_entries = 2; 65662306a36Sopenharmony_ci delay_base_time(adapter, qopt, 9); 65762306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 65862306a36Sopenharmony_ci goto failed; 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci /* change to different phase and shorter cycle time */ 66162306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 66262306a36Sopenharmony_ci qopt->cycle_time = 1500000; 66362306a36Sopenharmony_ci qopt->cycle_time_extension = 700000; 66462306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x98; 66562306a36Sopenharmony_ci qopt->entries[0].interval = 400000; 66662306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x99; 66762306a36Sopenharmony_ci qopt->entries[1].interval = 600000; 66862306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0x9A; 66962306a36Sopenharmony_ci qopt->entries[2].interval = 500000; 67062306a36Sopenharmony_ci qopt->num_entries = 3; 67162306a36Sopenharmony_ci delay_base_time(adapter, qopt, 3); 67262306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 67362306a36Sopenharmony_ci goto failed; 67462306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 100000); 67562306a36Sopenharmony_ci qopt->cycle_time = 500000; 67662306a36Sopenharmony_ci qopt->cycle_time_extension = 300000; 67762306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0x9B; 67862306a36Sopenharmony_ci qopt->entries[0].interval = 150000; 67962306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0x9C; 68062306a36Sopenharmony_ci qopt->entries[1].interval = 350000; 68162306a36Sopenharmony_ci qopt->num_entries = 2; 68262306a36Sopenharmony_ci delay_base_time(adapter, qopt, 9); 68362306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 68462306a36Sopenharmony_ci goto failed; 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci /* change to different cycle time */ 68762306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 68862306a36Sopenharmony_ci qopt->cycle_time = 1000000; 68962306a36Sopenharmony_ci qopt->cycle_time_extension = 700000; 69062306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0xAD; 69162306a36Sopenharmony_ci qopt->entries[0].interval = 400000; 69262306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0xAE; 69362306a36Sopenharmony_ci qopt->entries[1].interval = 300000; 69462306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0xAF; 69562306a36Sopenharmony_ci qopt->entries[2].interval = 300000; 69662306a36Sopenharmony_ci qopt->num_entries = 3; 69762306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 69862306a36Sopenharmony_ci goto failed; 69962306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 70062306a36Sopenharmony_ci qopt->cycle_time = 400000; 70162306a36Sopenharmony_ci qopt->cycle_time_extension = 100000; 70262306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0xA0; 70362306a36Sopenharmony_ci qopt->entries[0].interval = 200000; 70462306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0xA1; 70562306a36Sopenharmony_ci qopt->entries[1].interval = 200000; 70662306a36Sopenharmony_ci qopt->num_entries = 2; 70762306a36Sopenharmony_ci delay_base_time(adapter, qopt, 19); 70862306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 70962306a36Sopenharmony_ci goto failed; 71062306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 71162306a36Sopenharmony_ci qopt->cycle_time = 500000; 71262306a36Sopenharmony_ci qopt->cycle_time_extension = 499999; 71362306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0xB2; 71462306a36Sopenharmony_ci qopt->entries[0].interval = 100000; 71562306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0xB3; 71662306a36Sopenharmony_ci qopt->entries[1].interval = 100000; 71762306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0xB4; 71862306a36Sopenharmony_ci qopt->entries[2].interval = 100000; 71962306a36Sopenharmony_ci qopt->entries[3].gate_mask = 0xB5; 72062306a36Sopenharmony_ci qopt->entries[3].interval = 200000; 72162306a36Sopenharmony_ci qopt->num_entries = 4; 72262306a36Sopenharmony_ci delay_base_time(adapter, qopt, 19); 72362306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 72462306a36Sopenharmony_ci goto failed; 72562306a36Sopenharmony_ci qopt->base_time = ktime_set(0, 0); 72662306a36Sopenharmony_ci qopt->cycle_time = 6000000; 72762306a36Sopenharmony_ci qopt->cycle_time_extension = 5999999; 72862306a36Sopenharmony_ci qopt->entries[0].gate_mask = 0xC6; 72962306a36Sopenharmony_ci qopt->entries[0].interval = 1000000; 73062306a36Sopenharmony_ci qopt->entries[1].gate_mask = 0xC7; 73162306a36Sopenharmony_ci qopt->entries[1].interval = 1000000; 73262306a36Sopenharmony_ci qopt->entries[2].gate_mask = 0xC8; 73362306a36Sopenharmony_ci qopt->entries[2].interval = 1000000; 73462306a36Sopenharmony_ci qopt->entries[3].gate_mask = 0xC9; 73562306a36Sopenharmony_ci qopt->entries[3].interval = 1500000; 73662306a36Sopenharmony_ci qopt->entries[4].gate_mask = 0xCA; 73762306a36Sopenharmony_ci qopt->entries[4].interval = 1500000; 73862306a36Sopenharmony_ci qopt->num_entries = 5; 73962306a36Sopenharmony_ci delay_base_time(adapter, qopt, 1); 74062306a36Sopenharmony_ci if (!enable_check_taprio(adapter, qopt, 100)) 74162306a36Sopenharmony_ci goto failed; 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_ci if (!disable_taprio(adapter)) 74462306a36Sopenharmony_ci goto failed; 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci kfree(qopt); 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci return true; 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_cifailed: 75162306a36Sopenharmony_ci disable_taprio(adapter); 75262306a36Sopenharmony_ci kfree(qopt); 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci return false; 75562306a36Sopenharmony_ci} 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ciint tsnep_ethtool_get_test_count(void) 75862306a36Sopenharmony_ci{ 75962306a36Sopenharmony_ci return TSNEP_TEST_COUNT; 76062306a36Sopenharmony_ci} 76162306a36Sopenharmony_ci 76262306a36Sopenharmony_civoid tsnep_ethtool_get_test_strings(u8 *data) 76362306a36Sopenharmony_ci{ 76462306a36Sopenharmony_ci memcpy(data, tsnep_test_strings, sizeof(tsnep_test_strings)); 76562306a36Sopenharmony_ci} 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_civoid tsnep_ethtool_self_test(struct net_device *netdev, 76862306a36Sopenharmony_ci struct ethtool_test *eth_test, u64 *data) 76962306a36Sopenharmony_ci{ 77062306a36Sopenharmony_ci struct tsnep_adapter *adapter = netdev_priv(netdev); 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_ci eth_test->len = TSNEP_TEST_COUNT; 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci if (eth_test->flags != ETH_TEST_FL_OFFLINE) { 77562306a36Sopenharmony_ci /* no tests are done online */ 77662306a36Sopenharmony_ci data[TSNEP_TEST_ENABLE] = 0; 77762306a36Sopenharmony_ci data[TSNEP_TEST_TAPRIO] = 0; 77862306a36Sopenharmony_ci data[TSNEP_TEST_TAPRIO_CHANGE] = 0; 77962306a36Sopenharmony_ci data[TSNEP_TEST_TAPRIO_EXTENSION] = 0; 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci return; 78262306a36Sopenharmony_ci } 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_ci if (tsnep_test_gc_enable(adapter)) { 78562306a36Sopenharmony_ci data[TSNEP_TEST_ENABLE] = 0; 78662306a36Sopenharmony_ci } else { 78762306a36Sopenharmony_ci eth_test->flags |= ETH_TEST_FL_FAILED; 78862306a36Sopenharmony_ci data[TSNEP_TEST_ENABLE] = 1; 78962306a36Sopenharmony_ci } 79062306a36Sopenharmony_ci 79162306a36Sopenharmony_ci if (tsnep_test_taprio(adapter)) { 79262306a36Sopenharmony_ci data[TSNEP_TEST_TAPRIO] = 0; 79362306a36Sopenharmony_ci } else { 79462306a36Sopenharmony_ci eth_test->flags |= ETH_TEST_FL_FAILED; 79562306a36Sopenharmony_ci data[TSNEP_TEST_TAPRIO] = 1; 79662306a36Sopenharmony_ci } 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci if (tsnep_test_taprio_change(adapter)) { 79962306a36Sopenharmony_ci data[TSNEP_TEST_TAPRIO_CHANGE] = 0; 80062306a36Sopenharmony_ci } else { 80162306a36Sopenharmony_ci eth_test->flags |= ETH_TEST_FL_FAILED; 80262306a36Sopenharmony_ci data[TSNEP_TEST_TAPRIO_CHANGE] = 1; 80362306a36Sopenharmony_ci } 80462306a36Sopenharmony_ci 80562306a36Sopenharmony_ci if (tsnep_test_taprio_extension(adapter)) { 80662306a36Sopenharmony_ci data[TSNEP_TEST_TAPRIO_EXTENSION] = 0; 80762306a36Sopenharmony_ci } else { 80862306a36Sopenharmony_ci eth_test->flags |= ETH_TEST_FL_FAILED; 80962306a36Sopenharmony_ci data[TSNEP_TEST_TAPRIO_EXTENSION] = 1; 81062306a36Sopenharmony_ci } 81162306a36Sopenharmony_ci} 812