Linux Audio

Check our new training course

Loading...
v6.8
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2022 Schneider-Electric
   4 *
   5 * Clément Léger <clement.leger@bootlin.com>
   6 */
   7
   8#include <linux/clk.h>
   9#include <linux/etherdevice.h>
  10#include <linux/if_bridge.h>
  11#include <linux/if_ether.h>
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/of.h>
  15#include <linux/of_mdio.h>
  16#include <net/dsa.h>
  17
  18#include "rzn1_a5psw.h"
  19
  20struct a5psw_stats {
  21	u16 offset;
  22	const char name[ETH_GSTRING_LEN];
  23};
  24
  25#define STAT_DESC(_offset) {	\
  26	.offset = A5PSW_##_offset,	\
  27	.name = __stringify(_offset),	\
  28}
  29
  30static const struct a5psw_stats a5psw_stats[] = {
  31	STAT_DESC(aFramesTransmittedOK),
  32	STAT_DESC(aFramesReceivedOK),
  33	STAT_DESC(aFrameCheckSequenceErrors),
  34	STAT_DESC(aAlignmentErrors),
  35	STAT_DESC(aOctetsTransmittedOK),
  36	STAT_DESC(aOctetsReceivedOK),
  37	STAT_DESC(aTxPAUSEMACCtrlFrames),
  38	STAT_DESC(aRxPAUSEMACCtrlFrames),
  39	STAT_DESC(ifInErrors),
  40	STAT_DESC(ifOutErrors),
  41	STAT_DESC(ifInUcastPkts),
  42	STAT_DESC(ifInMulticastPkts),
  43	STAT_DESC(ifInBroadcastPkts),
  44	STAT_DESC(ifOutDiscards),
  45	STAT_DESC(ifOutUcastPkts),
  46	STAT_DESC(ifOutMulticastPkts),
  47	STAT_DESC(ifOutBroadcastPkts),
  48	STAT_DESC(etherStatsDropEvents),
  49	STAT_DESC(etherStatsOctets),
  50	STAT_DESC(etherStatsPkts),
  51	STAT_DESC(etherStatsUndersizePkts),
  52	STAT_DESC(etherStatsOversizePkts),
  53	STAT_DESC(etherStatsPkts64Octets),
  54	STAT_DESC(etherStatsPkts65to127Octets),
  55	STAT_DESC(etherStatsPkts128to255Octets),
  56	STAT_DESC(etherStatsPkts256to511Octets),
  57	STAT_DESC(etherStatsPkts1024to1518Octets),
  58	STAT_DESC(etherStatsPkts1519toXOctets),
  59	STAT_DESC(etherStatsJabbers),
  60	STAT_DESC(etherStatsFragments),
  61	STAT_DESC(VLANReceived),
  62	STAT_DESC(VLANTransmitted),
  63	STAT_DESC(aDeferred),
  64	STAT_DESC(aMultipleCollisions),
  65	STAT_DESC(aSingleCollisions),
  66	STAT_DESC(aLateCollisions),
  67	STAT_DESC(aExcessiveCollisions),
  68	STAT_DESC(aCarrierSenseErrors),
  69};
  70
  71static void a5psw_reg_writel(struct a5psw *a5psw, int offset, u32 value)
  72{
  73	writel(value, a5psw->base + offset);
  74}
  75
  76static u32 a5psw_reg_readl(struct a5psw *a5psw, int offset)
  77{
  78	return readl(a5psw->base + offset);
  79}
  80
  81static void a5psw_reg_rmw(struct a5psw *a5psw, int offset, u32 mask, u32 val)
  82{
  83	u32 reg;
  84
  85	spin_lock(&a5psw->reg_lock);
  86
  87	reg = a5psw_reg_readl(a5psw, offset);
  88	reg &= ~mask;
  89	reg |= val;
  90	a5psw_reg_writel(a5psw, offset, reg);
  91
  92	spin_unlock(&a5psw->reg_lock);
  93}
  94
  95static enum dsa_tag_protocol a5psw_get_tag_protocol(struct dsa_switch *ds,
  96						    int port,
  97						    enum dsa_tag_protocol mp)
  98{
  99	return DSA_TAG_PROTO_RZN1_A5PSW;
 100}
 101
 102static void a5psw_port_pattern_set(struct a5psw *a5psw, int port, int pattern,
 103				   bool enable)
 104{
 105	u32 rx_match = 0;
 106
 107	if (enable)
 108		rx_match |= A5PSW_RXMATCH_CONFIG_PATTERN(pattern);
 109
 110	a5psw_reg_rmw(a5psw, A5PSW_RXMATCH_CONFIG(port),
 111		      A5PSW_RXMATCH_CONFIG_PATTERN(pattern), rx_match);
 112}
 113
 114static void a5psw_port_mgmtfwd_set(struct a5psw *a5psw, int port, bool enable)
 115{
 116	/* Enable "management forward" pattern matching, this will forward
 117	 * packets from this port only towards the management port and thus
 118	 * isolate the port.
 119	 */
 120	a5psw_port_pattern_set(a5psw, port, A5PSW_PATTERN_MGMTFWD, enable);
 121}
 122
 123static void a5psw_port_tx_enable(struct a5psw *a5psw, int port, bool enable)
 124{
 125	u32 mask = A5PSW_PORT_ENA_TX(port);
 126	u32 reg = enable ? mask : 0;
 127
 128	/* Even though the port TX is disabled through TXENA bit in the
 129	 * PORT_ENA register, it can still send BPDUs. This depends on the tag
 130	 * configuration added when sending packets from the CPU port to the
 131	 * switch port. Indeed, when using forced forwarding without filtering,
 132	 * even disabled ports will be able to send packets that are tagged.
 133	 * This allows to implement STP support when ports are in a state where
 134	 * forwarding traffic should be stopped but BPDUs should still be sent.
 135	 */
 136	a5psw_reg_rmw(a5psw, A5PSW_PORT_ENA, mask, reg);
 137}
 138
 139static void a5psw_port_enable_set(struct a5psw *a5psw, int port, bool enable)
 140{
 141	u32 port_ena = 0;
 142
 143	if (enable)
 144		port_ena |= A5PSW_PORT_ENA_TX_RX(port);
 145
 146	a5psw_reg_rmw(a5psw, A5PSW_PORT_ENA, A5PSW_PORT_ENA_TX_RX(port),
 147		      port_ena);
 148}
 149
 150static int a5psw_lk_execute_ctrl(struct a5psw *a5psw, u32 *ctrl)
 151{
 152	int ret;
 153
 154	a5psw_reg_writel(a5psw, A5PSW_LK_ADDR_CTRL, *ctrl);
 155
 156	ret = readl_poll_timeout(a5psw->base + A5PSW_LK_ADDR_CTRL, *ctrl,
 157				 !(*ctrl & A5PSW_LK_ADDR_CTRL_BUSY),
 158				 A5PSW_LK_BUSY_USEC_POLL, A5PSW_CTRL_TIMEOUT);
 159	if (ret)
 160		dev_err(a5psw->dev, "LK_CTRL timeout waiting for BUSY bit\n");
 161
 162	return ret;
 163}
 164
 165static void a5psw_port_fdb_flush(struct a5psw *a5psw, int port)
 166{
 167	u32 ctrl = A5PSW_LK_ADDR_CTRL_DELETE_PORT | BIT(port);
 168
 169	mutex_lock(&a5psw->lk_lock);
 170	a5psw_lk_execute_ctrl(a5psw, &ctrl);
 171	mutex_unlock(&a5psw->lk_lock);
 172}
 173
 174static void a5psw_port_authorize_set(struct a5psw *a5psw, int port,
 175				     bool authorize)
 176{
 177	u32 reg = a5psw_reg_readl(a5psw, A5PSW_AUTH_PORT(port));
 178
 179	if (authorize)
 180		reg |= A5PSW_AUTH_PORT_AUTHORIZED;
 181	else
 182		reg &= ~A5PSW_AUTH_PORT_AUTHORIZED;
 183
 184	a5psw_reg_writel(a5psw, A5PSW_AUTH_PORT(port), reg);
 185}
 186
 187static void a5psw_port_disable(struct dsa_switch *ds, int port)
 188{
 189	struct a5psw *a5psw = ds->priv;
 190
 191	a5psw_port_authorize_set(a5psw, port, false);
 192	a5psw_port_enable_set(a5psw, port, false);
 193}
 194
 195static int a5psw_port_enable(struct dsa_switch *ds, int port,
 196			     struct phy_device *phy)
 197{
 198	struct a5psw *a5psw = ds->priv;
 199
 200	a5psw_port_authorize_set(a5psw, port, true);
 201	a5psw_port_enable_set(a5psw, port, true);
 202
 203	return 0;
 204}
 205
 206static int a5psw_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
 207{
 208	struct a5psw *a5psw = ds->priv;
 209
 210	new_mtu += ETH_HLEN + A5PSW_EXTRA_MTU_LEN + ETH_FCS_LEN;
 211	a5psw_reg_writel(a5psw, A5PSW_FRM_LENGTH(port), new_mtu);
 212
 213	return 0;
 214}
 215
 216static int a5psw_port_max_mtu(struct dsa_switch *ds, int port)
 217{
 218	return A5PSW_MAX_MTU;
 219}
 220
 221static void a5psw_phylink_get_caps(struct dsa_switch *ds, int port,
 222				   struct phylink_config *config)
 223{
 224	unsigned long *intf = config->supported_interfaces;
 225
 226	config->mac_capabilities = MAC_1000FD;
 227
 228	if (dsa_is_cpu_port(ds, port)) {
 229		/* GMII is used internally and GMAC2 is connected to the switch
 230		 * using 1000Mbps Full-Duplex mode only (cf ethernet manual)
 231		 */
 232		__set_bit(PHY_INTERFACE_MODE_GMII, intf);
 233	} else {
 234		config->mac_capabilities |= MAC_100 | MAC_10;
 235		phy_interface_set_rgmii(intf);
 236		__set_bit(PHY_INTERFACE_MODE_RMII, intf);
 237		__set_bit(PHY_INTERFACE_MODE_MII, intf);
 238	}
 239}
 240
 241static struct phylink_pcs *
 242a5psw_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
 243			     phy_interface_t interface)
 244{
 245	struct dsa_port *dp = dsa_to_port(ds, port);
 246	struct a5psw *a5psw = ds->priv;
 
 
 
 247
 248	if (!dsa_port_is_cpu(dp) && a5psw->pcs[port])
 249		return a5psw->pcs[port];
 250
 251	return NULL;
 
 
 
 252}
 253
 254static void a5psw_phylink_mac_link_down(struct dsa_switch *ds, int port,
 255					unsigned int mode,
 256					phy_interface_t interface)
 257{
 258	struct a5psw *a5psw = ds->priv;
 
 
 259	u32 cmd_cfg;
 260
 261	cmd_cfg = a5psw_reg_readl(a5psw, A5PSW_CMD_CFG(port));
 262	cmd_cfg &= ~(A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA);
 263	a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), cmd_cfg);
 264}
 265
 266static void a5psw_phylink_mac_link_up(struct dsa_switch *ds, int port,
 
 267				      unsigned int mode,
 268				      phy_interface_t interface,
 269				      struct phy_device *phydev, int speed,
 270				      int duplex, bool tx_pause, bool rx_pause)
 271{
 272	u32 cmd_cfg = A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA |
 273		      A5PSW_CMD_CFG_TX_CRC_APPEND;
 274	struct a5psw *a5psw = ds->priv;
 
 275
 276	if (speed == SPEED_1000)
 277		cmd_cfg |= A5PSW_CMD_CFG_ETH_SPEED;
 278
 279	if (duplex == DUPLEX_HALF)
 280		cmd_cfg |= A5PSW_CMD_CFG_HD_ENA;
 281
 282	cmd_cfg |= A5PSW_CMD_CFG_CNTL_FRM_ENA;
 283
 284	if (!rx_pause)
 285		cmd_cfg &= ~A5PSW_CMD_CFG_PAUSE_IGNORE;
 286
 287	a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), cmd_cfg);
 288}
 289
 290static int a5psw_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
 291{
 292	struct a5psw *a5psw = ds->priv;
 293	unsigned long rate;
 294	u64 max, tmp;
 295	u32 agetime;
 296
 297	rate = clk_get_rate(a5psw->clk);
 298	max = div64_ul(((u64)A5PSW_LK_AGETIME_MASK * A5PSW_TABLE_ENTRIES * 1024),
 299		       rate) * 1000;
 300	if (msecs > max)
 301		return -EINVAL;
 302
 303	tmp = div_u64(rate, MSEC_PER_SEC);
 304	agetime = div_u64(msecs * tmp, 1024 * A5PSW_TABLE_ENTRIES);
 305
 306	a5psw_reg_writel(a5psw, A5PSW_LK_AGETIME, agetime);
 307
 308	return 0;
 309}
 310
 311static void a5psw_port_learning_set(struct a5psw *a5psw, int port, bool learn)
 312{
 313	u32 mask = A5PSW_INPUT_LEARN_DIS(port);
 314	u32 reg = !learn ? mask : 0;
 315
 316	a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN, mask, reg);
 317}
 318
 319static void a5psw_port_rx_block_set(struct a5psw *a5psw, int port, bool block)
 320{
 321	u32 mask = A5PSW_INPUT_LEARN_BLOCK(port);
 322	u32 reg = block ? mask : 0;
 323
 324	a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN, mask, reg);
 325}
 326
 327static void a5psw_flooding_set_resolution(struct a5psw *a5psw, int port,
 328					  bool set)
 329{
 330	u8 offsets[] = {A5PSW_UCAST_DEF_MASK, A5PSW_BCAST_DEF_MASK,
 331			A5PSW_MCAST_DEF_MASK};
 332	int i;
 333
 334	for (i = 0; i < ARRAY_SIZE(offsets); i++)
 335		a5psw_reg_rmw(a5psw, offsets[i], BIT(port),
 336			      set ? BIT(port) : 0);
 337}
 338
 339static void a5psw_port_set_standalone(struct a5psw *a5psw, int port,
 340				      bool standalone)
 341{
 342	a5psw_port_learning_set(a5psw, port, !standalone);
 343	a5psw_flooding_set_resolution(a5psw, port, !standalone);
 344	a5psw_port_mgmtfwd_set(a5psw, port, standalone);
 345}
 346
 347static int a5psw_port_bridge_join(struct dsa_switch *ds, int port,
 348				  struct dsa_bridge bridge,
 349				  bool *tx_fwd_offload,
 350				  struct netlink_ext_ack *extack)
 351{
 352	struct a5psw *a5psw = ds->priv;
 353
 354	/* We only support 1 bridge device */
 355	if (a5psw->br_dev && bridge.dev != a5psw->br_dev) {
 356		NL_SET_ERR_MSG_MOD(extack,
 357				   "Forwarding offload supported for a single bridge");
 358		return -EOPNOTSUPP;
 359	}
 360
 361	a5psw->br_dev = bridge.dev;
 362	a5psw_port_set_standalone(a5psw, port, false);
 363
 364	a5psw->bridged_ports |= BIT(port);
 365
 366	return 0;
 367}
 368
 369static void a5psw_port_bridge_leave(struct dsa_switch *ds, int port,
 370				    struct dsa_bridge bridge)
 371{
 372	struct a5psw *a5psw = ds->priv;
 373
 374	a5psw->bridged_ports &= ~BIT(port);
 375
 376	a5psw_port_set_standalone(a5psw, port, true);
 377
 378	/* No more ports bridged */
 379	if (a5psw->bridged_ports == BIT(A5PSW_CPU_PORT))
 380		a5psw->br_dev = NULL;
 381}
 382
 383static int a5psw_port_pre_bridge_flags(struct dsa_switch *ds, int port,
 384				       struct switchdev_brport_flags flags,
 385				       struct netlink_ext_ack *extack)
 386{
 387	if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
 388			   BR_BCAST_FLOOD))
 389		return -EINVAL;
 390
 391	return 0;
 392}
 393
 394static int
 395a5psw_port_bridge_flags(struct dsa_switch *ds, int port,
 396			struct switchdev_brport_flags flags,
 397			struct netlink_ext_ack *extack)
 398{
 399	struct a5psw *a5psw = ds->priv;
 400	u32 val;
 401
 402	/* If a port is set as standalone, we do not want to be able to
 403	 * configure flooding nor learning which would result in joining the
 404	 * unique bridge. This can happen when a port leaves the bridge, in
 405	 * which case the DSA core will try to "clear" all flags for the
 406	 * standalone port (ie enable flooding, disable learning). In that case
 407	 * do not fail but do not apply the flags.
 408	 */
 409	if (!(a5psw->bridged_ports & BIT(port)))
 410		return 0;
 411
 412	if (flags.mask & BR_LEARNING) {
 413		val = flags.val & BR_LEARNING ? 0 : A5PSW_INPUT_LEARN_DIS(port);
 414		a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN,
 415			      A5PSW_INPUT_LEARN_DIS(port), val);
 416	}
 417
 418	if (flags.mask & BR_FLOOD) {
 419		val = flags.val & BR_FLOOD ? BIT(port) : 0;
 420		a5psw_reg_rmw(a5psw, A5PSW_UCAST_DEF_MASK, BIT(port), val);
 421	}
 422
 423	if (flags.mask & BR_MCAST_FLOOD) {
 424		val = flags.val & BR_MCAST_FLOOD ? BIT(port) : 0;
 425		a5psw_reg_rmw(a5psw, A5PSW_MCAST_DEF_MASK, BIT(port), val);
 426	}
 427
 428	if (flags.mask & BR_BCAST_FLOOD) {
 429		val = flags.val & BR_BCAST_FLOOD ? BIT(port) : 0;
 430		a5psw_reg_rmw(a5psw, A5PSW_BCAST_DEF_MASK, BIT(port), val);
 431	}
 432
 433	return 0;
 434}
 435
 436static void a5psw_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 437{
 438	bool learning_enabled, rx_enabled, tx_enabled;
 439	struct dsa_port *dp = dsa_to_port(ds, port);
 440	struct a5psw *a5psw = ds->priv;
 441
 442	switch (state) {
 443	case BR_STATE_DISABLED:
 444	case BR_STATE_BLOCKING:
 445	case BR_STATE_LISTENING:
 446		rx_enabled = false;
 447		tx_enabled = false;
 448		learning_enabled = false;
 449		break;
 450	case BR_STATE_LEARNING:
 451		rx_enabled = false;
 452		tx_enabled = false;
 453		learning_enabled = dp->learning;
 454		break;
 455	case BR_STATE_FORWARDING:
 456		rx_enabled = true;
 457		tx_enabled = true;
 458		learning_enabled = dp->learning;
 459		break;
 460	default:
 461		dev_err(ds->dev, "invalid STP state: %d\n", state);
 462		return;
 463	}
 464
 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);
 468}
 469
 470static void a5psw_port_fast_age(struct dsa_switch *ds, int port)
 471{
 472	struct a5psw *a5psw = ds->priv;
 473
 474	a5psw_port_fdb_flush(a5psw, port);
 475}
 476
 477static int a5psw_lk_execute_lookup(struct a5psw *a5psw, union lk_data *lk_data,
 478				   u16 *entry)
 479{
 480	u32 ctrl;
 481	int ret;
 482
 483	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_LO, lk_data->lo);
 484	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data->hi);
 485
 486	ctrl = A5PSW_LK_ADDR_CTRL_LOOKUP;
 487	ret = a5psw_lk_execute_ctrl(a5psw, &ctrl);
 488	if (ret)
 489		return ret;
 490
 491	*entry = ctrl & A5PSW_LK_ADDR_CTRL_ADDRESS;
 492
 493	return 0;
 494}
 495
 496static int a5psw_port_fdb_add(struct dsa_switch *ds, int port,
 497			      const unsigned char *addr, u16 vid,
 498			      struct dsa_db db)
 499{
 500	struct a5psw *a5psw = ds->priv;
 501	union lk_data lk_data = {0};
 502	bool inc_learncount = false;
 503	int ret = 0;
 504	u16 entry;
 505	u32 reg;
 506
 507	ether_addr_copy(lk_data.entry.mac, addr);
 508	lk_data.entry.port_mask = BIT(port);
 509
 510	mutex_lock(&a5psw->lk_lock);
 511
 512	/* Set the value to be written in the lookup table */
 513	ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
 514	if (ret)
 515		goto lk_unlock;
 516
 517	lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
 518	if (!lk_data.entry.valid) {
 519		inc_learncount = true;
 520		/* port_mask set to 0x1f when entry is not valid, clear it */
 521		lk_data.entry.port_mask = 0;
 522		lk_data.entry.prio = 0;
 523	}
 524
 525	lk_data.entry.port_mask |= BIT(port);
 526	lk_data.entry.is_static = 1;
 527	lk_data.entry.valid = 1;
 528
 529	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
 530
 531	reg = A5PSW_LK_ADDR_CTRL_WRITE | entry;
 532	ret = a5psw_lk_execute_ctrl(a5psw, &reg);
 533	if (ret)
 534		goto lk_unlock;
 535
 536	if (inc_learncount) {
 537		reg = A5PSW_LK_LEARNCOUNT_MODE_INC;
 538		a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
 539	}
 540
 541lk_unlock:
 542	mutex_unlock(&a5psw->lk_lock);
 543
 544	return ret;
 545}
 546
 547static int a5psw_port_fdb_del(struct dsa_switch *ds, int port,
 548			      const unsigned char *addr, u16 vid,
 549			      struct dsa_db db)
 550{
 551	struct a5psw *a5psw = ds->priv;
 552	union lk_data lk_data = {0};
 553	bool clear = false;
 554	u16 entry;
 555	u32 reg;
 556	int ret;
 557
 558	ether_addr_copy(lk_data.entry.mac, addr);
 559
 560	mutex_lock(&a5psw->lk_lock);
 561
 562	ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
 563	if (ret)
 564		goto lk_unlock;
 565
 566	lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
 567
 568	/* Our hardware does not associate any VID to the FDB entries so this
 569	 * means that if two entries were added for the same mac but for
 570	 * different VID, then, on the deletion of the first one, we would also
 571	 * delete the second one. Since there is unfortunately nothing we can do
 572	 * about that, do not return an error...
 573	 */
 574	if (!lk_data.entry.valid)
 575		goto lk_unlock;
 576
 577	lk_data.entry.port_mask &= ~BIT(port);
 578	/* If there is no more port in the mask, clear the entry */
 579	if (lk_data.entry.port_mask == 0)
 580		clear = true;
 581
 582	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
 583
 584	reg = entry;
 585	if (clear)
 586		reg |= A5PSW_LK_ADDR_CTRL_CLEAR;
 587	else
 588		reg |= A5PSW_LK_ADDR_CTRL_WRITE;
 589
 590	ret = a5psw_lk_execute_ctrl(a5psw, &reg);
 591	if (ret)
 592		goto lk_unlock;
 593
 594	/* Decrement LEARNCOUNT */
 595	if (clear) {
 596		reg = A5PSW_LK_LEARNCOUNT_MODE_DEC;
 597		a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
 598	}
 599
 600lk_unlock:
 601	mutex_unlock(&a5psw->lk_lock);
 602
 603	return ret;
 604}
 605
 606static int a5psw_port_fdb_dump(struct dsa_switch *ds, int port,
 607			       dsa_fdb_dump_cb_t *cb, void *data)
 608{
 609	struct a5psw *a5psw = ds->priv;
 610	union lk_data lk_data;
 611	int i = 0, ret = 0;
 612	u32 reg;
 613
 614	mutex_lock(&a5psw->lk_lock);
 615
 616	for (i = 0; i < A5PSW_TABLE_ENTRIES; i++) {
 617		reg = A5PSW_LK_ADDR_CTRL_READ | A5PSW_LK_ADDR_CTRL_WAIT | i;
 618
 619		ret = a5psw_lk_execute_ctrl(a5psw, &reg);
 620		if (ret)
 621			goto out_unlock;
 622
 623		lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
 624		/* If entry is not valid or does not contain the port, skip */
 625		if (!lk_data.entry.valid ||
 626		    !(lk_data.entry.port_mask & BIT(port)))
 627			continue;
 628
 629		lk_data.lo = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_LO);
 630
 631		ret = cb(lk_data.entry.mac, 0, lk_data.entry.is_static, data);
 632		if (ret)
 633			goto out_unlock;
 634	}
 635
 636out_unlock:
 637	mutex_unlock(&a5psw->lk_lock);
 638
 639	return ret;
 640}
 641
 642static int a5psw_port_vlan_filtering(struct dsa_switch *ds, int port,
 643				     bool vlan_filtering,
 644				     struct netlink_ext_ack *extack)
 645{
 646	u32 mask = BIT(port + A5PSW_VLAN_VERI_SHIFT) |
 647		   BIT(port + A5PSW_VLAN_DISC_SHIFT);
 648	u32 val = vlan_filtering ? mask : 0;
 649	struct a5psw *a5psw = ds->priv;
 650
 651	/* Disable/enable vlan tagging */
 652	a5psw_reg_rmw(a5psw, A5PSW_VLAN_IN_MODE_ENA, BIT(port),
 653		      vlan_filtering ? BIT(port) : 0);
 654
 655	/* Disable/enable vlan input filtering */
 656	a5psw_reg_rmw(a5psw, A5PSW_VLAN_VERIFY, mask, val);
 657
 658	return 0;
 659}
 660
 661static int a5psw_find_vlan_entry(struct a5psw *a5psw, u16 vid)
 662{
 663	u32 vlan_res;
 664	int i;
 665
 666	/* Find vlan for this port */
 667	for (i = 0; i < A5PSW_VLAN_COUNT; i++) {
 668		vlan_res = a5psw_reg_readl(a5psw, A5PSW_VLAN_RES(i));
 669		if (FIELD_GET(A5PSW_VLAN_RES_VLANID, vlan_res) == vid)
 670			return i;
 671	}
 672
 673	return -1;
 674}
 675
 676static int a5psw_new_vlan_res_entry(struct a5psw *a5psw, u16 newvid)
 677{
 678	u32 vlan_res;
 679	int i;
 680
 681	/* Find a free VLAN entry */
 682	for (i = 0; i < A5PSW_VLAN_COUNT; i++) {
 683		vlan_res = a5psw_reg_readl(a5psw, A5PSW_VLAN_RES(i));
 684		if (!(FIELD_GET(A5PSW_VLAN_RES_PORTMASK, vlan_res))) {
 685			vlan_res = FIELD_PREP(A5PSW_VLAN_RES_VLANID, newvid);
 686			a5psw_reg_writel(a5psw, A5PSW_VLAN_RES(i), vlan_res);
 687			return i;
 688		}
 689	}
 690
 691	return -1;
 692}
 693
 694static void a5psw_port_vlan_tagged_cfg(struct a5psw *a5psw,
 695				       unsigned int vlan_res_id, int port,
 696				       bool set)
 697{
 698	u32 mask = A5PSW_VLAN_RES_WR_PORTMASK | A5PSW_VLAN_RES_RD_TAGMASK |
 699		   BIT(port);
 700	u32 vlan_res_off = A5PSW_VLAN_RES(vlan_res_id);
 701	u32 val = A5PSW_VLAN_RES_WR_TAGMASK, reg;
 702
 703	if (set)
 704		val |= BIT(port);
 705
 706	/* Toggle tag mask read */
 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);
 710
 711	reg &= ~mask;
 712	reg |= val;
 713	a5psw_reg_writel(a5psw, vlan_res_off, reg);
 714}
 715
 716static void a5psw_port_vlan_cfg(struct a5psw *a5psw, unsigned int vlan_res_id,
 717				int port, bool set)
 718{
 719	u32 mask = A5PSW_VLAN_RES_WR_TAGMASK | BIT(port);
 720	u32 reg = A5PSW_VLAN_RES_WR_PORTMASK;
 721
 722	if (set)
 723		reg |= BIT(port);
 724
 725	a5psw_reg_rmw(a5psw, A5PSW_VLAN_RES(vlan_res_id), mask, reg);
 726}
 727
 728static int a5psw_port_vlan_add(struct dsa_switch *ds, int port,
 729			       const struct switchdev_obj_port_vlan *vlan,
 730			       struct netlink_ext_ack *extack)
 731{
 732	bool tagged = !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED);
 733	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
 734	struct a5psw *a5psw = ds->priv;
 735	u16 vid = vlan->vid;
 736	int vlan_res_id;
 737
 738	vlan_res_id = a5psw_find_vlan_entry(a5psw, vid);
 739	if (vlan_res_id < 0) {
 740		vlan_res_id = a5psw_new_vlan_res_entry(a5psw, vid);
 741		if (vlan_res_id < 0)
 742			return -ENOSPC;
 743	}
 744
 745	a5psw_port_vlan_cfg(a5psw, vlan_res_id, port, true);
 746	if (tagged)
 747		a5psw_port_vlan_tagged_cfg(a5psw, vlan_res_id, port, true);
 748
 749	/* Configure port to tag with corresponding VID, but do not enable it
 750	 * yet: wait for vlan filtering to be enabled to enable vlan port
 751	 * tagging
 752	 */
 753	if (pvid)
 754		a5psw_reg_writel(a5psw, A5PSW_SYSTEM_TAGINFO(port), vid);
 755
 756	return 0;
 757}
 758
 759static int a5psw_port_vlan_del(struct dsa_switch *ds, int port,
 760			       const struct switchdev_obj_port_vlan *vlan)
 761{
 762	struct a5psw *a5psw = ds->priv;
 763	u16 vid = vlan->vid;
 764	int vlan_res_id;
 765
 766	vlan_res_id = a5psw_find_vlan_entry(a5psw, vid);
 767	if (vlan_res_id < 0)
 768		return -EINVAL;
 769
 770	a5psw_port_vlan_cfg(a5psw, vlan_res_id, port, false);
 771	a5psw_port_vlan_tagged_cfg(a5psw, vlan_res_id, port, false);
 772
 773	return 0;
 774}
 775
 776static u64 a5psw_read_stat(struct a5psw *a5psw, u32 offset, int port)
 777{
 778	u32 reg_lo, reg_hi;
 779
 780	reg_lo = a5psw_reg_readl(a5psw, offset + A5PSW_PORT_OFFSET(port));
 781	/* A5PSW_STATS_HIWORD is latched on stat read */
 782	reg_hi = a5psw_reg_readl(a5psw, A5PSW_STATS_HIWORD);
 783
 784	return ((u64)reg_hi << 32) | reg_lo;
 785}
 786
 787static void a5psw_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 788			      uint8_t *data)
 789{
 790	unsigned int u;
 791
 792	if (stringset != ETH_SS_STATS)
 793		return;
 794
 795	for (u = 0; u < ARRAY_SIZE(a5psw_stats); u++) {
 796		memcpy(data + u * ETH_GSTRING_LEN, a5psw_stats[u].name,
 797		       ETH_GSTRING_LEN);
 798	}
 799}
 800
 801static void a5psw_get_ethtool_stats(struct dsa_switch *ds, int port,
 802				    uint64_t *data)
 803{
 804	struct a5psw *a5psw = ds->priv;
 805	unsigned int u;
 806
 807	for (u = 0; u < ARRAY_SIZE(a5psw_stats); u++)
 808		data[u] = a5psw_read_stat(a5psw, a5psw_stats[u].offset, port);
 809}
 810
 811static int a5psw_get_sset_count(struct dsa_switch *ds, int port, int sset)
 812{
 813	if (sset != ETH_SS_STATS)
 814		return 0;
 815
 816	return ARRAY_SIZE(a5psw_stats);
 817}
 818
 819static void a5psw_get_eth_mac_stats(struct dsa_switch *ds, int port,
 820				    struct ethtool_eth_mac_stats *mac_stats)
 821{
 822	struct a5psw *a5psw = ds->priv;
 823
 824#define RD(name) a5psw_read_stat(a5psw, A5PSW_##name, port)
 825	mac_stats->FramesTransmittedOK = RD(aFramesTransmittedOK);
 826	mac_stats->SingleCollisionFrames = RD(aSingleCollisions);
 827	mac_stats->MultipleCollisionFrames = RD(aMultipleCollisions);
 828	mac_stats->FramesReceivedOK = RD(aFramesReceivedOK);
 829	mac_stats->FrameCheckSequenceErrors = RD(aFrameCheckSequenceErrors);
 830	mac_stats->AlignmentErrors = RD(aAlignmentErrors);
 831	mac_stats->OctetsTransmittedOK = RD(aOctetsTransmittedOK);
 832	mac_stats->FramesWithDeferredXmissions = RD(aDeferred);
 833	mac_stats->LateCollisions = RD(aLateCollisions);
 834	mac_stats->FramesAbortedDueToXSColls = RD(aExcessiveCollisions);
 835	mac_stats->FramesLostDueToIntMACXmitError = RD(ifOutErrors);
 836	mac_stats->CarrierSenseErrors = RD(aCarrierSenseErrors);
 837	mac_stats->OctetsReceivedOK = RD(aOctetsReceivedOK);
 838	mac_stats->FramesLostDueToIntMACRcvError = RD(ifInErrors);
 839	mac_stats->MulticastFramesXmittedOK = RD(ifOutMulticastPkts);
 840	mac_stats->BroadcastFramesXmittedOK = RD(ifOutBroadcastPkts);
 841	mac_stats->FramesWithExcessiveDeferral = RD(aDeferred);
 842	mac_stats->MulticastFramesReceivedOK = RD(ifInMulticastPkts);
 843	mac_stats->BroadcastFramesReceivedOK = RD(ifInBroadcastPkts);
 844#undef RD
 845}
 846
 847static const struct ethtool_rmon_hist_range a5psw_rmon_ranges[] = {
 848	{ 0, 64 },
 849	{ 65, 127 },
 850	{ 128, 255 },
 851	{ 256, 511 },
 852	{ 512, 1023 },
 853	{ 1024, 1518 },
 854	{ 1519, A5PSW_MAX_MTU },
 855	{}
 856};
 857
 858static void a5psw_get_rmon_stats(struct dsa_switch *ds, int port,
 859				 struct ethtool_rmon_stats *rmon_stats,
 860				 const struct ethtool_rmon_hist_range **ranges)
 861{
 862	struct a5psw *a5psw = ds->priv;
 863
 864#define RD(name) a5psw_read_stat(a5psw, A5PSW_##name, port)
 865	rmon_stats->undersize_pkts = RD(etherStatsUndersizePkts);
 866	rmon_stats->oversize_pkts = RD(etherStatsOversizePkts);
 867	rmon_stats->fragments = RD(etherStatsFragments);
 868	rmon_stats->jabbers = RD(etherStatsJabbers);
 869	rmon_stats->hist[0] = RD(etherStatsPkts64Octets);
 870	rmon_stats->hist[1] = RD(etherStatsPkts65to127Octets);
 871	rmon_stats->hist[2] = RD(etherStatsPkts128to255Octets);
 872	rmon_stats->hist[3] = RD(etherStatsPkts256to511Octets);
 873	rmon_stats->hist[4] = RD(etherStatsPkts512to1023Octets);
 874	rmon_stats->hist[5] = RD(etherStatsPkts1024to1518Octets);
 875	rmon_stats->hist[6] = RD(etherStatsPkts1519toXOctets);
 876#undef RD
 877
 878	*ranges = a5psw_rmon_ranges;
 879}
 880
 881static void a5psw_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
 882				     struct ethtool_eth_ctrl_stats *ctrl_stats)
 883{
 884	struct a5psw *a5psw = ds->priv;
 885	u64 stat;
 886
 887	stat = a5psw_read_stat(a5psw, A5PSW_aTxPAUSEMACCtrlFrames, port);
 888	ctrl_stats->MACControlFramesTransmitted = stat;
 889	stat = a5psw_read_stat(a5psw, A5PSW_aRxPAUSEMACCtrlFrames, port);
 890	ctrl_stats->MACControlFramesReceived = stat;
 891}
 892
 893static void a5psw_vlan_setup(struct a5psw *a5psw, int port)
 894{
 895	u32 reg;
 896
 897	/* Enable TAG always mode for the port, this is actually controlled
 898	 * by VLAN_IN_MODE_ENA field which will be used for PVID insertion
 899	 */
 900	reg = A5PSW_VLAN_IN_MODE_TAG_ALWAYS;
 901	reg <<= A5PSW_VLAN_IN_MODE_PORT_SHIFT(port);
 902	a5psw_reg_rmw(a5psw, A5PSW_VLAN_IN_MODE, A5PSW_VLAN_IN_MODE_PORT(port),
 903		      reg);
 904
 905	/* Set transparent mode for output frame manipulation, this will depend
 906	 * on the VLAN_RES configuration mode
 907	 */
 908	reg = A5PSW_VLAN_OUT_MODE_TRANSPARENT;
 909	reg <<= A5PSW_VLAN_OUT_MODE_PORT_SHIFT(port);
 910	a5psw_reg_rmw(a5psw, A5PSW_VLAN_OUT_MODE,
 911		      A5PSW_VLAN_OUT_MODE_PORT(port), reg);
 912}
 913
 914static int a5psw_setup(struct dsa_switch *ds)
 915{
 916	struct a5psw *a5psw = ds->priv;
 917	int port, vlan, ret;
 918	struct dsa_port *dp;
 919	u32 reg;
 920
 921	/* Validate that there is only 1 CPU port with index A5PSW_CPU_PORT */
 922	dsa_switch_for_each_cpu_port(dp, ds) {
 923		if (dp->index != A5PSW_CPU_PORT) {
 924			dev_err(a5psw->dev, "Invalid CPU port\n");
 925			return -EINVAL;
 926		}
 927	}
 928
 929	/* Configure management port */
 930	reg = A5PSW_CPU_PORT | A5PSW_MGMT_CFG_ENABLE;
 931	a5psw_reg_writel(a5psw, A5PSW_MGMT_CFG, reg);
 932
 933	/* Set pattern 0 to forward all frame to mgmt port */
 934	a5psw_reg_writel(a5psw, A5PSW_PATTERN_CTRL(A5PSW_PATTERN_MGMTFWD),
 935			 A5PSW_PATTERN_CTRL_MGMTFWD);
 936
 937	/* Enable port tagging */
 938	reg = FIELD_PREP(A5PSW_MGMT_TAG_CFG_TAGFIELD, ETH_P_DSA_A5PSW);
 939	reg |= A5PSW_MGMT_TAG_CFG_ENABLE | A5PSW_MGMT_TAG_CFG_ALL_FRAMES;
 940	a5psw_reg_writel(a5psw, A5PSW_MGMT_TAG_CFG, reg);
 941
 942	/* Enable normal switch operation */
 943	reg = A5PSW_LK_ADDR_CTRL_BLOCKING | A5PSW_LK_ADDR_CTRL_LEARNING |
 944	      A5PSW_LK_ADDR_CTRL_AGEING | A5PSW_LK_ADDR_CTRL_ALLOW_MIGR |
 945	      A5PSW_LK_ADDR_CTRL_CLEAR_TABLE;
 946	a5psw_reg_writel(a5psw, A5PSW_LK_CTRL, reg);
 947
 948	ret = readl_poll_timeout(a5psw->base + A5PSW_LK_CTRL, reg,
 949				 !(reg & A5PSW_LK_ADDR_CTRL_CLEAR_TABLE),
 950				 A5PSW_LK_BUSY_USEC_POLL, A5PSW_CTRL_TIMEOUT);
 951	if (ret) {
 952		dev_err(a5psw->dev, "Failed to clear lookup table\n");
 953		return ret;
 954	}
 955
 956	/* Reset learn count to 0 */
 957	reg = A5PSW_LK_LEARNCOUNT_MODE_SET;
 958	a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
 959
 960	/* Clear VLAN resource table */
 961	reg = A5PSW_VLAN_RES_WR_PORTMASK | A5PSW_VLAN_RES_WR_TAGMASK;
 962	for (vlan = 0; vlan < A5PSW_VLAN_COUNT; vlan++)
 963		a5psw_reg_writel(a5psw, A5PSW_VLAN_RES(vlan), reg);
 964
 965	/* Reset all ports */
 966	dsa_switch_for_each_port(dp, ds) {
 967		port = dp->index;
 968
 969		/* Reset the port */
 970		a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port),
 971				 A5PSW_CMD_CFG_SW_RESET);
 972
 973		/* Enable only CPU port */
 974		a5psw_port_enable_set(a5psw, port, dsa_port_is_cpu(dp));
 975
 976		if (dsa_port_is_unused(dp))
 977			continue;
 978
 979		/* Enable egress flooding and learning for CPU port */
 980		if (dsa_port_is_cpu(dp)) {
 981			a5psw_flooding_set_resolution(a5psw, port, true);
 982			a5psw_port_learning_set(a5psw, port, true);
 983		}
 984
 985		/* Enable standalone mode for user ports */
 986		if (dsa_port_is_user(dp))
 987			a5psw_port_set_standalone(a5psw, port, true);
 988
 989		a5psw_vlan_setup(a5psw, port);
 990	}
 991
 992	return 0;
 993}
 994
 
 
 
 
 
 
 
 995static const struct dsa_switch_ops a5psw_switch_ops = {
 996	.get_tag_protocol = a5psw_get_tag_protocol,
 997	.setup = a5psw_setup,
 998	.port_disable = a5psw_port_disable,
 999	.port_enable = a5psw_port_enable,
1000	.phylink_get_caps = a5psw_phylink_get_caps,
1001	.phylink_mac_select_pcs = a5psw_phylink_mac_select_pcs,
1002	.phylink_mac_link_down = a5psw_phylink_mac_link_down,
1003	.phylink_mac_link_up = a5psw_phylink_mac_link_up,
1004	.port_change_mtu = a5psw_port_change_mtu,
1005	.port_max_mtu = a5psw_port_max_mtu,
1006	.get_sset_count = a5psw_get_sset_count,
1007	.get_strings = a5psw_get_strings,
1008	.get_ethtool_stats = a5psw_get_ethtool_stats,
1009	.get_eth_mac_stats = a5psw_get_eth_mac_stats,
1010	.get_eth_ctrl_stats = a5psw_get_eth_ctrl_stats,
1011	.get_rmon_stats = a5psw_get_rmon_stats,
1012	.set_ageing_time = a5psw_set_ageing_time,
1013	.port_bridge_join = a5psw_port_bridge_join,
1014	.port_bridge_leave = a5psw_port_bridge_leave,
1015	.port_pre_bridge_flags = a5psw_port_pre_bridge_flags,
1016	.port_bridge_flags = a5psw_port_bridge_flags,
1017	.port_stp_state_set = a5psw_port_stp_state_set,
1018	.port_fast_age = a5psw_port_fast_age,
1019	.port_vlan_filtering = a5psw_port_vlan_filtering,
1020	.port_vlan_add = a5psw_port_vlan_add,
1021	.port_vlan_del = a5psw_port_vlan_del,
1022	.port_fdb_add = a5psw_port_fdb_add,
1023	.port_fdb_del = a5psw_port_fdb_del,
1024	.port_fdb_dump = a5psw_port_fdb_dump,
1025};
1026
1027static int a5psw_mdio_wait_busy(struct a5psw *a5psw)
1028{
1029	u32 status;
1030	int err;
1031
1032	err = readl_poll_timeout(a5psw->base + A5PSW_MDIO_CFG_STATUS, status,
1033				 !(status & A5PSW_MDIO_CFG_STATUS_BUSY), 10,
1034				 1000 * USEC_PER_MSEC);
1035	if (err)
1036		dev_err(a5psw->dev, "MDIO command timeout\n");
1037
1038	return err;
1039}
1040
1041static int a5psw_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
1042{
1043	struct a5psw *a5psw = bus->priv;
1044	u32 cmd, status;
1045	int ret;
1046
1047	cmd = A5PSW_MDIO_COMMAND_READ;
1048	cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_REG_ADDR, phy_reg);
1049	cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_PHY_ADDR, phy_id);
1050
1051	a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd);
1052
1053	ret = a5psw_mdio_wait_busy(a5psw);
1054	if (ret)
1055		return ret;
1056
1057	ret = a5psw_reg_readl(a5psw, A5PSW_MDIO_DATA) & A5PSW_MDIO_DATA_MASK;
1058
1059	status = a5psw_reg_readl(a5psw, A5PSW_MDIO_CFG_STATUS);
1060	if (status & A5PSW_MDIO_CFG_STATUS_READERR)
1061		return -EIO;
1062
1063	return ret;
1064}
1065
1066static int a5psw_mdio_write(struct mii_bus *bus, int phy_id, int phy_reg,
1067			    u16 phy_data)
1068{
1069	struct a5psw *a5psw = bus->priv;
1070	u32 cmd;
1071
1072	cmd = FIELD_PREP(A5PSW_MDIO_COMMAND_REG_ADDR, phy_reg);
1073	cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_PHY_ADDR, phy_id);
1074
1075	a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd);
1076	a5psw_reg_writel(a5psw, A5PSW_MDIO_DATA, phy_data);
1077
1078	return a5psw_mdio_wait_busy(a5psw);
1079}
1080
1081static int a5psw_mdio_config(struct a5psw *a5psw, u32 mdio_freq)
1082{
1083	unsigned long rate;
1084	unsigned long div;
1085	u32 cfgstatus;
1086
1087	rate = clk_get_rate(a5psw->hclk);
1088	div = ((rate / mdio_freq) / 2);
1089	if (div > FIELD_MAX(A5PSW_MDIO_CFG_STATUS_CLKDIV) ||
1090	    div < A5PSW_MDIO_CLK_DIV_MIN) {
1091		dev_err(a5psw->dev, "MDIO clock div %ld out of range\n", div);
1092		return -ERANGE;
1093	}
1094
1095	cfgstatus = FIELD_PREP(A5PSW_MDIO_CFG_STATUS_CLKDIV, div);
1096
1097	a5psw_reg_writel(a5psw, A5PSW_MDIO_CFG_STATUS, cfgstatus);
1098
1099	return 0;
1100}
1101
1102static int a5psw_probe_mdio(struct a5psw *a5psw, struct device_node *node)
1103{
1104	struct device *dev = a5psw->dev;
1105	struct mii_bus *bus;
1106	u32 mdio_freq;
1107	int ret;
1108
1109	if (of_property_read_u32(node, "clock-frequency", &mdio_freq))
1110		mdio_freq = A5PSW_MDIO_DEF_FREQ;
1111
1112	ret = a5psw_mdio_config(a5psw, mdio_freq);
1113	if (ret)
1114		return ret;
1115
1116	bus = devm_mdiobus_alloc(dev);
1117	if (!bus)
1118		return -ENOMEM;
1119
1120	bus->name = "a5psw_mdio";
1121	bus->read = a5psw_mdio_read;
1122	bus->write = a5psw_mdio_write;
1123	bus->priv = a5psw;
1124	bus->parent = dev;
1125	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
1126
1127	a5psw->mii_bus = bus;
1128
1129	return devm_of_mdiobus_register(dev, bus, node);
1130}
1131
1132static void a5psw_pcs_free(struct a5psw *a5psw)
1133{
1134	int i;
1135
1136	for (i = 0; i < ARRAY_SIZE(a5psw->pcs); i++) {
1137		if (a5psw->pcs[i])
1138			miic_destroy(a5psw->pcs[i]);
1139	}
1140}
1141
1142static int a5psw_pcs_get(struct a5psw *a5psw)
1143{
1144	struct device_node *ports, *port, *pcs_node;
1145	struct phylink_pcs *pcs;
1146	int ret;
1147	u32 reg;
1148
1149	ports = of_get_child_by_name(a5psw->dev->of_node, "ethernet-ports");
1150	if (!ports)
1151		return -EINVAL;
1152
1153	for_each_available_child_of_node(ports, port) {
1154		pcs_node = of_parse_phandle(port, "pcs-handle", 0);
1155		if (!pcs_node)
1156			continue;
1157
1158		if (of_property_read_u32(port, "reg", &reg)) {
1159			ret = -EINVAL;
1160			goto free_pcs;
1161		}
1162
1163		if (reg >= ARRAY_SIZE(a5psw->pcs)) {
1164			ret = -ENODEV;
1165			goto free_pcs;
1166		}
1167
1168		pcs = miic_create(a5psw->dev, pcs_node);
1169		if (IS_ERR(pcs)) {
1170			dev_err(a5psw->dev, "Failed to create PCS for port %d\n",
1171				reg);
1172			ret = PTR_ERR(pcs);
1173			goto free_pcs;
1174		}
1175
1176		a5psw->pcs[reg] = pcs;
1177		of_node_put(pcs_node);
1178	}
1179	of_node_put(ports);
1180
1181	return 0;
1182
1183free_pcs:
1184	of_node_put(pcs_node);
1185	of_node_put(port);
1186	of_node_put(ports);
1187	a5psw_pcs_free(a5psw);
1188
1189	return ret;
1190}
1191
1192static int a5psw_probe(struct platform_device *pdev)
1193{
1194	struct device *dev = &pdev->dev;
1195	struct device_node *mdio;
1196	struct dsa_switch *ds;
1197	struct a5psw *a5psw;
1198	int ret;
1199
1200	a5psw = devm_kzalloc(dev, sizeof(*a5psw), GFP_KERNEL);
1201	if (!a5psw)
1202		return -ENOMEM;
1203
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);
1210
1211	a5psw->bridged_ports = BIT(A5PSW_CPU_PORT);
1212
1213	ret = a5psw_pcs_get(a5psw);
1214	if (ret)
1215		return ret;
1216
1217	a5psw->hclk = devm_clk_get(dev, "hclk");
1218	if (IS_ERR(a5psw->hclk)) {
1219		dev_err(dev, "failed get hclk clock\n");
1220		ret = PTR_ERR(a5psw->hclk);
1221		goto free_pcs;
1222	}
1223
1224	a5psw->clk = devm_clk_get(dev, "clk");
1225	if (IS_ERR(a5psw->clk)) {
1226		dev_err(dev, "failed get clk_switch clock\n");
1227		ret = PTR_ERR(a5psw->clk);
1228		goto free_pcs;
1229	}
1230
1231	ret = clk_prepare_enable(a5psw->clk);
1232	if (ret)
1233		goto free_pcs;
1234
1235	ret = clk_prepare_enable(a5psw->hclk);
1236	if (ret)
1237		goto clk_disable;
1238
1239	mdio = of_get_child_by_name(dev->of_node, "mdio");
1240	if (of_device_is_available(mdio)) {
1241		ret = a5psw_probe_mdio(a5psw, mdio);
1242		if (ret) {
1243			of_node_put(mdio);
1244			dev_err(dev, "Failed to register MDIO: %d\n", ret);
1245			goto hclk_disable;
1246		}
1247	}
1248
1249	of_node_put(mdio);
1250
1251	ds = &a5psw->ds;
1252	ds->dev = dev;
1253	ds->num_ports = A5PSW_PORTS_NUM;
1254	ds->ops = &a5psw_switch_ops;
 
1255	ds->priv = a5psw;
1256
1257	ret = dsa_register_switch(ds);
1258	if (ret) {
1259		dev_err(dev, "Failed to register DSA switch: %d\n", ret);
1260		goto hclk_disable;
1261	}
1262
1263	return 0;
1264
1265hclk_disable:
1266	clk_disable_unprepare(a5psw->hclk);
1267clk_disable:
1268	clk_disable_unprepare(a5psw->clk);
1269free_pcs:
1270	a5psw_pcs_free(a5psw);
1271
1272	return ret;
1273}
1274
1275static void a5psw_remove(struct platform_device *pdev)
1276{
1277	struct a5psw *a5psw = platform_get_drvdata(pdev);
1278
1279	if (!a5psw)
1280		return;
1281
1282	dsa_unregister_switch(&a5psw->ds);
1283	a5psw_pcs_free(a5psw);
1284	clk_disable_unprepare(a5psw->hclk);
1285	clk_disable_unprepare(a5psw->clk);
1286}
1287
1288static void a5psw_shutdown(struct platform_device *pdev)
1289{
1290	struct a5psw *a5psw = platform_get_drvdata(pdev);
1291
1292	if (!a5psw)
1293		return;
1294
1295	dsa_switch_shutdown(&a5psw->ds);
1296
1297	platform_set_drvdata(pdev, NULL);
1298}
1299
1300static const struct of_device_id a5psw_of_mtable[] = {
1301	{ .compatible = "renesas,rzn1-a5psw", },
1302	{ /* sentinel */ },
1303};
1304MODULE_DEVICE_TABLE(of, a5psw_of_mtable);
1305
1306static struct platform_driver a5psw_driver = {
1307	.driver = {
1308		.name	 = "rzn1_a5psw",
1309		.of_match_table = a5psw_of_mtable,
1310	},
1311	.probe = a5psw_probe,
1312	.remove_new = a5psw_remove,
1313	.shutdown = a5psw_shutdown,
1314};
1315module_platform_driver(a5psw_driver);
1316
1317MODULE_LICENSE("GPL");
1318MODULE_DESCRIPTION("Renesas RZ/N1 Advanced 5-port Switch driver");
1319MODULE_AUTHOR("Clément Léger <clement.leger@bootlin.com>");
v6.13.7
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2022 Schneider-Electric
   4 *
   5 * Clément Léger <clement.leger@bootlin.com>
   6 */
   7
   8#include <linux/clk.h>
   9#include <linux/etherdevice.h>
  10#include <linux/if_bridge.h>
  11#include <linux/if_ether.h>
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/of.h>
  15#include <linux/of_mdio.h>
  16#include <net/dsa.h>
  17
  18#include "rzn1_a5psw.h"
  19
  20struct a5psw_stats {
  21	u16 offset;
  22	const char name[ETH_GSTRING_LEN];
  23};
  24
  25#define STAT_DESC(_offset) {	\
  26	.offset = A5PSW_##_offset,	\
  27	.name = __stringify(_offset),	\
  28}
  29
  30static const struct a5psw_stats a5psw_stats[] = {
  31	STAT_DESC(aFramesTransmittedOK),
  32	STAT_DESC(aFramesReceivedOK),
  33	STAT_DESC(aFrameCheckSequenceErrors),
  34	STAT_DESC(aAlignmentErrors),
  35	STAT_DESC(aOctetsTransmittedOK),
  36	STAT_DESC(aOctetsReceivedOK),
  37	STAT_DESC(aTxPAUSEMACCtrlFrames),
  38	STAT_DESC(aRxPAUSEMACCtrlFrames),
  39	STAT_DESC(ifInErrors),
  40	STAT_DESC(ifOutErrors),
  41	STAT_DESC(ifInUcastPkts),
  42	STAT_DESC(ifInMulticastPkts),
  43	STAT_DESC(ifInBroadcastPkts),
  44	STAT_DESC(ifOutDiscards),
  45	STAT_DESC(ifOutUcastPkts),
  46	STAT_DESC(ifOutMulticastPkts),
  47	STAT_DESC(ifOutBroadcastPkts),
  48	STAT_DESC(etherStatsDropEvents),
  49	STAT_DESC(etherStatsOctets),
  50	STAT_DESC(etherStatsPkts),
  51	STAT_DESC(etherStatsUndersizePkts),
  52	STAT_DESC(etherStatsOversizePkts),
  53	STAT_DESC(etherStatsPkts64Octets),
  54	STAT_DESC(etherStatsPkts65to127Octets),
  55	STAT_DESC(etherStatsPkts128to255Octets),
  56	STAT_DESC(etherStatsPkts256to511Octets),
  57	STAT_DESC(etherStatsPkts1024to1518Octets),
  58	STAT_DESC(etherStatsPkts1519toXOctets),
  59	STAT_DESC(etherStatsJabbers),
  60	STAT_DESC(etherStatsFragments),
  61	STAT_DESC(VLANReceived),
  62	STAT_DESC(VLANTransmitted),
  63	STAT_DESC(aDeferred),
  64	STAT_DESC(aMultipleCollisions),
  65	STAT_DESC(aSingleCollisions),
  66	STAT_DESC(aLateCollisions),
  67	STAT_DESC(aExcessiveCollisions),
  68	STAT_DESC(aCarrierSenseErrors),
  69};
  70
  71static void a5psw_reg_writel(struct a5psw *a5psw, int offset, u32 value)
  72{
  73	writel(value, a5psw->base + offset);
  74}
  75
  76static u32 a5psw_reg_readl(struct a5psw *a5psw, int offset)
  77{
  78	return readl(a5psw->base + offset);
  79}
  80
  81static void a5psw_reg_rmw(struct a5psw *a5psw, int offset, u32 mask, u32 val)
  82{
  83	u32 reg;
  84
  85	spin_lock(&a5psw->reg_lock);
  86
  87	reg = a5psw_reg_readl(a5psw, offset);
  88	reg &= ~mask;
  89	reg |= val;
  90	a5psw_reg_writel(a5psw, offset, reg);
  91
  92	spin_unlock(&a5psw->reg_lock);
  93}
  94
  95static enum dsa_tag_protocol a5psw_get_tag_protocol(struct dsa_switch *ds,
  96						    int port,
  97						    enum dsa_tag_protocol mp)
  98{
  99	return DSA_TAG_PROTO_RZN1_A5PSW;
 100}
 101
 102static void a5psw_port_pattern_set(struct a5psw *a5psw, int port, int pattern,
 103				   bool enable)
 104{
 105	u32 rx_match = 0;
 106
 107	if (enable)
 108		rx_match |= A5PSW_RXMATCH_CONFIG_PATTERN(pattern);
 109
 110	a5psw_reg_rmw(a5psw, A5PSW_RXMATCH_CONFIG(port),
 111		      A5PSW_RXMATCH_CONFIG_PATTERN(pattern), rx_match);
 112}
 113
 114static void a5psw_port_mgmtfwd_set(struct a5psw *a5psw, int port, bool enable)
 115{
 116	/* Enable "management forward" pattern matching, this will forward
 117	 * packets from this port only towards the management port and thus
 118	 * isolate the port.
 119	 */
 120	a5psw_port_pattern_set(a5psw, port, A5PSW_PATTERN_MGMTFWD, enable);
 121}
 122
 123static void a5psw_port_tx_enable(struct a5psw *a5psw, int port, bool enable)
 124{
 125	u32 mask = A5PSW_PORT_ENA_TX(port);
 126	u32 reg = enable ? mask : 0;
 127
 128	/* Even though the port TX is disabled through TXENA bit in the
 129	 * PORT_ENA register, it can still send BPDUs. This depends on the tag
 130	 * configuration added when sending packets from the CPU port to the
 131	 * switch port. Indeed, when using forced forwarding without filtering,
 132	 * even disabled ports will be able to send packets that are tagged.
 133	 * This allows to implement STP support when ports are in a state where
 134	 * forwarding traffic should be stopped but BPDUs should still be sent.
 135	 */
 136	a5psw_reg_rmw(a5psw, A5PSW_PORT_ENA, mask, reg);
 137}
 138
 139static void a5psw_port_enable_set(struct a5psw *a5psw, int port, bool enable)
 140{
 141	u32 port_ena = 0;
 142
 143	if (enable)
 144		port_ena |= A5PSW_PORT_ENA_TX_RX(port);
 145
 146	a5psw_reg_rmw(a5psw, A5PSW_PORT_ENA, A5PSW_PORT_ENA_TX_RX(port),
 147		      port_ena);
 148}
 149
 150static int a5psw_lk_execute_ctrl(struct a5psw *a5psw, u32 *ctrl)
 151{
 152	int ret;
 153
 154	a5psw_reg_writel(a5psw, A5PSW_LK_ADDR_CTRL, *ctrl);
 155
 156	ret = readl_poll_timeout(a5psw->base + A5PSW_LK_ADDR_CTRL, *ctrl,
 157				 !(*ctrl & A5PSW_LK_ADDR_CTRL_BUSY),
 158				 A5PSW_LK_BUSY_USEC_POLL, A5PSW_CTRL_TIMEOUT);
 159	if (ret)
 160		dev_err(a5psw->dev, "LK_CTRL timeout waiting for BUSY bit\n");
 161
 162	return ret;
 163}
 164
 165static void a5psw_port_fdb_flush(struct a5psw *a5psw, int port)
 166{
 167	u32 ctrl = A5PSW_LK_ADDR_CTRL_DELETE_PORT | BIT(port);
 168
 169	mutex_lock(&a5psw->lk_lock);
 170	a5psw_lk_execute_ctrl(a5psw, &ctrl);
 171	mutex_unlock(&a5psw->lk_lock);
 172}
 173
 174static void a5psw_port_authorize_set(struct a5psw *a5psw, int port,
 175				     bool authorize)
 176{
 177	u32 reg = a5psw_reg_readl(a5psw, A5PSW_AUTH_PORT(port));
 178
 179	if (authorize)
 180		reg |= A5PSW_AUTH_PORT_AUTHORIZED;
 181	else
 182		reg &= ~A5PSW_AUTH_PORT_AUTHORIZED;
 183
 184	a5psw_reg_writel(a5psw, A5PSW_AUTH_PORT(port), reg);
 185}
 186
 187static void a5psw_port_disable(struct dsa_switch *ds, int port)
 188{
 189	struct a5psw *a5psw = ds->priv;
 190
 191	a5psw_port_authorize_set(a5psw, port, false);
 192	a5psw_port_enable_set(a5psw, port, false);
 193}
 194
 195static int a5psw_port_enable(struct dsa_switch *ds, int port,
 196			     struct phy_device *phy)
 197{
 198	struct a5psw *a5psw = ds->priv;
 199
 200	a5psw_port_authorize_set(a5psw, port, true);
 201	a5psw_port_enable_set(a5psw, port, true);
 202
 203	return 0;
 204}
 205
 206static int a5psw_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
 207{
 208	struct a5psw *a5psw = ds->priv;
 209
 210	new_mtu += ETH_HLEN + A5PSW_EXTRA_MTU_LEN + ETH_FCS_LEN;
 211	a5psw_reg_writel(a5psw, A5PSW_FRM_LENGTH(port), new_mtu);
 212
 213	return 0;
 214}
 215
 216static int a5psw_port_max_mtu(struct dsa_switch *ds, int port)
 217{
 218	return A5PSW_MAX_MTU;
 219}
 220
 221static void a5psw_phylink_get_caps(struct dsa_switch *ds, int port,
 222				   struct phylink_config *config)
 223{
 224	unsigned long *intf = config->supported_interfaces;
 225
 226	config->mac_capabilities = MAC_1000FD;
 227
 228	if (dsa_is_cpu_port(ds, port)) {
 229		/* GMII is used internally and GMAC2 is connected to the switch
 230		 * using 1000Mbps Full-Duplex mode only (cf ethernet manual)
 231		 */
 232		__set_bit(PHY_INTERFACE_MODE_GMII, intf);
 233	} else {
 234		config->mac_capabilities |= MAC_100 | MAC_10;
 235		phy_interface_set_rgmii(intf);
 236		__set_bit(PHY_INTERFACE_MODE_RMII, intf);
 237		__set_bit(PHY_INTERFACE_MODE_MII, intf);
 238	}
 239}
 240
 241static struct phylink_pcs *
 242a5psw_phylink_mac_select_pcs(struct phylink_config *config,
 243			     phy_interface_t interface)
 244{
 245	struct dsa_port *dp = dsa_phylink_to_port(config);
 246	struct a5psw *a5psw = dp->ds->priv;
 247
 248	if (dsa_port_is_cpu(dp))
 249		return NULL;
 250
 251	return a5psw->pcs[dp->index];
 252}
 253
 254static void a5psw_phylink_mac_config(struct phylink_config *config,
 255				     unsigned int mode,
 256				     const struct phylink_link_state *state)
 257{
 258}
 259
 260static void a5psw_phylink_mac_link_down(struct phylink_config *config,
 261					unsigned int mode,
 262					phy_interface_t interface)
 263{
 264	struct dsa_port *dp = dsa_phylink_to_port(config);
 265	struct a5psw *a5psw = dp->ds->priv;
 266	int port = dp->index;
 267	u32 cmd_cfg;
 268
 269	cmd_cfg = a5psw_reg_readl(a5psw, A5PSW_CMD_CFG(port));
 270	cmd_cfg &= ~(A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA);
 271	a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), cmd_cfg);
 272}
 273
 274static void a5psw_phylink_mac_link_up(struct phylink_config *config,
 275				      struct phy_device *phydev,
 276				      unsigned int mode,
 277				      phy_interface_t interface,
 278				      int speed, int duplex, bool tx_pause,
 279				      bool rx_pause)
 280{
 281	u32 cmd_cfg = A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA |
 282		      A5PSW_CMD_CFG_TX_CRC_APPEND;
 283	struct dsa_port *dp = dsa_phylink_to_port(config);
 284	struct a5psw *a5psw = dp->ds->priv;
 285
 286	if (speed == SPEED_1000)
 287		cmd_cfg |= A5PSW_CMD_CFG_ETH_SPEED;
 288
 289	if (duplex == DUPLEX_HALF)
 290		cmd_cfg |= A5PSW_CMD_CFG_HD_ENA;
 291
 292	cmd_cfg |= A5PSW_CMD_CFG_CNTL_FRM_ENA;
 293
 294	if (!rx_pause)
 295		cmd_cfg &= ~A5PSW_CMD_CFG_PAUSE_IGNORE;
 296
 297	a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(dp->index), cmd_cfg);
 298}
 299
 300static int a5psw_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
 301{
 302	struct a5psw *a5psw = ds->priv;
 303	unsigned long rate;
 304	u64 max, tmp;
 305	u32 agetime;
 306
 307	rate = clk_get_rate(a5psw->clk);
 308	max = div64_ul(((u64)A5PSW_LK_AGETIME_MASK * A5PSW_TABLE_ENTRIES * 1024),
 309		       rate) * 1000;
 310	if (msecs > max)
 311		return -EINVAL;
 312
 313	tmp = div_u64(rate, MSEC_PER_SEC);
 314	agetime = div_u64(msecs * tmp, 1024 * A5PSW_TABLE_ENTRIES);
 315
 316	a5psw_reg_writel(a5psw, A5PSW_LK_AGETIME, agetime);
 317
 318	return 0;
 319}
 320
 321static void a5psw_port_learning_set(struct a5psw *a5psw, int port, bool learn)
 322{
 323	u32 mask = A5PSW_INPUT_LEARN_DIS(port);
 324	u32 reg = !learn ? mask : 0;
 325
 326	a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN, mask, reg);
 327}
 328
 329static void a5psw_port_rx_block_set(struct a5psw *a5psw, int port, bool block)
 330{
 331	u32 mask = A5PSW_INPUT_LEARN_BLOCK(port);
 332	u32 reg = block ? mask : 0;
 333
 334	a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN, mask, reg);
 335}
 336
 337static void a5psw_flooding_set_resolution(struct a5psw *a5psw, int port,
 338					  bool set)
 339{
 340	u8 offsets[] = {A5PSW_UCAST_DEF_MASK, A5PSW_BCAST_DEF_MASK,
 341			A5PSW_MCAST_DEF_MASK};
 342	int i;
 343
 344	for (i = 0; i < ARRAY_SIZE(offsets); i++)
 345		a5psw_reg_rmw(a5psw, offsets[i], BIT(port),
 346			      set ? BIT(port) : 0);
 347}
 348
 349static void a5psw_port_set_standalone(struct a5psw *a5psw, int port,
 350				      bool standalone)
 351{
 352	a5psw_port_learning_set(a5psw, port, !standalone);
 353	a5psw_flooding_set_resolution(a5psw, port, !standalone);
 354	a5psw_port_mgmtfwd_set(a5psw, port, standalone);
 355}
 356
 357static int a5psw_port_bridge_join(struct dsa_switch *ds, int port,
 358				  struct dsa_bridge bridge,
 359				  bool *tx_fwd_offload,
 360				  struct netlink_ext_ack *extack)
 361{
 362	struct a5psw *a5psw = ds->priv;
 363
 364	/* We only support 1 bridge device */
 365	if (a5psw->br_dev && bridge.dev != a5psw->br_dev) {
 366		NL_SET_ERR_MSG_MOD(extack,
 367				   "Forwarding offload supported for a single bridge");
 368		return -EOPNOTSUPP;
 369	}
 370
 371	a5psw->br_dev = bridge.dev;
 372	a5psw_port_set_standalone(a5psw, port, false);
 373
 374	a5psw->bridged_ports |= BIT(port);
 375
 376	return 0;
 377}
 378
 379static void a5psw_port_bridge_leave(struct dsa_switch *ds, int port,
 380				    struct dsa_bridge bridge)
 381{
 382	struct a5psw *a5psw = ds->priv;
 383
 384	a5psw->bridged_ports &= ~BIT(port);
 385
 386	a5psw_port_set_standalone(a5psw, port, true);
 387
 388	/* No more ports bridged */
 389	if (a5psw->bridged_ports == BIT(A5PSW_CPU_PORT))
 390		a5psw->br_dev = NULL;
 391}
 392
 393static int a5psw_port_pre_bridge_flags(struct dsa_switch *ds, int port,
 394				       struct switchdev_brport_flags flags,
 395				       struct netlink_ext_ack *extack)
 396{
 397	if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
 398			   BR_BCAST_FLOOD))
 399		return -EINVAL;
 400
 401	return 0;
 402}
 403
 404static int
 405a5psw_port_bridge_flags(struct dsa_switch *ds, int port,
 406			struct switchdev_brport_flags flags,
 407			struct netlink_ext_ack *extack)
 408{
 409	struct a5psw *a5psw = ds->priv;
 410	u32 val;
 411
 412	/* If a port is set as standalone, we do not want to be able to
 413	 * configure flooding nor learning which would result in joining the
 414	 * unique bridge. This can happen when a port leaves the bridge, in
 415	 * which case the DSA core will try to "clear" all flags for the
 416	 * standalone port (ie enable flooding, disable learning). In that case
 417	 * do not fail but do not apply the flags.
 418	 */
 419	if (!(a5psw->bridged_ports & BIT(port)))
 420		return 0;
 421
 422	if (flags.mask & BR_LEARNING) {
 423		val = flags.val & BR_LEARNING ? 0 : A5PSW_INPUT_LEARN_DIS(port);
 424		a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN,
 425			      A5PSW_INPUT_LEARN_DIS(port), val);
 426	}
 427
 428	if (flags.mask & BR_FLOOD) {
 429		val = flags.val & BR_FLOOD ? BIT(port) : 0;
 430		a5psw_reg_rmw(a5psw, A5PSW_UCAST_DEF_MASK, BIT(port), val);
 431	}
 432
 433	if (flags.mask & BR_MCAST_FLOOD) {
 434		val = flags.val & BR_MCAST_FLOOD ? BIT(port) : 0;
 435		a5psw_reg_rmw(a5psw, A5PSW_MCAST_DEF_MASK, BIT(port), val);
 436	}
 437
 438	if (flags.mask & BR_BCAST_FLOOD) {
 439		val = flags.val & BR_BCAST_FLOOD ? BIT(port) : 0;
 440		a5psw_reg_rmw(a5psw, A5PSW_BCAST_DEF_MASK, BIT(port), val);
 441	}
 442
 443	return 0;
 444}
 445
 446static void a5psw_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 447{
 448	bool learning_enabled, rx_enabled, tx_enabled;
 449	struct dsa_port *dp = dsa_to_port(ds, port);
 450	struct a5psw *a5psw = ds->priv;
 451
 452	switch (state) {
 453	case BR_STATE_DISABLED:
 454	case BR_STATE_BLOCKING:
 455	case BR_STATE_LISTENING:
 456		rx_enabled = false;
 457		tx_enabled = false;
 458		learning_enabled = false;
 459		break;
 460	case BR_STATE_LEARNING:
 461		rx_enabled = false;
 462		tx_enabled = false;
 463		learning_enabled = dp->learning;
 464		break;
 465	case BR_STATE_FORWARDING:
 466		rx_enabled = true;
 467		tx_enabled = true;
 468		learning_enabled = dp->learning;
 469		break;
 470	default:
 471		dev_err(ds->dev, "invalid STP state: %d\n", state);
 472		return;
 473	}
 474
 475	a5psw_port_learning_set(a5psw, port, learning_enabled);
 476	a5psw_port_rx_block_set(a5psw, port, !rx_enabled);
 477	a5psw_port_tx_enable(a5psw, port, tx_enabled);
 478}
 479
 480static void a5psw_port_fast_age(struct dsa_switch *ds, int port)
 481{
 482	struct a5psw *a5psw = ds->priv;
 483
 484	a5psw_port_fdb_flush(a5psw, port);
 485}
 486
 487static int a5psw_lk_execute_lookup(struct a5psw *a5psw, union lk_data *lk_data,
 488				   u16 *entry)
 489{
 490	u32 ctrl;
 491	int ret;
 492
 493	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_LO, lk_data->lo);
 494	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data->hi);
 495
 496	ctrl = A5PSW_LK_ADDR_CTRL_LOOKUP;
 497	ret = a5psw_lk_execute_ctrl(a5psw, &ctrl);
 498	if (ret)
 499		return ret;
 500
 501	*entry = ctrl & A5PSW_LK_ADDR_CTRL_ADDRESS;
 502
 503	return 0;
 504}
 505
 506static int a5psw_port_fdb_add(struct dsa_switch *ds, int port,
 507			      const unsigned char *addr, u16 vid,
 508			      struct dsa_db db)
 509{
 510	struct a5psw *a5psw = ds->priv;
 511	union lk_data lk_data = {0};
 512	bool inc_learncount = false;
 513	int ret = 0;
 514	u16 entry;
 515	u32 reg;
 516
 517	ether_addr_copy(lk_data.entry.mac, addr);
 518	lk_data.entry.port_mask = BIT(port);
 519
 520	mutex_lock(&a5psw->lk_lock);
 521
 522	/* Set the value to be written in the lookup table */
 523	ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
 524	if (ret)
 525		goto lk_unlock;
 526
 527	lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
 528	if (!lk_data.entry.valid) {
 529		inc_learncount = true;
 530		/* port_mask set to 0x1f when entry is not valid, clear it */
 531		lk_data.entry.port_mask = 0;
 532		lk_data.entry.prio = 0;
 533	}
 534
 535	lk_data.entry.port_mask |= BIT(port);
 536	lk_data.entry.is_static = 1;
 537	lk_data.entry.valid = 1;
 538
 539	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
 540
 541	reg = A5PSW_LK_ADDR_CTRL_WRITE | entry;
 542	ret = a5psw_lk_execute_ctrl(a5psw, &reg);
 543	if (ret)
 544		goto lk_unlock;
 545
 546	if (inc_learncount) {
 547		reg = A5PSW_LK_LEARNCOUNT_MODE_INC;
 548		a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
 549	}
 550
 551lk_unlock:
 552	mutex_unlock(&a5psw->lk_lock);
 553
 554	return ret;
 555}
 556
 557static int a5psw_port_fdb_del(struct dsa_switch *ds, int port,
 558			      const unsigned char *addr, u16 vid,
 559			      struct dsa_db db)
 560{
 561	struct a5psw *a5psw = ds->priv;
 562	union lk_data lk_data = {0};
 563	bool clear = false;
 564	u16 entry;
 565	u32 reg;
 566	int ret;
 567
 568	ether_addr_copy(lk_data.entry.mac, addr);
 569
 570	mutex_lock(&a5psw->lk_lock);
 571
 572	ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
 573	if (ret)
 574		goto lk_unlock;
 575
 576	lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
 577
 578	/* Our hardware does not associate any VID to the FDB entries so this
 579	 * means that if two entries were added for the same mac but for
 580	 * different VID, then, on the deletion of the first one, we would also
 581	 * delete the second one. Since there is unfortunately nothing we can do
 582	 * about that, do not return an error...
 583	 */
 584	if (!lk_data.entry.valid)
 585		goto lk_unlock;
 586
 587	lk_data.entry.port_mask &= ~BIT(port);
 588	/* If there is no more port in the mask, clear the entry */
 589	if (lk_data.entry.port_mask == 0)
 590		clear = true;
 591
 592	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
 593
 594	reg = entry;
 595	if (clear)
 596		reg |= A5PSW_LK_ADDR_CTRL_CLEAR;
 597	else
 598		reg |= A5PSW_LK_ADDR_CTRL_WRITE;
 599
 600	ret = a5psw_lk_execute_ctrl(a5psw, &reg);
 601	if (ret)
 602		goto lk_unlock;
 603
 604	/* Decrement LEARNCOUNT */
 605	if (clear) {
 606		reg = A5PSW_LK_LEARNCOUNT_MODE_DEC;
 607		a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
 608	}
 609
 610lk_unlock:
 611	mutex_unlock(&a5psw->lk_lock);
 612
 613	return ret;
 614}
 615
 616static int a5psw_port_fdb_dump(struct dsa_switch *ds, int port,
 617			       dsa_fdb_dump_cb_t *cb, void *data)
 618{
 619	struct a5psw *a5psw = ds->priv;
 620	union lk_data lk_data;
 621	int i = 0, ret = 0;
 622	u32 reg;
 623
 624	mutex_lock(&a5psw->lk_lock);
 625
 626	for (i = 0; i < A5PSW_TABLE_ENTRIES; i++) {
 627		reg = A5PSW_LK_ADDR_CTRL_READ | A5PSW_LK_ADDR_CTRL_WAIT | i;
 628
 629		ret = a5psw_lk_execute_ctrl(a5psw, &reg);
 630		if (ret)
 631			goto out_unlock;
 632
 633		lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
 634		/* If entry is not valid or does not contain the port, skip */
 635		if (!lk_data.entry.valid ||
 636		    !(lk_data.entry.port_mask & BIT(port)))
 637			continue;
 638
 639		lk_data.lo = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_LO);
 640
 641		ret = cb(lk_data.entry.mac, 0, lk_data.entry.is_static, data);
 642		if (ret)
 643			goto out_unlock;
 644	}
 645
 646out_unlock:
 647	mutex_unlock(&a5psw->lk_lock);
 648
 649	return ret;
 650}
 651
 652static int a5psw_port_vlan_filtering(struct dsa_switch *ds, int port,
 653				     bool vlan_filtering,
 654				     struct netlink_ext_ack *extack)
 655{
 656	u32 mask = BIT(port + A5PSW_VLAN_VERI_SHIFT) |
 657		   BIT(port + A5PSW_VLAN_DISC_SHIFT);
 658	u32 val = vlan_filtering ? mask : 0;
 659	struct a5psw *a5psw = ds->priv;
 660
 661	/* Disable/enable vlan tagging */
 662	a5psw_reg_rmw(a5psw, A5PSW_VLAN_IN_MODE_ENA, BIT(port),
 663		      vlan_filtering ? BIT(port) : 0);
 664
 665	/* Disable/enable vlan input filtering */
 666	a5psw_reg_rmw(a5psw, A5PSW_VLAN_VERIFY, mask, val);
 667
 668	return 0;
 669}
 670
 671static int a5psw_find_vlan_entry(struct a5psw *a5psw, u16 vid)
 672{
 673	u32 vlan_res;
 674	int i;
 675
 676	/* Find vlan for this port */
 677	for (i = 0; i < A5PSW_VLAN_COUNT; i++) {
 678		vlan_res = a5psw_reg_readl(a5psw, A5PSW_VLAN_RES(i));
 679		if (FIELD_GET(A5PSW_VLAN_RES_VLANID, vlan_res) == vid)
 680			return i;
 681	}
 682
 683	return -1;
 684}
 685
 686static int a5psw_new_vlan_res_entry(struct a5psw *a5psw, u16 newvid)
 687{
 688	u32 vlan_res;
 689	int i;
 690
 691	/* Find a free VLAN entry */
 692	for (i = 0; i < A5PSW_VLAN_COUNT; i++) {
 693		vlan_res = a5psw_reg_readl(a5psw, A5PSW_VLAN_RES(i));
 694		if (!(FIELD_GET(A5PSW_VLAN_RES_PORTMASK, vlan_res))) {
 695			vlan_res = FIELD_PREP(A5PSW_VLAN_RES_VLANID, newvid);
 696			a5psw_reg_writel(a5psw, A5PSW_VLAN_RES(i), vlan_res);
 697			return i;
 698		}
 699	}
 700
 701	return -1;
 702}
 703
 704static void a5psw_port_vlan_tagged_cfg(struct a5psw *a5psw,
 705				       unsigned int vlan_res_id, int port,
 706				       bool set)
 707{
 708	u32 mask = A5PSW_VLAN_RES_WR_PORTMASK | A5PSW_VLAN_RES_RD_TAGMASK |
 709		   BIT(port);
 710	u32 vlan_res_off = A5PSW_VLAN_RES(vlan_res_id);
 711	u32 val = A5PSW_VLAN_RES_WR_TAGMASK, reg;
 712
 713	if (set)
 714		val |= BIT(port);
 715
 716	/* Toggle tag mask read */
 717	a5psw_reg_writel(a5psw, vlan_res_off, A5PSW_VLAN_RES_RD_TAGMASK);
 718	reg = a5psw_reg_readl(a5psw, vlan_res_off);
 719	a5psw_reg_writel(a5psw, vlan_res_off, A5PSW_VLAN_RES_RD_TAGMASK);
 720
 721	reg &= ~mask;
 722	reg |= val;
 723	a5psw_reg_writel(a5psw, vlan_res_off, reg);
 724}
 725
 726static void a5psw_port_vlan_cfg(struct a5psw *a5psw, unsigned int vlan_res_id,
 727				int port, bool set)
 728{
 729	u32 mask = A5PSW_VLAN_RES_WR_TAGMASK | BIT(port);
 730	u32 reg = A5PSW_VLAN_RES_WR_PORTMASK;
 731
 732	if (set)
 733		reg |= BIT(port);
 734
 735	a5psw_reg_rmw(a5psw, A5PSW_VLAN_RES(vlan_res_id), mask, reg);
 736}
 737
 738static int a5psw_port_vlan_add(struct dsa_switch *ds, int port,
 739			       const struct switchdev_obj_port_vlan *vlan,
 740			       struct netlink_ext_ack *extack)
 741{
 742	bool tagged = !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED);
 743	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
 744	struct a5psw *a5psw = ds->priv;
 745	u16 vid = vlan->vid;
 746	int vlan_res_id;
 747
 748	vlan_res_id = a5psw_find_vlan_entry(a5psw, vid);
 749	if (vlan_res_id < 0) {
 750		vlan_res_id = a5psw_new_vlan_res_entry(a5psw, vid);
 751		if (vlan_res_id < 0)
 752			return -ENOSPC;
 753	}
 754
 755	a5psw_port_vlan_cfg(a5psw, vlan_res_id, port, true);
 756	if (tagged)
 757		a5psw_port_vlan_tagged_cfg(a5psw, vlan_res_id, port, true);
 758
 759	/* Configure port to tag with corresponding VID, but do not enable it
 760	 * yet: wait for vlan filtering to be enabled to enable vlan port
 761	 * tagging
 762	 */
 763	if (pvid)
 764		a5psw_reg_writel(a5psw, A5PSW_SYSTEM_TAGINFO(port), vid);
 765
 766	return 0;
 767}
 768
 769static int a5psw_port_vlan_del(struct dsa_switch *ds, int port,
 770			       const struct switchdev_obj_port_vlan *vlan)
 771{
 772	struct a5psw *a5psw = ds->priv;
 773	u16 vid = vlan->vid;
 774	int vlan_res_id;
 775
 776	vlan_res_id = a5psw_find_vlan_entry(a5psw, vid);
 777	if (vlan_res_id < 0)
 778		return -EINVAL;
 779
 780	a5psw_port_vlan_cfg(a5psw, vlan_res_id, port, false);
 781	a5psw_port_vlan_tagged_cfg(a5psw, vlan_res_id, port, false);
 782
 783	return 0;
 784}
 785
 786static u64 a5psw_read_stat(struct a5psw *a5psw, u32 offset, int port)
 787{
 788	u32 reg_lo, reg_hi;
 789
 790	reg_lo = a5psw_reg_readl(a5psw, offset + A5PSW_PORT_OFFSET(port));
 791	/* A5PSW_STATS_HIWORD is latched on stat read */
 792	reg_hi = a5psw_reg_readl(a5psw, A5PSW_STATS_HIWORD);
 793
 794	return ((u64)reg_hi << 32) | reg_lo;
 795}
 796
 797static void a5psw_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 798			      uint8_t *data)
 799{
 800	unsigned int u;
 801
 802	if (stringset != ETH_SS_STATS)
 803		return;
 804
 805	for (u = 0; u < ARRAY_SIZE(a5psw_stats); u++)
 806		ethtool_puts(&data, a5psw_stats[u].name);
 
 
 807}
 808
 809static void a5psw_get_ethtool_stats(struct dsa_switch *ds, int port,
 810				    uint64_t *data)
 811{
 812	struct a5psw *a5psw = ds->priv;
 813	unsigned int u;
 814
 815	for (u = 0; u < ARRAY_SIZE(a5psw_stats); u++)
 816		data[u] = a5psw_read_stat(a5psw, a5psw_stats[u].offset, port);
 817}
 818
 819static int a5psw_get_sset_count(struct dsa_switch *ds, int port, int sset)
 820{
 821	if (sset != ETH_SS_STATS)
 822		return 0;
 823
 824	return ARRAY_SIZE(a5psw_stats);
 825}
 826
 827static void a5psw_get_eth_mac_stats(struct dsa_switch *ds, int port,
 828				    struct ethtool_eth_mac_stats *mac_stats)
 829{
 830	struct a5psw *a5psw = ds->priv;
 831
 832#define RD(name) a5psw_read_stat(a5psw, A5PSW_##name, port)
 833	mac_stats->FramesTransmittedOK = RD(aFramesTransmittedOK);
 834	mac_stats->SingleCollisionFrames = RD(aSingleCollisions);
 835	mac_stats->MultipleCollisionFrames = RD(aMultipleCollisions);
 836	mac_stats->FramesReceivedOK = RD(aFramesReceivedOK);
 837	mac_stats->FrameCheckSequenceErrors = RD(aFrameCheckSequenceErrors);
 838	mac_stats->AlignmentErrors = RD(aAlignmentErrors);
 839	mac_stats->OctetsTransmittedOK = RD(aOctetsTransmittedOK);
 840	mac_stats->FramesWithDeferredXmissions = RD(aDeferred);
 841	mac_stats->LateCollisions = RD(aLateCollisions);
 842	mac_stats->FramesAbortedDueToXSColls = RD(aExcessiveCollisions);
 843	mac_stats->FramesLostDueToIntMACXmitError = RD(ifOutErrors);
 844	mac_stats->CarrierSenseErrors = RD(aCarrierSenseErrors);
 845	mac_stats->OctetsReceivedOK = RD(aOctetsReceivedOK);
 846	mac_stats->FramesLostDueToIntMACRcvError = RD(ifInErrors);
 847	mac_stats->MulticastFramesXmittedOK = RD(ifOutMulticastPkts);
 848	mac_stats->BroadcastFramesXmittedOK = RD(ifOutBroadcastPkts);
 849	mac_stats->FramesWithExcessiveDeferral = RD(aDeferred);
 850	mac_stats->MulticastFramesReceivedOK = RD(ifInMulticastPkts);
 851	mac_stats->BroadcastFramesReceivedOK = RD(ifInBroadcastPkts);
 852#undef RD
 853}
 854
 855static const struct ethtool_rmon_hist_range a5psw_rmon_ranges[] = {
 856	{ 0, 64 },
 857	{ 65, 127 },
 858	{ 128, 255 },
 859	{ 256, 511 },
 860	{ 512, 1023 },
 861	{ 1024, 1518 },
 862	{ 1519, A5PSW_MAX_MTU },
 863	{}
 864};
 865
 866static void a5psw_get_rmon_stats(struct dsa_switch *ds, int port,
 867				 struct ethtool_rmon_stats *rmon_stats,
 868				 const struct ethtool_rmon_hist_range **ranges)
 869{
 870	struct a5psw *a5psw = ds->priv;
 871
 872#define RD(name) a5psw_read_stat(a5psw, A5PSW_##name, port)
 873	rmon_stats->undersize_pkts = RD(etherStatsUndersizePkts);
 874	rmon_stats->oversize_pkts = RD(etherStatsOversizePkts);
 875	rmon_stats->fragments = RD(etherStatsFragments);
 876	rmon_stats->jabbers = RD(etherStatsJabbers);
 877	rmon_stats->hist[0] = RD(etherStatsPkts64Octets);
 878	rmon_stats->hist[1] = RD(etherStatsPkts65to127Octets);
 879	rmon_stats->hist[2] = RD(etherStatsPkts128to255Octets);
 880	rmon_stats->hist[3] = RD(etherStatsPkts256to511Octets);
 881	rmon_stats->hist[4] = RD(etherStatsPkts512to1023Octets);
 882	rmon_stats->hist[5] = RD(etherStatsPkts1024to1518Octets);
 883	rmon_stats->hist[6] = RD(etherStatsPkts1519toXOctets);
 884#undef RD
 885
 886	*ranges = a5psw_rmon_ranges;
 887}
 888
 889static void a5psw_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
 890				     struct ethtool_eth_ctrl_stats *ctrl_stats)
 891{
 892	struct a5psw *a5psw = ds->priv;
 893	u64 stat;
 894
 895	stat = a5psw_read_stat(a5psw, A5PSW_aTxPAUSEMACCtrlFrames, port);
 896	ctrl_stats->MACControlFramesTransmitted = stat;
 897	stat = a5psw_read_stat(a5psw, A5PSW_aRxPAUSEMACCtrlFrames, port);
 898	ctrl_stats->MACControlFramesReceived = stat;
 899}
 900
 901static void a5psw_vlan_setup(struct a5psw *a5psw, int port)
 902{
 903	u32 reg;
 904
 905	/* Enable TAG always mode for the port, this is actually controlled
 906	 * by VLAN_IN_MODE_ENA field which will be used for PVID insertion
 907	 */
 908	reg = A5PSW_VLAN_IN_MODE_TAG_ALWAYS;
 909	reg <<= A5PSW_VLAN_IN_MODE_PORT_SHIFT(port);
 910	a5psw_reg_rmw(a5psw, A5PSW_VLAN_IN_MODE, A5PSW_VLAN_IN_MODE_PORT(port),
 911		      reg);
 912
 913	/* Set transparent mode for output frame manipulation, this will depend
 914	 * on the VLAN_RES configuration mode
 915	 */
 916	reg = A5PSW_VLAN_OUT_MODE_TRANSPARENT;
 917	reg <<= A5PSW_VLAN_OUT_MODE_PORT_SHIFT(port);
 918	a5psw_reg_rmw(a5psw, A5PSW_VLAN_OUT_MODE,
 919		      A5PSW_VLAN_OUT_MODE_PORT(port), reg);
 920}
 921
 922static int a5psw_setup(struct dsa_switch *ds)
 923{
 924	struct a5psw *a5psw = ds->priv;
 925	int port, vlan, ret;
 926	struct dsa_port *dp;
 927	u32 reg;
 928
 929	/* Validate that there is only 1 CPU port with index A5PSW_CPU_PORT */
 930	dsa_switch_for_each_cpu_port(dp, ds) {
 931		if (dp->index != A5PSW_CPU_PORT) {
 932			dev_err(a5psw->dev, "Invalid CPU port\n");
 933			return -EINVAL;
 934		}
 935	}
 936
 937	/* Configure management port */
 938	reg = A5PSW_CPU_PORT | A5PSW_MGMT_CFG_ENABLE;
 939	a5psw_reg_writel(a5psw, A5PSW_MGMT_CFG, reg);
 940
 941	/* Set pattern 0 to forward all frame to mgmt port */
 942	a5psw_reg_writel(a5psw, A5PSW_PATTERN_CTRL(A5PSW_PATTERN_MGMTFWD),
 943			 A5PSW_PATTERN_CTRL_MGMTFWD);
 944
 945	/* Enable port tagging */
 946	reg = FIELD_PREP(A5PSW_MGMT_TAG_CFG_TAGFIELD, ETH_P_DSA_A5PSW);
 947	reg |= A5PSW_MGMT_TAG_CFG_ENABLE | A5PSW_MGMT_TAG_CFG_ALL_FRAMES;
 948	a5psw_reg_writel(a5psw, A5PSW_MGMT_TAG_CFG, reg);
 949
 950	/* Enable normal switch operation */
 951	reg = A5PSW_LK_ADDR_CTRL_BLOCKING | A5PSW_LK_ADDR_CTRL_LEARNING |
 952	      A5PSW_LK_ADDR_CTRL_AGEING | A5PSW_LK_ADDR_CTRL_ALLOW_MIGR |
 953	      A5PSW_LK_ADDR_CTRL_CLEAR_TABLE;
 954	a5psw_reg_writel(a5psw, A5PSW_LK_CTRL, reg);
 955
 956	ret = readl_poll_timeout(a5psw->base + A5PSW_LK_CTRL, reg,
 957				 !(reg & A5PSW_LK_ADDR_CTRL_CLEAR_TABLE),
 958				 A5PSW_LK_BUSY_USEC_POLL, A5PSW_CTRL_TIMEOUT);
 959	if (ret) {
 960		dev_err(a5psw->dev, "Failed to clear lookup table\n");
 961		return ret;
 962	}
 963
 964	/* Reset learn count to 0 */
 965	reg = A5PSW_LK_LEARNCOUNT_MODE_SET;
 966	a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
 967
 968	/* Clear VLAN resource table */
 969	reg = A5PSW_VLAN_RES_WR_PORTMASK | A5PSW_VLAN_RES_WR_TAGMASK;
 970	for (vlan = 0; vlan < A5PSW_VLAN_COUNT; vlan++)
 971		a5psw_reg_writel(a5psw, A5PSW_VLAN_RES(vlan), reg);
 972
 973	/* Reset all ports */
 974	dsa_switch_for_each_port(dp, ds) {
 975		port = dp->index;
 976
 977		/* Reset the port */
 978		a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port),
 979				 A5PSW_CMD_CFG_SW_RESET);
 980
 981		/* Enable only CPU port */
 982		a5psw_port_enable_set(a5psw, port, dsa_port_is_cpu(dp));
 983
 984		if (dsa_port_is_unused(dp))
 985			continue;
 986
 987		/* Enable egress flooding and learning for CPU port */
 988		if (dsa_port_is_cpu(dp)) {
 989			a5psw_flooding_set_resolution(a5psw, port, true);
 990			a5psw_port_learning_set(a5psw, port, true);
 991		}
 992
 993		/* Enable standalone mode for user ports */
 994		if (dsa_port_is_user(dp))
 995			a5psw_port_set_standalone(a5psw, port, true);
 996
 997		a5psw_vlan_setup(a5psw, port);
 998	}
 999
1000	return 0;
1001}
1002
1003static const struct phylink_mac_ops a5psw_phylink_mac_ops = {
1004	.mac_select_pcs = a5psw_phylink_mac_select_pcs,
1005	.mac_config = a5psw_phylink_mac_config,
1006	.mac_link_down = a5psw_phylink_mac_link_down,
1007	.mac_link_up = a5psw_phylink_mac_link_up,
1008};
1009
1010static const struct dsa_switch_ops a5psw_switch_ops = {
1011	.get_tag_protocol = a5psw_get_tag_protocol,
1012	.setup = a5psw_setup,
1013	.port_disable = a5psw_port_disable,
1014	.port_enable = a5psw_port_enable,
1015	.phylink_get_caps = a5psw_phylink_get_caps,
 
 
 
1016	.port_change_mtu = a5psw_port_change_mtu,
1017	.port_max_mtu = a5psw_port_max_mtu,
1018	.get_sset_count = a5psw_get_sset_count,
1019	.get_strings = a5psw_get_strings,
1020	.get_ethtool_stats = a5psw_get_ethtool_stats,
1021	.get_eth_mac_stats = a5psw_get_eth_mac_stats,
1022	.get_eth_ctrl_stats = a5psw_get_eth_ctrl_stats,
1023	.get_rmon_stats = a5psw_get_rmon_stats,
1024	.set_ageing_time = a5psw_set_ageing_time,
1025	.port_bridge_join = a5psw_port_bridge_join,
1026	.port_bridge_leave = a5psw_port_bridge_leave,
1027	.port_pre_bridge_flags = a5psw_port_pre_bridge_flags,
1028	.port_bridge_flags = a5psw_port_bridge_flags,
1029	.port_stp_state_set = a5psw_port_stp_state_set,
1030	.port_fast_age = a5psw_port_fast_age,
1031	.port_vlan_filtering = a5psw_port_vlan_filtering,
1032	.port_vlan_add = a5psw_port_vlan_add,
1033	.port_vlan_del = a5psw_port_vlan_del,
1034	.port_fdb_add = a5psw_port_fdb_add,
1035	.port_fdb_del = a5psw_port_fdb_del,
1036	.port_fdb_dump = a5psw_port_fdb_dump,
1037};
1038
1039static int a5psw_mdio_wait_busy(struct a5psw *a5psw)
1040{
1041	u32 status;
1042	int err;
1043
1044	err = readl_poll_timeout(a5psw->base + A5PSW_MDIO_CFG_STATUS, status,
1045				 !(status & A5PSW_MDIO_CFG_STATUS_BUSY), 10,
1046				 1000 * USEC_PER_MSEC);
1047	if (err)
1048		dev_err(a5psw->dev, "MDIO command timeout\n");
1049
1050	return err;
1051}
1052
1053static int a5psw_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
1054{
1055	struct a5psw *a5psw = bus->priv;
1056	u32 cmd, status;
1057	int ret;
1058
1059	cmd = A5PSW_MDIO_COMMAND_READ;
1060	cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_REG_ADDR, phy_reg);
1061	cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_PHY_ADDR, phy_id);
1062
1063	a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd);
1064
1065	ret = a5psw_mdio_wait_busy(a5psw);
1066	if (ret)
1067		return ret;
1068
1069	ret = a5psw_reg_readl(a5psw, A5PSW_MDIO_DATA) & A5PSW_MDIO_DATA_MASK;
1070
1071	status = a5psw_reg_readl(a5psw, A5PSW_MDIO_CFG_STATUS);
1072	if (status & A5PSW_MDIO_CFG_STATUS_READERR)
1073		return -EIO;
1074
1075	return ret;
1076}
1077
1078static int a5psw_mdio_write(struct mii_bus *bus, int phy_id, int phy_reg,
1079			    u16 phy_data)
1080{
1081	struct a5psw *a5psw = bus->priv;
1082	u32 cmd;
1083
1084	cmd = FIELD_PREP(A5PSW_MDIO_COMMAND_REG_ADDR, phy_reg);
1085	cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_PHY_ADDR, phy_id);
1086
1087	a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd);
1088	a5psw_reg_writel(a5psw, A5PSW_MDIO_DATA, phy_data);
1089
1090	return a5psw_mdio_wait_busy(a5psw);
1091}
1092
1093static int a5psw_mdio_config(struct a5psw *a5psw, u32 mdio_freq)
1094{
1095	unsigned long rate;
1096	unsigned long div;
1097	u32 cfgstatus;
1098
1099	rate = clk_get_rate(a5psw->hclk);
1100	div = ((rate / mdio_freq) / 2);
1101	if (div > FIELD_MAX(A5PSW_MDIO_CFG_STATUS_CLKDIV) ||
1102	    div < A5PSW_MDIO_CLK_DIV_MIN) {
1103		dev_err(a5psw->dev, "MDIO clock div %ld out of range\n", div);
1104		return -ERANGE;
1105	}
1106
1107	cfgstatus = FIELD_PREP(A5PSW_MDIO_CFG_STATUS_CLKDIV, div);
1108
1109	a5psw_reg_writel(a5psw, A5PSW_MDIO_CFG_STATUS, cfgstatus);
1110
1111	return 0;
1112}
1113
1114static int a5psw_probe_mdio(struct a5psw *a5psw, struct device_node *node)
1115{
1116	struct device *dev = a5psw->dev;
1117	struct mii_bus *bus;
1118	u32 mdio_freq;
1119	int ret;
1120
1121	if (of_property_read_u32(node, "clock-frequency", &mdio_freq))
1122		mdio_freq = A5PSW_MDIO_DEF_FREQ;
1123
1124	ret = a5psw_mdio_config(a5psw, mdio_freq);
1125	if (ret)
1126		return ret;
1127
1128	bus = devm_mdiobus_alloc(dev);
1129	if (!bus)
1130		return -ENOMEM;
1131
1132	bus->name = "a5psw_mdio";
1133	bus->read = a5psw_mdio_read;
1134	bus->write = a5psw_mdio_write;
1135	bus->priv = a5psw;
1136	bus->parent = dev;
1137	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
1138
1139	a5psw->mii_bus = bus;
1140
1141	return devm_of_mdiobus_register(dev, bus, node);
1142}
1143
1144static void a5psw_pcs_free(struct a5psw *a5psw)
1145{
1146	int i;
1147
1148	for (i = 0; i < ARRAY_SIZE(a5psw->pcs); i++) {
1149		if (a5psw->pcs[i])
1150			miic_destroy(a5psw->pcs[i]);
1151	}
1152}
1153
1154static int a5psw_pcs_get(struct a5psw *a5psw)
1155{
1156	struct device_node *ports, *port, *pcs_node;
1157	struct phylink_pcs *pcs;
1158	int ret;
1159	u32 reg;
1160
1161	ports = of_get_child_by_name(a5psw->dev->of_node, "ethernet-ports");
1162	if (!ports)
1163		return -EINVAL;
1164
1165	for_each_available_child_of_node(ports, port) {
1166		pcs_node = of_parse_phandle(port, "pcs-handle", 0);
1167		if (!pcs_node)
1168			continue;
1169
1170		if (of_property_read_u32(port, "reg", &reg)) {
1171			ret = -EINVAL;
1172			goto free_pcs;
1173		}
1174
1175		if (reg >= ARRAY_SIZE(a5psw->pcs)) {
1176			ret = -ENODEV;
1177			goto free_pcs;
1178		}
1179
1180		pcs = miic_create(a5psw->dev, pcs_node);
1181		if (IS_ERR(pcs)) {
1182			dev_err(a5psw->dev, "Failed to create PCS for port %d\n",
1183				reg);
1184			ret = PTR_ERR(pcs);
1185			goto free_pcs;
1186		}
1187
1188		a5psw->pcs[reg] = pcs;
1189		of_node_put(pcs_node);
1190	}
1191	of_node_put(ports);
1192
1193	return 0;
1194
1195free_pcs:
1196	of_node_put(pcs_node);
1197	of_node_put(port);
1198	of_node_put(ports);
1199	a5psw_pcs_free(a5psw);
1200
1201	return ret;
1202}
1203
1204static int a5psw_probe(struct platform_device *pdev)
1205{
1206	struct device *dev = &pdev->dev;
1207	struct device_node *mdio;
1208	struct dsa_switch *ds;
1209	struct a5psw *a5psw;
1210	int ret;
1211
1212	a5psw = devm_kzalloc(dev, sizeof(*a5psw), GFP_KERNEL);
1213	if (!a5psw)
1214		return -ENOMEM;
1215
1216	a5psw->dev = dev;
1217	mutex_init(&a5psw->lk_lock);
1218	spin_lock_init(&a5psw->reg_lock);
1219	a5psw->base = devm_platform_ioremap_resource(pdev, 0);
1220	if (IS_ERR(a5psw->base))
1221		return PTR_ERR(a5psw->base);
1222
1223	a5psw->bridged_ports = BIT(A5PSW_CPU_PORT);
1224
1225	ret = a5psw_pcs_get(a5psw);
1226	if (ret)
1227		return ret;
1228
1229	a5psw->hclk = devm_clk_get(dev, "hclk");
1230	if (IS_ERR(a5psw->hclk)) {
1231		dev_err(dev, "failed get hclk clock\n");
1232		ret = PTR_ERR(a5psw->hclk);
1233		goto free_pcs;
1234	}
1235
1236	a5psw->clk = devm_clk_get(dev, "clk");
1237	if (IS_ERR(a5psw->clk)) {
1238		dev_err(dev, "failed get clk_switch clock\n");
1239		ret = PTR_ERR(a5psw->clk);
1240		goto free_pcs;
1241	}
1242
1243	ret = clk_prepare_enable(a5psw->clk);
1244	if (ret)
1245		goto free_pcs;
1246
1247	ret = clk_prepare_enable(a5psw->hclk);
1248	if (ret)
1249		goto clk_disable;
1250
1251	mdio = of_get_child_by_name(dev->of_node, "mdio");
1252	if (of_device_is_available(mdio)) {
1253		ret = a5psw_probe_mdio(a5psw, mdio);
1254		if (ret) {
1255			of_node_put(mdio);
1256			dev_err(dev, "Failed to register MDIO: %d\n", ret);
1257			goto hclk_disable;
1258		}
1259	}
1260
1261	of_node_put(mdio);
1262
1263	ds = &a5psw->ds;
1264	ds->dev = dev;
1265	ds->num_ports = A5PSW_PORTS_NUM;
1266	ds->ops = &a5psw_switch_ops;
1267	ds->phylink_mac_ops = &a5psw_phylink_mac_ops;
1268	ds->priv = a5psw;
1269
1270	ret = dsa_register_switch(ds);
1271	if (ret) {
1272		dev_err(dev, "Failed to register DSA switch: %d\n", ret);
1273		goto hclk_disable;
1274	}
1275
1276	return 0;
1277
1278hclk_disable:
1279	clk_disable_unprepare(a5psw->hclk);
1280clk_disable:
1281	clk_disable_unprepare(a5psw->clk);
1282free_pcs:
1283	a5psw_pcs_free(a5psw);
1284
1285	return ret;
1286}
1287
1288static void a5psw_remove(struct platform_device *pdev)
1289{
1290	struct a5psw *a5psw = platform_get_drvdata(pdev);
1291
1292	if (!a5psw)
1293		return;
1294
1295	dsa_unregister_switch(&a5psw->ds);
1296	a5psw_pcs_free(a5psw);
1297	clk_disable_unprepare(a5psw->hclk);
1298	clk_disable_unprepare(a5psw->clk);
1299}
1300
1301static void a5psw_shutdown(struct platform_device *pdev)
1302{
1303	struct a5psw *a5psw = platform_get_drvdata(pdev);
1304
1305	if (!a5psw)
1306		return;
1307
1308	dsa_switch_shutdown(&a5psw->ds);
1309
1310	platform_set_drvdata(pdev, NULL);
1311}
1312
1313static const struct of_device_id a5psw_of_mtable[] = {
1314	{ .compatible = "renesas,rzn1-a5psw", },
1315	{ /* sentinel */ },
1316};
1317MODULE_DEVICE_TABLE(of, a5psw_of_mtable);
1318
1319static struct platform_driver a5psw_driver = {
1320	.driver = {
1321		.name	 = "rzn1_a5psw",
1322		.of_match_table = a5psw_of_mtable,
1323	},
1324	.probe = a5psw_probe,
1325	.remove = a5psw_remove,
1326	.shutdown = a5psw_shutdown,
1327};
1328module_platform_driver(a5psw_driver);
1329
1330MODULE_LICENSE("GPL");
1331MODULE_DESCRIPTION("Renesas RZ/N1 Advanced 5-port Switch driver");
1332MODULE_AUTHOR("Clément Léger <clement.leger@bootlin.com>");