0001
0002
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
0095
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
0108 if (enabled)
0109 return false;
0110 } else if ((after - before) < TSNEP_GC_TIMEOUT * 14 / 16) {
0111
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }