Lines Matching +full:route +full:- +full:ptp

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>
68 * Every queue i holds top[i] - base[i] frames. in sja1105_init_mac_settings()
69 * Sum of top[i] - base[i] is 511 (max hardware limit). in sja1105_init_mac_settings()
80 /* No static correction for 1-step 1588 events */ in sja1105_init_mac_settings()
92 /* Don't drop double-tagged traffic */ in sja1105_init_mac_settings()
98 /* Disable learning and I/O on user ports by default - in sja1105_init_mac_settings()
109 table = &priv->static_config.tables[BLK_IDX_MAC_CONFIG]; in sja1105_init_mac_settings()
112 if (table->entry_count) { in sja1105_init_mac_settings()
113 kfree(table->entries); in sja1105_init_mac_settings()
114 table->entry_count = 0; in sja1105_init_mac_settings()
117 table->entries = kcalloc(SJA1105_NUM_PORTS, in sja1105_init_mac_settings()
118 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_mac_settings()
119 if (!table->entries) in sja1105_init_mac_settings()
120 return -ENOMEM; in sja1105_init_mac_settings()
122 table->entry_count = SJA1105_NUM_PORTS; in sja1105_init_mac_settings()
124 mac = table->entries; in sja1105_init_mac_settings()
128 if (i == dsa_upstream_port(priv->ds, i)) { in sja1105_init_mac_settings()
143 if (priv->info->part_no != SJA1105R_PART_NO && in sja1105_supports_sgmii()
144 priv->info->part_no != SJA1105S_PART_NO) in sja1105_supports_sgmii()
150 if (dsa_is_unused_port(priv->ds, port)) in sja1105_supports_sgmii()
159 struct device *dev = &priv->spidev->dev; in sja1105_init_mii_settings()
164 table = &priv->static_config.tables[BLK_IDX_XMII_PARAMS]; in sja1105_init_mii_settings()
167 if (table->entry_count) { in sja1105_init_mii_settings()
168 kfree(table->entries); in sja1105_init_mii_settings()
169 table->entry_count = 0; in sja1105_init_mii_settings()
172 table->entries = kcalloc(SJA1105_MAX_XMII_PARAMS_COUNT, in sja1105_init_mii_settings()
173 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_mii_settings()
174 if (!table->entries) in sja1105_init_mii_settings()
175 return -ENOMEM; in sja1105_init_mii_settings()
178 table->entry_count = SJA1105_MAX_XMII_PARAMS_COUNT; in sja1105_init_mii_settings()
180 mii = table->entries; in sja1105_init_mii_settings()
183 if (dsa_is_unused_port(priv->ds, i)) in sja1105_init_mii_settings()
188 mii->xmii_mode[i] = XMII_MODE_MII; in sja1105_init_mii_settings()
191 mii->xmii_mode[i] = XMII_MODE_RMII; in sja1105_init_mii_settings()
197 mii->xmii_mode[i] = XMII_MODE_RGMII; in sja1105_init_mii_settings()
201 return -EINVAL; in sja1105_init_mii_settings()
202 mii->xmii_mode[i] = XMII_MODE_SGMII; in sja1105_init_mii_settings()
214 mii->phy_mac[i] = XMII_MAC; in sja1105_init_mii_settings()
216 mii->phy_mac[i] = ports[i].role; in sja1105_init_mii_settings()
225 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; in sja1105_init_static_fdb()
230 if (table->entry_count) { in sja1105_init_static_fdb()
231 kfree(table->entries); in sja1105_init_static_fdb()
232 table->entry_count = 0; in sja1105_init_static_fdb()
256 /* Don't discard management traffic based on ENFPORT - in sja1105_init_l2_lookup_params()
274 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS]; in sja1105_init_l2_lookup_params()
276 if (table->entry_count) { in sja1105_init_l2_lookup_params()
277 kfree(table->entries); in sja1105_init_l2_lookup_params()
278 table->entry_count = 0; in sja1105_init_l2_lookup_params()
281 table->entries = kcalloc(SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, in sja1105_init_l2_lookup_params()
282 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_l2_lookup_params()
283 if (!table->entries) in sja1105_init_l2_lookup_params()
284 return -ENOMEM; in sja1105_init_l2_lookup_params()
286 table->entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT; in sja1105_init_l2_lookup_params()
289 ((struct sja1105_l2_lookup_params_entry *)table->entries)[0] = in sja1105_init_l2_lookup_params()
306 struct dsa_switch *ds = priv->ds; in sja1105_init_static_vlan()
309 table = &priv->static_config.tables[BLK_IDX_VLAN_LOOKUP]; in sja1105_init_static_vlan()
315 if (table->entry_count) { in sja1105_init_static_vlan()
316 kfree(table->entries); in sja1105_init_static_vlan()
317 table->entry_count = 0; in sja1105_init_static_vlan()
320 table->entries = kcalloc(1, table->ops->unpacked_entry_size, in sja1105_init_static_vlan()
322 if (!table->entries) in sja1105_init_static_vlan()
323 return -ENOMEM; in sja1105_init_static_vlan()
325 table->entry_count = 1; in sja1105_init_static_vlan()
327 /* VLAN 1: all DT-defined ports are members; no restrictions on in sja1105_init_static_vlan()
330 for (port = 0; port < ds->num_ports; port++) { in sja1105_init_static_vlan()
340 /* Let traffic that don't need dsa_8021q (e.g. STP, PTP) be in sja1105_init_static_vlan()
345 return -ENOMEM; in sja1105_init_static_vlan()
347 v->port = port; in sja1105_init_static_vlan()
348 v->vid = 1; in sja1105_init_static_vlan()
349 v->untagged = true; in sja1105_init_static_vlan()
351 v->pvid = true; in sja1105_init_static_vlan()
352 list_add(&v->list, &priv->dsa_8021q_vlans); in sja1105_init_static_vlan()
355 ((struct sja1105_vlan_lookup_entry *)table->entries)[0] = pvid; in sja1105_init_static_vlan()
365 table = &priv->static_config.tables[BLK_IDX_L2_FORWARDING]; in sja1105_init_l2_forwarding()
367 if (table->entry_count) { in sja1105_init_l2_forwarding()
368 kfree(table->entries); in sja1105_init_l2_forwarding()
369 table->entry_count = 0; in sja1105_init_l2_forwarding()
372 table->entries = kcalloc(SJA1105_MAX_L2_FORWARDING_COUNT, in sja1105_init_l2_forwarding()
373 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_l2_forwarding()
374 if (!table->entries) in sja1105_init_l2_forwarding()
375 return -ENOMEM; in sja1105_init_l2_forwarding()
377 table->entry_count = SJA1105_MAX_L2_FORWARDING_COUNT; in sja1105_init_l2_forwarding()
379 l2fwd = table->entries; in sja1105_init_l2_forwarding()
383 unsigned int upstream = dsa_upstream_port(priv->ds, i); in sja1105_init_l2_forwarding()
395 * Create a one-to-one mapping. in sja1105_init_l2_forwarding()
414 table = &priv->static_config.tables[BLK_IDX_L2_FORWARDING_PARAMS]; in sja1105_init_l2_forwarding_params()
416 if (table->entry_count) { in sja1105_init_l2_forwarding_params()
417 kfree(table->entries); in sja1105_init_l2_forwarding_params()
418 table->entry_count = 0; in sja1105_init_l2_forwarding_params()
421 table->entries = kcalloc(SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, in sja1105_init_l2_forwarding_params()
422 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_l2_forwarding_params()
423 if (!table->entries) in sja1105_init_l2_forwarding_params()
424 return -ENOMEM; in sja1105_init_l2_forwarding_params()
426 table->entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT; in sja1105_init_l2_forwarding_params()
429 ((struct sja1105_l2_forwarding_params_entry *)table->entries)[0] = in sja1105_init_l2_forwarding_params()
445 if (priv->vlan_state == SJA1105_VLAN_BEST_EFFORT) in sja1105_frame_memory_partitioning()
450 table = &priv->static_config.tables[BLK_IDX_L2_FORWARDING_PARAMS]; in sja1105_frame_memory_partitioning()
451 l2_fwd_params = table->entries; in sja1105_frame_memory_partitioning()
452 l2_fwd_params->part_spc[0] = max_mem; in sja1105_frame_memory_partitioning()
454 /* If we have any critical-traffic virtual links, we need to reserve in sja1105_frame_memory_partitioning()
457 * remaining for best-effort traffic. TODO: figure out a more flexible in sja1105_frame_memory_partitioning()
460 if (!priv->static_config.tables[BLK_IDX_VL_FORWARDING].entry_count) in sja1105_frame_memory_partitioning()
463 table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING_PARAMS]; in sja1105_frame_memory_partitioning()
464 vl_fwd_params = table->entries; in sja1105_frame_memory_partitioning()
466 l2_fwd_params->part_spc[0] -= SJA1105_VL_FRAME_MEMORY; in sja1105_frame_memory_partitioning()
467 vl_fwd_params->partspc[0] = SJA1105_VL_FRAME_MEMORY; in sja1105_frame_memory_partitioning()
475 .switchid = priv->ds->index, in sja1105_init_general_params()
476 /* Priority queue for link-local management frames in sja1105_init_general_params()
477 * (both ingress to and egress from CPU - PTP, STP etc) in sja1105_init_general_params()
491 * by installing a temporary 'management route' in sja1105_init_general_params()
493 .host_port = dsa_upstream_port(priv->ds, 0), in sja1105_init_general_params()
496 /* Link-local traffic received on casc_port will be forwarded in sja1105_init_general_params()
508 /* Only update correctionField for 1-step PTP (L2 transport) */ in sja1105_init_general_params()
518 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; in sja1105_init_general_params()
520 if (table->entry_count) { in sja1105_init_general_params()
521 kfree(table->entries); in sja1105_init_general_params()
522 table->entry_count = 0; in sja1105_init_general_params()
525 table->entries = kcalloc(SJA1105_MAX_GENERAL_PARAMS_COUNT, in sja1105_init_general_params()
526 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_general_params()
527 if (!table->entries) in sja1105_init_general_params()
528 return -ENOMEM; in sja1105_init_general_params()
530 table->entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT; in sja1105_init_general_params()
533 ((struct sja1105_general_params_entry *)table->entries)[0] = in sja1105_init_general_params()
544 table = &priv->static_config.tables[BLK_IDX_AVB_PARAMS]; in sja1105_init_avb_params()
547 if (table->entry_count) { in sja1105_init_avb_params()
548 kfree(table->entries); in sja1105_init_avb_params()
549 table->entry_count = 0; in sja1105_init_avb_params()
552 table->entries = kcalloc(SJA1105_MAX_AVB_PARAMS_COUNT, in sja1105_init_avb_params()
553 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_avb_params()
554 if (!table->entries) in sja1105_init_avb_params()
555 return -ENOMEM; in sja1105_init_avb_params()
557 table->entry_count = SJA1105_MAX_AVB_PARAMS_COUNT; in sja1105_init_avb_params()
559 avb = table->entries; in sja1105_init_avb_params()
562 avb->destmeta = SJA1105_META_DMAC; in sja1105_init_avb_params()
563 avb->srcmeta = SJA1105_META_SMAC; in sja1105_init_avb_params()
571 avb->cas_master = false; in sja1105_init_avb_params()
576 /* The L2 policing table is 2-stage. The table is looked up for each frame
584 * +------------+--------+ +---------------------------------+
586 * +------------+--------+ +---------------------------------+
588 * +------------+--------+ +---------------------------------+
590 * +------------+--------+ +---------------------------------+
592 * +------------+--------+ +---------------------------------+
594 * +------------+--------+ +---------------------------------+
596 * +------------+--------+ +---------------------------------+
598 * +------------+--------+ +---------------------------------+
600 * +------------+--------+ +---------------------------------+
602 * +------------+--------+
604 * +------------+--------+
606 * +------------+--------+
608 * +------------+--------+ +---------------------------------+
610 * +------------+--------+ +---------------------------------+
612 * In this driver, we shall use policers 0-4 as statically alocated port
627 table = &priv->static_config.tables[BLK_IDX_L2_POLICING]; in sja1105_init_l2_policing()
630 if (table->entry_count) { in sja1105_init_l2_policing()
631 kfree(table->entries); in sja1105_init_l2_policing()
632 table->entry_count = 0; in sja1105_init_l2_policing()
635 table->entries = kcalloc(SJA1105_MAX_L2_POLICING_COUNT, in sja1105_init_l2_policing()
636 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_init_l2_policing()
637 if (!table->entries) in sja1105_init_l2_policing()
638 return -ENOMEM; in sja1105_init_l2_policing()
640 table->entry_count = SJA1105_MAX_L2_POLICING_COUNT; in sja1105_init_l2_policing()
642 policing = table->entries; in sja1105_init_l2_policing()
658 if (dsa_is_cpu_port(priv->ds, port)) in sja1105_init_l2_policing()
675 sja1105_static_config_free(&priv->static_config); in sja1105_static_config_load()
676 rc = sja1105_static_config_init(&priv->static_config, in sja1105_static_config_load()
677 priv->info->static_ops, in sja1105_static_config_load()
678 priv->info->device_id); in sja1105_static_config_load()
729 priv->rgmii_rx_delay[i] = true; in sja1105_parse_rgmii_delays()
733 priv->rgmii_tx_delay[i] = true; in sja1105_parse_rgmii_delays()
735 if ((priv->rgmii_rx_delay[i] || priv->rgmii_tx_delay[i]) && in sja1105_parse_rgmii_delays()
736 !priv->info->setup_rgmii_delay) in sja1105_parse_rgmii_delays()
737 return -EINVAL; in sja1105_parse_rgmii_delays()
746 struct device *dev = &priv->spidev->dev; in sja1105_parse_ports_node()
760 return -ENODEV; in sja1105_parse_ports_node()
766 dev_err(dev, "Failed to read phy-mode or " in sja1105_parse_ports_node()
767 "phy-interface-type property for port %d\n", in sja1105_parse_ports_node()
770 return -ENODEV; in sja1105_parse_ports_node()
774 phy_node = of_parse_phandle(child, "phy-handle", 0); in sja1105_parse_ports_node()
777 dev_err(dev, "phy-handle or fixed-link " in sja1105_parse_ports_node()
780 return -ENODEV; in sja1105_parse_ports_node()
782 /* phy-handle is missing, but fixed-link isn't. in sja1105_parse_ports_node()
787 /* phy-handle present => put port in MAC role */ in sja1105_parse_ports_node()
793 if (of_property_read_bool(child, "sja1105,role-mac")) in sja1105_parse_ports_node()
795 else if (of_property_read_bool(child, "sja1105,role-phy")) in sja1105_parse_ports_node()
805 struct device *dev = &priv->spidev->dev; in sja1105_parse_dt()
806 struct device_node *switch_node = dev->of_node; in sja1105_parse_dt()
813 return -ENODEV; in sja1105_parse_dt()
824 const struct sja1105_regs *regs = priv->info->regs; in sja1105_sgmii_read()
828 rc = sja1105_xfer_u32(priv, SPI_READ, regs->sgmii + pcs_reg, &val, in sja1105_sgmii_read()
839 const struct sja1105_regs *regs = priv->info->regs; in sja1105_sgmii_write()
843 rc = sja1105_xfer_u32(priv, SPI_WRITE, regs->sgmii + pcs_reg, &val, in sja1105_sgmii_write()
856 /* DIGITAL_CONTROL_1: Enable vendor-specific MMD1, allow the PHY to in sja1105_sgmii_pcs_config()
870 /* BASIC_CONTROL: enable in-band AN now, if requested. Otherwise, in sja1105_sgmii_pcs_config()
895 dev_err(priv->ds->dev, "Invalid speed %d\n", speed); in sja1105_sgmii_pcs_force_speed()
915 struct device *dev = priv->ds->dev; in sja1105_adjust_port_config()
926 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_adjust_port_config()
927 mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries; in sja1105_adjust_port_config()
932 * the state->interface, but AN has not completed and the in sja1105_adjust_port_config()
935 * ok for power consumption in case AN will never complete - in sja1105_adjust_port_config()
951 return -EINVAL; in sja1105_adjust_port_config()
980 phy_mode = mii->xmii_mode[port]; in sja1105_adjust_port_config()
1000 mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries; in sja1105_phy_mode_mismatch()
1001 phy_mode = mii->xmii_mode[port]; in sja1105_phy_mode_mismatch()
1024 struct sja1105_private *priv = ds->priv; in sja1105_mac_config()
1027 if (sja1105_phy_mode_mismatch(priv, port, state->interface)) { in sja1105_mac_config()
1028 dev_err(ds->dev, "Changing PHY mode to %s not supported!\n", in sja1105_mac_config()
1029 phy_modes(state->interface)); in sja1105_mac_config()
1034 dev_err(ds->dev, "In-band AN not supported!\n"); in sja1105_mac_config()
1047 sja1105_inhibit_tx(ds->priv, BIT(port), true); in sja1105_mac_link_down()
1057 struct sja1105_private *priv = ds->priv; in sja1105_mac_link_up()
1076 struct sja1105_private *priv = ds->priv; in sja1105_phylink_validate()
1079 mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries; in sja1105_phylink_validate()
1082 * When @state->interface is %PHY_INTERFACE_MODE_NA, phylink in sja1105_phylink_validate()
1085 if (state->interface != PHY_INTERFACE_MODE_NA && in sja1105_phylink_validate()
1086 sja1105_phy_mode_mismatch(priv, port, state->interface)) { in sja1105_phylink_validate()
1092 * support half-duplex traffic modes. in sja1105_phylink_validate()
1099 if (mii->xmii_mode[port] == XMII_MODE_RGMII || in sja1105_phylink_validate()
1100 mii->xmii_mode[port] == XMII_MODE_SGMII) in sja1105_phylink_validate()
1104 bitmap_and(state->advertising, state->advertising, mask, in sja1105_phylink_validate()
1111 struct sja1105_private *priv = ds->priv; in sja1105_mac_pcs_get_state()
1114 /* Read the vendor-specific AUTONEG_INTR_STATUS register */ in sja1105_mac_pcs_get_state()
1121 state->speed = SPEED_10; in sja1105_mac_pcs_get_state()
1124 state->speed = SPEED_100; in sja1105_mac_pcs_get_state()
1127 state->speed = SPEED_1000; in sja1105_mac_pcs_get_state()
1130 dev_err(ds->dev, "Invalid SGMII PCS speed %lu\n", in sja1105_mac_pcs_get_state()
1133 state->duplex = SJA1105_AIS_DUPLEX_MODE(ais); in sja1105_mac_pcs_get_state()
1134 state->an_complete = SJA1105_AIS_COMPLETE(ais); in sja1105_mac_pcs_get_state()
1135 state->link = SJA1105_AIS_LINK_STATUS(ais); in sja1105_mac_pcs_get_state()
1148 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; in sja1105_find_static_fdb_entry()
1149 l2_lookup = table->entries; in sja1105_find_static_fdb_entry()
1151 for (i = 0; i < table->entry_count; i++) in sja1105_find_static_fdb_entry()
1152 if (l2_lookup[i].macaddr == requested->macaddr && in sja1105_find_static_fdb_entry()
1153 l2_lookup[i].vlanid == requested->vlanid && in sja1105_find_static_fdb_entry()
1157 return -1; in sja1105_find_static_fdb_entry()
1174 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; in sja1105_static_fdb_change()
1183 rc = sja1105_table_resize(table, table->entry_count + 1); in sja1105_static_fdb_change()
1187 match = table->entry_count - 1; in sja1105_static_fdb_change()
1191 l2_lookup = table->entries; in sja1105_static_fdb_change()
1207 l2_lookup[match] = l2_lookup[table->entry_count - 1]; in sja1105_static_fdb_change()
1208 return sja1105_table_resize(table, table->entry_count - 1); in sja1105_static_fdb_change()
1211 /* First-generation switches have a 4-way set associative TCAM that
1251 return -1; in sja1105et_is_fdb_entry_in_bin()
1258 struct sja1105_private *priv = ds->priv; in sja1105et_fdb_add()
1259 struct device *dev = ds->dev; in sja1105et_fdb_add()
1260 int last_unused = -1; in sja1105et_fdb_add()
1292 * static_config[BLK_IDX_L2_LOOKUP_PARAMS].entries->poly in sja1105et_fdb_add()
1318 struct sja1105_private *priv = ds->priv; in sja1105et_fdb_del()
1353 struct sja1105_private *priv = ds->priv; in sja1105pqrs_fdb_add()
1360 l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0); in sja1105pqrs_fdb_add()
1361 if (priv->vlan_state != SJA1105_VLAN_UNAWARE) { in sja1105pqrs_fdb_add()
1386 * This is slightly inefficient because the strategy is knock-knock at in sja1105pqrs_fdb_add()
1396 dev_err(ds->dev, "FDB is full, cannot add entry.\n"); in sja1105pqrs_fdb_add()
1397 return -EINVAL; in sja1105pqrs_fdb_add()
1416 struct sja1105_private *priv = ds->priv; in sja1105pqrs_fdb_del()
1423 l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0); in sja1105pqrs_fdb_del()
1424 if (priv->vlan_state != SJA1105_VLAN_UNAWARE) { in sja1105pqrs_fdb_del()
1459 struct sja1105_private *priv = ds->priv; in sja1105_fdb_add()
1466 * entries when in this mode - the actual VID doesn't matter except in sja1105_fdb_add()
1470 if (priv->vlan_state != SJA1105_VLAN_FILTERING_FULL) in sja1105_fdb_add()
1473 return priv->info->fdb_add_cmd(ds, port, addr, vid); in sja1105_fdb_add()
1479 struct sja1105_private *priv = ds->priv; in sja1105_fdb_del()
1481 if (priv->vlan_state != SJA1105_VLAN_FILTERING_FULL) in sja1105_fdb_del()
1484 return priv->info->fdb_del_cmd(ds, port, addr, vid); in sja1105_fdb_del()
1490 struct sja1105_private *priv = ds->priv; in sja1105_fdb_dump()
1491 struct device *dev = ds->dev; in sja1105_fdb_dump()
1502 if (rc == -ENOENT) in sja1105_fdb_dump()
1512 * 1024-sized FDB table needs to be traversed 4 times through in sja1105_fdb_dump()
1520 if (priv->vlan_state == SJA1105_VLAN_UNAWARE) in sja1105_fdb_dump()
1537 sja1105_fdb_add(ds, port, mdb->addr, mdb->vid); in sja1105_mdb_add()
1543 return sja1105_fdb_del(ds, port, mdb->addr, mdb->vid); in sja1105_mdb_del()
1550 struct sja1105_private *priv = ds->priv; in sja1105_bridge_member()
1553 l2_fwd = priv->static_config.tables[BLK_IDX_L2_FORWARDING].entries; in sja1105_bridge_member()
1572 if (dsa_to_port(ds, i)->bridge_dev != br) in sja1105_bridge_member()
1590 struct sja1105_private *priv = ds->priv; in sja1105_bridge_stp_state_set()
1593 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_bridge_stp_state_set()
1623 dev_err(ds->dev, "invalid STP state: %d\n", state); in sja1105_bridge_stp_state_set()
1649 for (i = 0; i < priv->info->num_cbs_shapers; i++) in sja1105_find_unused_cbs_shaper()
1650 if (!priv->cbs[i].idle_slope && !priv->cbs[i].send_slope) in sja1105_find_unused_cbs_shaper()
1653 return -1; in sja1105_find_unused_cbs_shaper()
1661 for (i = 0; i < priv->info->num_cbs_shapers; i++) { in sja1105_delete_cbs_shaper()
1662 struct sja1105_cbs_entry *cbs = &priv->cbs[i]; in sja1105_delete_cbs_shaper()
1664 if (cbs->port == port && cbs->prio == prio) { in sja1105_delete_cbs_shaper()
1677 struct sja1105_private *priv = ds->priv; in sja1105_setup_tc_cbs()
1681 if (!offload->enable) in sja1105_setup_tc_cbs()
1682 return sja1105_delete_cbs_shaper(priv, port, offload->queue); in sja1105_setup_tc_cbs()
1686 return -ENOSPC; in sja1105_setup_tc_cbs()
1688 cbs = &priv->cbs[index]; in sja1105_setup_tc_cbs()
1689 cbs->port = port; in sja1105_setup_tc_cbs()
1690 cbs->prio = offload->queue; in sja1105_setup_tc_cbs()
1694 cbs->credit_hi = offload->hicredit; in sja1105_setup_tc_cbs()
1695 cbs->credit_lo = abs(offload->locredit); in sja1105_setup_tc_cbs()
1697 cbs->idle_slope = offload->idleslope * BYTES_PER_KBIT; in sja1105_setup_tc_cbs()
1698 cbs->send_slope = abs(offload->sendslope * BYTES_PER_KBIT); in sja1105_setup_tc_cbs()
1699 /* Convert the negative values from 64-bit 2's complement in sja1105_setup_tc_cbs()
1700 * to 32-bit 2's complement (for the case of 0x80000000 whose in sja1105_setup_tc_cbs()
1703 cbs->credit_lo &= GENMASK_ULL(31, 0); in sja1105_setup_tc_cbs()
1704 cbs->send_slope &= GENMASK_ULL(31, 0); in sja1105_setup_tc_cbs()
1714 for (i = 0; i < priv->info->num_cbs_shapers; i++) { in sja1105_reload_cbs()
1715 struct sja1105_cbs_entry *cbs = &priv->cbs[i]; in sja1105_reload_cbs()
1717 if (!cbs->idle_slope && !cbs->send_slope) in sja1105_reload_cbs()
1733 [SJA1105_SCHEDULING] = "Time-aware scheduling",
1734 [SJA1105_BEST_EFFORT_POLICING] = "Best-effort policing",
1751 struct dsa_switch *ds = priv->ds; in sja1105_static_config_reload()
1758 mutex_lock(&priv->mgmt_lock); in sja1105_static_config_reload()
1760 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_static_config_reload()
1763 * in order to temporarily restore it to SJA1105_SPEED_AUTO - which the in sja1105_static_config_reload()
1775 /* No PTP operations can run right now */ in sja1105_static_config_reload()
1776 mutex_lock(&priv->ptp_data.lock); in sja1105_static_config_reload()
1795 /* Mid point, corresponds to pre-reset PTPCLKVAL */ in sja1105_static_config_reload()
1796 t12 = t1 + (t2 - t1) / 2; in sja1105_static_config_reload()
1797 /* Mid point, corresponds to post-reset PTPCLKVAL, aka 0 */ in sja1105_static_config_reload()
1798 t34 = t3 + (t4 - t3) / 2; in sja1105_static_config_reload()
1800 now += (t34 - t12); in sja1105_static_config_reload()
1805 mutex_unlock(&priv->ptp_data.lock); in sja1105_static_config_reload()
1807 dev_info(priv->ds->dev, in sja1105_static_config_reload()
1848 mutex_unlock(&priv->mgmt_lock); in sja1105_static_config_reload()
1857 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_pvid_apply()
1870 struct sja1105_private *other_priv = other_ds->priv; in sja1105_crosschip_bridge_join()
1871 struct sja1105_private *priv = ds->priv; in sja1105_crosschip_bridge_join()
1874 if (other_ds->ops != &sja1105_switch_ops) in sja1105_crosschip_bridge_join()
1877 for (port = 0; port < ds->num_ports; port++) { in sja1105_crosschip_bridge_join()
1880 if (dsa_to_port(ds, port)->bridge_dev != br) in sja1105_crosschip_bridge_join()
1883 rc = dsa_8021q_crosschip_bridge_join(priv->dsa_8021q_ctx, in sja1105_crosschip_bridge_join()
1885 other_priv->dsa_8021q_ctx, in sja1105_crosschip_bridge_join()
1890 rc = dsa_8021q_crosschip_bridge_join(other_priv->dsa_8021q_ctx, in sja1105_crosschip_bridge_join()
1892 priv->dsa_8021q_ctx, in sja1105_crosschip_bridge_join()
1907 struct sja1105_private *other_priv = other_ds->priv; in sja1105_crosschip_bridge_leave()
1908 struct sja1105_private *priv = ds->priv; in sja1105_crosschip_bridge_leave()
1911 if (other_ds->ops != &sja1105_switch_ops) in sja1105_crosschip_bridge_leave()
1914 for (port = 0; port < ds->num_ports; port++) { in sja1105_crosschip_bridge_leave()
1917 if (dsa_to_port(ds, port)->bridge_dev != br) in sja1105_crosschip_bridge_leave()
1920 dsa_8021q_crosschip_bridge_leave(priv->dsa_8021q_ctx, port, in sja1105_crosschip_bridge_leave()
1921 other_priv->dsa_8021q_ctx, in sja1105_crosschip_bridge_leave()
1924 dsa_8021q_crosschip_bridge_leave(other_priv->dsa_8021q_ctx, in sja1105_crosschip_bridge_leave()
1926 priv->dsa_8021q_ctx, port); in sja1105_crosschip_bridge_leave()
1932 struct sja1105_private *priv = ds->priv; in sja1105_setup_8021q_tagging()
1935 rc = dsa_8021q_setup(priv->dsa_8021q_ctx, enabled); in sja1105_setup_8021q_tagging()
1939 dev_info(ds->dev, "%s switch tagging\n", in sja1105_setup_8021q_tagging()
1962 return -1; in sja1105_find_free_subvlan()
1973 return -1; in sja1105_find_subvlan()
1979 struct sja1105_port *sp = &priv->ports[port]; in sja1105_find_committed_subvlan()
1981 return sja1105_find_subvlan(sp->subvlan_map, vid); in sja1105_find_committed_subvlan()
1995 struct sja1105_port *sp = &priv->ports[port]; in sja1105_commit_subvlan_map()
1999 sp->subvlan_map[subvlan] = subvlan_map[subvlan]; in sja1105_commit_subvlan_map()
2007 vlan = priv->static_config.tables[BLK_IDX_VLAN_LOOKUP].entries; in sja1105_is_vlan_configured()
2008 count = priv->static_config.tables[BLK_IDX_VLAN_LOOKUP].entry_count; in sja1105_is_vlan_configured()
2015 return -1; in sja1105_is_vlan_configured()
2032 return -1; in sja1105_find_retagging_entry()
2047 table = &priv->static_config.tables[BLK_IDX_VLAN_LOOKUP]; in sja1105_commit_vlans()
2048 vlan = table->entries; in sja1105_commit_vlans()
2058 dev_dbg(priv->ds->dev, "Deleting VLAN %d\n", i); in sja1105_commit_vlans()
2073 dev_dbg(priv->ds->dev, "Updating VLAN %d\n", i); in sja1105_commit_vlans()
2083 if (table->entry_count) in sja1105_commit_vlans()
2084 kfree(table->entries); in sja1105_commit_vlans()
2086 table->entries = kcalloc(num_vlans, table->ops->unpacked_entry_size, in sja1105_commit_vlans()
2088 if (!table->entries) in sja1105_commit_vlans()
2089 return -ENOMEM; in sja1105_commit_vlans()
2091 table->entry_count = num_vlans; in sja1105_commit_vlans()
2092 vlan = table->entries; in sja1105_commit_vlans()
2101 table = &priv->static_config.tables[BLK_IDX_RETAGGING]; in sja1105_commit_vlans()
2102 retagging = table->entries; in sja1105_commit_vlans()
2104 for (i = 0; i < table->entry_count; i++) { in sja1105_commit_vlans()
2111 if (table->entry_count) in sja1105_commit_vlans()
2112 kfree(table->entries); in sja1105_commit_vlans()
2114 table->entries = kcalloc(num_retagging, table->ops->unpacked_entry_size, in sja1105_commit_vlans()
2116 if (!table->entries) in sja1105_commit_vlans()
2117 return -ENOMEM; in sja1105_commit_vlans()
2119 table->entry_count = num_retagging; in sja1105_commit_vlans()
2120 retagging = table->entries; in sja1105_commit_vlans()
2155 if (priv->vlan_state == SJA1105_VLAN_FILTERING_FULL) in sja1105_commit_pvid()
2156 vlan_list = &priv->bridge_vlans; in sja1105_commit_pvid()
2158 vlan_list = &priv->dsa_8021q_vlans; in sja1105_commit_pvid()
2161 if (v->pvid) { in sja1105_commit_pvid()
2162 rc = sja1105_pvid_apply(priv, v->port, v->vid); in sja1105_commit_pvid()
2177 if (priv->vlan_state == SJA1105_VLAN_UNAWARE) in sja1105_build_bridge_vlans()
2180 list_for_each_entry(v, &priv->bridge_vlans, list) { in sja1105_build_bridge_vlans()
2181 int match = v->vid; in sja1105_build_bridge_vlans()
2183 new_vlan[match].vlanid = v->vid; in sja1105_build_bridge_vlans()
2184 new_vlan[match].vmemb_port |= BIT(v->port); in sja1105_build_bridge_vlans()
2185 new_vlan[match].vlan_bc |= BIT(v->port); in sja1105_build_bridge_vlans()
2186 if (!v->untagged) in sja1105_build_bridge_vlans()
2187 new_vlan[match].tag_port |= BIT(v->port); in sja1105_build_bridge_vlans()
2199 if (priv->vlan_state == SJA1105_VLAN_FILTERING_FULL) in sja1105_build_dsa_8021q_vlans()
2202 list_for_each_entry(v, &priv->dsa_8021q_vlans, list) { in sja1105_build_dsa_8021q_vlans()
2203 int match = v->vid; in sja1105_build_dsa_8021q_vlans()
2205 new_vlan[match].vlanid = v->vid; in sja1105_build_dsa_8021q_vlans()
2206 new_vlan[match].vmemb_port |= BIT(v->port); in sja1105_build_dsa_8021q_vlans()
2207 new_vlan[match].vlan_bc |= BIT(v->port); in sja1105_build_dsa_8021q_vlans()
2208 if (!v->untagged) in sja1105_build_dsa_8021q_vlans()
2209 new_vlan[match].tag_port |= BIT(v->port); in sja1105_build_dsa_8021q_vlans()
2224 if (priv->vlan_state != SJA1105_VLAN_BEST_EFFORT) in sja1105_build_subvlans()
2227 list_for_each_entry(v, &priv->bridge_vlans, list) { in sja1105_build_subvlans()
2228 int upstream = dsa_upstream_port(priv->ds, v->port); in sja1105_build_subvlans()
2232 /* Only sub-VLANs on user ports need to be applied. in sja1105_build_subvlans()
2236 if (!dsa_is_user_port(priv->ds, v->port)) in sja1105_build_subvlans()
2239 subvlan = sja1105_find_subvlan(subvlan_map[v->port], in sja1105_build_subvlans()
2240 v->vid); in sja1105_build_subvlans()
2242 subvlan = sja1105_find_free_subvlan(subvlan_map[v->port], in sja1105_build_subvlans()
2243 v->pvid); in sja1105_build_subvlans()
2245 dev_err(priv->ds->dev, "No more free subvlans\n"); in sja1105_build_subvlans()
2246 return -ENOSPC; in sja1105_build_subvlans()
2250 rx_vid = dsa_8021q_rx_vid_subvlan(priv->ds, v->port, subvlan); in sja1105_build_subvlans()
2252 /* @v->vid on @v->port needs to be retagged to @rx_vid in sja1105_build_subvlans()
2253 * on @upstream. Assume @v->vid on @v->port and on in sja1105_build_subvlans()
2259 new_vlan[match].vmemb_port |= BIT(v->port); in sja1105_build_subvlans()
2261 new_vlan[match].vlan_bc |= BIT(v->port); in sja1105_build_subvlans()
2266 if (!v->untagged) in sja1105_build_subvlans()
2267 new_vlan[match].tag_port |= BIT(v->port); in sja1105_build_subvlans()
2279 match = v->vid; in sja1105_build_subvlans()
2283 new_retagging[k].vlan_ing = v->vid; in sja1105_build_subvlans()
2285 new_retagging[k].ing_port = BIT(v->port); in sja1105_build_subvlans()
2288 dev_err(priv->ds->dev, "No more retagging rules\n"); in sja1105_build_subvlans()
2289 return -ENOSPC; in sja1105_build_subvlans()
2292 subvlan_map[v->port][subvlan] = v->vid; in sja1105_build_subvlans()
2317 if (priv->vlan_state != SJA1105_VLAN_BEST_EFFORT) in sja1105_build_crosschip_subvlans()
2322 list_for_each_entry(c, &priv->dsa_8021q_ctx->crosschip_links, list) { in sja1105_build_crosschip_subvlans()
2323 struct sja1105_private *other_priv = c->other_ctx->ds->priv; in sja1105_build_crosschip_subvlans()
2325 if (other_priv->vlan_state == SJA1105_VLAN_FILTERING_FULL) in sja1105_build_crosschip_subvlans()
2331 if (!dsa_is_user_port(priv->ds, c->port)) in sja1105_build_crosschip_subvlans()
2333 if (!dsa_is_user_port(c->other_ctx->ds, c->other_port)) in sja1105_build_crosschip_subvlans()
2337 list_for_each_entry(v, &other_priv->bridge_vlans, list) { in sja1105_build_crosschip_subvlans()
2341 if (v->port != c->other_port) in sja1105_build_crosschip_subvlans()
2345 * re-retagging, because its SVL field is 0 and we in sja1105_build_crosschip_subvlans()
2349 if (v->pvid) in sja1105_build_crosschip_subvlans()
2353 list_for_each_entry(w, &priv->bridge_vlans, list) { in sja1105_build_crosschip_subvlans()
2354 if (w->port == c->port && w->vid == v->vid) { in sja1105_build_crosschip_subvlans()
2364 if (tmp->vid == v->vid && in sja1105_build_crosschip_subvlans()
2365 tmp->untagged == v->untagged && in sja1105_build_crosschip_subvlans()
2366 tmp->port == c->port && in sja1105_build_crosschip_subvlans()
2367 tmp->other_port == v->port && in sja1105_build_crosschip_subvlans()
2368 tmp->other_ctx == c->other_ctx) { in sja1105_build_crosschip_subvlans()
2379 dev_err(priv->ds->dev, "Failed to allocate memory\n"); in sja1105_build_crosschip_subvlans()
2380 rc = -ENOMEM; in sja1105_build_crosschip_subvlans()
2383 tmp->vid = v->vid; in sja1105_build_crosschip_subvlans()
2384 tmp->port = c->port; in sja1105_build_crosschip_subvlans()
2385 tmp->other_port = v->port; in sja1105_build_crosschip_subvlans()
2386 tmp->other_ctx = c->other_ctx; in sja1105_build_crosschip_subvlans()
2387 tmp->untagged = v->untagged; in sja1105_build_crosschip_subvlans()
2388 list_add(&tmp->list, &crosschip_vlans); in sja1105_build_crosschip_subvlans()
2393 struct sja1105_private *other_priv = tmp->other_ctx->ds->priv; in sja1105_build_crosschip_subvlans()
2394 int upstream = dsa_upstream_port(priv->ds, tmp->port); in sja1105_build_crosschip_subvlans()
2399 tmp->other_port, in sja1105_build_crosschip_subvlans()
2400 tmp->vid); in sja1105_build_crosschip_subvlans()
2402 * have a subvlan for tmp->vid on tmp->other_port, but it in sja1105_build_crosschip_subvlans()
2406 rc = -EINVAL; in sja1105_build_crosschip_subvlans()
2410 rx_vid = dsa_8021q_rx_vid_subvlan(tmp->other_ctx->ds, in sja1105_build_crosschip_subvlans()
2411 tmp->other_port, in sja1105_build_crosschip_subvlans()
2414 /* The @rx_vid retagged from @tmp->vid on in sja1105_build_crosschip_subvlans()
2415 * {@tmp->other_ds, @tmp->other_port} needs to be in sja1105_build_crosschip_subvlans()
2416 * re-retagged to @tmp->vid on the way back to us. in sja1105_build_crosschip_subvlans()
2418 * Assume the original @tmp->vid is already configured in sja1105_build_crosschip_subvlans()
2426 new_vlan[match].vmemb_port |= BIT(tmp->port); in sja1105_build_crosschip_subvlans()
2434 if (!tmp->untagged) in sja1105_build_crosschip_subvlans()
2435 new_vlan[match].tag_port |= BIT(tmp->port); in sja1105_build_crosschip_subvlans()
2437 /* Deny egress of @rx_vid towards our front-panel port. in sja1105_build_crosschip_subvlans()
2439 * only the re-retagged packets (having the original, in sja1105_build_crosschip_subvlans()
2440 * pre-initial-retagging, VLAN @tmp->vid). in sja1105_build_crosschip_subvlans()
2442 new_vlan[match].vlan_bc &= ~BIT(tmp->port); in sja1105_build_crosschip_subvlans()
2449 upstream, rx_vid, tmp->vid); in sja1105_build_crosschip_subvlans()
2452 dev_err(priv->ds->dev, "No more retagging rules\n"); in sja1105_build_crosschip_subvlans()
2453 rc = -ENOSPC; in sja1105_build_crosschip_subvlans()
2460 new_retagging[k].vlan_egr = tmp->vid; in sja1105_build_crosschip_subvlans()
2462 new_retagging[k].egr_port |= BIT(tmp->port); in sja1105_build_crosschip_subvlans()
2467 list_del(&tmp->list); in sja1105_build_crosschip_subvlans()
2485 list_for_each_entry(c, &priv->dsa_8021q_ctx->crosschip_links, list) { in sja1105_notify_crosschip_switches()
2489 if (s->other_ctx == c->other_ctx) { in sja1105_notify_crosschip_switches()
2500 dev_err(priv->ds->dev, "Failed to allocate memory\n"); in sja1105_notify_crosschip_switches()
2501 rc = -ENOMEM; in sja1105_notify_crosschip_switches()
2504 s->other_ctx = c->other_ctx; in sja1105_notify_crosschip_switches()
2505 list_add(&s->list, &crosschip_switches); in sja1105_notify_crosschip_switches()
2509 struct sja1105_private *other_priv = s->other_ctx->ds->priv; in sja1105_notify_crosschip_switches()
2518 list_del(&s->list); in sja1105_notify_crosschip_switches()
2534 table = &priv->static_config.tables[BLK_IDX_VLAN_LOOKUP]; in sja1105_build_vlan_table()
2536 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_build_vlan_table()
2538 return -ENOMEM; in sja1105_build_vlan_table()
2540 table = &priv->static_config.tables[BLK_IDX_VLAN_LOOKUP]; in sja1105_build_vlan_table()
2542 table->ops->unpacked_entry_size, GFP_KERNEL); in sja1105_build_vlan_table()
2545 return -ENOMEM; in sja1105_build_vlan_table()
2554 for (i = 0; i < priv->ds->num_ports; i++) in sja1105_build_vlan_table()
2563 * - RX VLANs in sja1105_build_vlan_table()
2564 * - TX VLANs in sja1105_build_vlan_table()
2565 * - Crosschip links in sja1105_build_vlan_table()
2573 * - Sub-VLANs in sja1105_build_vlan_table()
2574 * - Sub-VLANs of crosschip switches in sja1105_build_vlan_table()
2594 for (i = 0; i < priv->ds->num_ports; i++) in sja1105_build_vlan_table()
2613 struct sja1105_private *priv = ds->priv; in sja1105_vlan_prepare()
2616 if (priv->vlan_state == SJA1105_VLAN_FILTERING_FULL) in sja1105_vlan_prepare()
2619 /* If the user wants best-effort VLAN filtering (aka vlan_filtering in sja1105_vlan_prepare()
2623 for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { in sja1105_vlan_prepare()
2625 dev_err(ds->dev, "Range 1024-3071 reserved for dsa_8021q operation\n"); in sja1105_vlan_prepare()
2626 return -EBUSY; in sja1105_vlan_prepare()
2642 struct sja1105_private *priv = ds->priv; in sja1105_vlan_filtering()
2651 list_for_each_entry(rule, &priv->flow_block.rules, list) { in sja1105_vlan_filtering()
2652 if (rule->type == SJA1105_RULE_VL) { in sja1105_vlan_filtering()
2653 dev_err(ds->dev, in sja1105_vlan_filtering()
2655 return -EBUSY; in sja1105_vlan_filtering()
2672 for (port = 0; port < ds->num_ports; port++) { in sja1105_vlan_filtering()
2673 struct sja1105_port *sp = &priv->ports[port]; in sja1105_vlan_filtering()
2676 sp->xmit_tpid = priv->info->qinq_tpid; in sja1105_vlan_filtering()
2678 sp->xmit_tpid = ETH_P_SJA1105; in sja1105_vlan_filtering()
2683 else if (priv->best_effort_vlan_filtering) in sja1105_vlan_filtering()
2688 if (priv->vlan_state == state) in sja1105_vlan_filtering()
2691 priv->vlan_state = state; in sja1105_vlan_filtering()
2695 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; in sja1105_vlan_filtering()
2696 general_params = table->entries; in sja1105_vlan_filtering()
2697 /* EtherType used to identify inner tagged (C-tag) VLAN traffic */ in sja1105_vlan_filtering()
2698 general_params->tpid = tpid; in sja1105_vlan_filtering()
2699 /* EtherType used to identify outer tagged (S-tag) VLAN traffic */ in sja1105_vlan_filtering()
2700 general_params->tpid2 = tpid2; in sja1105_vlan_filtering()
2704 general_params->incl_srcpt1 = enabled; in sja1105_vlan_filtering()
2705 general_params->incl_srcpt0 = enabled; in sja1105_vlan_filtering()
2707 want_tagging = priv->best_effort_vlan_filtering || !enabled; in sja1105_vlan_filtering()
2713 * pvid-tagged, and the FDB table gets populated with entries in sja1105_vlan_filtering()
2722 * learning badly - the VID of the learnt FDB entry is unique, aka in sja1105_vlan_filtering()
2727 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS]; in sja1105_vlan_filtering()
2728 l2_lookup_params = table->entries; in sja1105_vlan_filtering()
2729 l2_lookup_params->shared_learn = want_tagging; in sja1105_vlan_filtering()
2739 dev_err(ds->dev, "Failed to change VLAN Ethertype\n"); in sja1105_vlan_filtering()
2760 if (v->port == port && v->vid == vid && in sja1105_vlan_add_one()
2761 v->untagged == untagged && v->pvid == pvid) in sja1105_vlan_add_one()
2767 dev_err(ds->dev, "Out of memory while storing VLAN\n"); in sja1105_vlan_add_one()
2768 return -ENOMEM; in sja1105_vlan_add_one()
2771 v->port = port; in sja1105_vlan_add_one()
2772 v->vid = vid; in sja1105_vlan_add_one()
2773 v->untagged = untagged; in sja1105_vlan_add_one()
2774 v->pvid = pvid; in sja1105_vlan_add_one()
2775 list_add(&v->list, vlan_list); in sja1105_vlan_add_one()
2787 if (v->port == port && v->vid == vid) { in sja1105_vlan_del_one()
2788 list_del(&v->list); in sja1105_vlan_del_one()
2800 struct sja1105_private *priv = ds->priv; in sja1105_vlan_add()
2805 for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { in sja1105_vlan_add()
2806 rc = sja1105_vlan_add_one(ds, port, vid, vlan->flags, in sja1105_vlan_add()
2807 &priv->bridge_vlans); in sja1105_vlan_add()
2819 dev_err(ds->dev, "Failed to build VLAN table: %d\n", rc); in sja1105_vlan_add()
2825 struct sja1105_private *priv = ds->priv; in sja1105_vlan_del()
2830 for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { in sja1105_vlan_del()
2831 rc = sja1105_vlan_del_one(ds, port, vid, &priv->bridge_vlans); in sja1105_vlan_del()
2845 struct sja1105_private *priv = ds->priv; in sja1105_dsa_8021q_vlan_add()
2848 rc = sja1105_vlan_add_one(ds, port, vid, flags, &priv->dsa_8021q_vlans); in sja1105_dsa_8021q_vlan_add()
2857 struct sja1105_private *priv = ds->priv; in sja1105_dsa_8021q_vlan_del()
2860 rc = sja1105_vlan_del_one(ds, port, vid, &priv->dsa_8021q_vlans); in sja1105_dsa_8021q_vlan_del()
2872 /* The programming model for the SJA1105 switch is "all-at-once" via static
2887 struct sja1105_private *priv = ds->priv; in sja1105_setup()
2892 dev_err(ds->dev, "Failed to parse DT: %d\n", rc); in sja1105_setup()
2901 dev_err(ds->dev, "RGMII delay not supported\n"); in sja1105_setup()
2907 dev_err(ds->dev, "Failed to register PTP clock: %d\n", rc); in sja1105_setup()
2913 dev_err(ds->dev, "Failed to load static config: %d\n", rc); in sja1105_setup()
2919 dev_err(ds->dev, "Failed to configure MII clocking: %d\n", rc); in sja1105_setup()
2930 ds->vlan_filtering_is_global = true; in sja1105_setup()
2933 ds->num_tx_queues = SJA1105_NUM_TC; in sja1105_setup()
2935 ds->mtu_enforcement_ingress = true; in sja1105_setup()
2937 ds->configure_vlan_while_not_filtering = true; in sja1105_setup()
2956 struct sja1105_private *priv = ds->priv; in sja1105_teardown()
2961 struct sja1105_port *sp = &priv->ports[port]; in sja1105_teardown()
2966 if (sp->xmit_worker) in sja1105_teardown()
2967 kthread_destroy_worker(sp->xmit_worker); in sja1105_teardown()
2974 sja1105_static_config_free(&priv->static_config); in sja1105_teardown()
2976 list_for_each_entry_safe(v, n, &priv->dsa_8021q_vlans, list) { in sja1105_teardown()
2977 list_del(&v->list); in sja1105_teardown()
2981 list_for_each_entry_safe(v, n, &priv->bridge_vlans, list) { in sja1105_teardown()
2982 list_del(&v->list); in sja1105_teardown()
2995 slave = dsa_to_port(ds, port)->slave; in sja1105_port_enable()
2997 slave->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; in sja1105_port_enable()
3004 struct sja1105_private *priv = ds->priv; in sja1105_port_disable()
3005 struct sja1105_port *sp = &priv->ports[port]; in sja1105_port_disable()
3010 kthread_cancel_work_sync(&sp->xmit_work); in sja1105_port_disable()
3011 skb_queue_purge(&sp->xmit_queue); in sja1105_port_disable()
3018 struct sja1105_private *priv = ds->priv; in sja1105_mgmt_xmit()
3025 mgmt_route.macaddr = ether_addr_to_u64(hdr->h_dest); in sja1105_mgmt_xmit()
3039 dsa_enqueue_skb(skb, dsa_to_port(ds, port)->slave); in sja1105_mgmt_xmit()
3046 dev_err_ratelimited(priv->ds->dev, in sja1105_mgmt_xmit()
3047 "failed to poll for mgmt route\n"); in sja1105_mgmt_xmit()
3056 } while (mgmt_route.enfport && --timeout); in sja1105_mgmt_xmit()
3059 /* Clean up the management route so that a follow-up in sja1105_mgmt_xmit()
3061 * This is only hardware supported on P/Q/R/S - on E/T it is in sja1105_mgmt_xmit()
3062 * a no-op and we are silently discarding the -EOPNOTSUPP. in sja1105_mgmt_xmit()
3066 dev_err_ratelimited(priv->ds->dev, "xmit timed out\n"); in sja1105_mgmt_xmit()
3078 * route cannot be done from atomit context (SPI transfer takes a sleepable
3084 struct sja1105_tagger_data *tagger_data = sp->data; in sja1105_port_deferred_xmit()
3086 int port = sp - priv->ports; in sja1105_port_deferred_xmit()
3089 while ((skb = skb_dequeue(&sp->xmit_queue)) != NULL) { in sja1105_port_deferred_xmit()
3090 struct sk_buff *clone = DSA_SKB_CB(skb)->clone; in sja1105_port_deferred_xmit()
3092 mutex_lock(&priv->mgmt_lock); in sja1105_port_deferred_xmit()
3094 sja1105_mgmt_xmit(priv->ds, port, 0, skb, !!clone); in sja1105_port_deferred_xmit()
3098 sja1105_ptp_txtstamp_skb(priv->ds, port, clone); in sja1105_port_deferred_xmit()
3100 mutex_unlock(&priv->mgmt_lock); in sja1105_port_deferred_xmit()
3111 struct sja1105_private *priv = ds->priv; in sja1105_set_ageing_time()
3115 table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS]; in sja1105_set_ageing_time()
3116 l2_lookup_params = table->entries; in sja1105_set_ageing_time()
3120 if (l2_lookup_params->maxage == maxage) in sja1105_set_ageing_time()
3123 l2_lookup_params->maxage = maxage; in sja1105_set_ageing_time()
3131 struct sja1105_private *priv = ds->priv; in sja1105_change_mtu()
3138 policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries; in sja1105_change_mtu()
3150 return 2043 - VLAN_ETH_HLEN - ETH_FCS_LEN; in sja1105_get_max_mtu()
3163 return -EOPNOTSUPP; in sja1105_port_setup_tc()
3183 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; in sja1105_mirror_apply()
3184 general_params = table->entries; in sja1105_mirror_apply()
3186 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; in sja1105_mirror_apply()
3188 already_enabled = (general_params->mirr_port != SJA1105_NUM_PORTS); in sja1105_mirror_apply()
3189 if (already_enabled && enabled && general_params->mirr_port != to) { in sja1105_mirror_apply()
3190 dev_err(priv->ds->dev, in sja1105_mirror_apply()
3192 general_params->mirr_port); in sja1105_mirror_apply()
3193 return -EBUSY; in sja1105_mirror_apply()
3212 if (new_mirr_port != general_params->mirr_port) { in sja1105_mirror_apply()
3213 general_params->mirr_port = new_mirr_port; in sja1105_mirror_apply()
3234 return sja1105_mirror_apply(ds->priv, port, mirror->to_local_port, in sja1105_mirror_add()
3241 sja1105_mirror_apply(ds->priv, port, mirror->to_local_port, in sja1105_mirror_del()
3242 mirror->ingress, false); in sja1105_mirror_del()
3249 struct sja1105_private *priv = ds->priv; in sja1105_port_policer_add()
3251 policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries; in sja1105_port_policer_add()
3257 policing[port].rate = div_u64(512 * policer->rate_bytes_per_sec, in sja1105_port_policer_add()
3259 policing[port].smax = policer->burst; in sja1105_port_policer_add()
3267 struct sja1105_private *priv = ds->priv; in sja1105_port_policer_del()
3269 policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries; in sja1105_port_policer_del()
3331 const struct sja1105_regs *regs = priv->info->regs; in sja1105_check_device_id()
3333 struct device *dev = &priv->spidev->dev; in sja1105_check_device_id()
3339 rc = sja1105_xfer_u32(priv, SPI_READ, regs->device_id, &device_id, in sja1105_check_device_id()
3344 rc = sja1105_xfer_buf(priv, SPI_READ, regs->prod_id, prod_id, in sja1105_check_device_id()
3351 for (match = sja1105_dt_ids; match->compatible[0]; match++) { in sja1105_check_device_id()
3352 const struct sja1105_info *info = match->data; in sja1105_check_device_id()
3355 if (info->device_id != device_id || info->part_no != part_no) in sja1105_check_device_id()
3359 if (priv->info->device_id != device_id || in sja1105_check_device_id()
3360 priv->info->part_no != part_no) { in sja1105_check_device_id()
3362 priv->info->name, info->name); in sja1105_check_device_id()
3364 priv->info = info; in sja1105_check_device_id()
3373 return -ENODEV; in sja1105_check_device_id()
3379 struct device *dev = &spi->dev; in sja1105_probe()
3384 if (!dev->of_node) { in sja1105_probe()
3386 return -EINVAL; in sja1105_probe()
3391 return -ENOMEM; in sja1105_probe()
3394 priv->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); in sja1105_probe()
3395 if (IS_ERR(priv->reset_gpio)) in sja1105_probe()
3396 dev_dbg(dev, "reset-gpios not defined, ignoring\n"); in sja1105_probe()
3398 sja1105_hw_reset(priv->reset_gpio, 1, 1); in sja1105_probe()
3403 priv->spidev = spi; in sja1105_probe()
3407 spi->bits_per_word = 8; in sja1105_probe()
3414 priv->info = of_device_get_match_data(dev); in sja1105_probe()
3423 dev_info(dev, "Probed switch chip: %s\n", priv->info->name); in sja1105_probe()
3427 return -ENOMEM; in sja1105_probe()
3429 ds->dev = dev; in sja1105_probe()
3430 ds->num_ports = SJA1105_NUM_PORTS; in sja1105_probe()
3431 ds->ops = &sja1105_switch_ops; in sja1105_probe()
3432 ds->priv = priv; in sja1105_probe()
3433 priv->ds = ds; in sja1105_probe()
3435 tagger_data = &priv->tagger_data; in sja1105_probe()
3437 mutex_init(&priv->ptp_data.lock); in sja1105_probe()
3438 mutex_init(&priv->mgmt_lock); in sja1105_probe()
3440 priv->dsa_8021q_ctx = devm_kzalloc(dev, sizeof(*priv->dsa_8021q_ctx), in sja1105_probe()
3442 if (!priv->dsa_8021q_ctx) in sja1105_probe()
3443 return -ENOMEM; in sja1105_probe()
3445 priv->dsa_8021q_ctx->ops = &sja1105_dsa_8021q_ops; in sja1105_probe()
3446 priv->dsa_8021q_ctx->proto = htons(ETH_P_8021Q); in sja1105_probe()
3447 priv->dsa_8021q_ctx->ds = ds; in sja1105_probe()
3449 INIT_LIST_HEAD(&priv->dsa_8021q_ctx->crosschip_links); in sja1105_probe()
3450 INIT_LIST_HEAD(&priv->bridge_vlans); in sja1105_probe()
3451 INIT_LIST_HEAD(&priv->dsa_8021q_vlans); in sja1105_probe()
3456 rc = dsa_register_switch(priv->ds); in sja1105_probe()
3461 priv->cbs = devm_kcalloc(dev, priv->info->num_cbs_shapers, in sja1105_probe()
3464 if (!priv->cbs) in sja1105_probe()
3465 return -ENOMEM; in sja1105_probe()
3470 struct sja1105_port *sp = &priv->ports[port]; in sja1105_probe()
3478 dp->priv = sp; in sja1105_probe()
3479 sp->dp = dp; in sja1105_probe()
3480 sp->data = tagger_data; in sja1105_probe()
3481 slave = dp->slave; in sja1105_probe()
3482 kthread_init_work(&sp->xmit_work, sja1105_port_deferred_xmit); in sja1105_probe()
3483 sp->xmit_worker = kthread_create_worker(0, "%s_xmit", in sja1105_probe()
3484 slave->name); in sja1105_probe()
3485 if (IS_ERR(sp->xmit_worker)) { in sja1105_probe()
3486 rc = PTR_ERR(sp->xmit_worker); in sja1105_probe()
3487 dev_err(ds->dev, in sja1105_probe()
3492 skb_queue_head_init(&sp->xmit_queue); in sja1105_probe()
3493 sp->xmit_tpid = ETH_P_SJA1105; in sja1105_probe()
3496 sp->subvlan_map[subvlan] = VLAN_N_VID; in sja1105_probe()
3501 while (port-- > 0) { in sja1105_probe()
3502 struct sja1105_port *sp = &priv->ports[port]; in sja1105_probe()
3507 kthread_destroy_worker(sp->xmit_worker); in sja1105_probe()
3516 dsa_unregister_switch(priv->ds); in sja1105_remove()
3544 MODULE_AUTHOR("Georg Waibel <georg.waibel@sensor-technik.de>");