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>
50 if (!dsa_is_cpu_port(dev->ds, port)) in ksz9477_change_mtu()
72 mutex_lock(&dev->vlan_mutex); in ksz9477_get_vlan_table()
80 dev_dbg(dev->dev, "Failed to read vlan table\n"); in ksz9477_get_vlan_table()
91 mutex_unlock(&dev->vlan_mutex); in ksz9477_get_vlan_table()
101 mutex_lock(&dev->vlan_mutex); in ksz9477_set_vlan_table()
113 dev_dbg(dev->dev, "Failed to write vlan table\n"); in ksz9477_set_vlan_table()
120 dev->vlan_cache[vid].table[0] = vlan_table[0]; in ksz9477_set_vlan_table()
121 dev->vlan_cache[vid].table[1] = vlan_table[1]; in ksz9477_set_vlan_table()
122 dev->vlan_cache[vid].table[2] = vlan_table[2]; in ksz9477_set_vlan_table()
125 mutex_unlock(&dev->vlan_mutex); in ksz9477_set_vlan_table()
188 if (dev->chip_id == KSZ9893_CHIP_ID || in ksz9477_reset_switch()
189 dev->chip_id == KSZ8563_CHIP_ID || in ksz9477_reset_switch()
190 dev->chip_id == KSZ9563_CHIP_ID) in ksz9477_reset_switch()
194 if (dev->synclko_disable) in ksz9477_reset_switch()
196 else if (dev->synclko_125) in ksz9477_reset_switch()
205 struct ksz_port *p = &dev->ports[port]; in ksz9477_r_mib_cnt()
207 u32 data; in ksz9477_r_mib_cnt() local
211 data = p->freeze ? MIB_COUNTER_FLUSH_FREEZE : 0; in ksz9477_r_mib_cnt()
212 data |= MIB_COUNTER_READ; in ksz9477_r_mib_cnt()
213 data |= (addr << MIB_COUNTER_INDEX_S); in ksz9477_r_mib_cnt()
214 ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data); in ksz9477_r_mib_cnt()
221 dev_dbg(dev->dev, "Failed to get MIB\n"); in ksz9477_r_mib_cnt()
226 ksz_pread32(dev, port, REG_PORT_MIB_DATA, &data); in ksz9477_r_mib_cnt()
227 *cnt += data; in ksz9477_r_mib_cnt()
233 addr = dev->info->mib_names[addr].index; in ksz9477_r_mib_pkt()
240 struct ksz_port *p = &dev->ports[port]; in ksz9477_freeze_mib()
243 mutex_lock(&p->mib.cnt_mutex); in ksz9477_freeze_mib()
247 p->freeze = freeze; in ksz9477_freeze_mib()
248 mutex_unlock(&p->mib.cnt_mutex); in ksz9477_freeze_mib()
253 struct ksz_port_mib *mib = &dev->ports[port].mib; in ksz9477_port_init_cnt()
256 mutex_lock(&mib->cnt_mutex); in ksz9477_port_init_cnt()
261 mutex_unlock(&mib->cnt_mutex); in ksz9477_port_init_cnt()
265 u16 *data) in ksz9477_r_phy_quirks() argument
270 if (dev->chip_id == KSZ8563_CHIP_ID && reg == MII_BMSR) in ksz9477_r_phy_quirks()
271 *data &= ~(BMSR_ESTATEN | BMSR_ERCAP); in ksz9477_r_phy_quirks()
274 int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) in ksz9477_r_phy() argument
285 if (!dev->info->internal_phy[addr]) { in ksz9477_r_phy()
286 struct ksz_port *p = &dev->ports[addr]; in ksz9477_r_phy()
311 if (p->phydev.speed == SPEED_1000) in ksz9477_r_phy()
325 *data = val; in ksz9477_r_phy()
335 if (!dev->info->internal_phy[addr]) in ksz9477_w_phy()
341 /* Errata: When using SPI, I2C, or in-band register access, in ksz9477_w_phy()
343 * 32-bit writes instead of 16-bit writes. in ksz9477_w_phy()
362 const u16 *regs = dev->info->regs; in ksz9477_flush_dyn_mac_table()
363 u8 data; in ksz9477_flush_dyn_mac_table() local
369 if (port < dev->info->port_cnt) { in ksz9477_flush_dyn_mac_table()
371 ksz_pread8(dev, port, regs[P_STP_CTRL], &data); in ksz9477_flush_dyn_mac_table()
372 if (!(data & PORT_LEARN_DISABLE)) in ksz9477_flush_dyn_mac_table()
374 data | PORT_LEARN_DISABLE); in ksz9477_flush_dyn_mac_table()
376 ksz_pwrite8(dev, port, regs[P_STP_CTRL], data); in ksz9477_flush_dyn_mac_table()
404 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; in ksz9477_port_vlan_add()
407 err = ksz9477_get_vlan_table(dev, vlan->vid, vlan_table); in ksz9477_port_vlan_add()
413 vlan_table[0] = VLAN_VALID | (vlan->vid & VLAN_FID_M); in ksz9477_port_vlan_add()
418 vlan_table[1] &= ~(BIT(dev->cpu_port)); in ksz9477_port_vlan_add()
420 vlan_table[2] |= BIT(port) | BIT(dev->cpu_port); in ksz9477_port_vlan_add()
422 err = ksz9477_set_vlan_table(dev, vlan->vid, vlan_table); in ksz9477_port_vlan_add()
429 if (vlan->flags & BRIDGE_VLAN_INFO_PVID) in ksz9477_port_vlan_add()
430 ksz_pwrite16(dev, port, REG_PORT_DEFAULT_VID, vlan->vid); in ksz9477_port_vlan_add()
438 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; in ksz9477_port_vlan_del()
445 if (ksz9477_get_vlan_table(dev, vlan->vid, vlan_table)) { in ksz9477_port_vlan_del()
446 dev_dbg(dev->dev, "Failed to get vlan table\n"); in ksz9477_port_vlan_del()
447 return -ETIMEDOUT; in ksz9477_port_vlan_del()
452 if (pvid == vlan->vid) in ksz9477_port_vlan_del()
458 if (ksz9477_set_vlan_table(dev, vlan->vid, vlan_table)) { in ksz9477_port_vlan_del()
459 dev_dbg(dev->dev, "Failed to set vlan table\n"); in ksz9477_port_vlan_del()
460 return -ETIMEDOUT; in ksz9477_port_vlan_del()
472 u32 data; in ksz9477_fdb_add() local
475 mutex_lock(&dev->alu_mutex); in ksz9477_fdb_add()
478 data = vid << ALU_FID_INDEX_S; in ksz9477_fdb_add()
479 data |= ((addr[0] << 8) | addr[1]); in ksz9477_fdb_add()
480 ksz_write32(dev, REG_SW_ALU_INDEX_0, data); in ksz9477_fdb_add()
482 data = ((addr[2] << 24) | (addr[3] << 16)); in ksz9477_fdb_add()
483 data |= ((addr[4] << 8) | addr[5]); in ksz9477_fdb_add()
484 ksz_write32(dev, REG_SW_ALU_INDEX_1, data); in ksz9477_fdb_add()
492 dev_dbg(dev->dev, "Failed to read ALU\n"); in ksz9477_fdb_add()
516 dev_dbg(dev->dev, "Failed to write ALU\n"); in ksz9477_fdb_add()
519 mutex_unlock(&dev->alu_mutex); in ksz9477_fdb_add()
528 u32 data; in ksz9477_fdb_del() local
531 mutex_lock(&dev->alu_mutex); in ksz9477_fdb_del()
534 data = vid << ALU_FID_INDEX_S; in ksz9477_fdb_del()
535 data |= ((addr[0] << 8) | addr[1]); in ksz9477_fdb_del()
536 ksz_write32(dev, REG_SW_ALU_INDEX_0, data); in ksz9477_fdb_del()
538 data = ((addr[2] << 24) | (addr[3] << 16)); in ksz9477_fdb_del()
539 data |= ((addr[4] << 8) | addr[5]); in ksz9477_fdb_del()
540 ksz_write32(dev, REG_SW_ALU_INDEX_1, data); in ksz9477_fdb_del()
548 dev_dbg(dev->dev, "Failed to read ALU\n"); in ksz9477_fdb_del()
582 dev_dbg(dev->dev, "Failed to write ALU\n"); in ksz9477_fdb_del()
585 mutex_unlock(&dev->alu_mutex); in ksz9477_fdb_del()
592 alu->is_static = !!(alu_table[0] & ALU_V_STATIC_VALID); in ksz9477_convert_alu()
593 alu->is_src_filter = !!(alu_table[0] & ALU_V_SRC_FILTER); in ksz9477_convert_alu()
594 alu->is_dst_filter = !!(alu_table[0] & ALU_V_DST_FILTER); in ksz9477_convert_alu()
595 alu->prio_age = (alu_table[0] >> ALU_V_PRIO_AGE_CNT_S) & in ksz9477_convert_alu()
597 alu->mstp = alu_table[0] & ALU_V_MSTP_M; in ksz9477_convert_alu()
599 alu->is_override = !!(alu_table[1] & ALU_V_OVERRIDE); in ksz9477_convert_alu()
600 alu->is_use_fid = !!(alu_table[1] & ALU_V_USE_FID); in ksz9477_convert_alu()
601 alu->port_forward = alu_table[1] & ALU_V_PORT_MAP; in ksz9477_convert_alu()
603 alu->fid = (alu_table[2] >> ALU_V_FID_S) & ALU_V_FID_M; in ksz9477_convert_alu()
605 alu->mac[0] = (alu_table[2] >> 8) & 0xFF; in ksz9477_convert_alu()
606 alu->mac[1] = alu_table[2] & 0xFF; in ksz9477_convert_alu()
607 alu->mac[2] = (alu_table[3] >> 24) & 0xFF; in ksz9477_convert_alu()
608 alu->mac[3] = (alu_table[3] >> 16) & 0xFF; in ksz9477_convert_alu()
609 alu->mac[4] = (alu_table[3] >> 8) & 0xFF; in ksz9477_convert_alu()
610 alu->mac[5] = alu_table[3] & 0xFF; in ksz9477_convert_alu()
614 dsa_fdb_dump_cb_t *cb, void *data) in ksz9477_fdb_dump() argument
622 mutex_lock(&dev->alu_mutex); in ksz9477_fdb_dump()
634 } while (timeout-- > 0); in ksz9477_fdb_dump()
637 dev_dbg(dev->dev, "Failed to search ALU\n"); in ksz9477_fdb_dump()
638 ret = -ETIMEDOUT; in ksz9477_fdb_dump()
651 ret = cb(alu.mac, alu.fid, alu.is_static, data); in ksz9477_fdb_dump()
662 mutex_unlock(&dev->alu_mutex); in ksz9477_fdb_dump()
673 u32 data; in ksz9477_mdb_add() local
678 shifts = dev->info->shifts; in ksz9477_mdb_add()
679 masks = dev->info->masks; in ksz9477_mdb_add()
681 mac_hi = ((mdb->addr[0] << 8) | mdb->addr[1]); in ksz9477_mdb_add()
682 mac_lo = ((mdb->addr[2] << 24) | (mdb->addr[3] << 16)); in ksz9477_mdb_add()
683 mac_lo |= ((mdb->addr[4] << 8) | mdb->addr[5]); in ksz9477_mdb_add()
685 mutex_lock(&dev->alu_mutex); in ksz9477_mdb_add()
687 for (index = 0; index < dev->info->num_statics; index++) { in ksz9477_mdb_add()
689 data = (index << shifts[ALU_STAT_INDEX]) | in ksz9477_mdb_add()
691 ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); in ksz9477_mdb_add()
696 dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); in ksz9477_mdb_add()
705 if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) && in ksz9477_mdb_add()
718 if (index == dev->info->num_statics) { in ksz9477_mdb_add()
719 err = -ENOSPC; in ksz9477_mdb_add()
726 if (mdb->vid) in ksz9477_mdb_add()
728 static_table[2] = (mdb->vid << ALU_V_FID_S); in ksz9477_mdb_add()
734 data = (index << shifts[ALU_STAT_INDEX]) | ALU_STAT_START; in ksz9477_mdb_add()
735 ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); in ksz9477_mdb_add()
739 dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); in ksz9477_mdb_add()
742 mutex_unlock(&dev->alu_mutex); in ksz9477_mdb_add()
752 u32 data; in ksz9477_mdb_del() local
757 shifts = dev->info->shifts; in ksz9477_mdb_del()
758 masks = dev->info->masks; in ksz9477_mdb_del()
760 mac_hi = ((mdb->addr[0] << 8) | mdb->addr[1]); in ksz9477_mdb_del()
761 mac_lo = ((mdb->addr[2] << 24) | (mdb->addr[3] << 16)); in ksz9477_mdb_del()
762 mac_lo |= ((mdb->addr[4] << 8) | mdb->addr[5]); in ksz9477_mdb_del()
764 mutex_lock(&dev->alu_mutex); in ksz9477_mdb_del()
766 for (index = 0; index < dev->info->num_statics; index++) { in ksz9477_mdb_del()
768 data = (index << shifts[ALU_STAT_INDEX]) | in ksz9477_mdb_del()
770 ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); in ksz9477_mdb_del()
775 dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); in ksz9477_mdb_del()
785 if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) && in ksz9477_mdb_del()
795 if (index == dev->info->num_statics) in ksz9477_mdb_del()
811 data = (index << shifts[ALU_STAT_INDEX]) | ALU_STAT_START; in ksz9477_mdb_del()
812 ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); in ksz9477_mdb_del()
817 dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); in ksz9477_mdb_del()
820 mutex_unlock(&dev->alu_mutex); in ksz9477_mdb_del()
826 struct dsa_mall_mirror_tc_entry *mirror, in ksz9477_port_mirror_add() argument
829 u8 data; in ksz9477_port_mirror_add() local
836 for (p = 0; p < dev->info->port_cnt; p++) { in ksz9477_port_mirror_add()
838 if (p == mirror->to_local_port) in ksz9477_port_mirror_add()
841 ksz_pread8(dev, p, P_MIRROR_CTRL, &data); in ksz9477_port_mirror_add()
843 if (data & PORT_MIRROR_SNIFFER) { in ksz9477_port_mirror_add()
846 return -EBUSY; in ksz9477_port_mirror_add()
855 /* configure mirror port */ in ksz9477_port_mirror_add()
856 ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, in ksz9477_port_mirror_add()
865 struct dsa_mall_mirror_tc_entry *mirror) in ksz9477_port_mirror_del() argument
868 u8 data; in ksz9477_port_mirror_del() local
871 if (mirror->ingress) in ksz9477_port_mirror_del()
878 for (p = 0; p < dev->info->port_cnt; p++) { in ksz9477_port_mirror_del()
879 ksz_pread8(dev, p, P_MIRROR_CTRL, &data); in ksz9477_port_mirror_del()
881 if ((data & (PORT_MIRROR_RX | PORT_MIRROR_TX))) { in ksz9477_port_mirror_del()
889 ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, in ksz9477_port_mirror_del()
898 if (dev->info->internal_phy[port]) in ksz9477_get_interface()
911 config->mac_capabilities = MAC_10 | MAC_100 | MAC_ASYM_PAUSE | in ksz9477_get_caps()
914 if (dev->info->gbit_capable[port]) in ksz9477_get_caps()
915 config->mac_capabilities |= MAC_1000FD; in ksz9477_get_caps()
922 u8 data; in ksz9477_set_ageing_time() local
931 data = FIELD_GET(SW_AGE_PERIOD_10_8_M, secs); in ksz9477_set_ageing_time()
938 value |= FIELD_PREP(SW_AGE_CNT_M, data); in ksz9477_set_ageing_time()
945 u8 data; in ksz9477_port_queue_split() local
947 if (dev->info->num_tx_queues == 8) in ksz9477_port_queue_split()
948 data = PORT_EIGHT_QUEUE; in ksz9477_port_queue_split()
949 else if (dev->info->num_tx_queues == 4) in ksz9477_port_queue_split()
950 data = PORT_FOUR_QUEUE; in ksz9477_port_queue_split()
951 else if (dev->info->num_tx_queues == 2) in ksz9477_port_queue_split()
952 data = PORT_TWO_QUEUE; in ksz9477_port_queue_split()
954 data = PORT_SINGLE_QUEUE; in ksz9477_port_queue_split()
956 ksz_prmw8(dev, port, REG_PORT_CTRL_0, PORT_QUEUE_SPLIT_MASK, data); in ksz9477_port_queue_split()
961 struct dsa_switch *ds = dev->ds; in ksz9477_port_setup()
992 /* force flow control for non-PHY ports only */ in ksz9477_port_setup()
995 !dev->info->internal_phy[port]); in ksz9477_port_setup()
1005 if (dev->info->internal_phy[port]) in ksz9477_port_setup()
1011 struct ksz_device *dev = ds->priv; in ksz9477_config_cpu_port()
1015 for (i = 0; i < dev->info->port_cnt; i++) { in ksz9477_config_cpu_port()
1017 (dev->info->cpu_ports & (1 << i))) { in ksz9477_config_cpu_port()
1022 dev->cpu_port = i; in ksz9477_config_cpu_port()
1023 p = &dev->ports[i]; in ksz9477_config_cpu_port()
1030 if (!p->interface) { in ksz9477_config_cpu_port()
1031 if (dev->compat_interface) { in ksz9477_config_cpu_port()
1032 dev_warn(dev->dev, in ksz9477_config_cpu_port()
1033 "Using legacy switch \"phy-mode\" property, because it is missing on port %d node. " in ksz9477_config_cpu_port()
1036 p->interface = dev->compat_interface; in ksz9477_config_cpu_port()
1038 p->interface = interface; in ksz9477_config_cpu_port()
1041 if (interface && interface != p->interface) { in ksz9477_config_cpu_port()
1048 dev_info(dev->dev, in ksz9477_config_cpu_port()
1051 phy_modes(p->interface), in ksz9477_config_cpu_port()
1060 for (i = 0; i < dev->info->port_cnt; i++) { in ksz9477_config_cpu_port()
1061 if (i == dev->cpu_port) in ksz9477_config_cpu_port()
1070 u32 data; in ksz9477_enable_stp_addr() local
1073 masks = dev->info->masks; in ksz9477_enable_stp_addr()
1080 ALU_V_OVERRIDE | BIT(dev->cpu_port)); in ksz9477_enable_stp_addr()
1084 data = ALU_STAT_START | ALU_RESV_MCAST_ADDR | masks[ALU_STAT_WRITE]; in ksz9477_enable_stp_addr()
1086 ret = ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); in ksz9477_enable_stp_addr()
1093 dev_err(dev->dev, "Failed to update Reserved Multicast table\n"); in ksz9477_enable_stp_addr()
1102 struct ksz_device *dev = ds->priv; in ksz9477_setup()
1105 ds->mtu_enforcement_ingress = true; in ksz9477_setup()
1149 dev->port_mask = (1 << dev->info->port_cnt) - 1; in ksz9477_switch_init()