812 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (C) 2021 Gerhard Engleder <gerhard@engleder-embedded.com> */3 4#include "tsnep.h"5 6#include <net/pkt_sched.h>7 8enum tsnep_test {9 TSNEP_TEST_ENABLE = 0,10 TSNEP_TEST_TAPRIO,11 TSNEP_TEST_TAPRIO_CHANGE,12 TSNEP_TEST_TAPRIO_EXTENSION,13};14 15static const char tsnep_test_strings[][ETH_GSTRING_LEN] = {16 "Enable timeout (offline)",17 "TAPRIO (offline)",18 "TAPRIO change (offline)",19 "TAPRIO extension (offline)",20};21 22#define TSNEP_TEST_COUNT (sizeof(tsnep_test_strings) / ETH_GSTRING_LEN)23 24static bool enable_gc_timeout(struct tsnep_adapter *adapter)25{26 iowrite8(TSNEP_GC_ENABLE_TIMEOUT, adapter->addr + TSNEP_GC);27 if (!(ioread32(adapter->addr + TSNEP_GC) & TSNEP_GC_TIMEOUT_ACTIVE))28 return false;29 30 return true;31}32 33static bool gc_timeout_signaled(struct tsnep_adapter *adapter)34{35 if (ioread32(adapter->addr + TSNEP_GC) & TSNEP_GC_TIMEOUT_SIGNAL)36 return true;37 38 return false;39}40 41static bool ack_gc_timeout(struct tsnep_adapter *adapter)42{43 iowrite8(TSNEP_GC_ENABLE_TIMEOUT, adapter->addr + TSNEP_GC);44 if (ioread32(adapter->addr + TSNEP_GC) &45 (TSNEP_GC_TIMEOUT_ACTIVE | TSNEP_GC_TIMEOUT_SIGNAL))46 return false;47 return true;48}49 50static bool enable_gc(struct tsnep_adapter *adapter, bool a)51{52 u8 enable;53 u8 active;54 55 if (a) {56 enable = TSNEP_GC_ENABLE_A;57 active = TSNEP_GC_ACTIVE_A;58 } else {59 enable = TSNEP_GC_ENABLE_B;60 active = TSNEP_GC_ACTIVE_B;61 }62 63 iowrite8(enable, adapter->addr + TSNEP_GC);64 if (!(ioread32(adapter->addr + TSNEP_GC) & active))65 return false;66 67 return true;68}69 70static bool disable_gc(struct tsnep_adapter *adapter)71{72 iowrite8(TSNEP_GC_DISABLE, adapter->addr + TSNEP_GC);73 if (ioread32(adapter->addr + TSNEP_GC) &74 (TSNEP_GC_ACTIVE_A | TSNEP_GC_ACTIVE_B))75 return false;76 77 return true;78}79 80static bool gc_delayed_enable(struct tsnep_adapter *adapter, bool a, int delay)81{82 u64 before, after;83 u32 time;84 bool enabled;85 86 if (!disable_gc(adapter))87 return false;88 89 before = ktime_get_ns();90 91 if (!enable_gc_timeout(adapter))92 return false;93 94 /* for start time after timeout, the timeout can guarantee, that enable95 * is blocked if too late96 */97 time = ioread32(adapter->addr + ECM_SYSTEM_TIME_LOW);98 time += TSNEP_GC_TIMEOUT;99 iowrite32(time, adapter->addr + TSNEP_GC_TIME);100 101 ndelay(delay);102 103 enabled = enable_gc(adapter, a);104 after = ktime_get_ns();105 106 if (delay > TSNEP_GC_TIMEOUT) {107 /* timeout must have blocked enable */108 if (enabled)109 return false;110 } else if ((after - before) < TSNEP_GC_TIMEOUT * 14 / 16) {111 /* timeout must not have blocked enable */112 if (!enabled)113 return false;114 }115 116 if (enabled) {117 if (gc_timeout_signaled(adapter))118 return false;119 } else {120 if (!gc_timeout_signaled(adapter))121 return false;122 if (!ack_gc_timeout(adapter))123 return false;124 }125 126 if (!disable_gc(adapter))127 return false;128 129 return true;130}131 132static bool tsnep_test_gc_enable(struct tsnep_adapter *adapter)133{134 int i;135 136 iowrite32(0x80000001, adapter->addr + TSNEP_GCL_A + 0);137 iowrite32(100000, adapter->addr + TSNEP_GCL_A + 4);138 139 for (i = 0; i < 200000; i += 100) {140 if (!gc_delayed_enable(adapter, true, i))141 return false;142 }143 144 iowrite32(0x80000001, adapter->addr + TSNEP_GCL_B + 0);145 iowrite32(100000, adapter->addr + TSNEP_GCL_B + 4);146 147 for (i = 0; i < 200000; i += 100) {148 if (!gc_delayed_enable(adapter, false, i))149 return false;150 }151 152 return true;153}154 155static void delay_base_time(struct tsnep_adapter *adapter,156 struct tc_taprio_qopt_offload *qopt, s64 ms)157{158 u64 system_time;159 u64 base_time = ktime_to_ns(qopt->base_time);160 u64 n;161 162 tsnep_get_system_time(adapter, &system_time);163 system_time += ms * 1000000;164 n = div64_u64(system_time - base_time, qopt->cycle_time);165 166 qopt->base_time = ktime_add_ns(qopt->base_time,167 (n + 1) * qopt->cycle_time);168}169 170static void get_gate_state(struct tsnep_adapter *adapter, u32 *gc, u32 *gc_time,171 u64 *system_time)172{173 u32 time_high_before;174 u32 time_low;175 u32 time_high;176 u32 gc_time_before;177 178 time_high = ioread32(adapter->addr + ECM_SYSTEM_TIME_HIGH);179 *gc_time = ioread32(adapter->addr + TSNEP_GC_TIME);180 do {181 time_low = ioread32(adapter->addr + ECM_SYSTEM_TIME_LOW);182 *gc = ioread32(adapter->addr + TSNEP_GC);183 184 gc_time_before = *gc_time;185 *gc_time = ioread32(adapter->addr + TSNEP_GC_TIME);186 time_high_before = time_high;187 time_high = ioread32(adapter->addr + ECM_SYSTEM_TIME_HIGH);188 } while ((time_high != time_high_before) ||189 (*gc_time != gc_time_before));190 191 *system_time = (((u64)time_high) << 32) | ((u64)time_low);192}193 194static int get_operation(struct tsnep_gcl *gcl, u64 system_time, u64 *next)195{196 u64 n = div64_u64(system_time - gcl->base_time, gcl->cycle_time);197 u64 cycle_start = gcl->base_time + gcl->cycle_time * n;198 int i;199 200 *next = cycle_start;201 for (i = 0; i < gcl->count; i++) {202 *next += gcl->operation[i].interval;203 if (*next > system_time)204 break;205 }206 207 return i;208}209 210static bool check_gate(struct tsnep_adapter *adapter)211{212 u32 gc_time;213 u32 gc;214 u64 system_time;215 struct tsnep_gcl *curr;216 struct tsnep_gcl *prev;217 u64 next_time;218 u8 gate_open;219 u8 next_gate_open;220 221 get_gate_state(adapter, &gc, &gc_time, &system_time);222 223 if (gc & TSNEP_GC_ACTIVE_A) {224 curr = &adapter->gcl[0];225 prev = &adapter->gcl[1];226 } else if (gc & TSNEP_GC_ACTIVE_B) {227 curr = &adapter->gcl[1];228 prev = &adapter->gcl[0];229 } else {230 return false;231 }232 if (curr->start_time <= system_time) {233 /* GCL is already active */234 int index;235 236 index = get_operation(curr, system_time, &next_time);237 gate_open = curr->operation[index].properties & TSNEP_GCL_MASK;238 if (index == curr->count - 1)239 index = 0;240 else241 index++;242 next_gate_open =243 curr->operation[index].properties & TSNEP_GCL_MASK;244 } else if (curr->change) {245 /* operation of previous GCL is active */246 int index;247 u64 start_before;248 u64 n;249 250 index = get_operation(prev, system_time, &next_time);251 next_time = curr->start_time;252 start_before = prev->base_time;253 n = div64_u64(curr->start_time - start_before,254 prev->cycle_time);255 start_before += n * prev->cycle_time;256 if (curr->start_time == start_before)257 start_before -= prev->cycle_time;258 if (((start_before + prev->cycle_time_extension) >=259 curr->start_time) &&260 (curr->start_time - prev->cycle_time_extension <=261 system_time)) {262 /* extend */263 index = prev->count - 1;264 }265 gate_open = prev->operation[index].properties & TSNEP_GCL_MASK;266 next_gate_open =267 curr->operation[0].properties & TSNEP_GCL_MASK;268 } else {269 /* GCL is waiting for start */270 next_time = curr->start_time;271 gate_open = 0xFF;272 next_gate_open = curr->operation[0].properties & TSNEP_GCL_MASK;273 }274 275 if (gc_time != (next_time & 0xFFFFFFFF)) {276 dev_err(&adapter->pdev->dev, "gate control time 0x%x!=0x%llx\n",277 gc_time, next_time);278 return false;279 }280 if (((gc & TSNEP_GC_OPEN) >> TSNEP_GC_OPEN_SHIFT) != gate_open) {281 dev_err(&adapter->pdev->dev,282 "gate control open 0x%02x!=0x%02x\n",283 ((gc & TSNEP_GC_OPEN) >> TSNEP_GC_OPEN_SHIFT),284 gate_open);285 return false;286 }287 if (((gc & TSNEP_GC_NEXT_OPEN) >> TSNEP_GC_NEXT_OPEN_SHIFT) !=288 next_gate_open) {289 dev_err(&adapter->pdev->dev,290 "gate control next open 0x%02x!=0x%02x\n",291 ((gc & TSNEP_GC_NEXT_OPEN) >> TSNEP_GC_NEXT_OPEN_SHIFT),292 next_gate_open);293 return false;294 }295 296 return true;297}298 299static bool check_gate_duration(struct tsnep_adapter *adapter, s64 ms)300{301 ktime_t start = ktime_get();302 303 do {304 if (!check_gate(adapter))305 return false;306 } while (ktime_ms_delta(ktime_get(), start) < ms);307 308 return true;309}310 311static bool enable_check_taprio(struct tsnep_adapter *adapter,312 struct tc_taprio_qopt_offload *qopt, s64 ms)313{314 int retval;315 316 retval = tsnep_tc_setup(adapter->netdev, TC_SETUP_QDISC_TAPRIO, qopt);317 if (retval)318 return false;319 320 if (!check_gate_duration(adapter, ms))321 return false;322 323 return true;324}325 326static bool disable_taprio(struct tsnep_adapter *adapter)327{328 struct tc_taprio_qopt_offload qopt;329 int retval;330 331 memset(&qopt, 0, sizeof(qopt));332 qopt.cmd = TAPRIO_CMD_DESTROY;333 retval = tsnep_tc_setup(adapter->netdev, TC_SETUP_QDISC_TAPRIO, &qopt);334 if (retval)335 return false;336 337 return true;338}339 340static bool run_taprio(struct tsnep_adapter *adapter,341 struct tc_taprio_qopt_offload *qopt, s64 ms)342{343 if (!enable_check_taprio(adapter, qopt, ms))344 return false;345 346 if (!disable_taprio(adapter))347 return false;348 349 return true;350}351 352static bool tsnep_test_taprio(struct tsnep_adapter *adapter)353{354 struct tc_taprio_qopt_offload *qopt;355 int i;356 357 qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL);358 if (!qopt)359 return false;360 for (i = 0; i < 255; i++)361 qopt->entries[i].command = TC_TAPRIO_CMD_SET_GATES;362 363 qopt->cmd = TAPRIO_CMD_REPLACE;364 qopt->base_time = ktime_set(0, 0);365 qopt->cycle_time = 1500000;366 qopt->cycle_time_extension = 0;367 qopt->entries[0].gate_mask = 0x02;368 qopt->entries[0].interval = 200000;369 qopt->entries[1].gate_mask = 0x03;370 qopt->entries[1].interval = 800000;371 qopt->entries[2].gate_mask = 0x07;372 qopt->entries[2].interval = 240000;373 qopt->entries[3].gate_mask = 0x01;374 qopt->entries[3].interval = 80000;375 qopt->entries[4].gate_mask = 0x04;376 qopt->entries[4].interval = 70000;377 qopt->entries[5].gate_mask = 0x06;378 qopt->entries[5].interval = 60000;379 qopt->entries[6].gate_mask = 0x0F;380 qopt->entries[6].interval = 50000;381 qopt->num_entries = 7;382 if (!run_taprio(adapter, qopt, 100))383 goto failed;384 385 qopt->cmd = TAPRIO_CMD_REPLACE;386 qopt->base_time = ktime_set(0, 0);387 qopt->cycle_time = 411854;388 qopt->cycle_time_extension = 0;389 qopt->entries[0].gate_mask = 0x17;390 qopt->entries[0].interval = 23842;391 qopt->entries[1].gate_mask = 0x16;392 qopt->entries[1].interval = 13482;393 qopt->entries[2].gate_mask = 0x15;394 qopt->entries[2].interval = 49428;395 qopt->entries[3].gate_mask = 0x14;396 qopt->entries[3].interval = 38189;397 qopt->entries[4].gate_mask = 0x13;398 qopt->entries[4].interval = 92321;399 qopt->entries[5].gate_mask = 0x12;400 qopt->entries[5].interval = 71239;401 qopt->entries[6].gate_mask = 0x11;402 qopt->entries[6].interval = 69932;403 qopt->entries[7].gate_mask = 0x10;404 qopt->entries[7].interval = 53421;405 qopt->num_entries = 8;406 if (!run_taprio(adapter, qopt, 100))407 goto failed;408 409 qopt->cmd = TAPRIO_CMD_REPLACE;410 qopt->base_time = ktime_set(0, 0);411 delay_base_time(adapter, qopt, 12);412 qopt->cycle_time = 125000;413 qopt->cycle_time_extension = 0;414 qopt->entries[0].gate_mask = 0x27;415 qopt->entries[0].interval = 15000;416 qopt->entries[1].gate_mask = 0x26;417 qopt->entries[1].interval = 15000;418 qopt->entries[2].gate_mask = 0x25;419 qopt->entries[2].interval = 12500;420 qopt->entries[3].gate_mask = 0x24;421 qopt->entries[3].interval = 17500;422 qopt->entries[4].gate_mask = 0x23;423 qopt->entries[4].interval = 10000;424 qopt->entries[5].gate_mask = 0x22;425 qopt->entries[5].interval = 11000;426 qopt->entries[6].gate_mask = 0x21;427 qopt->entries[6].interval = 9000;428 qopt->entries[7].gate_mask = 0x20;429 qopt->entries[7].interval = 10000;430 qopt->entries[8].gate_mask = 0x20;431 qopt->entries[8].interval = 12500;432 qopt->entries[9].gate_mask = 0x20;433 qopt->entries[9].interval = 12500;434 qopt->num_entries = 10;435 if (!run_taprio(adapter, qopt, 100))436 goto failed;437 438 kfree(qopt);439 440 return true;441 442failed:443 disable_taprio(adapter);444 kfree(qopt);445 446 return false;447}448 449static bool tsnep_test_taprio_change(struct tsnep_adapter *adapter)450{451 struct tc_taprio_qopt_offload *qopt;452 int i;453 454 qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL);455 if (!qopt)456 return false;457 for (i = 0; i < 255; i++)458 qopt->entries[i].command = TC_TAPRIO_CMD_SET_GATES;459 460 qopt->cmd = TAPRIO_CMD_REPLACE;461 qopt->base_time = ktime_set(0, 0);462 qopt->cycle_time = 100000;463 qopt->cycle_time_extension = 0;464 qopt->entries[0].gate_mask = 0x30;465 qopt->entries[0].interval = 20000;466 qopt->entries[1].gate_mask = 0x31;467 qopt->entries[1].interval = 80000;468 qopt->num_entries = 2;469 if (!enable_check_taprio(adapter, qopt, 100))470 goto failed;471 472 /* change to identical */473 if (!enable_check_taprio(adapter, qopt, 100))474 goto failed;475 delay_base_time(adapter, qopt, 17);476 if (!enable_check_taprio(adapter, qopt, 100))477 goto failed;478 479 /* change to same cycle time */480 qopt->base_time = ktime_set(0, 0);481 qopt->entries[0].gate_mask = 0x42;482 qopt->entries[1].gate_mask = 0x43;483 delay_base_time(adapter, qopt, 2);484 if (!enable_check_taprio(adapter, qopt, 100))485 goto failed;486 qopt->base_time = ktime_set(0, 0);487 qopt->entries[0].gate_mask = 0x54;488 qopt->entries[0].interval = 33333;489 qopt->entries[1].gate_mask = 0x55;490 qopt->entries[1].interval = 66667;491 delay_base_time(adapter, qopt, 23);492 if (!enable_check_taprio(adapter, qopt, 100))493 goto failed;494 qopt->base_time = ktime_set(0, 0);495 qopt->entries[0].gate_mask = 0x66;496 qopt->entries[0].interval = 50000;497 qopt->entries[1].gate_mask = 0x67;498 qopt->entries[1].interval = 25000;499 qopt->entries[2].gate_mask = 0x68;500 qopt->entries[2].interval = 25000;501 qopt->num_entries = 3;502 delay_base_time(adapter, qopt, 11);503 if (!enable_check_taprio(adapter, qopt, 100))504 goto failed;505 506 /* change to multiple of cycle time */507 qopt->base_time = ktime_set(0, 0);508 qopt->cycle_time = 200000;509 qopt->entries[0].gate_mask = 0x79;510 qopt->entries[0].interval = 50000;511 qopt->entries[1].gate_mask = 0x7A;512 qopt->entries[1].interval = 150000;513 qopt->num_entries = 2;514 delay_base_time(adapter, qopt, 11);515 if (!enable_check_taprio(adapter, qopt, 100))516 goto failed;517 qopt->base_time = ktime_set(0, 0);518 qopt->cycle_time = 1000000;519 qopt->entries[0].gate_mask = 0x7B;520 qopt->entries[0].interval = 125000;521 qopt->entries[1].gate_mask = 0x7C;522 qopt->entries[1].interval = 250000;523 qopt->entries[2].gate_mask = 0x7D;524 qopt->entries[2].interval = 375000;525 qopt->entries[3].gate_mask = 0x7E;526 qopt->entries[3].interval = 250000;527 qopt->num_entries = 4;528 delay_base_time(adapter, qopt, 3);529 if (!enable_check_taprio(adapter, qopt, 100))530 goto failed;531 532 /* change to shorter cycle time */533 qopt->base_time = ktime_set(0, 0);534 qopt->cycle_time = 333333;535 qopt->entries[0].gate_mask = 0x8F;536 qopt->entries[0].interval = 166666;537 qopt->entries[1].gate_mask = 0x80;538 qopt->entries[1].interval = 166667;539 qopt->num_entries = 2;540 delay_base_time(adapter, qopt, 11);541 if (!enable_check_taprio(adapter, qopt, 100))542 goto failed;543 qopt->base_time = ktime_set(0, 0);544 qopt->cycle_time = 62500;545 qopt->entries[0].gate_mask = 0x81;546 qopt->entries[0].interval = 31250;547 qopt->entries[1].gate_mask = 0x82;548 qopt->entries[1].interval = 15625;549 qopt->entries[2].gate_mask = 0x83;550 qopt->entries[2].interval = 15625;551 qopt->num_entries = 3;552 delay_base_time(adapter, qopt, 1);553 if (!enable_check_taprio(adapter, qopt, 100))554 goto failed;555 556 /* change to longer cycle time */557 qopt->base_time = ktime_set(0, 0);558 qopt->cycle_time = 400000;559 qopt->entries[0].gate_mask = 0x84;560 qopt->entries[0].interval = 100000;561 qopt->entries[1].gate_mask = 0x85;562 qopt->entries[1].interval = 100000;563 qopt->entries[2].gate_mask = 0x86;564 qopt->entries[2].interval = 100000;565 qopt->entries[3].gate_mask = 0x87;566 qopt->entries[3].interval = 100000;567 qopt->num_entries = 4;568 delay_base_time(adapter, qopt, 7);569 if (!enable_check_taprio(adapter, qopt, 100))570 goto failed;571 qopt->base_time = ktime_set(0, 0);572 qopt->cycle_time = 1700000;573 qopt->entries[0].gate_mask = 0x88;574 qopt->entries[0].interval = 200000;575 qopt->entries[1].gate_mask = 0x89;576 qopt->entries[1].interval = 300000;577 qopt->entries[2].gate_mask = 0x8A;578 qopt->entries[2].interval = 600000;579 qopt->entries[3].gate_mask = 0x8B;580 qopt->entries[3].interval = 100000;581 qopt->entries[4].gate_mask = 0x8C;582 qopt->entries[4].interval = 500000;583 qopt->num_entries = 5;584 delay_base_time(adapter, qopt, 6);585 if (!enable_check_taprio(adapter, qopt, 100))586 goto failed;587 588 if (!disable_taprio(adapter))589 goto failed;590 591 kfree(qopt);592 593 return true;594 595failed:596 disable_taprio(adapter);597 kfree(qopt);598 599 return false;600}601 602static bool tsnep_test_taprio_extension(struct tsnep_adapter *adapter)603{604 struct tc_taprio_qopt_offload *qopt;605 int i;606 607 qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL);608 if (!qopt)609 return false;610 for (i = 0; i < 255; i++)611 qopt->entries[i].command = TC_TAPRIO_CMD_SET_GATES;612 613 qopt->cmd = TAPRIO_CMD_REPLACE;614 qopt->base_time = ktime_set(0, 0);615 qopt->cycle_time = 100000;616 qopt->cycle_time_extension = 50000;617 qopt->entries[0].gate_mask = 0x90;618 qopt->entries[0].interval = 20000;619 qopt->entries[1].gate_mask = 0x91;620 qopt->entries[1].interval = 80000;621 qopt->num_entries = 2;622 if (!enable_check_taprio(adapter, qopt, 100))623 goto failed;624 625 /* change to different phase */626 qopt->base_time = ktime_set(0, 50000);627 qopt->entries[0].gate_mask = 0x92;628 qopt->entries[0].interval = 33000;629 qopt->entries[1].gate_mask = 0x93;630 qopt->entries[1].interval = 67000;631 qopt->num_entries = 2;632 delay_base_time(adapter, qopt, 2);633 if (!enable_check_taprio(adapter, qopt, 100))634 goto failed;635 636 /* change to different phase and longer cycle time */637 qopt->base_time = ktime_set(0, 0);638 qopt->cycle_time = 1000000;639 qopt->cycle_time_extension = 700000;640 qopt->entries[0].gate_mask = 0x94;641 qopt->entries[0].interval = 400000;642 qopt->entries[1].gate_mask = 0x95;643 qopt->entries[1].interval = 600000;644 qopt->num_entries = 2;645 delay_base_time(adapter, qopt, 7);646 if (!enable_check_taprio(adapter, qopt, 100))647 goto failed;648 qopt->base_time = ktime_set(0, 700000);649 qopt->cycle_time = 2000000;650 qopt->cycle_time_extension = 1900000;651 qopt->entries[0].gate_mask = 0x96;652 qopt->entries[0].interval = 400000;653 qopt->entries[1].gate_mask = 0x97;654 qopt->entries[1].interval = 1600000;655 qopt->num_entries = 2;656 delay_base_time(adapter, qopt, 9);657 if (!enable_check_taprio(adapter, qopt, 100))658 goto failed;659 660 /* change to different phase and shorter cycle time */661 qopt->base_time = ktime_set(0, 0);662 qopt->cycle_time = 1500000;663 qopt->cycle_time_extension = 700000;664 qopt->entries[0].gate_mask = 0x98;665 qopt->entries[0].interval = 400000;666 qopt->entries[1].gate_mask = 0x99;667 qopt->entries[1].interval = 600000;668 qopt->entries[2].gate_mask = 0x9A;669 qopt->entries[2].interval = 500000;670 qopt->num_entries = 3;671 delay_base_time(adapter, qopt, 3);672 if (!enable_check_taprio(adapter, qopt, 100))673 goto failed;674 qopt->base_time = ktime_set(0, 100000);675 qopt->cycle_time = 500000;676 qopt->cycle_time_extension = 300000;677 qopt->entries[0].gate_mask = 0x9B;678 qopt->entries[0].interval = 150000;679 qopt->entries[1].gate_mask = 0x9C;680 qopt->entries[1].interval = 350000;681 qopt->num_entries = 2;682 delay_base_time(adapter, qopt, 9);683 if (!enable_check_taprio(adapter, qopt, 100))684 goto failed;685 686 /* change to different cycle time */687 qopt->base_time = ktime_set(0, 0);688 qopt->cycle_time = 1000000;689 qopt->cycle_time_extension = 700000;690 qopt->entries[0].gate_mask = 0xAD;691 qopt->entries[0].interval = 400000;692 qopt->entries[1].gate_mask = 0xAE;693 qopt->entries[1].interval = 300000;694 qopt->entries[2].gate_mask = 0xAF;695 qopt->entries[2].interval = 300000;696 qopt->num_entries = 3;697 if (!enable_check_taprio(adapter, qopt, 100))698 goto failed;699 qopt->base_time = ktime_set(0, 0);700 qopt->cycle_time = 400000;701 qopt->cycle_time_extension = 100000;702 qopt->entries[0].gate_mask = 0xA0;703 qopt->entries[0].interval = 200000;704 qopt->entries[1].gate_mask = 0xA1;705 qopt->entries[1].interval = 200000;706 qopt->num_entries = 2;707 delay_base_time(adapter, qopt, 19);708 if (!enable_check_taprio(adapter, qopt, 100))709 goto failed;710 qopt->base_time = ktime_set(0, 0);711 qopt->cycle_time = 500000;712 qopt->cycle_time_extension = 499999;713 qopt->entries[0].gate_mask = 0xB2;714 qopt->entries[0].interval = 100000;715 qopt->entries[1].gate_mask = 0xB3;716 qopt->entries[1].interval = 100000;717 qopt->entries[2].gate_mask = 0xB4;718 qopt->entries[2].interval = 100000;719 qopt->entries[3].gate_mask = 0xB5;720 qopt->entries[3].interval = 200000;721 qopt->num_entries = 4;722 delay_base_time(adapter, qopt, 19);723 if (!enable_check_taprio(adapter, qopt, 100))724 goto failed;725 qopt->base_time = ktime_set(0, 0);726 qopt->cycle_time = 6000000;727 qopt->cycle_time_extension = 5999999;728 qopt->entries[0].gate_mask = 0xC6;729 qopt->entries[0].interval = 1000000;730 qopt->entries[1].gate_mask = 0xC7;731 qopt->entries[1].interval = 1000000;732 qopt->entries[2].gate_mask = 0xC8;733 qopt->entries[2].interval = 1000000;734 qopt->entries[3].gate_mask = 0xC9;735 qopt->entries[3].interval = 1500000;736 qopt->entries[4].gate_mask = 0xCA;737 qopt->entries[4].interval = 1500000;738 qopt->num_entries = 5;739 delay_base_time(adapter, qopt, 1);740 if (!enable_check_taprio(adapter, qopt, 100))741 goto failed;742 743 if (!disable_taprio(adapter))744 goto failed;745 746 kfree(qopt);747 748 return true;749 750failed:751 disable_taprio(adapter);752 kfree(qopt);753 754 return false;755}756 757int tsnep_ethtool_get_test_count(void)758{759 return TSNEP_TEST_COUNT;760}761 762void tsnep_ethtool_get_test_strings(u8 *data)763{764 memcpy(data, tsnep_test_strings, sizeof(tsnep_test_strings));765}766 767void tsnep_ethtool_self_test(struct net_device *netdev,768 struct ethtool_test *eth_test, u64 *data)769{770 struct tsnep_adapter *adapter = netdev_priv(netdev);771 772 eth_test->len = TSNEP_TEST_COUNT;773 774 if (eth_test->flags != ETH_TEST_FL_OFFLINE) {775 /* no tests are done online */776 data[TSNEP_TEST_ENABLE] = 0;777 data[TSNEP_TEST_TAPRIO] = 0;778 data[TSNEP_TEST_TAPRIO_CHANGE] = 0;779 data[TSNEP_TEST_TAPRIO_EXTENSION] = 0;780 781 return;782 }783 784 if (tsnep_test_gc_enable(adapter)) {785 data[TSNEP_TEST_ENABLE] = 0;786 } else {787 eth_test->flags |= ETH_TEST_FL_FAILED;788 data[TSNEP_TEST_ENABLE] = 1;789 }790 791 if (tsnep_test_taprio(adapter)) {792 data[TSNEP_TEST_TAPRIO] = 0;793 } else {794 eth_test->flags |= ETH_TEST_FL_FAILED;795 data[TSNEP_TEST_TAPRIO] = 1;796 }797 798 if (tsnep_test_taprio_change(adapter)) {799 data[TSNEP_TEST_TAPRIO_CHANGE] = 0;800 } else {801 eth_test->flags |= ETH_TEST_FL_FAILED;802 data[TSNEP_TEST_TAPRIO_CHANGE] = 1;803 }804 805 if (tsnep_test_taprio_extension(adapter)) {806 data[TSNEP_TEST_TAPRIO_EXTENSION] = 0;807 } else {808 eth_test->flags |= ETH_TEST_FL_FAILED;809 data[TSNEP_TEST_TAPRIO_EXTENSION] = 1;810 }811}812