Lines Matching +full:termination +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018, Sensor-Technik Wiedemann GmbH
3 * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
19 #include <linux/pcs/pcs-xpcs.h>
62 vlan = priv->static_config.tables[BLK_IDX_VLAN_LOOKUP].entries; in sja1105_is_vlan_configured()
63 count = priv->static_config.tables[BLK_IDX_VLAN_LOOKUP].entry_count; in sja1105_is_vlan_configured()
70 return -1; in sja1105_is_vlan_configured()
75 struct sja1105_private *priv = ds->priv; in sja1105_drop_untagged()
78 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_drop_untagged()
93 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_pvid_apply()
107 struct sja1105_private *priv = ds->priv; in sja1105_commit_pvid()
113 if (dp->bridge_dev && br_vlan_enabled(dp->bridge_dev)) in sja1105_commit_pvid()
114 pvid = priv->bridge_pvid[port]; in sja1105_commit_pvid()
116 pvid = priv->tag_8021q_pvid[port]; in sja1105_commit_pvid()
123 * VLAN-aware bridge. When the tag_8021q pvid is used, we are in sja1105_commit_pvid()
129 if (pvid == priv->bridge_pvid[port]) { in sja1105_commit_pvid()
130 vlan = priv->static_config.tables[BLK_IDX_VLAN_LOOKUP].entries; in sja1105_commit_pvid()
148 * Every queue i holds top[i] - base[i] frames. in sja1105_init_mac_settings()
149 * Sum of top[i] - base[i] is 511 (max hardware limit). in sja1105_init_mac_settings()
159 .speed = priv->info->port_speed[SJA1105_SPEED_AUTO], in sja1105_init_mac_settings()
160 /* No static correction for 1-step 1588 events */ in sja1105_init_mac_settings()
172 /* Don't drop double-tagged traffic */ in sja1105_init_mac_settings()
178 /* Disable learning and I/O on user ports by default - in sja1105_init_mac_settings()
186 struct dsa_switch *ds = priv->ds; in sja1105_init_mac_settings()
190 table = &priv->static_config.tables[BLK_IDX_MAC_CONFIG]; in sja1105_init_mac_settings()
193 if (table->entry_count) { in sja1105_init_mac_settings()
194 kfree(table->entries); in sja1105_init_mac_settings()
195 table->entry_count = 0; in sja1105_init_mac_settings()
198 table->entries = kcalloc(table->ops->max_entry_count, in sja1105_init_mac_settings()
199 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_mac_settings()
200 if (!table->entries) in sja1105_init_mac_settings()
201 return -ENOMEM; in sja1105_init_mac_settings()
203 table->entry_count = table->ops->max_entry_count; in sja1105_init_mac_settings()
205 mac = table->entries; in sja1105_init_mac_settings()
207 list_for_each_entry(dp, &ds->dst->ports, list) { in sja1105_init_mac_settings()
208 if (dp->ds != ds) in sja1105_init_mac_settings()
211 mac[dp->index] = default_mac; in sja1105_init_mac_settings()
214 * enabled for the DSA ports. CPU ports use software-assisted in sja1105_init_mac_settings()
217 * CPU ports in a cross-chip topology if multiple CPU ports in sja1105_init_mac_settings()
221 dp->learning = true; in sja1105_init_mac_settings()
227 mac[dp->index].drpuntag = true; in sja1105_init_mac_settings()
235 struct device *dev = &priv->spidev->dev; in sja1105_init_mii_settings()
237 struct dsa_switch *ds = priv->ds; in sja1105_init_mii_settings()
241 table = &priv->static_config.tables[BLK_IDX_XMII_PARAMS]; in sja1105_init_mii_settings()
244 if (table->entry_count) { in sja1105_init_mii_settings()
245 kfree(table->entries); in sja1105_init_mii_settings()
246 table->entry_count = 0; in sja1105_init_mii_settings()
249 table->entries = kcalloc(table->ops->max_entry_count, in sja1105_init_mii_settings()
250 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_mii_settings()
251 if (!table->entries) in sja1105_init_mii_settings()
252 return -ENOMEM; in sja1105_init_mii_settings()
255 table->entry_count = table->ops->max_entry_count; in sja1105_init_mii_settings()
257 mii = table->entries; in sja1105_init_mii_settings()
259 for (i = 0; i < ds->num_ports; i++) { in sja1105_init_mii_settings()
262 if (dsa_is_unused_port(priv->ds, i)) in sja1105_init_mii_settings()
265 switch (priv->phy_mode[i]) { in sja1105_init_mii_settings()
267 if (priv->info->internal_phy[i] == SJA1105_NO_PHY) in sja1105_init_mii_settings()
270 mii->xmii_mode[i] = XMII_MODE_MII; in sja1105_init_mii_settings()
271 if (priv->info->internal_phy[i] == SJA1105_PHY_BASE_TX) in sja1105_init_mii_settings()
272 mii->special[i] = true; in sja1105_init_mii_settings()
279 if (!priv->info->supports_mii[i]) in sja1105_init_mii_settings()
282 mii->xmii_mode[i] = XMII_MODE_MII; in sja1105_init_mii_settings()
288 if (!priv->info->supports_rmii[i]) in sja1105_init_mii_settings()
291 mii->xmii_mode[i] = XMII_MODE_RMII; in sja1105_init_mii_settings()
297 if (!priv->info->supports_rgmii[i]) in sja1105_init_mii_settings()
300 mii->xmii_mode[i] = XMII_MODE_RGMII; in sja1105_init_mii_settings()
303 if (!priv->info->supports_sgmii[i]) in sja1105_init_mii_settings()
306 mii->xmii_mode[i] = XMII_MODE_SGMII; in sja1105_init_mii_settings()
307 mii->special[i] = true; in sja1105_init_mii_settings()
310 if (!priv->info->supports_2500basex[i]) in sja1105_init_mii_settings()
313 mii->xmii_mode[i] = XMII_MODE_SGMII; in sja1105_init_mii_settings()
314 mii->special[i] = true; in sja1105_init_mii_settings()
319 phy_modes(priv->phy_mode[i]), i); in sja1105_init_mii_settings()
320 return -EINVAL; in sja1105_init_mii_settings()
323 mii->phy_mac[i] = role; in sja1105_init_mii_settings()
334 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; in sja1105_init_static_fdb()
337 * entries, except for a special entry at the end which is a catch-all in sja1105_init_static_fdb()
340 if (table->entry_count) { in sja1105_init_static_fdb()
341 kfree(table->entries); in sja1105_init_static_fdb()
342 table->entry_count = 0; in sja1105_init_static_fdb()
345 if (!priv->info->can_limit_mcast_flood) in sja1105_init_static_fdb()
348 table->entries = kcalloc(1, table->ops->unpacked_entry_size, in sja1105_init_static_fdb()
350 if (!table->entries) in sja1105_init_static_fdb()
351 return -ENOMEM; in sja1105_init_static_fdb()
353 table->entry_count = 1; in sja1105_init_static_fdb()
354 l2_lookup = table->entries; in sja1105_init_static_fdb()
360 l2_lookup[0].index = SJA1105_MAX_L2_LOOKUP_COUNT - 1; in sja1105_init_static_fdb()
363 for (port = 0; port < priv->ds->num_ports; port++) in sja1105_init_static_fdb()
364 if (!dsa_is_unused_port(priv->ds, port)) in sja1105_init_static_fdb()
385 /* Don't discard management traffic based on ENFPORT - in sja1105_init_l2_lookup_params()
402 struct dsa_switch *ds = priv->ds; in sja1105_init_l2_lookup_params()
407 for (port = 0; port < ds->num_ports; port++) in sja1105_init_l2_lookup_params()
413 for (port = 0; port < ds->num_ports; port++) { in sja1105_init_l2_lookup_params()
420 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS]; in sja1105_init_l2_lookup_params()
422 if (table->entry_count) { in sja1105_init_l2_lookup_params()
423 kfree(table->entries); in sja1105_init_l2_lookup_params()
424 table->entry_count = 0; in sja1105_init_l2_lookup_params()
427 table->entries = kcalloc(table->ops->max_entry_count, in sja1105_init_l2_lookup_params()
428 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_l2_lookup_params()
429 if (!table->entries) in sja1105_init_l2_lookup_params()
430 return -ENOMEM; in sja1105_init_l2_lookup_params()
432 table->entry_count = table->ops->max_entry_count; in sja1105_init_l2_lookup_params()
435 ((struct sja1105_l2_lookup_params_entry *)table->entries)[0] = in sja1105_init_l2_lookup_params()
443 * All DT-defined ports are members of this VLAN, and there are no
460 struct dsa_switch *ds = priv->ds; in sja1105_init_static_vlan()
463 table = &priv->static_config.tables[BLK_IDX_VLAN_LOOKUP]; in sja1105_init_static_vlan()
465 if (table->entry_count) { in sja1105_init_static_vlan()
466 kfree(table->entries); in sja1105_init_static_vlan()
467 table->entry_count = 0; in sja1105_init_static_vlan()
470 table->entries = kzalloc(table->ops->unpacked_entry_size, in sja1105_init_static_vlan()
472 if (!table->entries) in sja1105_init_static_vlan()
473 return -ENOMEM; in sja1105_init_static_vlan()
475 table->entry_count = 1; in sja1105_init_static_vlan()
477 for (port = 0; port < ds->num_ports; port++) { in sja1105_init_static_vlan()
486 priv->tag_8021q_pvid[port] = SJA1105_DEFAULT_VLAN; in sja1105_init_static_vlan()
487 priv->bridge_pvid[port] = SJA1105_DEFAULT_VLAN; in sja1105_init_static_vlan()
491 ((struct sja1105_vlan_lookup_entry *)table->entries)[0] = pvid; in sja1105_init_static_vlan()
498 struct dsa_switch *ds = priv->ds; in sja1105_init_l2_forwarding()
505 table = &priv->static_config.tables[BLK_IDX_L2_FORWARDING]; in sja1105_init_l2_forwarding()
507 if (table->entry_count) { in sja1105_init_l2_forwarding()
508 kfree(table->entries); in sja1105_init_l2_forwarding()
509 table->entry_count = 0; in sja1105_init_l2_forwarding()
512 table->entries = kcalloc(table->ops->max_entry_count, in sja1105_init_l2_forwarding()
513 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_l2_forwarding()
514 if (!table->entries) in sja1105_init_l2_forwarding()
515 return -ENOMEM; in sja1105_init_l2_forwarding()
517 table->entry_count = table->ops->max_entry_count; in sja1105_init_l2_forwarding()
519 l2fwd = table->entries; in sja1105_init_l2_forwarding()
525 for (port = 0; port < ds->num_ports; port++) { in sja1105_init_l2_forwarding()
534 * only to the always-on domain (CPU port and DSA links) in sja1105_init_l2_forwarding()
536 for (from = 0; from < ds->num_ports; from++) { in sja1105_init_l2_forwarding()
540 for (to = 0; to < ds->num_ports; to++) { in sja1105_init_l2_forwarding()
553 * always-on domain). These can send packets to any enabled port except in sja1105_init_l2_forwarding()
556 for (from = 0; from < ds->num_ports; from++) { in sja1105_init_l2_forwarding()
560 for (to = 0; to < ds->num_ports; to++) { in sja1105_init_l2_forwarding()
580 * stack termination. in sja1105_init_l2_forwarding()
582 dst = ds->dst; in sja1105_init_l2_forwarding()
584 list_for_each_entry(dl, &dst->rtable, list) { in sja1105_init_l2_forwarding()
585 if (dl->dp->ds != ds || dl->link_dp->cpu_dp == dl->dp->cpu_dp) in sja1105_init_l2_forwarding()
588 from = dl->dp->index; in sja1105_init_l2_forwarding()
591 dev_warn(ds->dev, in sja1105_init_l2_forwarding()
604 for (port = 0; port < ds->num_ports; port++) { in sja1105_init_l2_forwarding()
608 priv->ucast_egress_floods |= BIT(port); in sja1105_init_l2_forwarding()
609 priv->bcast_egress_floods |= BIT(port); in sja1105_init_l2_forwarding()
613 * Create a one-to-one mapping. in sja1105_init_l2_forwarding()
616 for (port = 0; port < ds->num_ports; port++) { in sja1105_init_l2_forwarding()
620 l2fwd[ds->num_ports + tc].vlan_pmap[port] = tc; in sja1105_init_l2_forwarding()
623 l2fwd[ds->num_ports + tc].type_egrpcp2outputq = true; in sja1105_init_l2_forwarding()
632 struct dsa_switch *ds = priv->ds; in sja1110_init_pcp_remapping()
636 table = &priv->static_config.tables[BLK_IDX_PCP_REMAPPING]; in sja1110_init_pcp_remapping()
639 if (!table->ops->max_entry_count) in sja1110_init_pcp_remapping()
642 if (table->entry_count) { in sja1110_init_pcp_remapping()
643 kfree(table->entries); in sja1110_init_pcp_remapping()
644 table->entry_count = 0; in sja1110_init_pcp_remapping()
647 table->entries = kcalloc(table->ops->max_entry_count, in sja1110_init_pcp_remapping()
648 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1110_init_pcp_remapping()
649 if (!table->entries) in sja1110_init_pcp_remapping()
650 return -ENOMEM; in sja1110_init_pcp_remapping()
652 table->entry_count = table->ops->max_entry_count; in sja1110_init_pcp_remapping()
654 pcp_remap = table->entries; in sja1110_init_pcp_remapping()
657 for (port = 0; port < ds->num_ports; port++) { in sja1110_init_pcp_remapping()
673 table = &priv->static_config.tables[BLK_IDX_L2_FORWARDING_PARAMS]; in sja1105_init_l2_forwarding_params()
675 if (table->entry_count) { in sja1105_init_l2_forwarding_params()
676 kfree(table->entries); in sja1105_init_l2_forwarding_params()
677 table->entry_count = 0; in sja1105_init_l2_forwarding_params()
680 table->entries = kcalloc(table->ops->max_entry_count, in sja1105_init_l2_forwarding_params()
681 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_l2_forwarding_params()
682 if (!table->entries) in sja1105_init_l2_forwarding_params()
683 return -ENOMEM; in sja1105_init_l2_forwarding_params()
685 table->entry_count = table->ops->max_entry_count; in sja1105_init_l2_forwarding_params()
688 l2fwd_params = table->entries; in sja1105_init_l2_forwarding_params()
691 l2fwd_params->max_dynp = 0; in sja1105_init_l2_forwarding_params()
693 l2fwd_params->part_spc[0] = priv->info->max_frame_mem; in sja1105_init_l2_forwarding_params()
704 table = &priv->static_config.tables[BLK_IDX_L2_FORWARDING_PARAMS]; in sja1105_frame_memory_partitioning()
705 l2_fwd_params = table->entries; in sja1105_frame_memory_partitioning()
706 l2_fwd_params->part_spc[0] = SJA1105_MAX_FRAME_MEMORY; in sja1105_frame_memory_partitioning()
708 /* If we have any critical-traffic virtual links, we need to reserve in sja1105_frame_memory_partitioning()
711 * remaining for best-effort traffic. TODO: figure out a more flexible in sja1105_frame_memory_partitioning()
714 if (!priv->static_config.tables[BLK_IDX_VL_FORWARDING].entry_count) in sja1105_frame_memory_partitioning()
717 table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING_PARAMS]; in sja1105_frame_memory_partitioning()
718 vl_fwd_params = table->entries; in sja1105_frame_memory_partitioning()
720 l2_fwd_params->part_spc[0] -= SJA1105_VL_FRAME_MEMORY; in sja1105_frame_memory_partitioning()
721 vl_fwd_params->partspc[0] = SJA1105_VL_FRAME_MEMORY; in sja1105_frame_memory_partitioning()
727 * -----+----------------+---------------+---------------+---------------
729 * 1 |0, [5:10], retag| [1:2] | [3:4] | -
730 * 2 | 0, [5:10] | [1:3], retag | 4 | -
731 * 3 | 0, [5:10] |[1:2], 4, retag| 3 | -
732 * 4 | 0, 2, [5:10] | 1, retag | [3:4] | -
733 * 5 | 0, 1, [5:10] | 2, retag | [3:4] | -
734 * 14 | 0, [5:10] | [1:4], retag | - | -
735 * 15 | [5:10] | [0:4], retag | - | -
746 if (priv->info->device_id != SJA1110_DEVICE_ID) in sja1110_select_tdmaconfigidx()
749 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; in sja1110_select_tdmaconfigidx()
750 general_params = table->entries; in sja1110_select_tdmaconfigidx()
755 port_1_is_base_tx = priv->phy_mode[1] == PHY_INTERFACE_MODE_INTERNAL; in sja1110_select_tdmaconfigidx()
756 port_3_is_2500 = priv->phy_mode[3] == PHY_INTERFACE_MODE_2500BASEX; in sja1110_select_tdmaconfigidx()
757 port_4_is_2500 = priv->phy_mode[4] == PHY_INTERFACE_MODE_2500BASEX; in sja1110_select_tdmaconfigidx()
775 general_params->tdmaconfigidx = tdmaconfigidx; in sja1110_select_tdmaconfigidx()
781 struct dsa_switch *ds = priv->ds; in sja1105_init_topology()
788 general_params->host_port = ds->num_ports; in sja1105_init_topology()
790 /* Link-local traffic received on casc_port will be forwarded in sja1105_init_topology()
800 if (!priv->info->multiple_cascade_ports) in sja1105_init_topology()
801 general_params->casc_port = ds->num_ports; in sja1105_init_topology()
803 for (port = 0; port < ds->num_ports; port++) { in sja1105_init_topology()
808 * upstream-facing DSA links in sja1105_init_topology()
811 if (general_params->host_port == ds->num_ports) { in sja1105_init_topology()
812 general_params->host_port = port; in sja1105_init_topology()
814 dev_err(ds->dev, in sja1105_init_topology()
816 general_params->host_port, port); in sja1105_init_topology()
817 return -EINVAL; in sja1105_init_topology()
821 /* Cascade ports are downstream-facing DSA links */ in sja1105_init_topology()
823 if (priv->info->multiple_cascade_ports) { in sja1105_init_topology()
824 general_params->casc_port |= BIT(port); in sja1105_init_topology()
825 } else if (general_params->casc_port == ds->num_ports) { in sja1105_init_topology()
826 general_params->casc_port = port; in sja1105_init_topology()
828 dev_err(ds->dev, in sja1105_init_topology()
830 general_params->casc_port, port); in sja1105_init_topology()
831 return -EINVAL; in sja1105_init_topology()
836 if (general_params->host_port == ds->num_ports) { in sja1105_init_topology()
837 dev_err(ds->dev, "No host port configured\n"); in sja1105_init_topology()
838 return -EINVAL; in sja1105_init_topology()
849 .switchid = priv->ds->index, in sja1105_init_general_params()
850 /* Priority queue for link-local management frames in sja1105_init_general_params()
851 * (both ingress to and egress from CPU - PTP, STP etc) in sja1105_init_general_params()
863 .mirr_port = priv->ds->num_ports, in sja1105_init_general_params()
868 /* Only update correctionField for 1-step PTP (L2 transport) */ in sja1105_init_general_params()
888 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; in sja1105_init_general_params()
890 if (table->entry_count) { in sja1105_init_general_params()
891 kfree(table->entries); in sja1105_init_general_params()
892 table->entry_count = 0; in sja1105_init_general_params()
895 table->entries = kcalloc(table->ops->max_entry_count, in sja1105_init_general_params()
896 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_general_params()
897 if (!table->entries) in sja1105_init_general_params()
898 return -ENOMEM; in sja1105_init_general_params()
900 table->entry_count = table->ops->max_entry_count; in sja1105_init_general_params()
902 general_params = table->entries; in sja1105_init_general_params()
917 table = &priv->static_config.tables[BLK_IDX_AVB_PARAMS]; in sja1105_init_avb_params()
920 if (table->entry_count) { in sja1105_init_avb_params()
921 kfree(table->entries); in sja1105_init_avb_params()
922 table->entry_count = 0; in sja1105_init_avb_params()
925 table->entries = kcalloc(table->ops->max_entry_count, in sja1105_init_avb_params()
926 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_avb_params()
927 if (!table->entries) in sja1105_init_avb_params()
928 return -ENOMEM; in sja1105_init_avb_params()
930 table->entry_count = table->ops->max_entry_count; in sja1105_init_avb_params()
932 avb = table->entries; in sja1105_init_avb_params()
935 avb->destmeta = SJA1105_META_DMAC; in sja1105_init_avb_params()
936 avb->srcmeta = SJA1105_META_SMAC; in sja1105_init_avb_params()
944 avb->cas_master = false; in sja1105_init_avb_params()
949 /* The L2 policing table is 2-stage. The table is looked up for each frame
957 * +------------+--------+ +---------------------------------+
959 * +------------+--------+ +---------------------------------+
961 * +------------+--------+ +---------------------------------+
963 * +------------+--------+ +---------------------------------+
965 * +------------+--------+ +---------------------------------+
967 * +------------+--------+ +---------------------------------+
969 * +------------+--------+ +---------------------------------+
971 * +------------+--------+ +---------------------------------+
973 * +------------+--------+ +---------------------------------+
975 * +------------+--------+
977 * +------------+--------+
979 * +------------+--------+
981 * +------------+--------+ +---------------------------------+
983 * +------------+--------+ +---------------------------------+
985 * In this driver, we shall use policers 0-4 as statically alocated port
997 struct dsa_switch *ds = priv->ds; in sja1105_init_l2_policing()
1001 table = &priv->static_config.tables[BLK_IDX_L2_POLICING]; in sja1105_init_l2_policing()
1004 if (table->entry_count) { in sja1105_init_l2_policing()
1005 kfree(table->entries); in sja1105_init_l2_policing()
1006 table->entry_count = 0; in sja1105_init_l2_policing()
1009 table->entries = kcalloc(table->ops->max_entry_count, in sja1105_init_l2_policing()
1010 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_l2_policing()
1011 if (!table->entries) in sja1105_init_l2_policing()
1012 return -ENOMEM; in sja1105_init_l2_policing()
1014 table->entry_count = table->ops->max_entry_count; in sja1105_init_l2_policing()
1016 policing = table->entries; in sja1105_init_l2_policing()
1019 for (port = 0; port < ds->num_ports; port++) { in sja1105_init_l2_policing()
1020 int mcast = (ds->num_ports * (SJA1105_NUM_TC + 1)) + port; in sja1105_init_l2_policing()
1021 int bcast = (ds->num_ports * SJA1105_NUM_TC) + port; in sja1105_init_l2_policing()
1028 if (mcast <= table->ops->max_entry_count) in sja1105_init_l2_policing()
1033 for (port = 0; port < ds->num_ports; port++) { in sja1105_init_l2_policing()
1052 sja1105_static_config_free(&priv->static_config); in sja1105_static_config_load()
1053 rc = sja1105_static_config_init(&priv->static_config, in sja1105_static_config_load()
1054 priv->info->static_ops, in sja1105_static_config_load()
1055 priv->info->device_id); in sja1105_static_config_load()
1100 struct dsa_switch *ds = priv->ds; in sja1105_parse_rgmii_delays()
1103 for (port = 0; port < ds->num_ports; port++) { in sja1105_parse_rgmii_delays()
1104 if (!priv->fixed_link[port]) in sja1105_parse_rgmii_delays()
1107 if (priv->phy_mode[port] == PHY_INTERFACE_MODE_RGMII_RXID || in sja1105_parse_rgmii_delays()
1108 priv->phy_mode[port] == PHY_INTERFACE_MODE_RGMII_ID) in sja1105_parse_rgmii_delays()
1109 priv->rgmii_rx_delay[port] = true; in sja1105_parse_rgmii_delays()
1111 if (priv->phy_mode[port] == PHY_INTERFACE_MODE_RGMII_TXID || in sja1105_parse_rgmii_delays()
1112 priv->phy_mode[port] == PHY_INTERFACE_MODE_RGMII_ID) in sja1105_parse_rgmii_delays()
1113 priv->rgmii_tx_delay[port] = true; in sja1105_parse_rgmii_delays()
1115 if ((priv->rgmii_rx_delay[port] || priv->rgmii_tx_delay[port]) && in sja1105_parse_rgmii_delays()
1116 !priv->info->setup_rgmii_delay) in sja1105_parse_rgmii_delays()
1117 return -EINVAL; in sja1105_parse_rgmii_delays()
1125 struct device *dev = &priv->spidev->dev; in sja1105_parse_ports_node()
1139 return -ENODEV; in sja1105_parse_ports_node()
1145 dev_err(dev, "Failed to read phy-mode or " in sja1105_parse_ports_node()
1146 "phy-interface-type property for port %d\n", in sja1105_parse_ports_node()
1149 return -ENODEV; in sja1105_parse_ports_node()
1152 phy_node = of_parse_phandle(child, "phy-handle", 0); in sja1105_parse_ports_node()
1155 dev_err(dev, "phy-handle or fixed-link " in sja1105_parse_ports_node()
1158 return -ENODEV; in sja1105_parse_ports_node()
1160 /* phy-handle is missing, but fixed-link isn't. in sja1105_parse_ports_node()
1163 priv->fixed_link[index] = true; in sja1105_parse_ports_node()
1168 priv->phy_mode[index] = phy_mode; in sja1105_parse_ports_node()
1176 struct device *dev = &priv->spidev->dev; in sja1105_parse_dt()
1177 struct device_node *switch_node = dev->of_node; in sja1105_parse_dt()
1183 ports_node = of_get_child_by_name(switch_node, "ethernet-ports"); in sja1105_parse_dt()
1186 return -ENODEV; in sja1105_parse_dt()
1199 if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS]) in sja1105_port_speed_to_ethtool()
1201 if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS]) in sja1105_port_speed_to_ethtool()
1203 if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) in sja1105_port_speed_to_ethtool()
1205 if (speed == priv->info->port_speed[SJA1105_SPEED_2500MBPS]) in sja1105_port_speed_to_ethtool()
1215 struct device *dev = priv->ds->dev; in sja1105_adjust_port_config()
1225 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_adjust_port_config()
1230 * the state->interface, but AN has not completed and the in sja1105_adjust_port_config()
1233 * ok for power consumption in case AN will never complete - in sja1105_adjust_port_config()
1236 speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; in sja1105_adjust_port_config()
1239 speed = priv->info->port_speed[SJA1105_SPEED_10MBPS]; in sja1105_adjust_port_config()
1242 speed = priv->info->port_speed[SJA1105_SPEED_100MBPS]; in sja1105_adjust_port_config()
1245 speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; in sja1105_adjust_port_config()
1248 speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; in sja1105_adjust_port_config()
1252 return -EINVAL; in sja1105_adjust_port_config()
1262 if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII) in sja1105_adjust_port_config()
1263 mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; in sja1105_adjust_port_config()
1264 else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX) in sja1105_adjust_port_config()
1265 mac[port].speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; in sja1105_adjust_port_config()
1283 if (!phy_interface_mode_is_rgmii(priv->phy_mode[port])) in sja1105_adjust_port_config()
1299 return priv->phy_mode[port] != interface; in sja1105_phy_mode_mismatch()
1307 struct sja1105_private *priv = ds->priv; in sja1105_mac_config()
1310 if (sja1105_phy_mode_mismatch(priv, port, state->interface)) { in sja1105_mac_config()
1311 dev_err(ds->dev, "Changing PHY mode to %s not supported!\n", in sja1105_mac_config()
1312 phy_modes(state->interface)); in sja1105_mac_config()
1316 xpcs = priv->xpcs[port]; in sja1105_mac_config()
1319 phylink_set_pcs(dp->pl, &xpcs->pcs); in sja1105_mac_config()
1326 sja1105_inhibit_tx(ds->priv, BIT(port), true); in sja1105_mac_link_down()
1336 struct sja1105_private *priv = ds->priv; in sja1105_mac_link_up()
1352 struct sja1105_private *priv = ds->priv; in sja1105_phylink_validate()
1355 mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries; in sja1105_phylink_validate()
1358 * When @state->interface is %PHY_INTERFACE_MODE_NA, phylink in sja1105_phylink_validate()
1361 if (state->interface != PHY_INTERFACE_MODE_NA && in sja1105_phylink_validate()
1362 sja1105_phy_mode_mismatch(priv, port, state->interface)) { in sja1105_phylink_validate()
1368 * support half-duplex traffic modes. in sja1105_phylink_validate()
1375 if (mii->xmii_mode[port] == XMII_MODE_RGMII || in sja1105_phylink_validate()
1376 mii->xmii_mode[port] == XMII_MODE_SGMII) in sja1105_phylink_validate()
1378 if (priv->info->supports_2500basex[port]) { in sja1105_phylink_validate()
1384 bitmap_and(state->advertising, state->advertising, mask, in sja1105_phylink_validate()
1396 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; in sja1105_find_static_fdb_entry()
1397 l2_lookup = table->entries; in sja1105_find_static_fdb_entry()
1399 for (i = 0; i < table->entry_count; i++) in sja1105_find_static_fdb_entry()
1400 if (l2_lookup[i].macaddr == requested->macaddr && in sja1105_find_static_fdb_entry()
1401 l2_lookup[i].vlanid == requested->vlanid && in sja1105_find_static_fdb_entry()
1405 return -1; in sja1105_find_static_fdb_entry()
1422 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; in sja1105_static_fdb_change()
1431 rc = sja1105_table_resize(table, table->entry_count + 1); in sja1105_static_fdb_change()
1435 match = table->entry_count - 1; in sja1105_static_fdb_change()
1439 l2_lookup = table->entries; in sja1105_static_fdb_change()
1455 l2_lookup[match] = l2_lookup[table->entry_count - 1]; in sja1105_static_fdb_change()
1456 return sja1105_table_resize(table, table->entry_count - 1); in sja1105_static_fdb_change()
1459 /* First-generation switches have a 4-way set associative TCAM that
1499 return -1; in sja1105et_is_fdb_entry_in_bin()
1506 struct sja1105_private *priv = ds->priv; in sja1105et_fdb_add()
1507 struct device *dev = ds->dev; in sja1105et_fdb_add()
1508 int last_unused = -1; in sja1105et_fdb_add()
1541 * static_config[BLK_IDX_L2_LOOKUP_PARAMS].entries->poly in sja1105et_fdb_add()
1568 if (rc == -ENOENT) in sja1105et_fdb_add()
1591 struct sja1105_private *priv = ds->priv; in sja1105et_fdb_del()
1626 struct sja1105_private *priv = ds->priv; in sja1105pqrs_fdb_add()
1632 l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0); in sja1105pqrs_fdb_add()
1640 if (rc == 0 && tmp.index != SJA1105_MAX_L2_LOOKUP_COUNT - 1) { in sja1105pqrs_fdb_add()
1657 * This is slightly inefficient because the strategy is knock-knock at in sja1105pqrs_fdb_add()
1667 dev_err(ds->dev, "FDB is full, cannot add entry.\n"); in sja1105pqrs_fdb_add()
1668 return -EINVAL; in sja1105pqrs_fdb_add()
1697 dev_err(ds->dev, in sja1105pqrs_fdb_add()
1717 struct sja1105_private *priv = ds->priv; in sja1105pqrs_fdb_del()
1723 l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0); in sja1105pqrs_fdb_del()
1753 struct sja1105_private *priv = ds->priv; in sja1105_fdb_add()
1755 return priv->info->fdb_add_cmd(ds, port, addr, vid); in sja1105_fdb_add()
1761 struct sja1105_private *priv = ds->priv; in sja1105_fdb_del()
1763 return priv->info->fdb_del_cmd(ds, port, addr, vid); in sja1105_fdb_del()
1769 struct sja1105_private *priv = ds->priv; in sja1105_fdb_dump()
1770 struct device *dev = ds->dev; in sja1105_fdb_dump()
1781 if (rc == -ENOENT) in sja1105_fdb_dump()
1791 * 1024-sized FDB table needs to be traversed 4 times through in sja1105_fdb_dump()
1805 if (!priv->vlan_aware) in sja1105_fdb_dump()
1816 struct sja1105_private *priv = ds->priv; in sja1105_fast_age()
1827 if (rc == -ENOENT) in sja1105_fast_age()
1830 dev_err(ds->dev, "Failed to read FDB: %pe\n", in sja1105_fast_age()
1846 dev_err(ds->dev, in sja1105_fast_age()
1857 return sja1105_fdb_add(ds, port, mdb->addr, mdb->vid); in sja1105_mdb_add()
1863 return sja1105_fdb_del(ds, port, mdb->addr, mdb->vid); in sja1105_mdb_del()
1875 struct dsa_switch *ds = priv->ds; in sja1105_manage_flood_domains()
1878 l2_fwd = priv->static_config.tables[BLK_IDX_L2_FORWARDING].entries; in sja1105_manage_flood_domains()
1880 for (from = 0; from < ds->num_ports; from++) { in sja1105_manage_flood_domains()
1883 for (to = 0; to < priv->ds->num_ports; to++) { in sja1105_manage_flood_domains()
1887 if (priv->ucast_egress_floods & BIT(to)) in sja1105_manage_flood_domains()
1889 if (priv->bcast_egress_floods & BIT(to)) in sja1105_manage_flood_domains()
1914 struct sja1105_private *priv = ds->priv; in sja1105_bridge_member()
1917 l2_fwd = priv->static_config.tables[BLK_IDX_L2_FORWARDING].entries; in sja1105_bridge_member()
1919 for (i = 0; i < ds->num_ports; i++) { in sja1105_bridge_member()
1936 if (dsa_to_port(ds, i)->bridge_dev != br) in sja1105_bridge_member()
1963 struct sja1105_private *priv = ds->priv; in sja1105_bridge_stp_state_set()
1966 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_bridge_stp_state_set()
1988 mac[port].dyn_learn = dp->learning; in sja1105_bridge_stp_state_set()
1993 mac[port].dyn_learn = dp->learning; in sja1105_bridge_stp_state_set()
1996 dev_err(ds->dev, "invalid STP state: %d\n", state); in sja1105_bridge_stp_state_set()
2022 for (i = 0; i < priv->info->num_cbs_shapers; i++) in sja1105_find_unused_cbs_shaper()
2023 if (!priv->cbs[i].idle_slope && !priv->cbs[i].send_slope) in sja1105_find_unused_cbs_shaper()
2026 return -1; in sja1105_find_unused_cbs_shaper()
2034 for (i = 0; i < priv->info->num_cbs_shapers; i++) { in sja1105_delete_cbs_shaper()
2035 struct sja1105_cbs_entry *cbs = &priv->cbs[i]; in sja1105_delete_cbs_shaper()
2037 if (cbs->port == port && cbs->prio == prio) { in sja1105_delete_cbs_shaper()
2050 struct sja1105_private *priv = ds->priv; in sja1105_setup_tc_cbs()
2054 if (!offload->enable) in sja1105_setup_tc_cbs()
2055 return sja1105_delete_cbs_shaper(priv, port, offload->queue); in sja1105_setup_tc_cbs()
2059 return -ENOSPC; in sja1105_setup_tc_cbs()
2061 cbs = &priv->cbs[index]; in sja1105_setup_tc_cbs()
2062 cbs->port = port; in sja1105_setup_tc_cbs()
2063 cbs->prio = offload->queue; in sja1105_setup_tc_cbs()
2067 cbs->credit_hi = offload->hicredit; in sja1105_setup_tc_cbs()
2068 cbs->credit_lo = abs(offload->locredit); in sja1105_setup_tc_cbs()
2070 cbs->idle_slope = offload->idleslope * BYTES_PER_KBIT; in sja1105_setup_tc_cbs()
2071 cbs->send_slope = abs(offload->sendslope * BYTES_PER_KBIT); in sja1105_setup_tc_cbs()
2072 /* Convert the negative values from 64-bit 2's complement in sja1105_setup_tc_cbs()
2073 * to 32-bit 2's complement (for the case of 0x80000000 whose in sja1105_setup_tc_cbs()
2076 cbs->credit_lo &= GENMASK_ULL(31, 0); in sja1105_setup_tc_cbs()
2077 cbs->send_slope &= GENMASK_ULL(31, 0); in sja1105_setup_tc_cbs()
2090 if (!priv->cbs) in sja1105_reload_cbs()
2093 for (i = 0; i < priv->info->num_cbs_shapers; i++) { in sja1105_reload_cbs()
2094 struct sja1105_cbs_entry *cbs = &priv->cbs[i]; in sja1105_reload_cbs()
2096 if (!cbs->idle_slope && !cbs->send_slope) in sja1105_reload_cbs()
2112 [SJA1105_SCHEDULING] = "Time-aware scheduling",
2113 [SJA1105_BEST_EFFORT_POLICING] = "Best-effort policing",
2131 struct dsa_switch *ds = priv->ds; in sja1105_static_config_reload()
2137 mutex_lock(&priv->mgmt_lock); in sja1105_static_config_reload()
2139 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_static_config_reload()
2142 * in order to temporarily restore it to SJA1105_SPEED_AUTO - which the in sja1105_static_config_reload()
2146 for (i = 0; i < ds->num_ports; i++) { in sja1105_static_config_reload()
2151 mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; in sja1105_static_config_reload()
2153 if (priv->xpcs[i]) in sja1105_static_config_reload()
2154 bmcr[i] = mdiobus_read(priv->mdio_pcs, i, reg_addr); in sja1105_static_config_reload()
2158 mutex_lock(&priv->ptp_data.lock); in sja1105_static_config_reload()
2162 mutex_unlock(&priv->ptp_data.lock); in sja1105_static_config_reload()
2169 mutex_unlock(&priv->ptp_data.lock); in sja1105_static_config_reload()
2175 mutex_unlock(&priv->ptp_data.lock); in sja1105_static_config_reload()
2183 /* Mid point, corresponds to pre-reset PTPCLKVAL */ in sja1105_static_config_reload()
2184 t12 = t1 + (t2 - t1) / 2; in sja1105_static_config_reload()
2185 /* Mid point, corresponds to post-reset PTPCLKVAL, aka 0 */ in sja1105_static_config_reload()
2186 t34 = t3 + (t4 - t3) / 2; in sja1105_static_config_reload()
2188 now += (t34 - t12); in sja1105_static_config_reload()
2192 mutex_unlock(&priv->ptp_data.lock); in sja1105_static_config_reload()
2194 dev_info(priv->ds->dev, in sja1105_static_config_reload()
2202 if (priv->info->clocking_setup) { in sja1105_static_config_reload()
2203 rc = priv->info->clocking_setup(priv); in sja1105_static_config_reload()
2208 for (i = 0; i < ds->num_ports; i++) { in sja1105_static_config_reload()
2209 struct dw_xpcs *xpcs = priv->xpcs[i]; in sja1105_static_config_reload()
2221 else if (priv->fixed_link[i]) in sja1105_static_config_reload()
2226 rc = xpcs_do_config(xpcs, priv->phy_mode[i], mode); in sja1105_static_config_reload()
2233 if (priv->phy_mode[i] == PHY_INTERFACE_MODE_2500BASEX) in sja1105_static_config_reload()
2242 xpcs_link_up(&xpcs->pcs, mode, priv->phy_mode[i], in sja1105_static_config_reload()
2251 mutex_unlock(&priv->mgmt_lock); in sja1105_static_config_reload()
2260 struct sja1105_private *priv = ds->priv; in sja1105_get_tag_protocol()
2262 return priv->info->tag_proto; in sja1105_get_tag_protocol()
2274 struct sja1105_private *priv = ds->priv; in sja1105_vlan_filtering()
2280 list_for_each_entry(rule, &priv->flow_block.rules, list) { in sja1105_vlan_filtering()
2281 if (rule->type == SJA1105_RULE_VL) { in sja1105_vlan_filtering()
2284 return -EBUSY; in sja1105_vlan_filtering()
2298 if (priv->vlan_aware == enabled) in sja1105_vlan_filtering()
2301 priv->vlan_aware = enabled; in sja1105_vlan_filtering()
2303 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; in sja1105_vlan_filtering()
2304 general_params = table->entries; in sja1105_vlan_filtering()
2305 /* EtherType used to identify inner tagged (C-tag) VLAN traffic */ in sja1105_vlan_filtering()
2306 general_params->tpid = tpid; in sja1105_vlan_filtering()
2307 /* EtherType used to identify outer tagged (S-tag) VLAN traffic */ in sja1105_vlan_filtering()
2308 general_params->tpid2 = tpid2; in sja1105_vlan_filtering()
2312 general_params->incl_srcpt1 = enabled; in sja1105_vlan_filtering()
2313 general_params->incl_srcpt0 = enabled; in sja1105_vlan_filtering()
2319 * pvid-tagged, and the FDB table gets populated with entries in sja1105_vlan_filtering()
2328 * learning badly - the VID of the learnt FDB entry is unique, aka in sja1105_vlan_filtering()
2333 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS]; in sja1105_vlan_filtering()
2334 l2_lookup_params = table->entries; in sja1105_vlan_filtering()
2335 l2_lookup_params->shared_learn = !priv->vlan_aware; in sja1105_vlan_filtering()
2337 for (port = 0; port < ds->num_ports; port++) { in sja1105_vlan_filtering()
2360 table = &priv->static_config.tables[BLK_IDX_VLAN_LOOKUP]; in sja1105_vlan_add()
2364 rc = sja1105_table_resize(table, table->entry_count + 1); in sja1105_vlan_add()
2367 match = table->entry_count - 1; in sja1105_vlan_add()
2371 vlan = table->entries; in sja1105_vlan_add()
2398 table = &priv->static_config.tables[BLK_IDX_VLAN_LOOKUP]; in sja1105_vlan_del()
2406 vlan = table->entries; in sja1105_vlan_del()
2437 struct sja1105_private *priv = ds->priv; in sja1105_bridge_vlan_add()
2438 u16 flags = vlan->flags; in sja1105_bridge_vlan_add()
2443 if (vid_is_dsa_8021q(vlan->vid)) { in sja1105_bridge_vlan_add()
2445 "Range 1024-3071 reserved for dsa_8021q operation"); in sja1105_bridge_vlan_add()
2446 return -EBUSY; in sja1105_bridge_vlan_add()
2449 /* Always install bridge VLANs as egress-tagged on CPU and DSA ports */ in sja1105_bridge_vlan_add()
2453 rc = sja1105_vlan_add(priv, port, vlan->vid, flags, true); in sja1105_bridge_vlan_add()
2457 if (vlan->flags & BRIDGE_VLAN_INFO_PVID) in sja1105_bridge_vlan_add()
2458 priv->bridge_pvid[port] = vlan->vid; in sja1105_bridge_vlan_add()
2466 struct sja1105_private *priv = ds->priv; in sja1105_bridge_vlan_del()
2469 rc = sja1105_vlan_del(priv, port, vlan->vid); in sja1105_bridge_vlan_del()
2482 struct sja1105_private *priv = ds->priv; in sja1105_dsa_8021q_vlan_add()
2497 priv->tag_8021q_pvid[port] = vid; in sja1105_dsa_8021q_vlan_add()
2504 struct sja1105_private *priv = ds->priv; in sja1105_dsa_8021q_vlan_del()
2512 struct netlink_ext_ack *extack = info->info.extack; in sja1105_prechangeupper()
2513 struct net_device *upper = info->upper_dev; in sja1105_prechangeupper()
2514 struct dsa_switch_tree *dst = ds->dst; in sja1105_prechangeupper()
2519 return -EBUSY; in sja1105_prechangeupper()
2523 list_for_each_entry(dp, &dst->ports, list) { in sja1105_prechangeupper()
2524 if (dp->bridge_dev && dp->bridge_dev != upper && in sja1105_prechangeupper()
2525 br_vlan_enabled(dp->bridge_dev)) { in sja1105_prechangeupper()
2527 "Only one VLAN-aware bridge is supported"); in sja1105_prechangeupper()
2528 return -EBUSY; in sja1105_prechangeupper()
2538 struct sja1105_private *priv = ds->priv; in sja1105_port_disable()
2539 struct sja1105_port *sp = &priv->ports[port]; in sja1105_port_disable()
2544 kthread_cancel_work_sync(&sp->xmit_work); in sja1105_port_disable()
2545 skb_queue_purge(&sp->xmit_queue); in sja1105_port_disable()
2552 struct sja1105_private *priv = ds->priv; in sja1105_mgmt_xmit()
2559 mgmt_route.macaddr = ether_addr_to_u64(hdr->h_dest); in sja1105_mgmt_xmit()
2573 dsa_enqueue_skb(skb, dsa_to_port(ds, port)->slave); in sja1105_mgmt_xmit()
2580 dev_err_ratelimited(priv->ds->dev, in sja1105_mgmt_xmit()
2590 } while (mgmt_route.enfport && --timeout); in sja1105_mgmt_xmit()
2593 /* Clean up the management route so that a follow-up in sja1105_mgmt_xmit()
2595 * This is only hardware supported on P/Q/R/S - on E/T it is in sja1105_mgmt_xmit()
2596 * a no-op and we are silently discarding the -EOPNOTSUPP. in sja1105_mgmt_xmit()
2600 dev_err_ratelimited(priv->ds->dev, "xmit timed out\n"); in sja1105_mgmt_xmit()
2618 struct sja1105_tagger_data *tagger_data = sp->data; in sja1105_port_deferred_xmit()
2620 int port = sp - priv->ports; in sja1105_port_deferred_xmit()
2623 while ((skb = skb_dequeue(&sp->xmit_queue)) != NULL) { in sja1105_port_deferred_xmit()
2624 struct sk_buff *clone = SJA1105_SKB_CB(skb)->clone; in sja1105_port_deferred_xmit()
2626 mutex_lock(&priv->mgmt_lock); in sja1105_port_deferred_xmit()
2628 sja1105_mgmt_xmit(priv->ds, port, 0, skb, !!clone); in sja1105_port_deferred_xmit()
2632 sja1105_ptp_txtstamp_skb(priv->ds, port, clone); in sja1105_port_deferred_xmit()
2634 mutex_unlock(&priv->mgmt_lock); in sja1105_port_deferred_xmit()
2645 struct sja1105_private *priv = ds->priv; in sja1105_set_ageing_time()
2649 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS]; in sja1105_set_ageing_time()
2650 l2_lookup_params = table->entries; in sja1105_set_ageing_time()
2654 if (l2_lookup_params->maxage == maxage) in sja1105_set_ageing_time()
2657 l2_lookup_params->maxage = maxage; in sja1105_set_ageing_time()
2665 struct sja1105_private *priv = ds->priv; in sja1105_change_mtu()
2672 policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries; in sja1105_change_mtu()
2684 return 2043 - VLAN_ETH_HLEN - ETH_FCS_LEN; in sja1105_get_max_mtu()
2697 return -EOPNOTSUPP; in sja1105_port_setup_tc()
2712 struct dsa_switch *ds = priv->ds; in sja1105_mirror_apply()
2718 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; in sja1105_mirror_apply()
2719 general_params = table->entries; in sja1105_mirror_apply()
2721 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_mirror_apply()
2723 already_enabled = (general_params->mirr_port != ds->num_ports); in sja1105_mirror_apply()
2724 if (already_enabled && enabled && general_params->mirr_port != to) { in sja1105_mirror_apply()
2725 dev_err(priv->ds->dev, in sja1105_mirror_apply()
2727 general_params->mirr_port); in sja1105_mirror_apply()
2728 return -EBUSY; in sja1105_mirror_apply()
2737 for (port = 0; port < ds->num_ports; port++) { in sja1105_mirror_apply()
2745 new_mirr_port = ds->num_ports; in sja1105_mirror_apply()
2747 if (new_mirr_port != general_params->mirr_port) { in sja1105_mirror_apply()
2748 general_params->mirr_port = new_mirr_port; in sja1105_mirror_apply()
2769 return sja1105_mirror_apply(ds->priv, port, mirror->to_local_port, in sja1105_mirror_add()
2776 sja1105_mirror_apply(ds->priv, port, mirror->to_local_port, in sja1105_mirror_del()
2777 mirror->ingress, false); in sja1105_mirror_del()
2784 struct sja1105_private *priv = ds->priv; in sja1105_port_policer_add()
2786 policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries; in sja1105_port_policer_add()
2792 policing[port].rate = div_u64(512 * policer->rate_bytes_per_sec, in sja1105_port_policer_add()
2794 policing[port].smax = policer->burst; in sja1105_port_policer_add()
2802 struct sja1105_private *priv = ds->priv; in sja1105_port_policer_del()
2804 policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries; in sja1105_port_policer_del()
2817 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_port_set_learning()
2830 priv->ucast_egress_floods |= BIT(to); in sja1105_port_ucast_bcast_flood()
2832 priv->ucast_egress_floods &= ~BIT(to); in sja1105_port_ucast_bcast_flood()
2837 priv->bcast_egress_floods |= BIT(to); in sja1105_port_ucast_bcast_flood()
2839 priv->bcast_egress_floods &= ~BIT(to); in sja1105_port_ucast_bcast_flood()
2853 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; in sja1105_port_mcast_flood()
2854 l2_lookup = table->entries; in sja1105_port_mcast_flood()
2856 for (match = 0; match < table->entry_count; match++) in sja1105_port_mcast_flood()
2861 if (match == table->entry_count) { in sja1105_port_mcast_flood()
2864 return -ENOSPC; in sja1105_port_mcast_flood()
2882 struct sja1105_private *priv = ds->priv; in sja1105_port_pre_bridge_flags()
2886 return -EINVAL; in sja1105_port_pre_bridge_flags()
2889 !priv->info->can_limit_mcast_flood) { in sja1105_port_pre_bridge_flags()
2896 return -EINVAL; in sja1105_port_pre_bridge_flags()
2907 struct sja1105_private *priv = ds->priv; in sja1105_port_bridge_flags()
2928 if (flags.mask & BR_MCAST_FLOOD && priv->info->can_limit_mcast_flood) { in sja1105_port_bridge_flags()
2940 struct dsa_switch *ds = priv->ds; in sja1105_teardown_ports()
2943 for (port = 0; port < ds->num_ports; port++) { in sja1105_teardown_ports()
2944 struct sja1105_port *sp = &priv->ports[port]; in sja1105_teardown_ports()
2946 if (sp->xmit_worker) in sja1105_teardown_ports()
2947 kthread_destroy_worker(sp->xmit_worker); in sja1105_teardown_ports()
2953 struct sja1105_tagger_data *tagger_data = &priv->tagger_data; in sja1105_setup_ports()
2954 struct dsa_switch *ds = priv->ds; in sja1105_setup_ports()
2958 for (port = 0; port < ds->num_ports; port++) { in sja1105_setup_ports()
2959 struct sja1105_port *sp = &priv->ports[port]; in sja1105_setup_ports()
2967 dp->priv = sp; in sja1105_setup_ports()
2968 sp->dp = dp; in sja1105_setup_ports()
2969 sp->data = tagger_data; in sja1105_setup_ports()
2970 slave = dp->slave; in sja1105_setup_ports()
2971 kthread_init_work(&sp->xmit_work, sja1105_port_deferred_xmit); in sja1105_setup_ports()
2972 worker = kthread_create_worker(0, "%s_xmit", slave->name); in sja1105_setup_ports()
2975 dev_err(ds->dev, in sja1105_setup_ports()
2980 sp->xmit_worker = worker; in sja1105_setup_ports()
2981 skb_queue_head_init(&sp->xmit_queue); in sja1105_setup_ports()
2991 /* The programming model for the SJA1105 switch is "all-at-once" via static
3005 struct sja1105_private *priv = ds->priv; in sja1105_setup()
3008 if (priv->info->disable_microcontroller) { in sja1105_setup()
3009 rc = priv->info->disable_microcontroller(priv); in sja1105_setup()
3011 dev_err(ds->dev, in sja1105_setup()
3021 dev_err(ds->dev, "Failed to load static config: %d\n", rc); in sja1105_setup()
3026 if (priv->info->clocking_setup) { in sja1105_setup()
3027 rc = priv->info->clocking_setup(priv); in sja1105_setup()
3029 dev_err(ds->dev, in sja1105_setup()
3045 dev_err(ds->dev, "Failed to register PTP clock: %d\n", rc); in sja1105_setup()
3051 dev_err(ds->dev, "Failed to register MDIO bus: %pe\n", in sja1105_setup()
3074 ds->vlan_filtering_is_global = true; in sja1105_setup()
3075 ds->untag_bridge_pvid = true; in sja1105_setup()
3077 ds->num_fwd_offloading_bridges = 7; in sja1105_setup()
3080 ds->num_tx_queues = SJA1105_NUM_TC; in sja1105_setup()
3082 ds->mtu_enforcement_ingress = true; in sja1105_setup()
3083 ds->assisted_learning_on_cpu_port = true; in sja1105_setup()
3098 sja1105_static_config_free(&priv->static_config); in sja1105_setup()
3105 struct sja1105_private *priv = ds->priv; in sja1105_teardown()
3117 sja1105_static_config_free(&priv->static_config); in sja1105_teardown()
3174 const struct sja1105_regs *regs = priv->info->regs; in sja1105_check_device_id()
3176 struct device *dev = &priv->spidev->dev; in sja1105_check_device_id()
3182 rc = sja1105_xfer_u32(priv, SPI_READ, regs->device_id, &device_id, in sja1105_check_device_id()
3187 rc = sja1105_xfer_buf(priv, SPI_READ, regs->prod_id, prod_id, in sja1105_check_device_id()
3194 for (match = sja1105_dt_ids; match->compatible[0]; match++) { in sja1105_check_device_id()
3195 const struct sja1105_info *info = match->data; in sja1105_check_device_id()
3198 if (info->device_id != device_id || info->part_no != part_no) in sja1105_check_device_id()
3202 if (priv->info->device_id != device_id || in sja1105_check_device_id()
3203 priv->info->part_no != part_no) { in sja1105_check_device_id()
3205 priv->info->name, info->name); in sja1105_check_device_id()
3207 priv->info = info; in sja1105_check_device_id()
3216 return -ENODEV; in sja1105_check_device_id()
3221 struct device *dev = &spi->dev; in sja1105_probe()
3227 if (!dev->of_node) { in sja1105_probe()
3229 return -EINVAL; in sja1105_probe()
3234 return -ENOMEM; in sja1105_probe()
3237 priv->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); in sja1105_probe()
3238 if (IS_ERR(priv->reset_gpio)) in sja1105_probe()
3239 dev_dbg(dev, "reset-gpios not defined, ignoring\n"); in sja1105_probe()
3241 sja1105_hw_reset(priv->reset_gpio, 1, 1); in sja1105_probe()
3246 priv->spidev = spi; in sja1105_probe()
3250 spi->bits_per_word = 8; in sja1105_probe()
3270 /* We need to send at least one 64-bit word of SPI payload per message in sja1105_probe()
3275 return -EINVAL; in sja1105_probe()
3278 priv->max_xfer_len = SJA1105_SIZE_SPI_MSG_MAXLEN; in sja1105_probe()
3279 if (priv->max_xfer_len > max_xfer) in sja1105_probe()
3280 priv->max_xfer_len = max_xfer; in sja1105_probe()
3281 if (priv->max_xfer_len > max_msg - SJA1105_SIZE_SPI_MSG_HEADER) in sja1105_probe()
3282 priv->max_xfer_len = max_msg - SJA1105_SIZE_SPI_MSG_HEADER; in sja1105_probe()
3284 priv->info = of_device_get_match_data(dev); in sja1105_probe()
3293 dev_info(dev, "Probed switch chip: %s\n", priv->info->name); in sja1105_probe()
3297 return -ENOMEM; in sja1105_probe()
3299 ds->dev = dev; in sja1105_probe()
3300 ds->num_ports = priv->info->num_ports; in sja1105_probe()
3301 ds->ops = &sja1105_switch_ops; in sja1105_probe()
3302 ds->priv = priv; in sja1105_probe()
3303 priv->ds = ds; in sja1105_probe()
3305 mutex_init(&priv->ptp_data.lock); in sja1105_probe()
3306 mutex_init(&priv->mgmt_lock); in sja1105_probe()
3310 dev_err(ds->dev, "Failed to parse DT: %d\n", rc); in sja1105_probe()
3319 dev_err(ds->dev, "RGMII delay not supported\n"); in sja1105_probe()
3324 priv->cbs = devm_kcalloc(dev, priv->info->num_cbs_shapers, in sja1105_probe()
3327 if (!priv->cbs) in sja1105_probe()
3328 return -ENOMEM; in sja1105_probe()
3331 return dsa_register_switch(priv->ds); in sja1105_probe()
3341 dsa_unregister_switch(priv->ds); in sja1105_remove()
3355 dsa_switch_shutdown(priv->ds); in sja1105_shutdown()
3389 MODULE_AUTHOR("Georg Waibel <georg.waibel@sensor-technik.de>");