Lines Matching +full:data +full:- +full:mirror
1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
68 return regmap_read(priv->regmap, reg, val); in qca8k_read()
73 return regmap_write(priv->regmap, reg, val); in qca8k_write()
78 return regmap_update_bits(priv->regmap, reg, mask, write_val); in qca8k_rmw()
90 regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
91 regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
92 regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
93 regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
94 regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
95 regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
96 regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
109 if (priv->mgmt_master && priv->info->ops->read_eth && in qca8k_bulk_read()
110 !priv->info->ops->read_eth(priv, reg, val, len)) in qca8k_bulk_read()
114 ret = regmap_read(priv->regmap, reg + (i * 4), val + i); in qca8k_bulk_read()
128 if (priv->mgmt_master && priv->info->ops->write_eth && in qca8k_bulk_write()
129 !priv->info->ops->write_eth(priv, reg, val, len)) in qca8k_bulk_write()
135 ret = regmap_write(priv->regmap, reg + (i * 4), tmp); in qca8k_bulk_write()
147 return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, in qca8k_busy_wait()
161 /* vid - 83:72 */ in qca8k_fdb_read()
162 fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); in qca8k_fdb_read()
163 /* aging - 67:64 */ in qca8k_fdb_read()
164 fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); in qca8k_fdb_read()
165 /* portmask - 54:48 */ in qca8k_fdb_read()
166 fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); in qca8k_fdb_read()
167 /* mac - 47:0 */ in qca8k_fdb_read()
168 fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); in qca8k_fdb_read()
169 fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); in qca8k_fdb_read()
170 fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); in qca8k_fdb_read()
171 fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); in qca8k_fdb_read()
172 fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); in qca8k_fdb_read()
173 fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); in qca8k_fdb_read()
183 /* vid - 83:72 */ in qca8k_fdb_write()
185 /* aging - 67:64 */ in qca8k_fdb_write()
187 /* portmask - 54:48 */ in qca8k_fdb_write()
189 /* mac - 47:0 */ in qca8k_fdb_write()
231 return -1; in qca8k_fdb_access()
242 qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); in qca8k_fdb_next()
255 mutex_lock(&priv->reg_mutex); in qca8k_fdb_add()
257 ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); in qca8k_fdb_add()
258 mutex_unlock(&priv->reg_mutex); in qca8k_fdb_add()
268 mutex_lock(&priv->reg_mutex); in qca8k_fdb_del()
270 ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); in qca8k_fdb_del()
271 mutex_unlock(&priv->reg_mutex); in qca8k_fdb_del()
278 mutex_lock(&priv->reg_mutex); in qca8k_fdb_flush()
279 qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); in qca8k_fdb_flush()
280 mutex_unlock(&priv->reg_mutex); in qca8k_fdb_flush()
289 mutex_lock(&priv->reg_mutex); in qca8k_fdb_search_and_insert()
292 ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); in qca8k_fdb_search_and_insert()
302 ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); in qca8k_fdb_search_and_insert()
311 ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); in qca8k_fdb_search_and_insert()
314 mutex_unlock(&priv->reg_mutex); in qca8k_fdb_search_and_insert()
324 mutex_lock(&priv->reg_mutex); in qca8k_fdb_search_and_del()
327 ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); in qca8k_fdb_search_and_del()
333 ret = -EINVAL; in qca8k_fdb_search_and_del()
337 ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); in qca8k_fdb_search_and_del()
349 ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); in qca8k_fdb_search_and_del()
352 mutex_unlock(&priv->reg_mutex); in qca8k_fdb_search_and_del()
383 return -ENOMEM; in qca8k_vlan_access()
401 mutex_lock(&priv->reg_mutex); in qca8k_vlan_add()
422 mutex_unlock(&priv->reg_mutex); in qca8k_vlan_add()
433 mutex_lock(&priv->reg_mutex); in qca8k_vlan_del()
465 mutex_unlock(&priv->reg_mutex); in qca8k_vlan_del()
474 mutex_lock(&priv->reg_mutex); in qca8k_mib_init()
475 ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, in qca8k_mib_init()
486 ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); in qca8k_mib_init()
493 mutex_unlock(&priv->reg_mutex); in qca8k_mib_init()
506 regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); in qca8k_port_set_status()
508 regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); in qca8k_port_set_status()
512 uint8_t *data) in qca8k_get_strings() argument
514 struct qca8k_priv *priv = ds->priv; in qca8k_get_strings()
520 for (i = 0; i < priv->info->mib_count; i++) in qca8k_get_strings()
521 strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, in qca8k_get_strings()
526 uint64_t *data) in qca8k_get_ethtool_stats() argument
528 struct qca8k_priv *priv = ds->priv; in qca8k_get_ethtool_stats()
534 if (priv->mgmt_master && priv->info->ops->autocast_mib && in qca8k_get_ethtool_stats()
535 priv->info->ops->autocast_mib(ds, port, data) > 0) in qca8k_get_ethtool_stats()
538 for (i = 0; i < priv->info->mib_count; i++) { in qca8k_get_ethtool_stats()
540 reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; in qca8k_get_ethtool_stats()
546 if (mib->size == 2) { in qca8k_get_ethtool_stats()
552 data[i] = val; in qca8k_get_ethtool_stats()
553 if (mib->size == 2) in qca8k_get_ethtool_stats()
554 data[i] |= (u64)hi << 32; in qca8k_get_ethtool_stats()
560 struct qca8k_priv *priv = ds->priv; in qca8k_get_sset_count()
565 return priv->info->mib_count; in qca8k_get_sset_count()
572 struct qca8k_priv *priv = ds->priv; in qca8k_set_mac_eee()
576 mutex_lock(&priv->reg_mutex); in qca8k_set_mac_eee()
581 if (eee->eee_enabled) in qca8k_set_mac_eee()
588 mutex_unlock(&priv->reg_mutex); in qca8k_set_mac_eee()
601 struct qca8k_priv *priv = ds->priv; in qca8k_port_stp_state_set()
632 struct qca8k_priv *priv = ds->priv; in qca8k_port_bridge_join()
636 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; in qca8k_port_bridge_join()
647 ret = regmap_set_bits(priv->regmap, in qca8k_port_bridge_join()
666 struct qca8k_priv *priv = ds->priv; in qca8k_port_bridge_leave()
669 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; in qca8k_port_bridge_leave()
679 regmap_clear_bits(priv->regmap, in qca8k_port_bridge_leave()
693 struct qca8k_priv *priv = ds->priv; in qca8k_port_fast_age()
695 mutex_lock(&priv->reg_mutex); in qca8k_port_fast_age()
697 mutex_unlock(&priv->reg_mutex); in qca8k_port_fast_age()
702 struct qca8k_priv *priv = ds->priv; in qca8k_set_ageing_time()
715 return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, in qca8k_set_ageing_time()
723 struct qca8k_priv *priv = ds->priv; in qca8k_port_enable()
726 priv->port_enabled_map |= BIT(port); in qca8k_port_enable()
736 struct qca8k_priv *priv = ds->priv; in qca8k_port_disable()
739 priv->port_enabled_map &= ~BIT(port); in qca8k_port_disable()
744 struct qca8k_priv *priv = ds->priv; in qca8k_port_change_mtu()
761 if (priv->port_enabled_map & BIT(0)) in qca8k_port_change_mtu()
764 if (priv->port_enabled_map & BIT(6)) in qca8k_port_change_mtu()
771 if (priv->port_enabled_map & BIT(0)) in qca8k_port_change_mtu()
774 if (priv->port_enabled_map & BIT(6)) in qca8k_port_change_mtu()
800 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; in qca8k_port_fdb_add()
810 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; in qca8k_port_fdb_del()
820 dsa_fdb_dump_cb_t *cb, void *data) in qca8k_port_fdb_dump() argument
822 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; in qca8k_port_fdb_dump()
828 mutex_lock(&priv->reg_mutex); in qca8k_port_fdb_dump()
829 while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { in qca8k_port_fdb_dump()
833 ret = cb(_fdb.mac, _fdb.vid, is_static, data); in qca8k_port_fdb_dump()
837 mutex_unlock(&priv->reg_mutex); in qca8k_port_fdb_dump()
846 struct qca8k_priv *priv = ds->priv; in qca8k_port_mdb_add()
847 const u8 *addr = mdb->addr; in qca8k_port_mdb_add()
848 u16 vid = mdb->vid; in qca8k_port_mdb_add()
857 struct qca8k_priv *priv = ds->priv; in qca8k_port_mdb_del()
858 const u8 *addr = mdb->addr; in qca8k_port_mdb_del()
859 u16 vid = mdb->vid; in qca8k_port_mdb_del()
865 struct dsa_mall_mirror_tc_entry *mirror, in qca8k_port_mirror_add() argument
868 struct qca8k_priv *priv = ds->priv; in qca8k_port_mirror_add()
873 if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) in qca8k_port_mirror_add()
874 return -EEXIST; in qca8k_port_mirror_add()
876 ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); in qca8k_port_mirror_add()
880 /* QCA83xx can have only one port set to mirror mode. in qca8k_port_mirror_add()
882 * When no mirror port is set, the values is set to 0xF in qca8k_port_mirror_add()
885 if (monitor_port != 0xF && monitor_port != mirror->to_local_port) in qca8k_port_mirror_add()
886 return -EEXIST; in qca8k_port_mirror_add()
890 mirror->to_local_port); in qca8k_port_mirror_add()
891 ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, in qca8k_port_mirror_add()
904 ret = regmap_update_bits(priv->regmap, reg, val, val); in qca8k_port_mirror_add()
908 /* Track mirror port for tx and rx to decide when the in qca8k_port_mirror_add()
909 * mirror port has to be disabled. in qca8k_port_mirror_add()
912 priv->mirror_rx |= BIT(port); in qca8k_port_mirror_add()
914 priv->mirror_tx |= BIT(port); in qca8k_port_mirror_add()
920 struct dsa_mall_mirror_tc_entry *mirror) in qca8k_port_mirror_del() argument
922 struct qca8k_priv *priv = ds->priv; in qca8k_port_mirror_del()
926 if (mirror->ingress) { in qca8k_port_mirror_del()
934 ret = regmap_clear_bits(priv->regmap, reg, val); in qca8k_port_mirror_del()
938 if (mirror->ingress) in qca8k_port_mirror_del()
939 priv->mirror_rx &= ~BIT(port); in qca8k_port_mirror_del()
941 priv->mirror_tx &= ~BIT(port); in qca8k_port_mirror_del()
943 /* No port set to send packet to mirror port. Disable mirror port */ in qca8k_port_mirror_del()
944 if (!priv->mirror_rx && !priv->mirror_tx) { in qca8k_port_mirror_del()
946 ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, in qca8k_port_mirror_del()
952 dev_err(priv->dev, "Failed to del mirror port from %d", port); in qca8k_port_mirror_del()
959 struct qca8k_priv *priv = ds->priv; in qca8k_port_vlan_filtering()
979 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; in qca8k_port_vlan_add()
980 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; in qca8k_port_vlan_add()
981 struct qca8k_priv *priv = ds->priv; in qca8k_port_vlan_add()
984 ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); in qca8k_port_vlan_add()
986 dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); in qca8k_port_vlan_add()
993 QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); in qca8k_port_vlan_add()
998 QCA8K_PORT_VLAN_CVID(vlan->vid) | in qca8k_port_vlan_add()
999 QCA8K_PORT_VLAN_SVID(vlan->vid)); in qca8k_port_vlan_add()
1008 struct qca8k_priv *priv = ds->priv; in qca8k_port_vlan_del()
1011 ret = qca8k_vlan_del(priv, port, vlan->vid); in qca8k_port_vlan_del()
1013 dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); in qca8k_port_vlan_del()
1029 dsa_lag_foreach_port(dp, ds->dst, &lag) in qca8k_lag_can_offload()
1039 if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) { in qca8k_lag_can_offload()
1045 if (info->hash_type != NETDEV_LAG_HASH_L2 && in qca8k_lag_can_offload()
1046 info->hash_type != NETDEV_LAG_HASH_L23) { in qca8k_lag_can_offload()
1060 struct qca8k_priv *priv = ds->priv; in qca8k_lag_setup_hash()
1065 switch (info->hash_type) { in qca8k_lag_setup_hash()
1075 return -EOPNOTSUPP; in qca8k_lag_setup_hash()
1079 dsa_lags_foreach_id(i, ds->dst) in qca8k_lag_setup_hash()
1080 if (i != lag.id && dsa_lag_by_id(ds->dst, i)) { in qca8k_lag_setup_hash()
1093 priv->lag_hash_mode = hash; in qca8k_lag_setup_hash()
1094 } else if (priv->lag_hash_mode != hash) { in qca8k_lag_setup_hash()
1096 return -EOPNOTSUPP; in qca8k_lag_setup_hash()
1099 return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, in qca8k_lag_setup_hash()
1106 struct qca8k_priv *priv = ds->priv; in qca8k_lag_refresh_portmap()
1110 /* DSA LAG IDs are one-based, hardware is zero-based */ in qca8k_lag_refresh_portmap()
1111 id = lag.id - 1; in qca8k_lag_refresh_portmap()
1114 ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); in qca8k_lag_refresh_portmap()
1127 ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, in qca8k_lag_refresh_portmap()
1135 ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); in qca8k_lag_refresh_portmap()
1165 return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), in qca8k_lag_refresh_portmap()
1179 return -EOPNOTSUPP; in qca8k_port_lag_join()
1200 if (!priv->info) in qca8k_read_switch_id()
1201 return -ENODEV; in qca8k_read_switch_id()
1205 return -ENODEV; in qca8k_read_switch_id()
1208 if (id != priv->info->id) { in qca8k_read_switch_id()
1209 dev_err(priv->dev, in qca8k_read_switch_id()
1211 id, priv->info->id); in qca8k_read_switch_id()
1212 return -ENODEV; in qca8k_read_switch_id()
1215 priv->switch_id = id; in qca8k_read_switch_id()
1218 priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); in qca8k_read_switch_id()