Lines Matching defs:a5psw

71 static void a5psw_reg_writel(struct a5psw *a5psw, int offset, u32 value)
73 writel(value, a5psw->base + offset);
76 static u32 a5psw_reg_readl(struct a5psw *a5psw, int offset)
78 return readl(a5psw->base + offset);
81 static void a5psw_reg_rmw(struct a5psw *a5psw, int offset, u32 mask, u32 val)
85 spin_lock(&a5psw->reg_lock);
87 reg = a5psw_reg_readl(a5psw, offset);
90 a5psw_reg_writel(a5psw, offset, reg);
92 spin_unlock(&a5psw->reg_lock);
102 static void a5psw_port_pattern_set(struct a5psw *a5psw, int port, int pattern,
110 a5psw_reg_rmw(a5psw, A5PSW_RXMATCH_CONFIG(port),
114 static void a5psw_port_mgmtfwd_set(struct a5psw *a5psw, int port, bool enable)
120 a5psw_port_pattern_set(a5psw, port, A5PSW_PATTERN_MGMTFWD, enable);
123 static void a5psw_port_tx_enable(struct a5psw *a5psw, int port, bool enable)
136 a5psw_reg_rmw(a5psw, A5PSW_PORT_ENA, mask, reg);
139 static void a5psw_port_enable_set(struct a5psw *a5psw, int port, bool enable)
146 a5psw_reg_rmw(a5psw, A5PSW_PORT_ENA, A5PSW_PORT_ENA_TX_RX(port),
150 static int a5psw_lk_execute_ctrl(struct a5psw *a5psw, u32 *ctrl)
154 a5psw_reg_writel(a5psw, A5PSW_LK_ADDR_CTRL, *ctrl);
156 ret = readl_poll_timeout(a5psw->base + A5PSW_LK_ADDR_CTRL, *ctrl,
160 dev_err(a5psw->dev, "LK_CTRL timeout waiting for BUSY bit\n");
165 static void a5psw_port_fdb_flush(struct a5psw *a5psw, int port)
169 mutex_lock(&a5psw->lk_lock);
170 a5psw_lk_execute_ctrl(a5psw, &ctrl);
171 mutex_unlock(&a5psw->lk_lock);
174 static void a5psw_port_authorize_set(struct a5psw *a5psw, int port,
177 u32 reg = a5psw_reg_readl(a5psw, A5PSW_AUTH_PORT(port));
184 a5psw_reg_writel(a5psw, A5PSW_AUTH_PORT(port), reg);
189 struct a5psw *a5psw = ds->priv;
191 a5psw_port_authorize_set(a5psw, port, false);
192 a5psw_port_enable_set(a5psw, port, false);
198 struct a5psw *a5psw = ds->priv;
200 a5psw_port_authorize_set(a5psw, port, true);
201 a5psw_port_enable_set(a5psw, port, true);
208 struct a5psw *a5psw = ds->priv;
211 a5psw_reg_writel(a5psw, A5PSW_FRM_LENGTH(port), new_mtu);
246 struct a5psw *a5psw = ds->priv;
248 if (!dsa_port_is_cpu(dp) && a5psw->pcs[port])
249 return a5psw->pcs[port];
258 struct a5psw *a5psw = ds->priv;
261 cmd_cfg = a5psw_reg_readl(a5psw, A5PSW_CMD_CFG(port));
263 a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), cmd_cfg);
274 struct a5psw *a5psw = ds->priv;
287 a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), cmd_cfg);
292 struct a5psw *a5psw = ds->priv;
297 rate = clk_get_rate(a5psw->clk);
306 a5psw_reg_writel(a5psw, A5PSW_LK_AGETIME, agetime);
311 static void a5psw_port_learning_set(struct a5psw *a5psw, int port, bool learn)
316 a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN, mask, reg);
319 static void a5psw_port_rx_block_set(struct a5psw *a5psw, int port, bool block)
324 a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN, mask, reg);
327 static void a5psw_flooding_set_resolution(struct a5psw *a5psw, int port,
335 a5psw_reg_rmw(a5psw, offsets[i], BIT(port),
339 static void a5psw_port_set_standalone(struct a5psw *a5psw, int port,
342 a5psw_port_learning_set(a5psw, port, !standalone);
343 a5psw_flooding_set_resolution(a5psw, port, !standalone);
344 a5psw_port_mgmtfwd_set(a5psw, port, standalone);
352 struct a5psw *a5psw = ds->priv;
355 if (a5psw->br_dev && bridge.dev != a5psw->br_dev) {
361 a5psw->br_dev = bridge.dev;
362 a5psw_port_set_standalone(a5psw, port, false);
364 a5psw->bridged_ports |= BIT(port);
372 struct a5psw *a5psw = ds->priv;
374 a5psw->bridged_ports &= ~BIT(port);
376 a5psw_port_set_standalone(a5psw, port, true);
379 if (a5psw->bridged_ports == BIT(A5PSW_CPU_PORT))
380 a5psw->br_dev = NULL;
399 struct a5psw *a5psw = ds->priv;
409 if (!(a5psw->bridged_ports & BIT(port)))
414 a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN,
420 a5psw_reg_rmw(a5psw, A5PSW_UCAST_DEF_MASK, BIT(port), val);
425 a5psw_reg_rmw(a5psw, A5PSW_MCAST_DEF_MASK, BIT(port), val);
430 a5psw_reg_rmw(a5psw, A5PSW_BCAST_DEF_MASK, BIT(port), val);
440 struct a5psw *a5psw = ds->priv;
465 a5psw_port_learning_set(a5psw, port, learning_enabled);
466 a5psw_port_rx_block_set(a5psw, port, !rx_enabled);
467 a5psw_port_tx_enable(a5psw, port, tx_enabled);
472 struct a5psw *a5psw = ds->priv;
474 a5psw_port_fdb_flush(a5psw, port);
477 static int a5psw_lk_execute_lookup(struct a5psw *a5psw, union lk_data *lk_data,
483 a5psw_reg_writel(a5psw, A5PSW_LK_DATA_LO, lk_data->lo);
484 a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data->hi);
487 ret = a5psw_lk_execute_ctrl(a5psw, &ctrl);
500 struct a5psw *a5psw = ds->priv;
510 mutex_lock(&a5psw->lk_lock);
513 ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
517 lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
529 a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
532 ret = a5psw_lk_execute_ctrl(a5psw, &reg);
538 a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
542 mutex_unlock(&a5psw->lk_lock);
551 struct a5psw *a5psw = ds->priv;
560 mutex_lock(&a5psw->lk_lock);
562 ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
566 lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
582 a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
590 ret = a5psw_lk_execute_ctrl(a5psw, &reg);
597 a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
601 mutex_unlock(&a5psw->lk_lock);
609 struct a5psw *a5psw = ds->priv;
614 mutex_lock(&a5psw->lk_lock);
619 ret = a5psw_lk_execute_ctrl(a5psw, &reg);
623 lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
629 lk_data.lo = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_LO);
637 mutex_unlock(&a5psw->lk_lock);
649 struct a5psw *a5psw = ds->priv;
652 a5psw_reg_rmw(a5psw, A5PSW_VLAN_IN_MODE_ENA, BIT(port),
656 a5psw_reg_rmw(a5psw, A5PSW_VLAN_VERIFY, mask, val);
661 static int a5psw_find_vlan_entry(struct a5psw *a5psw, u16 vid)
668 vlan_res = a5psw_reg_readl(a5psw, A5PSW_VLAN_RES(i));
676 static int a5psw_new_vlan_res_entry(struct a5psw *a5psw, u16 newvid)
683 vlan_res = a5psw_reg_readl(a5psw, A5PSW_VLAN_RES(i));
686 a5psw_reg_writel(a5psw, A5PSW_VLAN_RES(i), vlan_res);
694 static void a5psw_port_vlan_tagged_cfg(struct a5psw *a5psw,
707 a5psw_reg_writel(a5psw, vlan_res_off, A5PSW_VLAN_RES_RD_TAGMASK);
708 reg = a5psw_reg_readl(a5psw, vlan_res_off);
709 a5psw_reg_writel(a5psw, vlan_res_off, A5PSW_VLAN_RES_RD_TAGMASK);
713 a5psw_reg_writel(a5psw, vlan_res_off, reg);
716 static void a5psw_port_vlan_cfg(struct a5psw *a5psw, unsigned int vlan_res_id,
725 a5psw_reg_rmw(a5psw, A5PSW_VLAN_RES(vlan_res_id), mask, reg);
734 struct a5psw *a5psw = ds->priv;
738 vlan_res_id = a5psw_find_vlan_entry(a5psw, vid);
740 vlan_res_id = a5psw_new_vlan_res_entry(a5psw, vid);
745 a5psw_port_vlan_cfg(a5psw, vlan_res_id, port, true);
747 a5psw_port_vlan_tagged_cfg(a5psw, vlan_res_id, port, true);
754 a5psw_reg_writel(a5psw, A5PSW_SYSTEM_TAGINFO(port), vid);
762 struct a5psw *a5psw = ds->priv;
766 vlan_res_id = a5psw_find_vlan_entry(a5psw, vid);
770 a5psw_port_vlan_cfg(a5psw, vlan_res_id, port, false);
771 a5psw_port_vlan_tagged_cfg(a5psw, vlan_res_id, port, false);
776 static u64 a5psw_read_stat(struct a5psw *a5psw, u32 offset, int port)
780 reg_lo = a5psw_reg_readl(a5psw, offset + A5PSW_PORT_OFFSET(port));
782 reg_hi = a5psw_reg_readl(a5psw, A5PSW_STATS_HIWORD);
804 struct a5psw *a5psw = ds->priv;
808 data[u] = a5psw_read_stat(a5psw, a5psw_stats[u].offset, port);
822 struct a5psw *a5psw = ds->priv;
824 #define RD(name) a5psw_read_stat(a5psw, A5PSW_##name, port)
862 struct a5psw *a5psw = ds->priv;
864 #define RD(name) a5psw_read_stat(a5psw, A5PSW_##name, port)
884 struct a5psw *a5psw = ds->priv;
887 stat = a5psw_read_stat(a5psw, A5PSW_aTxPAUSEMACCtrlFrames, port);
889 stat = a5psw_read_stat(a5psw, A5PSW_aRxPAUSEMACCtrlFrames, port);
893 static void a5psw_vlan_setup(struct a5psw *a5psw, int port)
902 a5psw_reg_rmw(a5psw, A5PSW_VLAN_IN_MODE, A5PSW_VLAN_IN_MODE_PORT(port),
910 a5psw_reg_rmw(a5psw, A5PSW_VLAN_OUT_MODE,
916 struct a5psw *a5psw = ds->priv;
924 dev_err(a5psw->dev, "Invalid CPU port\n");
931 a5psw_reg_writel(a5psw, A5PSW_MGMT_CFG, reg);
934 a5psw_reg_writel(a5psw, A5PSW_PATTERN_CTRL(A5PSW_PATTERN_MGMTFWD),
940 a5psw_reg_writel(a5psw, A5PSW_MGMT_TAG_CFG, reg);
946 a5psw_reg_writel(a5psw, A5PSW_LK_CTRL, reg);
948 ret = readl_poll_timeout(a5psw->base + A5PSW_LK_CTRL, reg,
952 dev_err(a5psw->dev, "Failed to clear lookup table\n");
958 a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
963 a5psw_reg_writel(a5psw, A5PSW_VLAN_RES(vlan), reg);
970 a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port),
974 a5psw_port_enable_set(a5psw, port, dsa_port_is_cpu(dp));
981 a5psw_flooding_set_resolution(a5psw, port, true);
982 a5psw_port_learning_set(a5psw, port, true);
987 a5psw_port_set_standalone(a5psw, port, true);
989 a5psw_vlan_setup(a5psw, port);
1027 static int a5psw_mdio_wait_busy(struct a5psw *a5psw)
1032 err = readl_poll_timeout(a5psw->base + A5PSW_MDIO_CFG_STATUS, status,
1036 dev_err(a5psw->dev, "MDIO command timeout\n");
1043 struct a5psw *a5psw = bus->priv;
1051 a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd);
1053 ret = a5psw_mdio_wait_busy(a5psw);
1057 ret = a5psw_reg_readl(a5psw, A5PSW_MDIO_DATA) & A5PSW_MDIO_DATA_MASK;
1059 status = a5psw_reg_readl(a5psw, A5PSW_MDIO_CFG_STATUS);
1069 struct a5psw *a5psw = bus->priv;
1075 a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd);
1076 a5psw_reg_writel(a5psw, A5PSW_MDIO_DATA, phy_data);
1078 return a5psw_mdio_wait_busy(a5psw);
1081 static int a5psw_mdio_config(struct a5psw *a5psw, u32 mdio_freq)
1087 rate = clk_get_rate(a5psw->hclk);
1091 dev_err(a5psw->dev, "MDIO clock div %ld out of range\n", div);
1097 a5psw_reg_writel(a5psw, A5PSW_MDIO_CFG_STATUS, cfgstatus);
1102 static int a5psw_probe_mdio(struct a5psw *a5psw, struct device_node *node)
1104 struct device *dev = a5psw->dev;
1112 ret = a5psw_mdio_config(a5psw, mdio_freq);
1123 bus->priv = a5psw;
1127 a5psw->mii_bus = bus;
1132 static void a5psw_pcs_free(struct a5psw *a5psw)
1136 for (i = 0; i < ARRAY_SIZE(a5psw->pcs); i++) {
1137 if (a5psw->pcs[i])
1138 miic_destroy(a5psw->pcs[i]);
1142 static int a5psw_pcs_get(struct a5psw *a5psw)
1149 ports = of_get_child_by_name(a5psw->dev->of_node, "ethernet-ports");
1163 if (reg >= ARRAY_SIZE(a5psw->pcs)) {
1168 pcs = miic_create(a5psw->dev, pcs_node);
1170 dev_err(a5psw->dev, "Failed to create PCS for port %d\n",
1176 a5psw->pcs[reg] = pcs;
1187 a5psw_pcs_free(a5psw);
1197 struct a5psw *a5psw;
1200 a5psw = devm_kzalloc(dev, sizeof(*a5psw), GFP_KERNEL);
1201 if (!a5psw)
1204 a5psw->dev = dev;
1205 mutex_init(&a5psw->lk_lock);
1206 spin_lock_init(&a5psw->reg_lock);
1207 a5psw->base = devm_platform_ioremap_resource(pdev, 0);
1208 if (IS_ERR(a5psw->base))
1209 return PTR_ERR(a5psw->base);
1211 a5psw->bridged_ports = BIT(A5PSW_CPU_PORT);
1213 ret = a5psw_pcs_get(a5psw);
1217 a5psw->hclk = devm_clk_get(dev, "hclk");
1218 if (IS_ERR(a5psw->hclk)) {
1220 ret = PTR_ERR(a5psw->hclk);
1224 a5psw->clk = devm_clk_get(dev, "clk");
1225 if (IS_ERR(a5psw->clk)) {
1227 ret = PTR_ERR(a5psw->clk);
1231 ret = clk_prepare_enable(a5psw->clk);
1235 ret = clk_prepare_enable(a5psw->hclk);
1241 ret = a5psw_probe_mdio(a5psw, mdio);
1251 ds = &a5psw->ds;
1255 ds->priv = a5psw;
1266 clk_disable_unprepare(a5psw->hclk);
1268 clk_disable_unprepare(a5psw->clk);
1270 a5psw_pcs_free(a5psw);
1277 struct a5psw *a5psw = platform_get_drvdata(pdev);
1279 if (!a5psw)
1282 dsa_unregister_switch(&a5psw->ds);
1283 a5psw_pcs_free(a5psw);
1284 clk_disable_unprepare(a5psw->hclk);
1285 clk_disable_unprepare(a5psw->clk);
1292 struct a5psw *a5psw = platform_get_drvdata(pdev);
1294 if (!a5psw)
1297 dsa_switch_shutdown(&a5psw->ds);
1303 { .compatible = "renesas,rzn1-a5psw", },