Lines Matching +full:data +full:- +full:mirror
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2017-2019 Microchip Technology Inc.
11 #include <linux/platform_data/microchip-ksz.h>
24 regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0); in ksz_cfg()
30 regmap_update_bits(dev->regmap[0], PORT_CTRL_ADDR(port, offset), in ksz_port_cfg()
36 regmap_update_bits(dev->regmap[2], addr, bits, set ? bits : 0); in ksz9477_cfg32()
42 regmap_update_bits(dev->regmap[2], PORT_CTRL_ADDR(port, offset), in ksz9477_port_cfg32()
53 /* Cache the per-port MTU setting */ in ksz9477_change_mtu()
54 dev->ports[port].max_frame = frame_size; in ksz9477_change_mtu()
56 for (i = 0; i < dev->info->port_cnt; i++) in ksz9477_change_mtu()
57 max_frame = max(max_frame, dev->ports[i].max_frame); in ksz9477_change_mtu()
59 return regmap_update_bits(dev->regmap[1], REG_SW_MTU__2, in ksz9477_change_mtu()
65 return KSZ9477_MAX_FRAME_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN; in ksz9477_max_mtu()
72 return regmap_read_poll_timeout(dev->regmap[0], REG_SW_VLAN_CTRL, in ksz9477_wait_vlan_ctrl_ready()
81 mutex_lock(&dev->vlan_mutex); in ksz9477_get_vlan_table()
89 dev_dbg(dev->dev, "Failed to read vlan table\n"); in ksz9477_get_vlan_table()
100 mutex_unlock(&dev->vlan_mutex); in ksz9477_get_vlan_table()
110 mutex_lock(&dev->vlan_mutex); in ksz9477_set_vlan_table()
122 dev_dbg(dev->dev, "Failed to write vlan table\n"); in ksz9477_set_vlan_table()
129 dev->vlan_cache[vid].table[0] = vlan_table[0]; in ksz9477_set_vlan_table()
130 dev->vlan_cache[vid].table[1] = vlan_table[1]; in ksz9477_set_vlan_table()
131 dev->vlan_cache[vid].table[2] = vlan_table[2]; in ksz9477_set_vlan_table()
134 mutex_unlock(&dev->vlan_mutex); in ksz9477_set_vlan_table()
159 return regmap_read_poll_timeout(dev->regmap[2], REG_SW_ALU_CTRL__4, in ksz9477_wait_alu_ready()
167 return regmap_read_poll_timeout(dev->regmap[2], in ksz9477_wait_alu_sta_ready()
182 regmap_update_bits(dev->regmap[0], REG_SW_GLOBAL_SERIAL_CTRL_0, in ksz9477_reset_switch()
197 if (dev->chip_id == KSZ9893_CHIP_ID || in ksz9477_reset_switch()
198 dev->chip_id == KSZ8563_CHIP_ID) in ksz9477_reset_switch()
202 if (dev->synclko_disable) in ksz9477_reset_switch()
204 else if (dev->synclko_125) in ksz9477_reset_switch()
213 struct ksz_port *p = &dev->ports[port]; in ksz9477_r_mib_cnt()
215 u32 data; in ksz9477_r_mib_cnt() local
219 data = p->freeze ? MIB_COUNTER_FLUSH_FREEZE : 0; in ksz9477_r_mib_cnt()
220 data |= MIB_COUNTER_READ; in ksz9477_r_mib_cnt()
221 data |= (addr << MIB_COUNTER_INDEX_S); in ksz9477_r_mib_cnt()
222 ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data); in ksz9477_r_mib_cnt()
224 ret = regmap_read_poll_timeout(dev->regmap[2], in ksz9477_r_mib_cnt()
229 dev_dbg(dev->dev, "Failed to get MIB\n"); in ksz9477_r_mib_cnt()
234 ksz_pread32(dev, port, REG_PORT_MIB_DATA, &data); in ksz9477_r_mib_cnt()
235 *cnt += data; in ksz9477_r_mib_cnt()
241 addr = dev->info->mib_names[addr].index; in ksz9477_r_mib_pkt()
248 struct ksz_port *p = &dev->ports[port]; in ksz9477_freeze_mib()
251 mutex_lock(&p->mib.cnt_mutex); in ksz9477_freeze_mib()
255 p->freeze = freeze; in ksz9477_freeze_mib()
256 mutex_unlock(&p->mib.cnt_mutex); in ksz9477_freeze_mib()
261 struct ksz_port_mib *mib = &dev->ports[port].mib; in ksz9477_port_init_cnt()
264 mutex_lock(&mib->cnt_mutex); in ksz9477_port_init_cnt()
269 mutex_unlock(&mib->cnt_mutex); in ksz9477_port_init_cnt()
273 u16 *data) in ksz9477_r_phy_quirks() argument
278 if (dev->chip_id == KSZ8563_CHIP_ID && reg == MII_BMSR) in ksz9477_r_phy_quirks()
279 *data &= ~(BMSR_ESTATEN | BMSR_ERCAP); in ksz9477_r_phy_quirks()
282 int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) in ksz9477_r_phy() argument
293 if (!dev->info->internal_phy[addr]) { in ksz9477_r_phy()
294 struct ksz_port *p = &dev->ports[addr]; in ksz9477_r_phy()
319 if (p->phydev.speed == SPEED_1000) in ksz9477_r_phy()
333 *data = val; in ksz9477_r_phy()
341 if (!dev->info->internal_phy[addr]) in ksz9477_w_phy()
354 const u16 *regs = dev->info->regs; in ksz9477_flush_dyn_mac_table()
355 u8 data; in ksz9477_flush_dyn_mac_table() local
357 regmap_update_bits(dev->regmap[0], REG_SW_LUE_CTRL_2, in ksz9477_flush_dyn_mac_table()
361 if (port < dev->info->port_cnt) { in ksz9477_flush_dyn_mac_table()
363 ksz_pread8(dev, port, regs[P_STP_CTRL], &data); in ksz9477_flush_dyn_mac_table()
364 if (!(data & PORT_LEARN_DISABLE)) in ksz9477_flush_dyn_mac_table()
366 data | PORT_LEARN_DISABLE); in ksz9477_flush_dyn_mac_table()
368 ksz_pwrite8(dev, port, regs[P_STP_CTRL], data); in ksz9477_flush_dyn_mac_table()
396 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; in ksz9477_port_vlan_add()
399 err = ksz9477_get_vlan_table(dev, vlan->vid, vlan_table); in ksz9477_port_vlan_add()
405 vlan_table[0] = VLAN_VALID | (vlan->vid & VLAN_FID_M); in ksz9477_port_vlan_add()
410 vlan_table[1] &= ~(BIT(dev->cpu_port)); in ksz9477_port_vlan_add()
412 vlan_table[2] |= BIT(port) | BIT(dev->cpu_port); in ksz9477_port_vlan_add()
414 err = ksz9477_set_vlan_table(dev, vlan->vid, vlan_table); in ksz9477_port_vlan_add()
421 if (vlan->flags & BRIDGE_VLAN_INFO_PVID) in ksz9477_port_vlan_add()
422 ksz_pwrite16(dev, port, REG_PORT_DEFAULT_VID, vlan->vid); in ksz9477_port_vlan_add()
430 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; in ksz9477_port_vlan_del()
437 if (ksz9477_get_vlan_table(dev, vlan->vid, vlan_table)) { in ksz9477_port_vlan_del()
438 dev_dbg(dev->dev, "Failed to get vlan table\n"); in ksz9477_port_vlan_del()
439 return -ETIMEDOUT; in ksz9477_port_vlan_del()
444 if (pvid == vlan->vid) in ksz9477_port_vlan_del()
450 if (ksz9477_set_vlan_table(dev, vlan->vid, vlan_table)) { in ksz9477_port_vlan_del()
451 dev_dbg(dev->dev, "Failed to set vlan table\n"); in ksz9477_port_vlan_del()
452 return -ETIMEDOUT; in ksz9477_port_vlan_del()
464 u32 data; in ksz9477_fdb_add() local
467 mutex_lock(&dev->alu_mutex); in ksz9477_fdb_add()
470 data = vid << ALU_FID_INDEX_S; in ksz9477_fdb_add()
471 data |= ((addr[0] << 8) | addr[1]); in ksz9477_fdb_add()
472 ksz_write32(dev, REG_SW_ALU_INDEX_0, data); in ksz9477_fdb_add()
474 data = ((addr[2] << 24) | (addr[3] << 16)); in ksz9477_fdb_add()
475 data |= ((addr[4] << 8) | addr[5]); in ksz9477_fdb_add()
476 ksz_write32(dev, REG_SW_ALU_INDEX_1, data); in ksz9477_fdb_add()
484 dev_dbg(dev->dev, "Failed to read ALU\n"); in ksz9477_fdb_add()
508 dev_dbg(dev->dev, "Failed to write ALU\n"); in ksz9477_fdb_add()
511 mutex_unlock(&dev->alu_mutex); in ksz9477_fdb_add()
520 u32 data; in ksz9477_fdb_del() local
523 mutex_lock(&dev->alu_mutex); in ksz9477_fdb_del()
526 data = vid << ALU_FID_INDEX_S; in ksz9477_fdb_del()
527 data |= ((addr[0] << 8) | addr[1]); in ksz9477_fdb_del()
528 ksz_write32(dev, REG_SW_ALU_INDEX_0, data); in ksz9477_fdb_del()
530 data = ((addr[2] << 24) | (addr[3] << 16)); in ksz9477_fdb_del()
531 data |= ((addr[4] << 8) | addr[5]); in ksz9477_fdb_del()
532 ksz_write32(dev, REG_SW_ALU_INDEX_1, data); in ksz9477_fdb_del()
540 dev_dbg(dev->dev, "Failed to read ALU\n"); in ksz9477_fdb_del()
574 dev_dbg(dev->dev, "Failed to write ALU\n"); in ksz9477_fdb_del()
577 mutex_unlock(&dev->alu_mutex); in ksz9477_fdb_del()
584 alu->is_static = !!(alu_table[0] & ALU_V_STATIC_VALID); in ksz9477_convert_alu()
585 alu->is_src_filter = !!(alu_table[0] & ALU_V_SRC_FILTER); in ksz9477_convert_alu()
586 alu->is_dst_filter = !!(alu_table[0] & ALU_V_DST_FILTER); in ksz9477_convert_alu()
587 alu->prio_age = (alu_table[0] >> ALU_V_PRIO_AGE_CNT_S) & in ksz9477_convert_alu()
589 alu->mstp = alu_table[0] & ALU_V_MSTP_M; in ksz9477_convert_alu()
591 alu->is_override = !!(alu_table[1] & ALU_V_OVERRIDE); in ksz9477_convert_alu()
592 alu->is_use_fid = !!(alu_table[1] & ALU_V_USE_FID); in ksz9477_convert_alu()
593 alu->port_forward = alu_table[1] & ALU_V_PORT_MAP; in ksz9477_convert_alu()
595 alu->fid = (alu_table[2] >> ALU_V_FID_S) & ALU_V_FID_M; in ksz9477_convert_alu()
597 alu->mac[0] = (alu_table[2] >> 8) & 0xFF; in ksz9477_convert_alu()
598 alu->mac[1] = alu_table[2] & 0xFF; in ksz9477_convert_alu()
599 alu->mac[2] = (alu_table[3] >> 24) & 0xFF; in ksz9477_convert_alu()
600 alu->mac[3] = (alu_table[3] >> 16) & 0xFF; in ksz9477_convert_alu()
601 alu->mac[4] = (alu_table[3] >> 8) & 0xFF; in ksz9477_convert_alu()
602 alu->mac[5] = alu_table[3] & 0xFF; in ksz9477_convert_alu()
606 dsa_fdb_dump_cb_t *cb, void *data) in ksz9477_fdb_dump() argument
614 mutex_lock(&dev->alu_mutex); in ksz9477_fdb_dump()
626 } while (timeout-- > 0); in ksz9477_fdb_dump()
629 dev_dbg(dev->dev, "Failed to search ALU\n"); in ksz9477_fdb_dump()
630 ret = -ETIMEDOUT; in ksz9477_fdb_dump()
643 ret = cb(alu.mac, alu.fid, alu.is_static, data); in ksz9477_fdb_dump()
654 mutex_unlock(&dev->alu_mutex); in ksz9477_fdb_dump()
665 u32 data; in ksz9477_mdb_add() local
670 shifts = dev->info->shifts; in ksz9477_mdb_add()
671 masks = dev->info->masks; in ksz9477_mdb_add()
673 mac_hi = ((mdb->addr[0] << 8) | mdb->addr[1]); in ksz9477_mdb_add()
674 mac_lo = ((mdb->addr[2] << 24) | (mdb->addr[3] << 16)); in ksz9477_mdb_add()
675 mac_lo |= ((mdb->addr[4] << 8) | mdb->addr[5]); in ksz9477_mdb_add()
677 mutex_lock(&dev->alu_mutex); in ksz9477_mdb_add()
679 for (index = 0; index < dev->info->num_statics; index++) { in ksz9477_mdb_add()
681 data = (index << shifts[ALU_STAT_INDEX]) | in ksz9477_mdb_add()
683 ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); in ksz9477_mdb_add()
688 dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); in ksz9477_mdb_add()
697 if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) && in ksz9477_mdb_add()
710 if (index == dev->info->num_statics) { in ksz9477_mdb_add()
711 err = -ENOSPC; in ksz9477_mdb_add()
718 if (mdb->vid) in ksz9477_mdb_add()
720 static_table[2] = (mdb->vid << ALU_V_FID_S); in ksz9477_mdb_add()
726 data = (index << shifts[ALU_STAT_INDEX]) | ALU_STAT_START; in ksz9477_mdb_add()
727 ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); in ksz9477_mdb_add()
731 dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); in ksz9477_mdb_add()
734 mutex_unlock(&dev->alu_mutex); in ksz9477_mdb_add()
744 u32 data; in ksz9477_mdb_del() local
749 shifts = dev->info->shifts; in ksz9477_mdb_del()
750 masks = dev->info->masks; in ksz9477_mdb_del()
752 mac_hi = ((mdb->addr[0] << 8) | mdb->addr[1]); in ksz9477_mdb_del()
753 mac_lo = ((mdb->addr[2] << 24) | (mdb->addr[3] << 16)); in ksz9477_mdb_del()
754 mac_lo |= ((mdb->addr[4] << 8) | mdb->addr[5]); in ksz9477_mdb_del()
756 mutex_lock(&dev->alu_mutex); in ksz9477_mdb_del()
758 for (index = 0; index < dev->info->num_statics; index++) { in ksz9477_mdb_del()
760 data = (index << shifts[ALU_STAT_INDEX]) | in ksz9477_mdb_del()
762 ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); in ksz9477_mdb_del()
767 dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); in ksz9477_mdb_del()
777 if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) && in ksz9477_mdb_del()
787 if (index == dev->info->num_statics) in ksz9477_mdb_del()
803 data = (index << shifts[ALU_STAT_INDEX]) | ALU_STAT_START; in ksz9477_mdb_del()
804 ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); in ksz9477_mdb_del()
809 dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); in ksz9477_mdb_del()
812 mutex_unlock(&dev->alu_mutex); in ksz9477_mdb_del()
818 struct dsa_mall_mirror_tc_entry *mirror, in ksz9477_port_mirror_add() argument
821 u8 data; in ksz9477_port_mirror_add() local
828 for (p = 0; p < dev->info->port_cnt; p++) { in ksz9477_port_mirror_add()
830 if (p == mirror->to_local_port) in ksz9477_port_mirror_add()
833 ksz_pread8(dev, p, P_MIRROR_CTRL, &data); in ksz9477_port_mirror_add()
835 if (data & PORT_MIRROR_SNIFFER) { in ksz9477_port_mirror_add()
838 return -EBUSY; in ksz9477_port_mirror_add()
847 /* configure mirror port */ in ksz9477_port_mirror_add()
848 ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, in ksz9477_port_mirror_add()
857 struct dsa_mall_mirror_tc_entry *mirror) in ksz9477_port_mirror_del() argument
860 u8 data; in ksz9477_port_mirror_del() local
863 if (mirror->ingress) in ksz9477_port_mirror_del()
870 for (p = 0; p < dev->info->port_cnt; p++) { in ksz9477_port_mirror_del()
871 ksz_pread8(dev, p, P_MIRROR_CTRL, &data); in ksz9477_port_mirror_del()
873 if ((data & (PORT_MIRROR_RX | PORT_MIRROR_TX))) { in ksz9477_port_mirror_del()
881 ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, in ksz9477_port_mirror_del()
890 if (dev->info->internal_phy[port]) in ksz9477_get_interface()
915 * Silicon Errata and Data Sheet Clarification documents: in ksz9477_phy_errata_setup()
928 * (1000BASE-T, 100BASE-TX, 10BASE-Te) in ksz9477_phy_errata_setup()
935 if (dev->info->gbit_capable[port]) in ksz9477_phy_errata_setup()
938 /* Register settings are required to meet data sheet in ksz9477_phy_errata_setup()
959 config->mac_capabilities = MAC_10 | MAC_100 | MAC_ASYM_PAUSE | in ksz9477_get_caps()
962 if (dev->info->gbit_capable[port]) in ksz9477_get_caps()
963 config->mac_capabilities |= MAC_1000FD; in ksz9477_get_caps()
970 u8 data; in ksz9477_set_ageing_time() local
979 data = FIELD_GET(SW_AGE_PERIOD_10_8_M, secs); in ksz9477_set_ageing_time()
986 value |= FIELD_PREP(SW_AGE_CNT_M, data); in ksz9477_set_ageing_time()
993 struct dsa_switch *ds = dev->ds; in ksz9477_port_setup()
1022 if (dev->info->internal_phy[port]) { in ksz9477_port_setup()
1028 if (dev->info->phy_errata_9477) in ksz9477_port_setup()
1045 if (dev->info->internal_phy[port]) in ksz9477_port_setup()
1051 struct ksz_device *dev = ds->priv; in ksz9477_config_cpu_port()
1055 for (i = 0; i < dev->info->port_cnt; i++) { in ksz9477_config_cpu_port()
1057 (dev->info->cpu_ports & (1 << i))) { in ksz9477_config_cpu_port()
1062 dev->cpu_port = i; in ksz9477_config_cpu_port()
1063 p = &dev->ports[i]; in ksz9477_config_cpu_port()
1070 if (!p->interface) { in ksz9477_config_cpu_port()
1071 if (dev->compat_interface) { in ksz9477_config_cpu_port()
1072 dev_warn(dev->dev, in ksz9477_config_cpu_port()
1073 "Using legacy switch \"phy-mode\" property, because it is missing on port %d node. " in ksz9477_config_cpu_port()
1076 p->interface = dev->compat_interface; in ksz9477_config_cpu_port()
1078 p->interface = interface; in ksz9477_config_cpu_port()
1081 if (interface && interface != p->interface) { in ksz9477_config_cpu_port()
1088 dev_info(dev->dev, in ksz9477_config_cpu_port()
1091 phy_modes(p->interface), in ksz9477_config_cpu_port()
1100 for (i = 0; i < dev->info->port_cnt; i++) { in ksz9477_config_cpu_port()
1101 if (i == dev->cpu_port) in ksz9477_config_cpu_port()
1110 u32 data; in ksz9477_enable_stp_addr() local
1113 masks = dev->info->masks; in ksz9477_enable_stp_addr()
1120 ALU_V_OVERRIDE | BIT(dev->cpu_port)); in ksz9477_enable_stp_addr()
1124 data = ALU_STAT_START | ALU_RESV_MCAST_ADDR | masks[ALU_STAT_WRITE]; in ksz9477_enable_stp_addr()
1126 ret = ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); in ksz9477_enable_stp_addr()
1133 dev_err(dev->dev, "Failed to update Reserved Multicast table\n"); in ksz9477_enable_stp_addr()
1142 struct ksz_device *dev = ds->priv; in ksz9477_setup()
1156 ret = regmap_update_bits(dev->regmap[1], REG_SW_MTU__2, REG_SW_MTU_MASK, in ksz9477_setup()
1180 dev->port_mask = (1 << dev->info->port_cnt) - 1; in ksz9477_switch_init()