tsnep_selftests.c 21 KB

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