Lines Matching +full:0 +full:- +full:indexed

1 // SPDX-License-Identifier: GPL-2.0
21 return -ENOMEM; in sja1105_insert_gate_entry()
23 e->rule = rule; in sja1105_insert_gate_entry()
24 e->gate_state = gate_state; in sja1105_insert_gate_entry()
25 e->interval = entry_time; in sja1105_insert_gate_entry()
27 if (list_empty(&gating_cfg->entries)) { in sja1105_insert_gate_entry()
28 list_add(&e->list, &gating_cfg->entries); in sja1105_insert_gate_entry()
32 list_for_each_entry(p, &gating_cfg->entries, list) { in sja1105_insert_gate_entry()
33 if (p->interval == e->interval) { in sja1105_insert_gate_entry()
36 rc = -EBUSY; in sja1105_insert_gate_entry()
40 if (e->interval < p->interval) in sja1105_insert_gate_entry()
43 list_add(&e->list, p->list.prev); in sja1105_insert_gate_entry()
46 gating_cfg->num_entries++; in sja1105_insert_gate_entry()
48 return 0; in sja1105_insert_gate_entry()
54 /* The gate entries contain absolute times in their e->interval field. Convert
55 * that to proper intervals (i.e. "0, 5, 10, 15" to "5, 5, 5, 5").
65 list_for_each_entry(e, &gating_cfg->entries, list) { in sja1105_gating_cfg_time_to_interval()
68 prev = e->list.prev; in sja1105_gating_cfg_time_to_interval()
70 if (prev == &gating_cfg->entries) in sja1105_gating_cfg_time_to_interval()
74 p->interval = e->interval - p->interval; in sja1105_gating_cfg_time_to_interval()
76 last_e = list_last_entry(&gating_cfg->entries, in sja1105_gating_cfg_time_to_interval()
78 last_e->interval = cycle_time - last_e->interval; in sja1105_gating_cfg_time_to_interval()
85 list_for_each_entry_safe(e, n, &gating_cfg->entries, list) { in sja1105_free_gating_config()
86 list_del(&e->list); in sja1105_free_gating_config()
94 struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg; in sja1105_compose_gating_subschedule()
96 s64 max_cycle_time = 0; in sja1105_compose_gating_subschedule()
97 s64 its_base_time = 0; in sja1105_compose_gating_subschedule()
98 int i, rc = 0; in sja1105_compose_gating_subschedule()
102 list_for_each_entry(rule, &priv->flow_block.rules, list) { in sja1105_compose_gating_subschedule()
103 if (rule->type != SJA1105_RULE_VL) in sja1105_compose_gating_subschedule()
105 if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED) in sja1105_compose_gating_subschedule()
108 if (max_cycle_time < rule->vl.cycle_time) { in sja1105_compose_gating_subschedule()
109 max_cycle_time = rule->vl.cycle_time; in sja1105_compose_gating_subschedule()
110 its_base_time = rule->vl.base_time; in sja1105_compose_gating_subschedule()
115 return 0; in sja1105_compose_gating_subschedule()
117 dev_dbg(priv->ds->dev, "max_cycle_time %lld its_base_time %lld\n", in sja1105_compose_gating_subschedule()
120 gating_cfg->base_time = its_base_time; in sja1105_compose_gating_subschedule()
121 gating_cfg->cycle_time = max_cycle_time; in sja1105_compose_gating_subschedule()
122 gating_cfg->num_entries = 0; in sja1105_compose_gating_subschedule()
124 list_for_each_entry(rule, &priv->flow_block.rules, list) { in sja1105_compose_gating_subschedule()
128 if (rule->type != SJA1105_RULE_VL) in sja1105_compose_gating_subschedule()
130 if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED) in sja1105_compose_gating_subschedule()
137 rbt = future_base_time(rule->vl.base_time, rule->vl.cycle_time, in sja1105_compose_gating_subschedule()
139 rbt -= its_base_time; in sja1105_compose_gating_subschedule()
143 for (i = 0; i < rule->vl.num_entries; i++) { in sja1105_compose_gating_subschedule()
144 u8 gate_state = rule->vl.entries[i].gate_state; in sja1105_compose_gating_subschedule()
155 entry_time += rule->vl.cycle_time; in sja1105_compose_gating_subschedule()
157 time += rule->vl.entries[i].interval; in sja1105_compose_gating_subschedule()
163 return 0; in sja1105_compose_gating_subschedule()
171 * However it also has one other operating mode (VLLUPFORMAT=0) where it acts
172 * somewhat closer to a pre-standard implementation of IEEE 802.1Qci
173 * (Per-Stream Filtering and Policing), which is what the driver is going to be
177 * Key = {DMAC && VLANID +---------+ Key = { (DMAC[47:16] & VLMASK ==
179 * && INGRESS PORT} +---------+ (both fixed)
180 * (exact match, | && DMAC[15:0] == VLID
183 * ------------
184 * 0 (PSFP) / \ 1 (ARINC664)
185 * +-----------/ VLLUPFORMAT \----------+
188 * 0 (forwarding) v ------------ |
189 * ------------ |
191 * +---/ ISCRITICAL \-----------+ |
194 * v ------------ index of rule contents of rule
197 * | +---------+--------+
201 * | (indexed by VLID)
202 * | +---------+
203 * | +--------------| |
204 * | | select TYPE +---------+
206 * | 0 (rate ------------ 1 (time
208 * | +------/ TYPE \------------+
211 * | VL Policing ------------ VL Policing
212 * | (indexed by VLID) (indexed by VLID)
213 * | +---------+ +---------+
214 * | | TYPE=0 | | TYPE=1 |
215 * | +---------+ +---------+
217 * | to rate-limit re-enter VL Forwarding
221 * | select MAXLEN -> exceed => drop select MAXLEN -> exceed => drop
225 * | (indexed by SHARINDX) (indexed by SHARINDX)
226 * | +---------+ +---------+
227 * | | TYPE=0 | | TYPE=1 |
228 * | +---------+ +---------+
234 * | (indexed by SHARINDX) (indexed by SHARINDX)
235 * | +---------+ +---------+
236 * | | TYPE=0 | | TYPE=1 |
237 * | +---------+ +---------+
240 * | select BAG, -> exceed => drop |
242 * | | ----------------------------------------------
246 * | | +----/ \-+
251 * | | | ---------------------------------------------- |
258 * The per-port classification key is always composed of {DMAC, VID, PCP} and
259 * is non-maskable. This 'looks like' the NULL stream identification function
261 * ports operate as VLAN-unaware, we do allow the user to not specify the VLAN
262 * ID and PCP, and then the port-based defaults will be used.
269 * b. 'police': turn it into a rate-constrained VL, with bandwidth limitation
272 * c. 'gate': turn it into a time-triggered VL, which can be only be received
279 if (a->macaddr < b->macaddr) in sja1105_vl_key_lower()
281 if (a->macaddr > b->macaddr) in sja1105_vl_key_lower()
283 if (a->vlanid < b->vlanid) in sja1105_vl_key_lower()
285 if (a->vlanid > b->vlanid) in sja1105_vl_key_lower()
287 if (a->port < b->port) in sja1105_vl_key_lower()
289 if (a->port > b->port) in sja1105_vl_key_lower()
291 if (a->vlanprior < b->vlanprior) in sja1105_vl_key_lower()
293 if (a->vlanprior > b->vlanprior) in sja1105_vl_key_lower()
304 if (!dp->bridge) in sja1105_port_get_tag_8021q_vid()
321 int num_virtual_links = 0; in sja1105_init_virtual_links()
322 int max_sharindx = 0; in sja1105_init_virtual_links()
326 list_for_each_entry(rule, &priv->flow_block.rules, list) { in sja1105_init_virtual_links()
327 if (rule->type != SJA1105_RULE_VL) in sja1105_init_virtual_links()
330 num_virtual_links += hweight_long(rule->port_mask); in sja1105_init_virtual_links()
332 if (rule->vl.type != SJA1105_VL_NONCRITICAL) in sja1105_init_virtual_links()
334 if (max_sharindx < rule->vl.sharindx) in sja1105_init_virtual_links()
335 max_sharindx = rule->vl.sharindx; in sja1105_init_virtual_links()
340 return -ENOSPC; in sja1105_init_virtual_links()
345 return -ENOSPC; in sja1105_init_virtual_links()
351 table = &priv->static_config.tables[BLK_IDX_VL_LOOKUP]; in sja1105_init_virtual_links()
352 if (table->entry_count) { in sja1105_init_virtual_links()
353 kfree(table->entries); in sja1105_init_virtual_links()
354 table->entry_count = 0; in sja1105_init_virtual_links()
358 table = &priv->static_config.tables[BLK_IDX_VL_POLICING]; in sja1105_init_virtual_links()
359 if (table->entry_count) { in sja1105_init_virtual_links()
360 kfree(table->entries); in sja1105_init_virtual_links()
361 table->entry_count = 0; in sja1105_init_virtual_links()
365 table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING]; in sja1105_init_virtual_links()
366 if (table->entry_count) { in sja1105_init_virtual_links()
367 kfree(table->entries); in sja1105_init_virtual_links()
368 table->entry_count = 0; in sja1105_init_virtual_links()
372 table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING_PARAMS]; in sja1105_init_virtual_links()
373 if (table->entry_count) { in sja1105_init_virtual_links()
374 kfree(table->entries); in sja1105_init_virtual_links()
375 table->entry_count = 0; in sja1105_init_virtual_links()
380 return 0; in sja1105_init_virtual_links()
382 /* Pre-allocate space in the static config tables */ in sja1105_init_virtual_links()
385 table = &priv->static_config.tables[BLK_IDX_VL_LOOKUP]; in sja1105_init_virtual_links()
386 table->entries = kcalloc(num_virtual_links, in sja1105_init_virtual_links()
387 table->ops->unpacked_entry_size, in sja1105_init_virtual_links()
389 if (!table->entries) in sja1105_init_virtual_links()
390 return -ENOMEM; in sja1105_init_virtual_links()
391 table->entry_count = num_virtual_links; in sja1105_init_virtual_links()
392 vl_lookup = table->entries; in sja1105_init_virtual_links()
394 k = 0; in sja1105_init_virtual_links()
396 list_for_each_entry(rule, &priv->flow_block.rules, list) { in sja1105_init_virtual_links()
399 if (rule->type != SJA1105_RULE_VL) in sja1105_init_virtual_links()
402 for_each_set_bit(port, &rule->port_mask, SJA1105_MAX_NUM_PORTS) { in sja1105_init_virtual_links()
405 vl_lookup[k].macaddr = rule->key.vl.dmac; in sja1105_init_virtual_links()
406 if (rule->key.type == SJA1105_KEY_VLAN_AWARE_VL) { in sja1105_init_virtual_links()
407 vl_lookup[k].vlanid = rule->key.vl.vid; in sja1105_init_virtual_links()
408 vl_lookup[k].vlanprior = rule->key.vl.pcp; in sja1105_init_virtual_links()
411 struct dsa_port *dp = dsa_to_port(priv->ds, port); in sja1105_init_virtual_links()
415 vl_lookup[k].vlanprior = 0; in sja1105_init_virtual_links()
421 if (rule->vl.type == SJA1105_VL_NONCRITICAL) in sja1105_init_virtual_links()
422 vl_lookup[k].destports = rule->vl.destports; in sja1105_init_virtual_links()
425 vl_lookup[k].flow_cookie = rule->cookie; in sja1105_init_virtual_links()
435 for (i = 0; i < num_virtual_links; i++) { in sja1105_init_virtual_links()
451 return 0; in sja1105_init_virtual_links()
454 table = &priv->static_config.tables[BLK_IDX_VL_POLICING]; in sja1105_init_virtual_links()
455 table->entries = kcalloc(max_sharindx, table->ops->unpacked_entry_size, in sja1105_init_virtual_links()
457 if (!table->entries) in sja1105_init_virtual_links()
458 return -ENOMEM; in sja1105_init_virtual_links()
459 table->entry_count = max_sharindx; in sja1105_init_virtual_links()
460 vl_policing = table->entries; in sja1105_init_virtual_links()
463 table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING]; in sja1105_init_virtual_links()
464 table->entries = kcalloc(max_sharindx, table->ops->unpacked_entry_size, in sja1105_init_virtual_links()
466 if (!table->entries) in sja1105_init_virtual_links()
467 return -ENOMEM; in sja1105_init_virtual_links()
468 table->entry_count = max_sharindx; in sja1105_init_virtual_links()
469 vl_fwd = table->entries; in sja1105_init_virtual_links()
472 table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING_PARAMS]; in sja1105_init_virtual_links()
473 table->entries = kcalloc(1, table->ops->unpacked_entry_size, in sja1105_init_virtual_links()
475 if (!table->entries) in sja1105_init_virtual_links()
476 return -ENOMEM; in sja1105_init_virtual_links()
477 table->entry_count = 1; in sja1105_init_virtual_links()
479 for (i = 0; i < num_virtual_links; i++) { in sja1105_init_virtual_links()
483 if (rule->vl.type == SJA1105_VL_NONCRITICAL) in sja1105_init_virtual_links()
485 if (rule->vl.type == SJA1105_VL_TIME_TRIGGERED) { in sja1105_init_virtual_links()
486 int sharindx = rule->vl.sharindx; in sja1105_init_virtual_links()
490 vl_policing[i].maxlen = rule->vl.maxlen; in sja1105_init_virtual_links()
495 vl_fwd[sharindx].priority = rule->vl.ipv; in sja1105_init_virtual_links()
496 vl_fwd[sharindx].partition = 0; in sja1105_init_virtual_links()
497 vl_fwd[sharindx].destports = rule->vl.destports; in sja1105_init_virtual_links()
503 return 0; in sja1105_init_virtual_links()
512 struct dsa_port *dp = dsa_to_port(priv->ds, port); in sja1105_vl_redirect()
516 if (!vlan_aware && key->type != SJA1105_KEY_VLAN_UNAWARE_VL) { in sja1105_vl_redirect()
519 return -EOPNOTSUPP; in sja1105_vl_redirect()
520 } else if (vlan_aware && key->type != SJA1105_KEY_VLAN_AWARE_VL) { in sja1105_vl_redirect()
523 return -EOPNOTSUPP; in sja1105_vl_redirect()
529 return -ENOMEM; in sja1105_vl_redirect()
531 rule->cookie = cookie; in sja1105_vl_redirect()
532 rule->type = SJA1105_RULE_VL; in sja1105_vl_redirect()
533 rule->key = *key; in sja1105_vl_redirect()
534 list_add(&rule->list, &priv->flow_block.rules); in sja1105_vl_redirect()
537 rule->port_mask |= BIT(port); in sja1105_vl_redirect()
539 rule->vl.destports |= destports; in sja1105_vl_redirect()
541 rule->vl.destports = destports; in sja1105_vl_redirect()
545 rule->port_mask &= ~BIT(port); in sja1105_vl_redirect()
546 if (!rule->port_mask) { in sja1105_vl_redirect()
547 list_del(&rule->list); in sja1105_vl_redirect()
560 rule->port_mask &= ~BIT(port); in sja1105_vl_delete()
561 if (!rule->port_mask) { in sja1105_vl_delete()
562 list_del(&rule->list); in sja1105_vl_delete()
575 if (rc < 0) in sja1105_vl_delete()
588 struct dsa_port *dp = dsa_to_port(priv->ds, port); in sja1105_vl_gate()
590 int ipv = -1; in sja1105_vl_gate()
597 return -EOPNOTSUPP; in sja1105_vl_gate()
604 return -ERANGE; in sja1105_vl_gate()
611 return -ERANGE; in sja1105_vl_gate()
614 if (!vlan_aware && key->type != SJA1105_KEY_VLAN_UNAWARE_VL) { in sja1105_vl_gate()
617 return -EOPNOTSUPP; in sja1105_vl_gate()
618 } else if (vlan_aware && key->type != SJA1105_KEY_VLAN_AWARE_VL) { in sja1105_vl_gate()
621 return -EOPNOTSUPP; in sja1105_vl_gate()
627 return -ENOMEM; in sja1105_vl_gate()
629 list_add(&rule->list, &priv->flow_block.rules); in sja1105_vl_gate()
630 rule->cookie = cookie; in sja1105_vl_gate()
631 rule->type = SJA1105_RULE_VL; in sja1105_vl_gate()
632 rule->key = *key; in sja1105_vl_gate()
633 rule->vl.type = SJA1105_VL_TIME_TRIGGERED; in sja1105_vl_gate()
634 rule->vl.sharindx = index; in sja1105_vl_gate()
635 rule->vl.base_time = base_time; in sja1105_vl_gate()
636 rule->vl.cycle_time = cycle_time; in sja1105_vl_gate()
637 rule->vl.num_entries = num_entries; in sja1105_vl_gate()
638 rule->vl.entries = kcalloc(num_entries, in sja1105_vl_gate()
641 if (!rule->vl.entries) { in sja1105_vl_gate()
642 rc = -ENOMEM; in sja1105_vl_gate()
646 for (i = 0; i < num_entries; i++) { in sja1105_vl_gate()
652 rc = -ERANGE; in sja1105_vl_gate()
659 rc = -ERANGE; in sja1105_vl_gate()
667 rc = -ERANGE; in sja1105_vl_gate()
671 if (entries[i].maxoctets != -1) { in sja1105_vl_gate()
674 rc = -EOPNOTSUPP; in sja1105_vl_gate()
678 if (ipv == -1) { in sja1105_vl_gate()
683 rc = -EOPNOTSUPP; in sja1105_vl_gate()
687 rule->vl.entries[i] = entries[i]; in sja1105_vl_gate()
690 if (ipv == -1) { in sja1105_vl_gate()
691 if (key->type == SJA1105_KEY_VLAN_AWARE_VL) in sja1105_vl_gate()
692 ipv = key->vl.pcp; in sja1105_vl_gate()
694 ipv = 0; in sja1105_vl_gate()
697 /* TODO: support per-flow MTU */ in sja1105_vl_gate()
698 rule->vl.maxlen = VLAN_ETH_FRAME_LEN + ETH_FCS_LEN; in sja1105_vl_gate()
699 rule->vl.ipv = ipv; in sja1105_vl_gate()
702 rule->port_mask |= BIT(port); in sja1105_vl_gate()
712 if (sja1105_gating_check_conflicts(priv, -1, extack)) { in sja1105_vl_gate()
713 NL_SET_ERR_MSG_MOD(extack, "Conflict with tc-taprio schedule"); in sja1105_vl_gate()
714 rc = -ERANGE; in sja1105_vl_gate()
720 rule->port_mask &= ~BIT(port); in sja1105_vl_gate()
721 if (!rule->port_mask) { in sja1105_vl_gate()
722 list_del(&rule->list); in sja1105_vl_gate()
723 kfree(rule->vl.entries); in sja1105_vl_gate()
738 if (WARN_ON(key->type != SJA1105_KEY_VLAN_AWARE_VL && in sja1105_find_vlid()
739 key->type != SJA1105_KEY_VLAN_UNAWARE_VL)) in sja1105_find_vlid()
740 return -1; in sja1105_find_vlid()
742 table = &priv->static_config.tables[BLK_IDX_VL_LOOKUP]; in sja1105_find_vlid()
743 vl_lookup = table->entries; in sja1105_find_vlid()
745 for (i = 0; i < table->entry_count; i++) { in sja1105_find_vlid()
746 if (key->type == SJA1105_KEY_VLAN_AWARE_VL) { in sja1105_find_vlid()
748 vl_lookup[i].macaddr == key->vl.dmac && in sja1105_find_vlid()
749 vl_lookup[i].vlanid == key->vl.vid && in sja1105_find_vlid()
750 vl_lookup[i].vlanprior == key->vl.pcp) in sja1105_find_vlid()
754 vl_lookup[i].macaddr == key->vl.dmac) in sja1105_find_vlid()
759 return -1; in sja1105_find_vlid()
766 const struct sja1105_regs *regs = priv->info->regs; in sja1105_vl_stats()
767 u8 buf[SJA1105_SIZE_VL_STATUS] = {0}; in sja1105_vl_stats()
774 if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED) in sja1105_vl_stats()
775 return 0; in sja1105_vl_stats()
777 vlid = sja1105_find_vlid(priv, port, &rule->key); in sja1105_vl_stats()
778 if (vlid < 0) in sja1105_vl_stats()
779 return 0; in sja1105_vl_stats()
781 rc = sja1105_xfer_buf(priv, SPI_READ, regs->vl_status + 2 * vlid, buf, in sja1105_vl_stats()
789 sja1105_unpack(buf, &unreleased, 15, 0, SJA1105_SIZE_VL_STATUS); in sja1105_vl_stats()
794 flow_stats_update(stats, 0, pkts - rule->vl.stats.pkts, 0, in sja1105_vl_stats()
795 jiffies - rule->vl.stats.lastused, in sja1105_vl_stats()
798 rule->vl.stats.pkts = pkts; in sja1105_vl_stats()
799 rule->vl.stats.lastused = jiffies; in sja1105_vl_stats()
801 return 0; in sja1105_vl_stats()