sja1105_vl.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright 2020 NXP
  3. */
  4. #include <net/tc_act/tc_gate.h>
  5. #include <linux/dsa/8021q.h>
  6. #include "sja1105_vl.h"
  7. #define SJA1105_SIZE_VL_STATUS 8
  8. /* Insert into the global gate list, sorted by gate action time. */
  9. static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
  10. struct sja1105_rule *rule,
  11. u8 gate_state, s64 entry_time,
  12. struct netlink_ext_ack *extack)
  13. {
  14. struct sja1105_gate_entry *e;
  15. int rc;
  16. e = kzalloc(sizeof(*e), GFP_KERNEL);
  17. if (!e)
  18. return -ENOMEM;
  19. e->rule = rule;
  20. e->gate_state = gate_state;
  21. e->interval = entry_time;
  22. if (list_empty(&gating_cfg->entries)) {
  23. list_add(&e->list, &gating_cfg->entries);
  24. } else {
  25. struct sja1105_gate_entry *p;
  26. list_for_each_entry(p, &gating_cfg->entries, list) {
  27. if (p->interval == e->interval) {
  28. NL_SET_ERR_MSG_MOD(extack,
  29. "Gate conflict");
  30. rc = -EBUSY;
  31. goto err;
  32. }
  33. if (e->interval < p->interval)
  34. break;
  35. }
  36. list_add(&e->list, p->list.prev);
  37. }
  38. gating_cfg->num_entries++;
  39. return 0;
  40. err:
  41. kfree(e);
  42. return rc;
  43. }
  44. /* The gate entries contain absolute times in their e->interval field. Convert
  45. * that to proper intervals (i.e. "0, 5, 10, 15" to "5, 5, 5, 5").
  46. */
  47. static void
  48. sja1105_gating_cfg_time_to_interval(struct sja1105_gating_config *gating_cfg,
  49. u64 cycle_time)
  50. {
  51. struct sja1105_gate_entry *last_e;
  52. struct sja1105_gate_entry *e;
  53. struct list_head *prev;
  54. list_for_each_entry(e, &gating_cfg->entries, list) {
  55. struct sja1105_gate_entry *p;
  56. prev = e->list.prev;
  57. if (prev == &gating_cfg->entries)
  58. continue;
  59. p = list_entry(prev, struct sja1105_gate_entry, list);
  60. p->interval = e->interval - p->interval;
  61. }
  62. last_e = list_last_entry(&gating_cfg->entries,
  63. struct sja1105_gate_entry, list);
  64. last_e->interval = cycle_time - last_e->interval;
  65. }
  66. static void sja1105_free_gating_config(struct sja1105_gating_config *gating_cfg)
  67. {
  68. struct sja1105_gate_entry *e, *n;
  69. list_for_each_entry_safe(e, n, &gating_cfg->entries, list) {
  70. list_del(&e->list);
  71. kfree(e);
  72. }
  73. }
  74. static int sja1105_compose_gating_subschedule(struct sja1105_private *priv,
  75. struct netlink_ext_ack *extack)
  76. {
  77. struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg;
  78. struct sja1105_rule *rule;
  79. s64 max_cycle_time = 0;
  80. s64 its_base_time = 0;
  81. int i, rc = 0;
  82. sja1105_free_gating_config(gating_cfg);
  83. list_for_each_entry(rule, &priv->flow_block.rules, list) {
  84. if (rule->type != SJA1105_RULE_VL)
  85. continue;
  86. if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
  87. continue;
  88. if (max_cycle_time < rule->vl.cycle_time) {
  89. max_cycle_time = rule->vl.cycle_time;
  90. its_base_time = rule->vl.base_time;
  91. }
  92. }
  93. if (!max_cycle_time)
  94. return 0;
  95. dev_dbg(priv->ds->dev, "max_cycle_time %lld its_base_time %lld\n",
  96. max_cycle_time, its_base_time);
  97. gating_cfg->base_time = its_base_time;
  98. gating_cfg->cycle_time = max_cycle_time;
  99. gating_cfg->num_entries = 0;
  100. list_for_each_entry(rule, &priv->flow_block.rules, list) {
  101. s64 time;
  102. s64 rbt;
  103. if (rule->type != SJA1105_RULE_VL)
  104. continue;
  105. if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
  106. continue;
  107. /* Calculate the difference between this gating schedule's
  108. * base time, and the base time of the gating schedule with the
  109. * longest cycle time. We call it the relative base time (rbt).
  110. */
  111. rbt = future_base_time(rule->vl.base_time, rule->vl.cycle_time,
  112. its_base_time);
  113. rbt -= its_base_time;
  114. time = rbt;
  115. for (i = 0; i < rule->vl.num_entries; i++) {
  116. u8 gate_state = rule->vl.entries[i].gate_state;
  117. s64 entry_time = time;
  118. while (entry_time < max_cycle_time) {
  119. rc = sja1105_insert_gate_entry(gating_cfg, rule,
  120. gate_state,
  121. entry_time,
  122. extack);
  123. if (rc)
  124. goto err;
  125. entry_time += rule->vl.cycle_time;
  126. }
  127. time += rule->vl.entries[i].interval;
  128. }
  129. }
  130. sja1105_gating_cfg_time_to_interval(gating_cfg, max_cycle_time);
  131. return 0;
  132. err:
  133. sja1105_free_gating_config(gating_cfg);
  134. return rc;
  135. }
  136. /* The switch flow classification core implements TTEthernet, which 'thinks' in
  137. * terms of Virtual Links (VL), a concept borrowed from ARINC 664 part 7.
  138. * However it also has one other operating mode (VLLUPFORMAT=0) where it acts
  139. * somewhat closer to a pre-standard implementation of IEEE 802.1Qci
  140. * (Per-Stream Filtering and Policing), which is what the driver is going to be
  141. * implementing.
  142. *
  143. * VL Lookup
  144. * Key = {DMAC && VLANID +---------+ Key = { (DMAC[47:16] & VLMASK ==
  145. * && VLAN PCP | | VLMARKER)
  146. * && INGRESS PORT} +---------+ (both fixed)
  147. * (exact match, | && DMAC[15:0] == VLID
  148. * all specified in rule) | (specified in rule)
  149. * v && INGRESS PORT }
  150. * ------------
  151. * 0 (PSFP) / \ 1 (ARINC664)
  152. * +-----------/ VLLUPFORMAT \----------+
  153. * | \ (fixed) / |
  154. * | \ / |
  155. * 0 (forwarding) v ------------ |
  156. * ------------ |
  157. * / \ 1 (QoS classification) |
  158. * +---/ ISCRITICAL \-----------+ |
  159. * | \ (per rule) / | |
  160. * | \ / VLID taken from VLID taken from
  161. * v ------------ index of rule contents of rule
  162. * select that matched that matched
  163. * DESTPORTS | |
  164. * | +---------+--------+
  165. * | |
  166. * | v
  167. * | VL Forwarding
  168. * | (indexed by VLID)
  169. * | +---------+
  170. * | +--------------| |
  171. * | | select TYPE +---------+
  172. * | v
  173. * | 0 (rate ------------ 1 (time
  174. * | constrained) / \ triggered)
  175. * | +------/ TYPE \------------+
  176. * | | \ (per VLID) / |
  177. * | v \ / v
  178. * | VL Policing ------------ VL Policing
  179. * | (indexed by VLID) (indexed by VLID)
  180. * | +---------+ +---------+
  181. * | | TYPE=0 | | TYPE=1 |
  182. * | +---------+ +---------+
  183. * | select SHARINDX select SHARINDX to
  184. * | to rate-limit re-enter VL Forwarding
  185. * | groups of VL's with new VLID for egress
  186. * | to same quota |
  187. * | | |
  188. * | select MAXLEN -> exceed => drop select MAXLEN -> exceed => drop
  189. * | | |
  190. * | v v
  191. * | VL Forwarding VL Forwarding
  192. * | (indexed by SHARINDX) (indexed by SHARINDX)
  193. * | +---------+ +---------+
  194. * | | TYPE=0 | | TYPE=1 |
  195. * | +---------+ +---------+
  196. * | select PRIORITY, select PRIORITY,
  197. * | PARTITION, DESTPORTS PARTITION, DESTPORTS
  198. * | | |
  199. * | v v
  200. * | VL Policing VL Policing
  201. * | (indexed by SHARINDX) (indexed by SHARINDX)
  202. * | +---------+ +---------+
  203. * | | TYPE=0 | | TYPE=1 |
  204. * | +---------+ +---------+
  205. * | | |
  206. * | v |
  207. * | select BAG, -> exceed => drop |
  208. * | JITTER v
  209. * | | ----------------------------------------------
  210. * | | / Reception Window is open for this VL \
  211. * | | / (the Schedule Table executes an entry i \
  212. * | | / M <= i < N, for which these conditions hold): \ no
  213. * | | +----/ \-+
  214. * | | |yes \ WINST[M] == 1 && WINSTINDEX[M] == VLID / |
  215. * | | | \ WINEND[N] == 1 && WINSTINDEX[N] == VLID / |
  216. * | | | \ / |
  217. * | | | \ (the VL window has opened and not yet closed)/ |
  218. * | | | ---------------------------------------------- |
  219. * | | v v
  220. * | | dispatch to DESTPORTS when the Schedule Table drop
  221. * | | executes an entry i with TXEN == 1 && VLINDEX == i
  222. * v v
  223. * dispatch immediately to DESTPORTS
  224. *
  225. * The per-port classification key is always composed of {DMAC, VID, PCP} and
  226. * is non-maskable. This 'looks like' the NULL stream identification function
  227. * from IEEE 802.1CB clause 6, except for the extra VLAN PCP. When the switch
  228. * ports operate as VLAN-unaware, we do allow the user to not specify the VLAN
  229. * ID and PCP, and then the port-based defaults will be used.
  230. *
  231. * In TTEthernet, routing is something that needs to be done manually for each
  232. * Virtual Link. So the flow action must always include one of:
  233. * a. 'redirect', 'trap' or 'drop': select the egress port list
  234. * Additionally, the following actions may be applied on a Virtual Link,
  235. * turning it into 'critical' traffic:
  236. * b. 'police': turn it into a rate-constrained VL, with bandwidth limitation
  237. * given by the maximum frame length, bandwidth allocation gap (BAG) and
  238. * maximum jitter.
  239. * c. 'gate': turn it into a time-triggered VL, which can be only be received
  240. * and forwarded according to a given schedule.
  241. */
  242. static bool sja1105_vl_key_lower(struct sja1105_vl_lookup_entry *a,
  243. struct sja1105_vl_lookup_entry *b)
  244. {
  245. if (a->macaddr < b->macaddr)
  246. return true;
  247. if (a->macaddr > b->macaddr)
  248. return false;
  249. if (a->vlanid < b->vlanid)
  250. return true;
  251. if (a->vlanid > b->vlanid)
  252. return false;
  253. if (a->port < b->port)
  254. return true;
  255. if (a->port > b->port)
  256. return false;
  257. if (a->vlanprior < b->vlanprior)
  258. return true;
  259. if (a->vlanprior > b->vlanprior)
  260. return false;
  261. /* Keys are equal */
  262. return false;
  263. }
  264. /* FIXME: this should change when the bridge upper of the port changes. */
  265. static u16 sja1105_port_get_tag_8021q_vid(struct dsa_port *dp)
  266. {
  267. unsigned long bridge_num;
  268. if (!dp->bridge)
  269. return dsa_tag_8021q_standalone_vid(dp);
  270. bridge_num = dsa_port_bridge_num_get(dp);
  271. return dsa_tag_8021q_bridge_vid(bridge_num);
  272. }
  273. static int sja1105_init_virtual_links(struct sja1105_private *priv,
  274. struct netlink_ext_ack *extack)
  275. {
  276. struct sja1105_vl_policing_entry *vl_policing;
  277. struct sja1105_vl_forwarding_entry *vl_fwd;
  278. struct sja1105_vl_lookup_entry *vl_lookup;
  279. bool have_critical_virtual_links = false;
  280. struct sja1105_table *table;
  281. struct sja1105_rule *rule;
  282. int num_virtual_links = 0;
  283. int max_sharindx = 0;
  284. int i, j, k;
  285. /* Figure out the dimensioning of the problem */
  286. list_for_each_entry(rule, &priv->flow_block.rules, list) {
  287. if (rule->type != SJA1105_RULE_VL)
  288. continue;
  289. /* Each VL lookup entry matches on a single ingress port */
  290. num_virtual_links += hweight_long(rule->port_mask);
  291. if (rule->vl.type != SJA1105_VL_NONCRITICAL)
  292. have_critical_virtual_links = true;
  293. if (max_sharindx < rule->vl.sharindx)
  294. max_sharindx = rule->vl.sharindx;
  295. }
  296. if (num_virtual_links > SJA1105_MAX_VL_LOOKUP_COUNT) {
  297. NL_SET_ERR_MSG_MOD(extack, "Not enough VL entries available");
  298. return -ENOSPC;
  299. }
  300. if (max_sharindx + 1 > SJA1105_MAX_VL_LOOKUP_COUNT) {
  301. NL_SET_ERR_MSG_MOD(extack, "Policer index out of range");
  302. return -ENOSPC;
  303. }
  304. max_sharindx = max_t(int, num_virtual_links, max_sharindx) + 1;
  305. /* Discard previous VL Lookup Table */
  306. table = &priv->static_config.tables[BLK_IDX_VL_LOOKUP];
  307. if (table->entry_count) {
  308. kfree(table->entries);
  309. table->entry_count = 0;
  310. }
  311. /* Discard previous VL Policing Table */
  312. table = &priv->static_config.tables[BLK_IDX_VL_POLICING];
  313. if (table->entry_count) {
  314. kfree(table->entries);
  315. table->entry_count = 0;
  316. }
  317. /* Discard previous VL Forwarding Table */
  318. table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING];
  319. if (table->entry_count) {
  320. kfree(table->entries);
  321. table->entry_count = 0;
  322. }
  323. /* Discard previous VL Forwarding Parameters Table */
  324. table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING_PARAMS];
  325. if (table->entry_count) {
  326. kfree(table->entries);
  327. table->entry_count = 0;
  328. }
  329. /* Nothing to do */
  330. if (!num_virtual_links)
  331. return 0;
  332. /* Pre-allocate space in the static config tables */
  333. /* VL Lookup Table */
  334. table = &priv->static_config.tables[BLK_IDX_VL_LOOKUP];
  335. table->entries = kcalloc(num_virtual_links,
  336. table->ops->unpacked_entry_size,
  337. GFP_KERNEL);
  338. if (!table->entries)
  339. return -ENOMEM;
  340. table->entry_count = num_virtual_links;
  341. vl_lookup = table->entries;
  342. k = 0;
  343. list_for_each_entry(rule, &priv->flow_block.rules, list) {
  344. unsigned long port;
  345. if (rule->type != SJA1105_RULE_VL)
  346. continue;
  347. for_each_set_bit(port, &rule->port_mask, SJA1105_MAX_NUM_PORTS) {
  348. vl_lookup[k].format = SJA1105_VL_FORMAT_PSFP;
  349. vl_lookup[k].port = port;
  350. vl_lookup[k].macaddr = rule->key.vl.dmac;
  351. if (rule->key.type == SJA1105_KEY_VLAN_AWARE_VL) {
  352. vl_lookup[k].vlanid = rule->key.vl.vid;
  353. vl_lookup[k].vlanprior = rule->key.vl.pcp;
  354. } else {
  355. /* FIXME */
  356. struct dsa_port *dp = dsa_to_port(priv->ds, port);
  357. u16 vid = sja1105_port_get_tag_8021q_vid(dp);
  358. vl_lookup[k].vlanid = vid;
  359. vl_lookup[k].vlanprior = 0;
  360. }
  361. /* For critical VLs, the DESTPORTS mask is taken from
  362. * the VL Forwarding Table, so no point in putting it
  363. * in the VL Lookup Table
  364. */
  365. if (rule->vl.type == SJA1105_VL_NONCRITICAL)
  366. vl_lookup[k].destports = rule->vl.destports;
  367. else
  368. vl_lookup[k].iscritical = true;
  369. vl_lookup[k].flow_cookie = rule->cookie;
  370. k++;
  371. }
  372. }
  373. /* UM10944.pdf chapter 4.2.3 VL Lookup table:
  374. * "the entries in the VL Lookup table must be sorted in ascending
  375. * order (i.e. the smallest value must be loaded first) according to
  376. * the following sort order: MACADDR, VLANID, PORT, VLANPRIOR."
  377. */
  378. for (i = 0; i < num_virtual_links; i++) {
  379. struct sja1105_vl_lookup_entry *a = &vl_lookup[i];
  380. for (j = i + 1; j < num_virtual_links; j++) {
  381. struct sja1105_vl_lookup_entry *b = &vl_lookup[j];
  382. if (sja1105_vl_key_lower(b, a)) {
  383. struct sja1105_vl_lookup_entry tmp = *a;
  384. *a = *b;
  385. *b = tmp;
  386. }
  387. }
  388. }
  389. if (!have_critical_virtual_links)
  390. return 0;
  391. /* VL Policing Table */
  392. table = &priv->static_config.tables[BLK_IDX_VL_POLICING];
  393. table->entries = kcalloc(max_sharindx, table->ops->unpacked_entry_size,
  394. GFP_KERNEL);
  395. if (!table->entries)
  396. return -ENOMEM;
  397. table->entry_count = max_sharindx;
  398. vl_policing = table->entries;
  399. /* VL Forwarding Table */
  400. table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING];
  401. table->entries = kcalloc(max_sharindx, table->ops->unpacked_entry_size,
  402. GFP_KERNEL);
  403. if (!table->entries)
  404. return -ENOMEM;
  405. table->entry_count = max_sharindx;
  406. vl_fwd = table->entries;
  407. /* VL Forwarding Parameters Table */
  408. table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING_PARAMS];
  409. table->entries = kcalloc(1, table->ops->unpacked_entry_size,
  410. GFP_KERNEL);
  411. if (!table->entries)
  412. return -ENOMEM;
  413. table->entry_count = 1;
  414. for (i = 0; i < num_virtual_links; i++) {
  415. unsigned long cookie = vl_lookup[i].flow_cookie;
  416. struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
  417. if (rule->vl.type == SJA1105_VL_NONCRITICAL)
  418. continue;
  419. if (rule->vl.type == SJA1105_VL_TIME_TRIGGERED) {
  420. int sharindx = rule->vl.sharindx;
  421. vl_policing[i].type = 1;
  422. vl_policing[i].sharindx = sharindx;
  423. vl_policing[i].maxlen = rule->vl.maxlen;
  424. vl_policing[sharindx].type = 1;
  425. vl_fwd[i].type = 1;
  426. vl_fwd[sharindx].type = 1;
  427. vl_fwd[sharindx].priority = rule->vl.ipv;
  428. vl_fwd[sharindx].partition = 0;
  429. vl_fwd[sharindx].destports = rule->vl.destports;
  430. }
  431. }
  432. sja1105_frame_memory_partitioning(priv);
  433. return 0;
  434. }
  435. int sja1105_vl_redirect(struct sja1105_private *priv, int port,
  436. struct netlink_ext_ack *extack, unsigned long cookie,
  437. struct sja1105_key *key, unsigned long destports,
  438. bool append)
  439. {
  440. struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
  441. struct dsa_port *dp = dsa_to_port(priv->ds, port);
  442. bool vlan_aware = dsa_port_is_vlan_filtering(dp);
  443. int rc;
  444. if (!vlan_aware && key->type != SJA1105_KEY_VLAN_UNAWARE_VL) {
  445. NL_SET_ERR_MSG_MOD(extack,
  446. "Can only redirect based on DMAC");
  447. return -EOPNOTSUPP;
  448. } else if (vlan_aware && key->type != SJA1105_KEY_VLAN_AWARE_VL) {
  449. NL_SET_ERR_MSG_MOD(extack,
  450. "Can only redirect based on {DMAC, VID, PCP}");
  451. return -EOPNOTSUPP;
  452. }
  453. if (!rule) {
  454. rule = kzalloc(sizeof(*rule), GFP_KERNEL);
  455. if (!rule)
  456. return -ENOMEM;
  457. rule->cookie = cookie;
  458. rule->type = SJA1105_RULE_VL;
  459. rule->key = *key;
  460. list_add(&rule->list, &priv->flow_block.rules);
  461. }
  462. rule->port_mask |= BIT(port);
  463. if (append)
  464. rule->vl.destports |= destports;
  465. else
  466. rule->vl.destports = destports;
  467. rc = sja1105_init_virtual_links(priv, extack);
  468. if (rc) {
  469. rule->port_mask &= ~BIT(port);
  470. if (!rule->port_mask) {
  471. list_del(&rule->list);
  472. kfree(rule);
  473. }
  474. }
  475. return rc;
  476. }
  477. int sja1105_vl_delete(struct sja1105_private *priv, int port,
  478. struct sja1105_rule *rule, struct netlink_ext_ack *extack)
  479. {
  480. int rc;
  481. rule->port_mask &= ~BIT(port);
  482. if (!rule->port_mask) {
  483. list_del(&rule->list);
  484. kfree(rule);
  485. }
  486. rc = sja1105_compose_gating_subschedule(priv, extack);
  487. if (rc)
  488. return rc;
  489. rc = sja1105_init_virtual_links(priv, extack);
  490. if (rc)
  491. return rc;
  492. rc = sja1105_init_scheduling(priv);
  493. if (rc < 0)
  494. return rc;
  495. return sja1105_static_config_reload(priv, SJA1105_VIRTUAL_LINKS);
  496. }
  497. int sja1105_vl_gate(struct sja1105_private *priv, int port,
  498. struct netlink_ext_ack *extack, unsigned long cookie,
  499. struct sja1105_key *key, u32 index, s32 prio,
  500. u64 base_time, u64 cycle_time, u64 cycle_time_ext,
  501. u32 num_entries, struct action_gate_entry *entries)
  502. {
  503. struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
  504. struct dsa_port *dp = dsa_to_port(priv->ds, port);
  505. bool vlan_aware = dsa_port_is_vlan_filtering(dp);
  506. int ipv = -1;
  507. int i, rc;
  508. s32 rem;
  509. if (cycle_time_ext) {
  510. NL_SET_ERR_MSG_MOD(extack,
  511. "Cycle time extension not supported");
  512. return -EOPNOTSUPP;
  513. }
  514. div_s64_rem(base_time, sja1105_delta_to_ns(1), &rem);
  515. if (rem) {
  516. NL_SET_ERR_MSG_MOD(extack,
  517. "Base time must be multiple of 200 ns");
  518. return -ERANGE;
  519. }
  520. div_s64_rem(cycle_time, sja1105_delta_to_ns(1), &rem);
  521. if (rem) {
  522. NL_SET_ERR_MSG_MOD(extack,
  523. "Cycle time must be multiple of 200 ns");
  524. return -ERANGE;
  525. }
  526. if (!vlan_aware && key->type != SJA1105_KEY_VLAN_UNAWARE_VL) {
  527. NL_SET_ERR_MSG_MOD(extack,
  528. "Can only gate based on DMAC");
  529. return -EOPNOTSUPP;
  530. } else if (vlan_aware && key->type != SJA1105_KEY_VLAN_AWARE_VL) {
  531. NL_SET_ERR_MSG_MOD(extack,
  532. "Can only gate based on {DMAC, VID, PCP}");
  533. return -EOPNOTSUPP;
  534. }
  535. if (!rule) {
  536. rule = kzalloc(sizeof(*rule), GFP_KERNEL);
  537. if (!rule)
  538. return -ENOMEM;
  539. list_add(&rule->list, &priv->flow_block.rules);
  540. rule->cookie = cookie;
  541. rule->type = SJA1105_RULE_VL;
  542. rule->key = *key;
  543. rule->vl.type = SJA1105_VL_TIME_TRIGGERED;
  544. rule->vl.sharindx = index;
  545. rule->vl.base_time = base_time;
  546. rule->vl.cycle_time = cycle_time;
  547. rule->vl.num_entries = num_entries;
  548. rule->vl.entries = kcalloc(num_entries,
  549. sizeof(struct action_gate_entry),
  550. GFP_KERNEL);
  551. if (!rule->vl.entries) {
  552. rc = -ENOMEM;
  553. goto out;
  554. }
  555. for (i = 0; i < num_entries; i++) {
  556. div_s64_rem(entries[i].interval,
  557. sja1105_delta_to_ns(1), &rem);
  558. if (rem) {
  559. NL_SET_ERR_MSG_MOD(extack,
  560. "Interval must be multiple of 200 ns");
  561. rc = -ERANGE;
  562. goto out;
  563. }
  564. if (!entries[i].interval) {
  565. NL_SET_ERR_MSG_MOD(extack,
  566. "Interval cannot be zero");
  567. rc = -ERANGE;
  568. goto out;
  569. }
  570. if (ns_to_sja1105_delta(entries[i].interval) >
  571. SJA1105_TAS_MAX_DELTA) {
  572. NL_SET_ERR_MSG_MOD(extack,
  573. "Maximum interval is 52 ms");
  574. rc = -ERANGE;
  575. goto out;
  576. }
  577. if (entries[i].maxoctets != -1) {
  578. NL_SET_ERR_MSG_MOD(extack,
  579. "Cannot offload IntervalOctetMax");
  580. rc = -EOPNOTSUPP;
  581. goto out;
  582. }
  583. if (ipv == -1) {
  584. ipv = entries[i].ipv;
  585. } else if (ipv != entries[i].ipv) {
  586. NL_SET_ERR_MSG_MOD(extack,
  587. "Only support a single IPV per VL");
  588. rc = -EOPNOTSUPP;
  589. goto out;
  590. }
  591. rule->vl.entries[i] = entries[i];
  592. }
  593. if (ipv == -1) {
  594. if (key->type == SJA1105_KEY_VLAN_AWARE_VL)
  595. ipv = key->vl.pcp;
  596. else
  597. ipv = 0;
  598. }
  599. /* TODO: support per-flow MTU */
  600. rule->vl.maxlen = VLAN_ETH_FRAME_LEN + ETH_FCS_LEN;
  601. rule->vl.ipv = ipv;
  602. }
  603. rule->port_mask |= BIT(port);
  604. rc = sja1105_compose_gating_subschedule(priv, extack);
  605. if (rc)
  606. goto out;
  607. rc = sja1105_init_virtual_links(priv, extack);
  608. if (rc)
  609. goto out;
  610. if (sja1105_gating_check_conflicts(priv, -1, extack)) {
  611. NL_SET_ERR_MSG_MOD(extack, "Conflict with tc-taprio schedule");
  612. rc = -ERANGE;
  613. goto out;
  614. }
  615. out:
  616. if (rc) {
  617. rule->port_mask &= ~BIT(port);
  618. if (!rule->port_mask) {
  619. list_del(&rule->list);
  620. kfree(rule->vl.entries);
  621. kfree(rule);
  622. }
  623. }
  624. return rc;
  625. }
  626. static int sja1105_find_vlid(struct sja1105_private *priv, int port,
  627. struct sja1105_key *key)
  628. {
  629. struct sja1105_vl_lookup_entry *vl_lookup;
  630. struct sja1105_table *table;
  631. int i;
  632. if (WARN_ON(key->type != SJA1105_KEY_VLAN_AWARE_VL &&
  633. key->type != SJA1105_KEY_VLAN_UNAWARE_VL))
  634. return -1;
  635. table = &priv->static_config.tables[BLK_IDX_VL_LOOKUP];
  636. vl_lookup = table->entries;
  637. for (i = 0; i < table->entry_count; i++) {
  638. if (key->type == SJA1105_KEY_VLAN_AWARE_VL) {
  639. if (vl_lookup[i].port == port &&
  640. vl_lookup[i].macaddr == key->vl.dmac &&
  641. vl_lookup[i].vlanid == key->vl.vid &&
  642. vl_lookup[i].vlanprior == key->vl.pcp)
  643. return i;
  644. } else {
  645. if (vl_lookup[i].port == port &&
  646. vl_lookup[i].macaddr == key->vl.dmac)
  647. return i;
  648. }
  649. }
  650. return -1;
  651. }
  652. int sja1105_vl_stats(struct sja1105_private *priv, int port,
  653. struct sja1105_rule *rule, struct flow_stats *stats,
  654. struct netlink_ext_ack *extack)
  655. {
  656. const struct sja1105_regs *regs = priv->info->regs;
  657. u8 buf[SJA1105_SIZE_VL_STATUS] = {0};
  658. u64 unreleased;
  659. u64 timingerr;
  660. u64 lengtherr;
  661. int vlid, rc;
  662. u64 pkts;
  663. if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
  664. return 0;
  665. vlid = sja1105_find_vlid(priv, port, &rule->key);
  666. if (vlid < 0)
  667. return 0;
  668. rc = sja1105_xfer_buf(priv, SPI_READ, regs->vl_status + 2 * vlid, buf,
  669. SJA1105_SIZE_VL_STATUS);
  670. if (rc) {
  671. NL_SET_ERR_MSG_MOD(extack, "SPI access failed");
  672. return rc;
  673. }
  674. sja1105_unpack(buf, &timingerr, 31, 16, SJA1105_SIZE_VL_STATUS);
  675. sja1105_unpack(buf, &unreleased, 15, 0, SJA1105_SIZE_VL_STATUS);
  676. sja1105_unpack(buf, &lengtherr, 47, 32, SJA1105_SIZE_VL_STATUS);
  677. pkts = timingerr + unreleased + lengtherr;
  678. flow_stats_update(stats, 0, pkts - rule->vl.stats.pkts, 0,
  679. jiffies - rule->vl.stats.lastused,
  680. FLOW_ACTION_HW_STATS_IMMEDIATE);
  681. rule->vl.stats.pkts = pkts;
  682. rule->vl.stats.lastused = jiffies;
  683. return 0;
  684. }