xref: /linux/drivers/net/dsa/mxl862xx/mxl862xx.c (revision 13ea4d4888c4614e496faa84d19a37f272116cc0)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Driver for MaxLinear MxL862xx switch family
4  *
5  * Copyright (C) 2024 MaxLinear Inc.
6  * Copyright (C) 2025 John Crispin <john@phrozen.org>
7  * Copyright (C) 2025 Daniel Golle <daniel@makrotopia.org>
8  */
9 
10 #include <linux/bitfield.h>
11 #include <linux/delay.h>
12 #include <linux/etherdevice.h>
13 #include <linux/if_bridge.h>
14 #include <linux/module.h>
15 #include <linux/of_device.h>
16 #include <linux/of_mdio.h>
17 #include <linux/phy.h>
18 #include <linux/phylink.h>
19 #include <net/dsa.h>
20 
21 #include "mxl862xx.h"
22 #include "mxl862xx-api.h"
23 #include "mxl862xx-cmd.h"
24 #include "mxl862xx-host.h"
25 #include "mxl862xx-phylink.h"
26 
27 /* Polling interval for RMON counter accumulation. At 2.5 Gbps with
28  * minimum-size (64-byte) frames, a 32-bit packet counter wraps in ~880s.
29  * 2s gives a comfortable margin.
30  */
31 #define MXL862XX_STATS_POLL_INTERVAL	(2 * HZ)
32 
33 struct mxl862xx_mib_desc {
34 	unsigned int size;
35 	unsigned int offset;
36 	const char *name;
37 };
38 
39 #define MIB_DESC(_size, _name, _element)					\
40 {									\
41 	.size = _size,							\
42 	.name = _name,							\
43 	.offset = offsetof(struct mxl862xx_rmon_port_cnt, _element)	\
44 }
45 
46 /* Hardware-specific counters not covered by any standardized stats callback. */
47 static const struct mxl862xx_mib_desc mxl862xx_mib[] = {
48 	MIB_DESC(1, "TxAcmDroppedPkts", tx_acm_dropped_pkts),
49 	MIB_DESC(1, "RxFilteredPkts", rx_filtered_pkts),
50 	MIB_DESC(1, "RxExtendedVlanDiscardPkts", rx_extended_vlan_discard_pkts),
51 	MIB_DESC(1, "MtuExceedDiscardPkts", mtu_exceed_discard_pkts),
52 	MIB_DESC(2, "RxBadBytes", rx_bad_bytes),
53 };
54 
55 static const struct ethtool_rmon_hist_range mxl862xx_rmon_ranges[] = {
56 	{ 0, 64 },
57 	{ 65, 127 },
58 	{ 128, 255 },
59 	{ 256, 511 },
60 	{ 512, 1023 },
61 	{ 1024, 10240 },
62 	{}
63 };
64 
65 #define MXL862XX_SDMA_PCTRLP(p)		(0xbc0 + ((p) * 0x6))
66 #define MXL862XX_SDMA_PCTRL_EN		BIT(0)
67 
68 #define MXL862XX_FDMA_PCTRLP(p)		(0xa80 + ((p) * 0x6))
69 #define MXL862XX_FDMA_PCTRL_EN		BIT(0)
70 
71 #define MXL862XX_READY_TIMEOUT_MS	10000
72 #define MXL862XX_READY_POLL_MS		100
73 
74 #define MXL862XX_TCM_INST_SEL		0xe00
75 #define MXL862XX_TCM_CBS		0xe12
76 #define MXL862XX_TCM_EBS		0xe13
77 
78 static const int mxl862xx_flood_meters[] = {
79 	MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC,
80 	MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP,
81 	MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP,
82 	MXL862XX_BRIDGE_PORT_EGRESS_METER_BROADCAST,
83 };
84 
85 enum mxl862xx_evlan_action {
86 	EVLAN_ACCEPT,			/* pass-through, no tag removal */
87 	EVLAN_STRIP_IF_UNTAGGED,	/* remove 1 tag if entry's untagged flag set */
88 	EVLAN_PVID_OR_DISCARD,		/* insert PVID tag or discard if no PVID */
89 	EVLAN_STRIP1_AND_PVID_OR_DISCARD,/* strip 1 tag + insert PVID, or discard */
90 };
91 
92 struct mxl862xx_evlan_rule_desc {
93 	u8 outer_type;		/* enum mxl862xx_extended_vlan_filter_type */
94 	u8 inner_type;		/* enum mxl862xx_extended_vlan_filter_type */
95 	u8 outer_tpid;		/* enum mxl862xx_extended_vlan_filter_tpid */
96 	u8 inner_tpid;		/* enum mxl862xx_extended_vlan_filter_tpid */
97 	bool match_vid;		/* true: match on VID from the vid parameter */
98 	u8 action;		/* enum mxl862xx_evlan_action */
99 };
100 
101 /* Shorthand constants for readability */
102 #define FT_NORMAL	MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NORMAL
103 #define FT_NO_FILTER	MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_FILTER
104 #define FT_DEFAULT	MXL862XX_EXTENDEDVLAN_FILTER_TYPE_DEFAULT
105 #define FT_NO_TAG	MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_TAG
106 #define TP_NONE		MXL862XX_EXTENDEDVLAN_FILTER_TPID_NO_FILTER
107 #define TP_8021Q	MXL862XX_EXTENDEDVLAN_FILTER_TPID_8021Q
108 
109 /*
110  * VLAN-aware ingress: 7 final catchall rules.
111  *
112  * VLAN Filter handles VID membership for tagged frames, so the
113  * Extended VLAN ingress block only needs to handle:
114  * - Priority-tagged (VID=0): strip + insert PVID
115  * - Untagged: insert PVID or discard
116  * - Standard 802.1Q VID>0: pass through (VF handles membership)
117  * - Non-8021Q TPID (0x88A8 etc.): treat as untagged
118  *
119  * Rule ordering is critical: the EVLAN engine scans entries in
120  * ascending index order and stops at the first match.
121  *
122  * The 802.1Q ACCEPT rules (indices 3--4) must appear BEFORE the
123  * NO_FILTER catchalls (indices 5--6). NO_FILTER matches any tag
124  * regardless of TPID, so without the ACCEPT guard, it would also
125  * catch standard 802.1Q VID>0 frames and corrupt them. With the
126  * guard, 802.1Q VID>0 frames match the ACCEPT rules first and
127  * pass through untouched; only non-8021Q TPID frames pass through
128  * to the NO_FILTER catchalls.
129  */
130 static const struct mxl862xx_evlan_rule_desc ingress_aware_final[] = {
131 	/* 802.1p / priority-tagged (VID 0): strip + PVID */
132 	{ FT_NORMAL,    FT_NORMAL, TP_8021Q, TP_8021Q, true,  EVLAN_STRIP1_AND_PVID_OR_DISCARD },
133 	{ FT_NORMAL,    FT_NO_TAG, TP_8021Q, TP_NONE,  true,  EVLAN_STRIP1_AND_PVID_OR_DISCARD },
134 	/* Untagged: PVID insertion or discard */
135 	{ FT_NO_TAG,    FT_NO_TAG, TP_NONE,  TP_NONE,  false, EVLAN_PVID_OR_DISCARD },
136 	/* 802.1Q VID>0: accept - VF handles membership.
137 	 * match_vid=false means any VID; VID=0 is already caught above.
138 	 */
139 	{ FT_NORMAL,    FT_NORMAL, TP_8021Q, TP_8021Q, false, EVLAN_ACCEPT },
140 	{ FT_NORMAL,    FT_NO_TAG, TP_8021Q, TP_NONE,  false, EVLAN_ACCEPT },
141 	/* Non-8021Q TPID (0x88A8 etc.): treat as untagged - strip + PVID */
142 	{ FT_NO_FILTER, FT_NO_FILTER, TP_NONE, TP_NONE, false, EVLAN_STRIP1_AND_PVID_OR_DISCARD },
143 	{ FT_NO_FILTER, FT_NO_TAG,    TP_NONE, TP_NONE, false, EVLAN_STRIP1_AND_PVID_OR_DISCARD },
144 };
145 
146 /*
147  * VID-specific accept rules (VLAN-aware, standard tag, 2 per VID).
148  * Outer tag carries the VLAN; inner may or may not be present.
149  */
150 static const struct mxl862xx_evlan_rule_desc vid_accept_standard[] = {
151 	{ FT_NORMAL, FT_NORMAL, TP_8021Q, TP_8021Q, true, EVLAN_STRIP_IF_UNTAGGED },
152 	{ FT_NORMAL, FT_NO_TAG, TP_8021Q, TP_NONE,  true, EVLAN_STRIP_IF_UNTAGGED },
153 };
154 
155 /*
156  * Egress tag-stripping rules for VLAN-unaware mode (2 per untagged VID).
157  * The HW sees the MxL tag as outer; the real VLAN tag, if any, is inner.
158  */
159 static const struct mxl862xx_evlan_rule_desc vid_accept_egress_unaware[] = {
160 	{ FT_NO_FILTER, FT_NORMAL, TP_NONE, TP_8021Q, true,  EVLAN_STRIP_IF_UNTAGGED },
161 	{ FT_NO_FILTER, FT_NO_TAG, TP_NONE, TP_NONE,  false, EVLAN_STRIP_IF_UNTAGGED },
162 };
163 
164 static enum dsa_tag_protocol mxl862xx_get_tag_protocol(struct dsa_switch *ds,
165 						       int port,
166 						       enum dsa_tag_protocol m)
167 {
168 	return DSA_TAG_PROTO_MXL862;
169 }
170 
171 /* PHY access via firmware relay */
172 static int mxl862xx_phy_read_mmd(struct mxl862xx_priv *priv, int addr,
173 				 int devadd, int regnum)
174 {
175 	struct mdio_relay_data param = {
176 		.phy = addr,
177 		.mmd = devadd,
178 		.reg = cpu_to_le16(regnum),
179 	};
180 	int ret;
181 
182 	ret = MXL862XX_API_READ(priv, INT_GPHY_READ, param);
183 	if (ret)
184 		return ret;
185 
186 	return le16_to_cpu(param.data);
187 }
188 
189 static int mxl862xx_phy_write_mmd(struct mxl862xx_priv *priv, int addr,
190 				  int devadd, int regnum, u16 data)
191 {
192 	struct mdio_relay_data param = {
193 		.phy = addr,
194 		.mmd = devadd,
195 		.reg = cpu_to_le16(regnum),
196 		.data = cpu_to_le16(data),
197 	};
198 
199 	return MXL862XX_API_WRITE(priv, INT_GPHY_WRITE, param);
200 }
201 
202 static int mxl862xx_phy_read_mii_bus(struct mii_bus *bus, int addr, int regnum)
203 {
204 	return mxl862xx_phy_read_mmd(bus->priv, addr, 0, regnum);
205 }
206 
207 static int mxl862xx_phy_write_mii_bus(struct mii_bus *bus, int addr,
208 				      int regnum, u16 val)
209 {
210 	return mxl862xx_phy_write_mmd(bus->priv, addr, 0, regnum, val);
211 }
212 
213 static int mxl862xx_phy_read_c45_mii_bus(struct mii_bus *bus, int addr,
214 					 int devadd, int regnum)
215 {
216 	return mxl862xx_phy_read_mmd(bus->priv, addr, devadd, regnum);
217 }
218 
219 static int mxl862xx_phy_write_c45_mii_bus(struct mii_bus *bus, int addr,
220 					  int devadd, int regnum, u16 val)
221 {
222 	return mxl862xx_phy_write_mmd(bus->priv, addr, devadd, regnum, val);
223 }
224 
225 static int mxl862xx_wait_ready(struct dsa_switch *ds)
226 {
227 	struct mxl862xx_sys_fw_image_version ver = {};
228 	unsigned long start = jiffies, timeout;
229 	struct mxl862xx_priv *priv = ds->priv;
230 	struct mxl862xx_cfg cfg = {};
231 	int ret;
232 
233 	timeout = start + msecs_to_jiffies(MXL862XX_READY_TIMEOUT_MS);
234 	msleep(2000); /* it always takes at least 2 seconds */
235 	do {
236 		ret = MXL862XX_API_READ_QUIET(priv, SYS_MISC_FW_VERSION, ver);
237 		if (ret || !ver.iv_major)
238 			goto not_ready_yet;
239 
240 		/* being able to perform CFGGET indicates that
241 		 * the firmware is ready
242 		 */
243 		ret = MXL862XX_API_READ_QUIET(priv,
244 					      MXL862XX_COMMON_CFGGET,
245 					      cfg);
246 		if (ret)
247 			goto not_ready_yet;
248 
249 		dev_info(ds->dev, "switch ready after %ums, firmware %u.%u.%u (build %u)\n",
250 			 jiffies_to_msecs(jiffies - start),
251 			 ver.iv_major, ver.iv_minor,
252 			 le16_to_cpu(ver.iv_revision),
253 			 le32_to_cpu(ver.iv_build_num));
254 		priv->fw_version.major = ver.iv_major;
255 		priv->fw_version.minor = ver.iv_minor;
256 		priv->fw_version.revision = le16_to_cpu(ver.iv_revision);
257 		return 0;
258 
259 not_ready_yet:
260 		msleep(MXL862XX_READY_POLL_MS);
261 	} while (time_before(jiffies, timeout));
262 
263 	dev_err(ds->dev, "switch not responding after reset\n");
264 	return -ETIMEDOUT;
265 }
266 
267 static int mxl862xx_setup_mdio(struct dsa_switch *ds)
268 {
269 	struct mxl862xx_priv *priv = ds->priv;
270 	struct device *dev = ds->dev;
271 	struct device_node *mdio_np;
272 	struct mii_bus *bus;
273 	int ret;
274 
275 	bus = devm_mdiobus_alloc(dev);
276 	if (!bus)
277 		return -ENOMEM;
278 
279 	bus->priv = priv;
280 	bus->name = KBUILD_MODNAME "-mii";
281 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev));
282 	bus->read_c45 = mxl862xx_phy_read_c45_mii_bus;
283 	bus->write_c45 = mxl862xx_phy_write_c45_mii_bus;
284 	bus->read = mxl862xx_phy_read_mii_bus;
285 	bus->write = mxl862xx_phy_write_mii_bus;
286 	bus->parent = dev;
287 	bus->phy_mask = ~ds->phys_mii_mask;
288 
289 	mdio_np = of_get_child_by_name(dev->of_node, "mdio");
290 	if (!mdio_np)
291 		return -ENODEV;
292 
293 	ret = devm_of_mdiobus_register(dev, bus, mdio_np);
294 	of_node_put(mdio_np);
295 
296 	return ret;
297 }
298 
299 static int mxl862xx_bridge_config_fwd(struct dsa_switch *ds, u16 bridge_id,
300 				      bool ucast_flood, bool mcast_flood,
301 				      bool bcast_flood)
302 {
303 	struct mxl862xx_bridge_config bridge_config = {};
304 	struct mxl862xx_priv *priv = ds->priv;
305 	int ret;
306 
307 	bridge_config.mask = cpu_to_le32(MXL862XX_BRIDGE_CONFIG_MASK_FORWARDING_MODE);
308 	bridge_config.bridge_id = cpu_to_le16(bridge_id);
309 
310 	bridge_config.forward_unknown_unicast = cpu_to_le32(ucast_flood ?
311 		MXL862XX_BRIDGE_FORWARD_FLOOD : MXL862XX_BRIDGE_FORWARD_DISCARD);
312 
313 	bridge_config.forward_unknown_multicast_ip = cpu_to_le32(mcast_flood ?
314 		MXL862XX_BRIDGE_FORWARD_FLOOD : MXL862XX_BRIDGE_FORWARD_DISCARD);
315 	bridge_config.forward_unknown_multicast_non_ip =
316 		bridge_config.forward_unknown_multicast_ip;
317 
318 	bridge_config.forward_broadcast = cpu_to_le32(bcast_flood ?
319 		MXL862XX_BRIDGE_FORWARD_FLOOD : MXL862XX_BRIDGE_FORWARD_DISCARD);
320 
321 	ret = MXL862XX_API_WRITE(priv, MXL862XX_BRIDGE_CONFIGSET, bridge_config);
322 	if (ret)
323 		dev_err(ds->dev, "failed to configure bridge %u forwarding: %d\n",
324 			bridge_id, ret);
325 
326 	return ret;
327 }
328 
329 /* Allocate a single zero-rate meter shared by all ports and flood types.
330  * All flood-blocking egress sub-meters point to this one meter so that any
331  * packet hitting this meter is unconditionally dropped.
332  *
333  * The firmware API requires CBS >= 64 (its bs2ls encoder clamps smaller
334  * values), so the meter is initially configured with CBS=EBS=64.
335  * A zero-rate bucket starts full at CBS bytes, which would let one packet
336  * through before the bucket empties. To eliminate this one-packet leak we
337  * override CBS and EBS to zero via direct register writes after the API call;
338  * the hardware accepts CBS=0 and immediately flags the bucket as exceeded,
339  * so no traffic can ever pass.
340  */
341 static int mxl862xx_setup_drop_meter(struct dsa_switch *ds)
342 {
343 	struct mxl862xx_qos_meter_cfg meter = {};
344 	struct mxl862xx_priv *priv = ds->priv;
345 	struct mxl862xx_register_mod reg;
346 	int ret;
347 
348 	/* meter_id=0 means auto-alloc */
349 	ret = MXL862XX_API_READ(priv, MXL862XX_QOS_METERALLOC, meter);
350 	if (ret)
351 		return ret;
352 
353 	meter.enable = true;
354 	meter.cbs = cpu_to_le32(64);
355 	meter.ebs = cpu_to_le32(64);
356 	snprintf(meter.meter_name, sizeof(meter.meter_name), "drop");
357 
358 	ret = MXL862XX_API_WRITE(priv, MXL862XX_QOS_METERCFGSET, meter);
359 	if (ret)
360 		return ret;
361 
362 	priv->drop_meter = le16_to_cpu(meter.meter_id);
363 
364 	/* Select the meter instance for subsequent TCM register access. */
365 	reg.addr = cpu_to_le16(MXL862XX_TCM_INST_SEL);
366 	reg.data = cpu_to_le16(priv->drop_meter);
367 	reg.mask = cpu_to_le16(0xffff);
368 	ret = MXL862XX_API_WRITE(priv, MXL862XX_COMMON_REGISTERMOD, reg);
369 	if (ret)
370 		return ret;
371 
372 	/* Zero CBS so the committed bucket starts empty (exceeded). */
373 	reg.addr = cpu_to_le16(MXL862XX_TCM_CBS);
374 	reg.data = 0;
375 	ret = MXL862XX_API_WRITE(priv, MXL862XX_COMMON_REGISTERMOD, reg);
376 	if (ret)
377 		return ret;
378 
379 	/* Zero EBS so the excess bucket starts empty (exceeded). */
380 	reg.addr = cpu_to_le16(MXL862XX_TCM_EBS);
381 	return MXL862XX_API_WRITE(priv, MXL862XX_COMMON_REGISTERMOD, reg);
382 }
383 
384 static int mxl862xx_set_bridge_port(struct dsa_switch *ds, int port)
385 {
386 	struct mxl862xx_bridge_port_config br_port_cfg = {};
387 	struct dsa_port *dp = dsa_to_port(ds, port);
388 	struct mxl862xx_priv *priv = ds->priv;
389 	struct mxl862xx_port *p = &priv->ports[port];
390 	struct dsa_port *member_dp;
391 	u16 bridge_id;
392 	u16 vf_scan;
393 	bool enable;
394 	int i, idx;
395 
396 	if (dsa_port_is_unused(dp))
397 		return 0;
398 
399 	if (dsa_port_is_cpu(dp)) {
400 		dsa_switch_for_each_user_port(member_dp, ds) {
401 			if (member_dp->cpu_dp->index != port)
402 				continue;
403 			mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
404 						    member_dp->index);
405 		}
406 	} else if (dp->bridge) {
407 		dsa_switch_for_each_bridge_member(member_dp, ds,
408 						  dp->bridge->dev) {
409 			if (member_dp->index == port)
410 				continue;
411 			mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
412 						    member_dp->index);
413 		}
414 		mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
415 					    dp->cpu_dp->index);
416 	} else {
417 		mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
418 					    dp->cpu_dp->index);
419 		p->flood_block = 0;
420 		p->learning = false;
421 	}
422 
423 	bridge_id = dp->bridge ? priv->bridges[dp->bridge->num] : p->fid;
424 
425 	br_port_cfg.bridge_port_id = cpu_to_le16(port);
426 	br_port_cfg.bridge_id = cpu_to_le16(bridge_id);
427 	br_port_cfg.mask = cpu_to_le32(MXL862XX_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID |
428 				       MXL862XX_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP |
429 				       MXL862XX_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING |
430 				       MXL862XX_BRIDGE_PORT_CONFIG_MASK_EGRESS_SUB_METER |
431 				       MXL862XX_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN |
432 				       MXL862XX_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN |
433 				       MXL862XX_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN_FILTER |
434 				       MXL862XX_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN_FILTER1 |
435 				       MXL862XX_BRIDGE_PORT_CONFIG_MASK_VLAN_BASED_MAC_LEARNING);
436 	br_port_cfg.src_mac_learning_disable = !p->learning;
437 
438 	/* Extended VLAN block assignments.
439 	 * Ingress: block_size is sent as-is (all entries are finals).
440 	 * Egress: n_active narrows the scan window to only the
441 	 * entries actually written by evlan_program_egress.
442 	 */
443 	br_port_cfg.ingress_extended_vlan_enable = p->ingress_evlan.in_use;
444 	br_port_cfg.ingress_extended_vlan_block_id =
445 		cpu_to_le16(p->ingress_evlan.block_id);
446 	br_port_cfg.ingress_extended_vlan_block_size =
447 		cpu_to_le16(p->ingress_evlan.block_size);
448 	br_port_cfg.egress_extended_vlan_enable = p->egress_evlan.in_use;
449 	br_port_cfg.egress_extended_vlan_block_id =
450 		cpu_to_le16(p->egress_evlan.block_id);
451 	br_port_cfg.egress_extended_vlan_block_size =
452 		cpu_to_le16(p->egress_evlan.n_active);
453 
454 	/* VLAN Filter block assignments (per-port).
455 	 * The block_size sent to the firmware narrows the HW scan
456 	 * window to [block_id, block_id + active_count), relying on
457 	 * discard_unmatched_tagged for frames outside that range.
458 	 * When active_count=0, send 1 to scan only the DISCARD
459 	 * sentinel at index 0 (block_size=0 would disable narrowing
460 	 * and scan the entire allocated block).
461 	 *
462 	 * The bridge check ensures VF is disabled when the port
463 	 * leaves the bridge, without needing to prematurely clear
464 	 * vlan_filtering (which the DSA framework handles later via
465 	 * port_vlan_filtering).
466 	 */
467 	if (p->vf.allocated && p->vlan_filtering &&
468 	    dsa_port_bridge_dev_get(dp)) {
469 		vf_scan = max_t(u16, p->vf.active_count, 1);
470 		br_port_cfg.ingress_vlan_filter_enable = 1;
471 		br_port_cfg.ingress_vlan_filter_block_id =
472 			cpu_to_le16(p->vf.block_id);
473 		br_port_cfg.ingress_vlan_filter_block_size =
474 			cpu_to_le16(vf_scan);
475 
476 		br_port_cfg.egress_vlan_filter1enable = 1;
477 		br_port_cfg.egress_vlan_filter1block_id =
478 			cpu_to_le16(p->vf.block_id);
479 		br_port_cfg.egress_vlan_filter1block_size =
480 			cpu_to_le16(vf_scan);
481 	} else {
482 		br_port_cfg.ingress_vlan_filter_enable = 0;
483 		br_port_cfg.egress_vlan_filter1enable = 0;
484 	}
485 
486 	/* IVL when VLAN-aware: include VID in FDB lookup keys so that
487 	 * learned entries are per-VID. In VLAN-unaware mode, SVL is
488 	 * used (VID excluded from key).
489 	 */
490 	br_port_cfg.vlan_src_mac_vid_enable = p->vlan_filtering;
491 	br_port_cfg.vlan_dst_mac_vid_enable = p->vlan_filtering;
492 
493 	for (i = 0; i < ARRAY_SIZE(mxl862xx_flood_meters); i++) {
494 		idx = mxl862xx_flood_meters[i];
495 		enable = !!(p->flood_block & BIT(idx));
496 
497 		br_port_cfg.egress_traffic_sub_meter_id[idx] =
498 			enable ? cpu_to_le16(priv->drop_meter) : 0;
499 		br_port_cfg.egress_sub_metering_enable[idx] = enable;
500 	}
501 
502 	return MXL862XX_API_WRITE(priv, MXL862XX_BRIDGEPORT_CONFIGSET,
503 				  br_port_cfg);
504 }
505 
506 static int mxl862xx_sync_bridge_members(struct dsa_switch *ds,
507 					const struct dsa_bridge *bridge)
508 {
509 	struct dsa_port *dp;
510 	int ret = 0, err;
511 
512 	dsa_switch_for_each_bridge_member(dp, ds, bridge->dev) {
513 		err = mxl862xx_set_bridge_port(ds, dp->index);
514 		if (err)
515 			ret = err;
516 	}
517 
518 	return ret;
519 }
520 
521 static int mxl862xx_evlan_block_alloc(struct mxl862xx_priv *priv,
522 				      struct mxl862xx_evlan_block *blk)
523 {
524 	struct mxl862xx_extendedvlan_alloc param = {};
525 	int ret;
526 
527 	param.number_of_entries = cpu_to_le16(blk->block_size);
528 
529 	ret = MXL862XX_API_READ(priv, MXL862XX_EXTENDEDVLAN_ALLOC, param);
530 	if (ret)
531 		return ret;
532 
533 	blk->block_id = le16_to_cpu(param.extended_vlan_block_id);
534 	blk->allocated = true;
535 
536 	return 0;
537 }
538 
539 static int mxl862xx_vf_block_alloc(struct mxl862xx_priv *priv,
540 				   u16 size, u16 *block_id)
541 {
542 	struct mxl862xx_vlanfilter_alloc param = {};
543 	int ret;
544 
545 	param.number_of_entries = cpu_to_le16(size);
546 	param.discard_untagged = 0;
547 	param.discard_unmatched_tagged = 1;
548 
549 	ret = MXL862XX_API_READ(priv, MXL862XX_VLANFILTER_ALLOC, param);
550 	if (ret)
551 		return ret;
552 
553 	*block_id = le16_to_cpu(param.vlan_filter_block_id);
554 	return 0;
555 }
556 
557 static int mxl862xx_vf_entry_discard(struct mxl862xx_priv *priv,
558 				     u16 block_id, u16 index)
559 {
560 	struct mxl862xx_vlanfilter_config cfg = {};
561 
562 	cfg.vlan_filter_block_id = cpu_to_le16(block_id);
563 	cfg.entry_index = cpu_to_le16(index);
564 	cfg.vlan_filter_mask = cpu_to_le32(MXL862XX_VLAN_FILTER_TCI_MASK_VID);
565 	cfg.val = cpu_to_le32(0);
566 	cfg.discard_matched = 1;
567 
568 	return MXL862XX_API_WRITE(priv, MXL862XX_VLANFILTER_SET, cfg);
569 }
570 
571 static int mxl862xx_vf_alloc(struct mxl862xx_priv *priv,
572 			     struct mxl862xx_vf_block *vf)
573 {
574 	int ret;
575 
576 	ret = mxl862xx_vf_block_alloc(priv, vf->block_size, &vf->block_id);
577 	if (ret)
578 		return ret;
579 
580 	vf->allocated = true;
581 	vf->active_count = 0;
582 
583 	/* Sentinel: block VID-0 when scan window covers only index 0 */
584 	return mxl862xx_vf_entry_discard(priv, vf->block_id, 0);
585 }
586 
587 static int mxl862xx_allocate_bridge(struct mxl862xx_priv *priv)
588 {
589 	struct mxl862xx_bridge_alloc br_alloc = {};
590 	int ret;
591 
592 	ret = MXL862XX_API_READ(priv, MXL862XX_BRIDGE_ALLOC, br_alloc);
593 	if (ret)
594 		return ret;
595 
596 	return le16_to_cpu(br_alloc.bridge_id);
597 }
598 
599 static void mxl862xx_free_bridge(struct dsa_switch *ds,
600 				 const struct dsa_bridge *bridge)
601 {
602 	struct mxl862xx_priv *priv = ds->priv;
603 	u16 fw_id = priv->bridges[bridge->num];
604 	struct mxl862xx_bridge_alloc br_alloc = {
605 		.bridge_id = cpu_to_le16(fw_id),
606 	};
607 	int ret;
608 
609 	ret = MXL862XX_API_WRITE(priv, MXL862XX_BRIDGE_FREE, br_alloc);
610 	if (ret) {
611 		dev_err(ds->dev, "failed to free fw bridge %u: %pe\n",
612 			fw_id, ERR_PTR(ret));
613 		return;
614 	}
615 
616 	priv->bridges[bridge->num] = 0;
617 }
618 
619 static int mxl862xx_setup(struct dsa_switch *ds)
620 {
621 	struct mxl862xx_priv *priv = ds->priv;
622 	int n_user_ports = 0, max_vlans;
623 	int ingress_finals, vid_rules;
624 	struct dsa_port *dp;
625 	int ret, i;
626 
627 	ret = mxl862xx_reset(priv);
628 	if (ret)
629 		return ret;
630 
631 	ret = mxl862xx_wait_ready(ds);
632 	if (ret)
633 		return ret;
634 
635 	mutex_init(&priv->serdes_lock);
636 	for (i = 0; i < ARRAY_SIZE(priv->serdes_ports); i++)
637 		mxl862xx_setup_pcs(priv, &priv->serdes_ports[i],
638 				   i + MXL862XX_FIRST_SERDES_PORT);
639 
640 	/* Calculate Extended VLAN block sizes.
641 	 * With VLAN Filter handling VID membership checks:
642 	 *   Ingress: only final catchall rules (PVID insertion, 802.1Q
643 	 *            accept, non-8021Q TPID handling, discard).
644 	 *            Block sized to exactly fit the finals -- no per-VID
645 	 *            ingress EVLAN rules are needed. (7 entries.)
646 	 *   Egress:  2 rules per VID that needs tag stripping (untagged VIDs).
647 	 *            No egress final catchalls -- VLAN Filter does the discard.
648 	 *   CPU:     EVLAN is left disabled on CPU ports -- frames pass
649 	 *            through without EVLAN processing.
650 	 *
651 	 * Total EVLAN budget:
652 	 *   n_user_ports * (ingress + egress) <= 1024.
653 	 * Ingress blocks are small (7 entries), so almost all capacity
654 	 * goes to egress VID rules.
655 	 */
656 	dsa_switch_for_each_user_port(dp, ds)
657 		n_user_ports++;
658 
659 	if (n_user_ports) {
660 		ingress_finals = ARRAY_SIZE(ingress_aware_final);
661 		vid_rules = ARRAY_SIZE(vid_accept_standard);
662 
663 		/* Ingress block: fixed at finals count (7 entries) */
664 		priv->evlan_ingress_size = ingress_finals;
665 
666 		/* Egress block: remaining budget divided equally among
667 		 * user ports. Each untagged VID needs vid_rules (2)
668 		 * EVLAN entries for tag stripping. Tagged-only VIDs
669 		 * need no EVLAN rules at all.
670 		 */
671 		max_vlans = (MXL862XX_TOTAL_EVLAN_ENTRIES -
672 			     n_user_ports * ingress_finals) /
673 			    (n_user_ports * vid_rules);
674 		priv->evlan_egress_size = vid_rules * max_vlans;
675 
676 		/* VLAN Filter block: one per user port. The 1024-entry
677 		 * table is divided equally among user ports. Each port
678 		 * gets its own VF block for per-port VID membership --
679 		 * discard_unmatched_tagged handles the rest.
680 		 */
681 		priv->vf_block_size = MXL862XX_TOTAL_VF_ENTRIES / n_user_ports;
682 	}
683 
684 	ret = mxl862xx_setup_drop_meter(ds);
685 	if (ret)
686 		return ret;
687 
688 	schedule_delayed_work(&priv->stats_work,
689 			      MXL862XX_STATS_POLL_INTERVAL);
690 
691 	return mxl862xx_setup_mdio(ds);
692 }
693 
694 static int mxl862xx_port_state(struct dsa_switch *ds, int port, bool enable)
695 {
696 	struct mxl862xx_register_mod sdma = {
697 		.addr = cpu_to_le16(MXL862XX_SDMA_PCTRLP(port)),
698 		.data = cpu_to_le16(enable ? MXL862XX_SDMA_PCTRL_EN : 0),
699 		.mask = cpu_to_le16(MXL862XX_SDMA_PCTRL_EN),
700 	};
701 	struct mxl862xx_register_mod fdma = {
702 		.addr = cpu_to_le16(MXL862XX_FDMA_PCTRLP(port)),
703 		.data = cpu_to_le16(enable ? MXL862XX_FDMA_PCTRL_EN : 0),
704 		.mask = cpu_to_le16(MXL862XX_FDMA_PCTRL_EN),
705 	};
706 	int ret;
707 
708 	ret = MXL862XX_API_WRITE(ds->priv, MXL862XX_COMMON_REGISTERMOD, sdma);
709 	if (ret)
710 		return ret;
711 
712 	return MXL862XX_API_WRITE(ds->priv, MXL862XX_COMMON_REGISTERMOD, fdma);
713 }
714 
715 static int mxl862xx_port_enable(struct dsa_switch *ds, int port,
716 				struct phy_device *phydev)
717 {
718 	return mxl862xx_port_state(ds, port, true);
719 }
720 
721 static void mxl862xx_port_disable(struct dsa_switch *ds, int port)
722 {
723 	if (mxl862xx_port_state(ds, port, false))
724 		dev_err(ds->dev, "failed to disable port %d\n", port);
725 }
726 
727 static void mxl862xx_port_fast_age(struct dsa_switch *ds, int port)
728 {
729 	struct mxl862xx_mac_table_clear param = {
730 		.type = MXL862XX_MAC_CLEAR_PHY_PORT,
731 		.port_id = port,
732 	};
733 
734 	if (MXL862XX_API_WRITE(ds->priv, MXL862XX_MAC_TABLECLEARCOND, param))
735 		dev_err(ds->dev, "failed to clear fdb on port %d\n", port);
736 }
737 
738 static int mxl862xx_configure_ctp_port(struct dsa_switch *ds, int port,
739 				       u16 first_ctp_port_id,
740 				       u16 number_of_ctp_ports)
741 {
742 	struct mxl862xx_ctp_port_assignment ctp_assign = {
743 		.logical_port_id = port,
744 		.first_ctp_port_id = cpu_to_le16(first_ctp_port_id),
745 		.number_of_ctp_port = cpu_to_le16(number_of_ctp_ports),
746 		.mode = cpu_to_le32(MXL862XX_LOGICAL_PORT_ETHERNET),
747 	};
748 
749 	return MXL862XX_API_WRITE(ds->priv, MXL862XX_CTP_PORTASSIGNMENTSET,
750 				  ctp_assign);
751 }
752 
753 static int mxl862xx_configure_sp_tag_proto(struct dsa_switch *ds, int port,
754 					   bool enable)
755 {
756 	struct mxl862xx_ss_sp_tag tag = {
757 		.pid = port,
758 		.mask = MXL862XX_SS_SP_TAG_MASK_RX | MXL862XX_SS_SP_TAG_MASK_TX,
759 		.rx = enable ? MXL862XX_SS_SP_TAG_RX_TAG_NO_INSERT :
760 			       MXL862XX_SS_SP_TAG_RX_NO_TAG_INSERT,
761 		.tx = enable ? MXL862XX_SS_SP_TAG_TX_TAG_NO_REMOVE :
762 			       MXL862XX_SS_SP_TAG_TX_TAG_REMOVE,
763 	};
764 
765 	return MXL862XX_API_WRITE(ds->priv, MXL862XX_SS_SPTAG_SET, tag);
766 }
767 
768 static int mxl862xx_evlan_write_rule(struct mxl862xx_priv *priv,
769 				     u16 block_id, u16 entry_index,
770 				     const struct mxl862xx_evlan_rule_desc *desc,
771 				     u16 vid, bool untagged, u16 pvid)
772 {
773 	struct mxl862xx_extendedvlan_config cfg = {};
774 	struct mxl862xx_extendedvlan_filter_vlan *fv;
775 
776 	cfg.extended_vlan_block_id = cpu_to_le16(block_id);
777 	cfg.entry_index = cpu_to_le16(entry_index);
778 
779 	/* Populate filter */
780 	cfg.filter.outer_vlan.type = cpu_to_le32(desc->outer_type);
781 	cfg.filter.inner_vlan.type = cpu_to_le32(desc->inner_type);
782 	cfg.filter.outer_vlan.tpid = cpu_to_le32(desc->outer_tpid);
783 	cfg.filter.inner_vlan.tpid = cpu_to_le32(desc->inner_tpid);
784 
785 	if (desc->match_vid) {
786 		/* For egress unaware: outer=NO_FILTER, match on inner tag */
787 		if (desc->outer_type == FT_NO_FILTER)
788 			fv = &cfg.filter.inner_vlan;
789 		else
790 			fv = &cfg.filter.outer_vlan;
791 
792 		fv->vid_enable = 1;
793 		fv->vid_val = cpu_to_le32(vid);
794 	}
795 
796 	/* Populate treatment based on action */
797 	switch (desc->action) {
798 	case EVLAN_ACCEPT:
799 		cfg.treatment.remove_tag =
800 			cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG);
801 		break;
802 
803 	case EVLAN_STRIP_IF_UNTAGGED:
804 		cfg.treatment.remove_tag = cpu_to_le32(untagged ?
805 			MXL862XX_EXTENDEDVLAN_TREATMENT_REMOVE_1_TAG :
806 			MXL862XX_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG);
807 		break;
808 
809 	case EVLAN_PVID_OR_DISCARD:
810 		if (pvid) {
811 			cfg.treatment.remove_tag =
812 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG);
813 			cfg.treatment.add_outer_vlan = 1;
814 			cfg.treatment.outer_vlan.vid_mode =
815 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_VID_VAL);
816 			cfg.treatment.outer_vlan.vid_val = cpu_to_le32(pvid);
817 			cfg.treatment.outer_vlan.tpid =
818 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_8021Q);
819 		} else {
820 			cfg.treatment.remove_tag =
821 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM);
822 		}
823 		break;
824 
825 	case EVLAN_STRIP1_AND_PVID_OR_DISCARD:
826 		if (pvid) {
827 			cfg.treatment.remove_tag =
828 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_REMOVE_1_TAG);
829 			cfg.treatment.add_outer_vlan = 1;
830 			cfg.treatment.outer_vlan.vid_mode =
831 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_VID_VAL);
832 			cfg.treatment.outer_vlan.vid_val = cpu_to_le32(pvid);
833 			cfg.treatment.outer_vlan.tpid =
834 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_8021Q);
835 		} else {
836 			cfg.treatment.remove_tag =
837 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM);
838 		}
839 		break;
840 	}
841 
842 	return MXL862XX_API_WRITE(priv, MXL862XX_EXTENDEDVLAN_SET, cfg);
843 }
844 
845 static int mxl862xx_evlan_deactivate_entry(struct mxl862xx_priv *priv,
846 					   u16 block_id, u16 entry_index)
847 {
848 	struct mxl862xx_extendedvlan_config cfg = {};
849 
850 	cfg.extended_vlan_block_id = cpu_to_le16(block_id);
851 	cfg.entry_index = cpu_to_le16(entry_index);
852 
853 	/* Use an unreachable filter (DEFAULT+DEFAULT) with DISCARD treatment.
854 	 * A zeroed entry would have NORMAL+NORMAL filter which matches
855 	 * real double-tagged traffic and passes it through.
856 	 */
857 	cfg.filter.outer_vlan.type =
858 		cpu_to_le32(MXL862XX_EXTENDEDVLAN_FILTER_TYPE_DEFAULT);
859 	cfg.filter.inner_vlan.type =
860 		cpu_to_le32(MXL862XX_EXTENDEDVLAN_FILTER_TYPE_DEFAULT);
861 	cfg.treatment.remove_tag =
862 		cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM);
863 
864 	return MXL862XX_API_WRITE(priv, MXL862XX_EXTENDEDVLAN_SET, cfg);
865 }
866 
867 static int mxl862xx_evlan_write_final_rules(struct mxl862xx_priv *priv,
868 					    struct mxl862xx_evlan_block *blk,
869 					    const struct mxl862xx_evlan_rule_desc *rules,
870 					    int n_rules, u16 pvid)
871 {
872 	u16 start_idx = blk->block_size - n_rules;
873 	int i, ret;
874 
875 	for (i = 0; i < n_rules; i++) {
876 		ret = mxl862xx_evlan_write_rule(priv, blk->block_id,
877 						start_idx + i, &rules[i],
878 						0, false, pvid);
879 		if (ret)
880 			return ret;
881 	}
882 
883 	return 0;
884 }
885 
886 static int mxl862xx_vf_entry_set(struct mxl862xx_priv *priv,
887 				 u16 block_id, u16 index, u16 vid)
888 {
889 	struct mxl862xx_vlanfilter_config cfg = {};
890 
891 	cfg.vlan_filter_block_id = cpu_to_le16(block_id);
892 	cfg.entry_index = cpu_to_le16(index);
893 	cfg.vlan_filter_mask = cpu_to_le32(MXL862XX_VLAN_FILTER_TCI_MASK_VID);
894 	cfg.val = cpu_to_le32(vid);
895 	cfg.discard_matched = 0;
896 
897 	return MXL862XX_API_WRITE(priv, MXL862XX_VLANFILTER_SET, cfg);
898 }
899 
900 static struct mxl862xx_vf_vid *mxl862xx_vf_find_vid(struct mxl862xx_vf_block *vf,
901 						    u16 vid)
902 {
903 	struct mxl862xx_vf_vid *ve;
904 
905 	list_for_each_entry(ve, &vf->vids, list)
906 		if (ve->vid == vid)
907 			return ve;
908 
909 	return NULL;
910 }
911 
912 static int mxl862xx_vf_add_vid(struct mxl862xx_priv *priv,
913 			       struct mxl862xx_vf_block *vf,
914 			       u16 vid, bool untagged)
915 {
916 	struct mxl862xx_vf_vid *ve;
917 	int ret;
918 
919 	ve = mxl862xx_vf_find_vid(vf, vid);
920 	if (ve) {
921 		ve->untagged = untagged;
922 		return 0;
923 	}
924 
925 	if (vf->active_count >= vf->block_size)
926 		return -ENOSPC;
927 
928 	ve = kzalloc_obj(*ve);
929 	if (!ve)
930 		return -ENOMEM;
931 
932 	ve->vid = vid;
933 	ve->index = vf->active_count;
934 	ve->untagged = untagged;
935 
936 	ret = mxl862xx_vf_entry_set(priv, vf->block_id, ve->index, vid);
937 	if (ret) {
938 		kfree(ve);
939 		return ret;
940 	}
941 
942 	list_add_tail(&ve->list, &vf->vids);
943 	vf->active_count++;
944 
945 	return 0;
946 }
947 
948 static int mxl862xx_vf_del_vid(struct mxl862xx_priv *priv,
949 			       struct mxl862xx_vf_block *vf, u16 vid)
950 {
951 	struct mxl862xx_vf_vid *ve, *last_ve;
952 	u16 gap, last;
953 	int ret;
954 
955 	ve = mxl862xx_vf_find_vid(vf, vid);
956 	if (!ve)
957 		return 0;
958 
959 	if (!vf->allocated) {
960 		/* Software-only state -- just remove the tracking entry */
961 		list_del(&ve->list);
962 		kfree(ve);
963 		vf->active_count--;
964 		return 0;
965 	}
966 
967 	gap = ve->index;
968 	last = vf->active_count - 1;
969 
970 	if (vf->active_count == 1) {
971 		/* Last VID -- restore DISCARD sentinel at index 0 */
972 		ret = mxl862xx_vf_entry_discard(priv, vf->block_id, 0);
973 		if (ret)
974 			return ret;
975 	} else if (gap < last) {
976 		/* Swap: move the last ALLOW entry into the gap */
977 		list_for_each_entry(last_ve, &vf->vids, list)
978 			if (last_ve->index == last)
979 				break;
980 
981 		if (WARN_ON(list_entry_is_head(last_ve, &vf->vids, list)))
982 			return -EINVAL;
983 
984 		ret = mxl862xx_vf_entry_set(priv, vf->block_id,
985 					    gap, last_ve->vid);
986 		if (ret)
987 			return ret;
988 
989 		last_ve->index = gap;
990 	}
991 
992 	list_del(&ve->list);
993 	kfree(ve);
994 	vf->active_count--;
995 
996 	return 0;
997 }
998 
999 static int mxl862xx_evlan_program_ingress(struct mxl862xx_priv *priv, int port)
1000 {
1001 	struct mxl862xx_port *p = &priv->ports[port];
1002 	struct mxl862xx_evlan_block *blk = &p->ingress_evlan;
1003 
1004 	if (!p->vlan_filtering)
1005 		return 0;
1006 
1007 	blk->in_use = true;
1008 	blk->n_active = blk->block_size;
1009 
1010 	return mxl862xx_evlan_write_final_rules(priv, blk,
1011 						ingress_aware_final,
1012 						ARRAY_SIZE(ingress_aware_final),
1013 						p->pvid);
1014 }
1015 
1016 static int mxl862xx_evlan_program_egress(struct mxl862xx_priv *priv, int port)
1017 {
1018 	struct mxl862xx_port *p = &priv->ports[port];
1019 	struct mxl862xx_evlan_block *blk = &p->egress_evlan;
1020 	const struct mxl862xx_evlan_rule_desc *vid_rules;
1021 	struct mxl862xx_vf_vid *vfv;
1022 	u16 old_active = blk->n_active;
1023 	u16 idx = 0, i;
1024 	int n_vid, ret;
1025 
1026 	if (p->vlan_filtering) {
1027 		vid_rules = vid_accept_standard;
1028 		n_vid = ARRAY_SIZE(vid_accept_standard);
1029 	} else {
1030 		vid_rules = vid_accept_egress_unaware;
1031 		n_vid = ARRAY_SIZE(vid_accept_egress_unaware);
1032 	}
1033 
1034 	list_for_each_entry(vfv, &p->vf.vids, list) {
1035 		if (!vfv->untagged)
1036 			continue;
1037 
1038 		if (idx + n_vid > blk->block_size)
1039 			return -ENOSPC;
1040 
1041 		ret = mxl862xx_evlan_write_rule(priv, blk->block_id,
1042 						idx++, &vid_rules[0],
1043 						vfv->vid, vfv->untagged,
1044 						p->pvid);
1045 		if (ret)
1046 			return ret;
1047 
1048 		if (n_vid > 1) {
1049 			ret = mxl862xx_evlan_write_rule(priv, blk->block_id,
1050 							idx++, &vid_rules[1],
1051 							vfv->vid,
1052 							vfv->untagged,
1053 							p->pvid);
1054 			if (ret)
1055 				return ret;
1056 		}
1057 	}
1058 
1059 	/* Deactivate stale entries that are no longer needed.
1060 	 * This closes the brief window between writing the new rules
1061 	 * and set_bridge_port narrowing the scan window.
1062 	 */
1063 	for (i = idx; i < old_active; i++) {
1064 		ret = mxl862xx_evlan_deactivate_entry(priv,
1065 						      blk->block_id,
1066 						      i);
1067 		if (ret)
1068 			return ret;
1069 	}
1070 
1071 	blk->n_active = idx;
1072 	blk->in_use = idx > 0;
1073 
1074 	return 0;
1075 }
1076 
1077 static int mxl862xx_port_vlan_filtering(struct dsa_switch *ds, int port,
1078 					bool vlan_filtering,
1079 					struct netlink_ext_ack *extack)
1080 {
1081 	struct mxl862xx_priv *priv = ds->priv;
1082 	struct mxl862xx_port *p = &priv->ports[port];
1083 	bool old_vlan_filtering = p->vlan_filtering;
1084 	bool old_in_use = p->ingress_evlan.in_use;
1085 	bool changed = (p->vlan_filtering != vlan_filtering);
1086 	int ret;
1087 
1088 	p->vlan_filtering = vlan_filtering;
1089 
1090 	if (changed) {
1091 		/* When leaving VLAN-aware mode, release the ingress HW
1092 		 * block. The firmware passes frames through unchanged
1093 		 * when no ingress EVLAN block is assigned, so the block
1094 		 * is unnecessary in unaware mode.
1095 		 */
1096 		if (!vlan_filtering)
1097 			p->ingress_evlan.in_use = false;
1098 
1099 		ret = mxl862xx_evlan_program_ingress(priv, port);
1100 		if (ret)
1101 			goto err_restore;
1102 
1103 		ret = mxl862xx_evlan_program_egress(priv, port);
1104 		if (ret)
1105 			goto err_restore;
1106 	}
1107 
1108 	return mxl862xx_set_bridge_port(ds, port);
1109 
1110 	/* No HW rollback -- restoring SW state is sufficient for a correct retry. */
1111 err_restore:
1112 	p->vlan_filtering = old_vlan_filtering;
1113 	p->ingress_evlan.in_use = old_in_use;
1114 	return ret;
1115 }
1116 
1117 static int mxl862xx_port_vlan_add(struct dsa_switch *ds, int port,
1118 				  const struct switchdev_obj_port_vlan *vlan,
1119 				  struct netlink_ext_ack *extack)
1120 {
1121 	struct mxl862xx_priv *priv = ds->priv;
1122 	struct mxl862xx_port *p = &priv->ports[port];
1123 	bool untagged = !!(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED);
1124 	u16 vid = vlan->vid;
1125 	u16 old_pvid = p->pvid;
1126 	bool pvid_changed = false;
1127 	int ret;
1128 
1129 	/* CPU port is VLAN-transparent: the SP tag handles port
1130 	 * identification and the host-side DSA tagger manages VLAN
1131 	 * delivery. Egress EVLAN catchalls are set up once in
1132 	 * setup_cpu_bridge; no per-VID VF/EVLAN programming needed.
1133 	 */
1134 	if (dsa_is_cpu_port(ds, port))
1135 		return 0;
1136 
1137 	/* Update PVID tracking */
1138 	if (vlan->flags & BRIDGE_VLAN_INFO_PVID) {
1139 		if (p->pvid != vid) {
1140 			p->pvid = vid;
1141 			pvid_changed = true;
1142 		}
1143 	} else if (p->pvid == vid) {
1144 		p->pvid = 0;
1145 		pvid_changed = true;
1146 	}
1147 
1148 	/* Add/update VID in this port's VLAN Filter block.
1149 	 * VF must be updated before programming egress EVLAN because
1150 	 * evlan_program_egress walks the VF VID list.
1151 	 */
1152 	ret = mxl862xx_vf_add_vid(priv, &p->vf, vid, untagged);
1153 	if (ret)
1154 		goto err_pvid;
1155 
1156 	/* Reprogram ingress finals if PVID changed */
1157 	if (pvid_changed) {
1158 		ret = mxl862xx_evlan_program_ingress(priv, port);
1159 		if (ret)
1160 			goto err_rollback;
1161 	}
1162 
1163 	/* Reprogram egress tag-stripping rules (walks VF VID list) */
1164 	ret = mxl862xx_evlan_program_egress(priv, port);
1165 	if (ret)
1166 		goto err_rollback;
1167 
1168 	/* Apply VLAN block IDs and MAC learning flags to bridge port */
1169 	ret = mxl862xx_set_bridge_port(ds, port);
1170 	if (ret)
1171 		goto err_rollback;
1172 
1173 	return 0;
1174 
1175 err_rollback:
1176 	/* Best-effort: undo VF add and restore consistent hardware state.
1177 	 * A retry of port_vlan_add will converge since vf_add_vid is
1178 	 * idempotent.
1179 	 */
1180 	p->pvid = old_pvid;
1181 	mxl862xx_vf_del_vid(priv, &p->vf, vid);
1182 	mxl862xx_evlan_program_ingress(priv, port);
1183 	mxl862xx_evlan_program_egress(priv, port);
1184 	mxl862xx_set_bridge_port(ds, port);
1185 	return ret;
1186 err_pvid:
1187 	p->pvid = old_pvid;
1188 	return ret;
1189 }
1190 
1191 static int mxl862xx_port_vlan_del(struct dsa_switch *ds, int port,
1192 				  const struct switchdev_obj_port_vlan *vlan)
1193 {
1194 	struct mxl862xx_priv *priv = ds->priv;
1195 	struct mxl862xx_port *p = &priv->ports[port];
1196 	struct mxl862xx_vf_vid *ve;
1197 	bool pvid_changed = false;
1198 	u16 vid = vlan->vid;
1199 	bool old_untagged;
1200 	u16 old_pvid;
1201 	int ret;
1202 
1203 	if (dsa_is_cpu_port(ds, port))
1204 		return 0;
1205 
1206 	ve = mxl862xx_vf_find_vid(&p->vf, vid);
1207 	if (!ve)
1208 		return 0;
1209 	old_untagged = ve->untagged;
1210 	old_pvid = p->pvid;
1211 
1212 	/* Clear PVID if we're deleting it */
1213 	if (p->pvid == vid) {
1214 		p->pvid = 0;
1215 		pvid_changed = true;
1216 	}
1217 
1218 	/* Remove VID from this port's VLAN Filter block.
1219 	 * Must happen before egress reprogram so the VID is no
1220 	 * longer in the list that evlan_program_egress walks.
1221 	 */
1222 	ret = mxl862xx_vf_del_vid(priv, &p->vf, vid);
1223 	if (ret)
1224 		goto err_pvid;
1225 
1226 	/* Reprogram egress tag-stripping rules (VID is now gone) */
1227 	ret = mxl862xx_evlan_program_egress(priv, port);
1228 	if (ret)
1229 		goto err_rollback;
1230 
1231 	/* If PVID changed, reprogram ingress finals */
1232 	if (pvid_changed) {
1233 		ret = mxl862xx_evlan_program_ingress(priv, port);
1234 		if (ret)
1235 			goto err_rollback;
1236 	}
1237 
1238 	ret = mxl862xx_set_bridge_port(ds, port);
1239 	if (ret)
1240 		goto err_rollback;
1241 
1242 	return 0;
1243 
1244 err_rollback:
1245 	/* Best-effort: re-add the VID and restore consistent hardware
1246 	 * state. A retry of port_vlan_del will converge.
1247 	 */
1248 	p->pvid = old_pvid;
1249 	mxl862xx_vf_add_vid(priv, &p->vf, vid, old_untagged);
1250 	mxl862xx_evlan_program_egress(priv, port);
1251 	mxl862xx_evlan_program_ingress(priv, port);
1252 	mxl862xx_set_bridge_port(ds, port);
1253 	return ret;
1254 err_pvid:
1255 	p->pvid = old_pvid;
1256 	return ret;
1257 }
1258 
1259 static int mxl862xx_setup_cpu_bridge(struct dsa_switch *ds, int port)
1260 {
1261 	struct mxl862xx_priv *priv = ds->priv;
1262 	struct mxl862xx_port *p = &priv->ports[port];
1263 
1264 	p->fid = MXL862XX_DEFAULT_BRIDGE;
1265 	p->learning = true;
1266 
1267 	/* EVLAN is left disabled on CPU ports -- frames pass through
1268 	 * without EVLAN processing. Only the portmap and bridge
1269 	 * assignment need to be configured.
1270 	 */
1271 
1272 	return mxl862xx_set_bridge_port(ds, port);
1273 }
1274 
1275 static int mxl862xx_port_bridge_join(struct dsa_switch *ds, int port,
1276 				     const struct dsa_bridge bridge,
1277 				     bool *tx_fwd_offload,
1278 				     struct netlink_ext_ack *extack)
1279 {
1280 	struct mxl862xx_priv *priv = ds->priv;
1281 	int ret;
1282 
1283 	if (!priv->bridges[bridge.num]) {
1284 		ret = mxl862xx_allocate_bridge(priv);
1285 		if (ret < 0)
1286 			return ret;
1287 
1288 		priv->bridges[bridge.num] = ret;
1289 
1290 		/* Free bridge here on error, DSA rollback won't. */
1291 		ret = mxl862xx_sync_bridge_members(ds, &bridge);
1292 		if (ret) {
1293 			mxl862xx_free_bridge(ds, &bridge);
1294 			return ret;
1295 		}
1296 
1297 		return 0;
1298 	}
1299 
1300 	return mxl862xx_sync_bridge_members(ds, &bridge);
1301 }
1302 
1303 static void mxl862xx_port_bridge_leave(struct dsa_switch *ds, int port,
1304 				       const struct dsa_bridge bridge)
1305 {
1306 	struct mxl862xx_priv *priv = ds->priv;
1307 	struct mxl862xx_port *p = &priv->ports[port];
1308 	int err;
1309 
1310 	err = mxl862xx_sync_bridge_members(ds, &bridge);
1311 	if (err)
1312 		dev_err(ds->dev,
1313 			"failed to sync bridge members after port %d left: %pe\n",
1314 			port, ERR_PTR(err));
1315 
1316 	/* Revert leaving port, omitted by the sync above, to its
1317 	 * single-port bridge
1318 	 */
1319 	p->pvid = 0;
1320 	p->ingress_evlan.in_use = false;
1321 	p->egress_evlan.in_use = false;
1322 
1323 	err = mxl862xx_set_bridge_port(ds, port);
1324 	if (err)
1325 		dev_err(ds->dev,
1326 			"failed to update bridge port %d state: %pe\n", port,
1327 			ERR_PTR(err));
1328 
1329 	if (!dsa_bridge_ports(ds, bridge.dev))
1330 		mxl862xx_free_bridge(ds, &bridge);
1331 }
1332 
1333 static int mxl862xx_port_setup(struct dsa_switch *ds, int port)
1334 {
1335 	struct mxl862xx_priv *priv = ds->priv;
1336 	struct dsa_port *dp = dsa_to_port(ds, port);
1337 	bool is_cpu_port = dsa_port_is_cpu(dp);
1338 	int ret;
1339 
1340 	ret = mxl862xx_port_state(ds, port, false);
1341 	if (ret)
1342 		return ret;
1343 
1344 	mxl862xx_port_fast_age(ds, port);
1345 
1346 	if (dsa_port_is_unused(dp))
1347 		return 0;
1348 
1349 	if (dsa_port_is_dsa(dp)) {
1350 		dev_err(ds->dev, "port %d: DSA links not supported\n", port);
1351 		return -EOPNOTSUPP;
1352 	}
1353 
1354 	ret = mxl862xx_configure_sp_tag_proto(ds, port, is_cpu_port);
1355 	if (ret)
1356 		return ret;
1357 
1358 	ret = mxl862xx_configure_ctp_port(ds, port, port,
1359 					  is_cpu_port ? 32 - port : 1);
1360 	if (ret)
1361 		return ret;
1362 
1363 	if (is_cpu_port)
1364 		return mxl862xx_setup_cpu_bridge(ds, port);
1365 
1366 	/* setup single-port bridge for user ports.
1367 	 * If this fails, the FID is leaked -- but the port then transitions
1368 	 * to unused, and the FID pool is sized to tolerate this.
1369 	 */
1370 	ret = mxl862xx_allocate_bridge(priv);
1371 	if (ret < 0) {
1372 		dev_err(ds->dev, "failed to allocate a bridge for port %d\n", port);
1373 		return ret;
1374 	}
1375 	priv->ports[port].fid = ret;
1376 	/* Standalone ports should not flood unknown unicast or multicast
1377 	 * towards the CPU by default; only broadcast is needed initially.
1378 	 */
1379 	ret = mxl862xx_bridge_config_fwd(ds, priv->ports[port].fid,
1380 					 false, false, true);
1381 	if (ret)
1382 		return ret;
1383 	ret = mxl862xx_set_bridge_port(ds, port);
1384 	if (ret)
1385 		return ret;
1386 
1387 	priv->ports[port].ingress_evlan.block_size = priv->evlan_ingress_size;
1388 	ret = mxl862xx_evlan_block_alloc(priv, &priv->ports[port].ingress_evlan);
1389 	if (ret)
1390 		return ret;
1391 
1392 	priv->ports[port].egress_evlan.block_size = priv->evlan_egress_size;
1393 	ret = mxl862xx_evlan_block_alloc(priv, &priv->ports[port].egress_evlan);
1394 	if (ret)
1395 		return ret;
1396 
1397 	priv->ports[port].vf.block_size = priv->vf_block_size;
1398 	INIT_LIST_HEAD(&priv->ports[port].vf.vids);
1399 	ret = mxl862xx_vf_alloc(priv, &priv->ports[port].vf);
1400 	if (ret)
1401 		return ret;
1402 
1403 	priv->ports[port].setup_done = true;
1404 
1405 	return 0;
1406 }
1407 
1408 static void mxl862xx_port_teardown(struct dsa_switch *ds, int port)
1409 {
1410 	struct mxl862xx_priv *priv = ds->priv;
1411 	struct dsa_port *dp = dsa_to_port(ds, port);
1412 
1413 	if (dsa_port_is_unused(dp))
1414 		return;
1415 
1416 	/* Prevent deferred host_flood_work from acting on stale state.
1417 	 * The flag is checked under rtnl_lock() by the worker; since
1418 	 * teardown also runs under RTNL, this is race-free.
1419 	 *
1420 	 * HW EVLAN/VF blocks are not freed here -- the firmware receives
1421 	 * a full reset on the next probe, which reclaims all resources.
1422 	 */
1423 	priv->ports[port].setup_done = false;
1424 }
1425 
1426 static int mxl862xx_get_fid(struct dsa_switch *ds, struct dsa_db db)
1427 {
1428 	struct mxl862xx_priv *priv = ds->priv;
1429 
1430 	switch (db.type) {
1431 	case DSA_DB_PORT:
1432 		return priv->ports[db.dp->index].fid;
1433 
1434 	case DSA_DB_BRIDGE:
1435 		if (!priv->bridges[db.bridge.num])
1436 			return -ENOENT;
1437 		return priv->bridges[db.bridge.num];
1438 
1439 	default:
1440 		return -EOPNOTSUPP;
1441 	}
1442 }
1443 
1444 static int mxl862xx_port_fdb_add(struct dsa_switch *ds, int port,
1445 				 const unsigned char *addr, u16 vid, struct dsa_db db)
1446 {
1447 	struct mxl862xx_mac_table_add param = {};
1448 	int fid = mxl862xx_get_fid(ds, db), ret;
1449 	struct mxl862xx_priv *priv = ds->priv;
1450 
1451 	if (fid < 0)
1452 		return fid;
1453 
1454 	param.port_id = cpu_to_le32(port);
1455 	param.static_entry = true;
1456 	param.fid = cpu_to_le16(fid);
1457 	param.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, vid));
1458 	ether_addr_copy(param.mac, addr);
1459 
1460 	ret = MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYADD, param);
1461 	if (ret)
1462 		dev_err(ds->dev, "failed to add FDB entry on port %d\n", port);
1463 
1464 	return ret;
1465 }
1466 
1467 static int mxl862xx_port_fdb_del(struct dsa_switch *ds, int port,
1468 				 const unsigned char *addr, u16 vid, const struct dsa_db db)
1469 {
1470 	struct mxl862xx_mac_table_remove param = {};
1471 	int fid = mxl862xx_get_fid(ds, db), ret;
1472 	struct mxl862xx_priv *priv = ds->priv;
1473 
1474 	if (fid < 0)
1475 		return fid;
1476 
1477 	param.fid = cpu_to_le16(fid);
1478 	param.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, vid));
1479 	ether_addr_copy(param.mac, addr);
1480 
1481 	ret = MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYREMOVE, param);
1482 	if (ret)
1483 		dev_err(ds->dev, "failed to remove FDB entry on port %d\n", port);
1484 
1485 	return ret;
1486 }
1487 
1488 static int mxl862xx_port_fdb_dump(struct dsa_switch *ds, int port,
1489 				  dsa_fdb_dump_cb_t *cb, void *data)
1490 {
1491 	struct mxl862xx_mac_table_read param = { .initial = 1 };
1492 	struct mxl862xx_priv *priv = ds->priv;
1493 	u32 entry_port_id;
1494 	int ret;
1495 
1496 	while (true) {
1497 		ret = MXL862XX_API_READ(priv, MXL862XX_MAC_TABLEENTRYREAD, param);
1498 		if (ret)
1499 			return ret;
1500 
1501 		if (param.last)
1502 			break;
1503 
1504 		entry_port_id = le32_to_cpu(param.port_id);
1505 
1506 		if (entry_port_id == port) {
1507 			ret = cb(param.mac, FIELD_GET(MXL862XX_TCI_VLAN_ID,
1508 						      le16_to_cpu(param.tci)),
1509 				 param.static_entry, data);
1510 			if (ret)
1511 				return ret;
1512 		}
1513 
1514 		memset(&param, 0, sizeof(param));
1515 	}
1516 
1517 	return 0;
1518 }
1519 
1520 static int mxl862xx_port_mdb_add(struct dsa_switch *ds, int port,
1521 				 const struct switchdev_obj_port_mdb *mdb,
1522 				 const struct dsa_db db)
1523 {
1524 	struct mxl862xx_mac_table_query qparam = {};
1525 	struct mxl862xx_mac_table_add aparam = {};
1526 	struct mxl862xx_priv *priv = ds->priv;
1527 	int fid, ret;
1528 
1529 	fid = mxl862xx_get_fid(ds, db);
1530 	if (fid < 0)
1531 		return fid;
1532 
1533 	ether_addr_copy(qparam.mac, mdb->addr);
1534 	qparam.fid = cpu_to_le16(fid);
1535 	qparam.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, mdb->vid));
1536 
1537 	ret = MXL862XX_API_READ(priv, MXL862XX_MAC_TABLEENTRYQUERY, qparam);
1538 	if (ret)
1539 		return ret;
1540 
1541 	/* Build the ADD command using portmap mode */
1542 	ether_addr_copy(aparam.mac, mdb->addr);
1543 	aparam.fid = cpu_to_le16(fid);
1544 	aparam.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, mdb->vid));
1545 	aparam.static_entry = true;
1546 	aparam.port_id = cpu_to_le32(MXL862XX_PORTMAP_FLAG);
1547 
1548 	if (qparam.found)
1549 		memcpy(aparam.port_map, qparam.port_map,
1550 		       sizeof(aparam.port_map));
1551 
1552 	mxl862xx_fw_portmap_set_bit(aparam.port_map, port);
1553 
1554 	return MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYADD, aparam);
1555 }
1556 
1557 static int mxl862xx_port_mdb_del(struct dsa_switch *ds, int port,
1558 				 const struct switchdev_obj_port_mdb *mdb,
1559 				 const struct dsa_db db)
1560 {
1561 	struct mxl862xx_mac_table_remove rparam = {};
1562 	struct mxl862xx_mac_table_query qparam = {};
1563 	struct mxl862xx_mac_table_add aparam = {};
1564 	int fid = mxl862xx_get_fid(ds, db), ret;
1565 	struct mxl862xx_priv *priv = ds->priv;
1566 
1567 	if (fid < 0)
1568 		return fid;
1569 
1570 	qparam.fid = cpu_to_le16(fid);
1571 	qparam.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, mdb->vid));
1572 	ether_addr_copy(qparam.mac, mdb->addr);
1573 
1574 	ret = MXL862XX_API_READ(priv, MXL862XX_MAC_TABLEENTRYQUERY, qparam);
1575 	if (ret)
1576 		return ret;
1577 
1578 	if (!qparam.found)
1579 		return 0;
1580 
1581 	mxl862xx_fw_portmap_clear_bit(qparam.port_map, port);
1582 
1583 	if (mxl862xx_fw_portmap_is_empty(qparam.port_map)) {
1584 		rparam.fid = cpu_to_le16(fid);
1585 		rparam.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, mdb->vid));
1586 		ether_addr_copy(rparam.mac, mdb->addr);
1587 		ret = MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYREMOVE, rparam);
1588 	} else {
1589 		/* Write back with reduced portmap */
1590 		aparam.fid = cpu_to_le16(fid);
1591 		aparam.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, mdb->vid));
1592 		ether_addr_copy(aparam.mac, mdb->addr);
1593 		aparam.static_entry = true;
1594 		aparam.port_id = cpu_to_le32(MXL862XX_PORTMAP_FLAG);
1595 		memcpy(aparam.port_map, qparam.port_map, sizeof(aparam.port_map));
1596 		ret = MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYADD, aparam);
1597 	}
1598 
1599 	return ret;
1600 }
1601 
1602 static int mxl862xx_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
1603 {
1604 	struct mxl862xx_cfg param = {};
1605 	int ret;
1606 
1607 	ret = MXL862XX_API_READ(ds->priv, MXL862XX_COMMON_CFGGET, param);
1608 	if (ret) {
1609 		dev_err(ds->dev, "failed to read switch config\n");
1610 		return ret;
1611 	}
1612 
1613 	param.mac_table_age_timer = cpu_to_le32(MXL862XX_AGETIMER_CUSTOM);
1614 	param.age_timer = cpu_to_le32(msecs / 1000);
1615 	ret = MXL862XX_API_WRITE(ds->priv, MXL862XX_COMMON_CFGSET, param);
1616 	if (ret)
1617 		dev_err(ds->dev, "failed to set ageing\n");
1618 
1619 	return ret;
1620 }
1621 
1622 static void mxl862xx_port_stp_state_set(struct dsa_switch *ds, int port,
1623 					u8 state)
1624 {
1625 	struct mxl862xx_stp_port_cfg param = {
1626 		.port_id = cpu_to_le16(port),
1627 	};
1628 	struct mxl862xx_priv *priv = ds->priv;
1629 	int ret;
1630 
1631 	switch (state) {
1632 	case BR_STATE_DISABLED:
1633 		param.port_state = cpu_to_le32(MXL862XX_STP_PORT_STATE_DISABLE);
1634 		break;
1635 	case BR_STATE_BLOCKING:
1636 	case BR_STATE_LISTENING:
1637 		param.port_state = cpu_to_le32(MXL862XX_STP_PORT_STATE_BLOCKING);
1638 		break;
1639 	case BR_STATE_LEARNING:
1640 		param.port_state = cpu_to_le32(MXL862XX_STP_PORT_STATE_LEARNING);
1641 		break;
1642 	case BR_STATE_FORWARDING:
1643 		param.port_state = cpu_to_le32(MXL862XX_STP_PORT_STATE_FORWARD);
1644 		break;
1645 	default:
1646 		dev_err(ds->dev, "invalid STP state: %d\n", state);
1647 		return;
1648 	}
1649 
1650 	ret = MXL862XX_API_WRITE(priv, MXL862XX_STP_PORTCFGSET, param);
1651 	if (ret) {
1652 		dev_err(ds->dev, "failed to set STP state on port %d\n", port);
1653 		return;
1654 	}
1655 
1656 	/* The firmware may re-enable MAC learning as a side-effect of entering
1657 	 * LEARNING or FORWARDING state (per 802.1D defaults).
1658 	 * Re-apply the driver's intended learning and metering config so that
1659 	 * standalone ports keep learning disabled.
1660 	 */
1661 	ret = mxl862xx_set_bridge_port(ds, port);
1662 	if (ret)
1663 		dev_err(ds->dev, "failed to reapply brport flags on port %d\n",
1664 			port);
1665 
1666 	mxl862xx_port_fast_age(ds, port);
1667 }
1668 
1669 /* Deferred work handler for host flood configuration.
1670  *
1671  * port_set_host_flood is called from atomic context (under
1672  * netif_addr_lock), so firmware calls must be deferred. The worker
1673  * acquires rtnl_lock() to serialize with DSA callbacks that access the
1674  * same driver state.
1675  */
1676 static void mxl862xx_host_flood_work_fn(struct work_struct *work)
1677 {
1678 	struct mxl862xx_port *p = container_of(work, struct mxl862xx_port,
1679 					       host_flood_work);
1680 	struct mxl862xx_priv *priv = p->priv;
1681 	struct dsa_switch *ds = priv->ds;
1682 
1683 	rtnl_lock();
1684 
1685 	/* Port may have been torn down between scheduling and now. */
1686 	if (!p->setup_done) {
1687 		rtnl_unlock();
1688 		return;
1689 	}
1690 
1691 	/* Always write to the standalone FID. When standalone it takes effect
1692 	 * immediately; when bridged the port uses the shared bridge FID so the
1693 	 * write is a no-op for current forwarding, but the state is preserved
1694 	 * in hardware and is ready once the port returns to standalone.
1695 	 */
1696 	mxl862xx_bridge_config_fwd(ds, p->fid, p->host_flood_uc,
1697 				   p->host_flood_mc, true);
1698 
1699 	rtnl_unlock();
1700 }
1701 
1702 static void mxl862xx_port_set_host_flood(struct dsa_switch *ds, int port,
1703 					 bool uc, bool mc)
1704 {
1705 	struct mxl862xx_priv *priv = ds->priv;
1706 	struct mxl862xx_port *p = &priv->ports[port];
1707 
1708 	p->host_flood_uc = uc;
1709 	p->host_flood_mc = mc;
1710 	schedule_work(&p->host_flood_work);
1711 }
1712 
1713 static int mxl862xx_port_pre_bridge_flags(struct dsa_switch *ds, int port,
1714 					  const struct switchdev_brport_flags flags,
1715 					  struct netlink_ext_ack *extack)
1716 {
1717 	if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD |
1718 			   BR_LEARNING))
1719 		return -EINVAL;
1720 
1721 	return 0;
1722 }
1723 
1724 static int mxl862xx_port_bridge_flags(struct dsa_switch *ds, int port,
1725 				      const struct switchdev_brport_flags flags,
1726 				      struct netlink_ext_ack *extack)
1727 {
1728 	struct mxl862xx_priv *priv = ds->priv;
1729 	unsigned long old_block = priv->ports[port].flood_block;
1730 	unsigned long block = old_block;
1731 	int ret;
1732 
1733 	if (flags.mask & BR_FLOOD) {
1734 		if (flags.val & BR_FLOOD)
1735 			block &= ~BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC);
1736 		else
1737 			block |= BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC);
1738 	}
1739 
1740 	if (flags.mask & BR_MCAST_FLOOD) {
1741 		if (flags.val & BR_MCAST_FLOOD) {
1742 			block &= ~BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP);
1743 			block &= ~BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP);
1744 		} else {
1745 			block |= BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP);
1746 			block |= BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP);
1747 		}
1748 	}
1749 
1750 	if (flags.mask & BR_BCAST_FLOOD) {
1751 		if (flags.val & BR_BCAST_FLOOD)
1752 			block &= ~BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_BROADCAST);
1753 		else
1754 			block |= BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_BROADCAST);
1755 	}
1756 
1757 	if (flags.mask & BR_LEARNING)
1758 		priv->ports[port].learning = !!(flags.val & BR_LEARNING);
1759 
1760 	if (block != old_block || (flags.mask & BR_LEARNING)) {
1761 		priv->ports[port].flood_block = block;
1762 		ret = mxl862xx_set_bridge_port(ds, port);
1763 		if (ret)
1764 			return ret;
1765 	}
1766 
1767 	return 0;
1768 }
1769 
1770 static void mxl862xx_get_strings(struct dsa_switch *ds, int port,
1771 				 u32 stringset, u8 *data)
1772 {
1773 	int i;
1774 
1775 	if (stringset != ETH_SS_STATS)
1776 		return;
1777 
1778 	for (i = 0; i < ARRAY_SIZE(mxl862xx_mib); i++)
1779 		ethtool_puts(&data, mxl862xx_mib[i].name);
1780 }
1781 
1782 static int mxl862xx_get_sset_count(struct dsa_switch *ds, int port, int sset)
1783 {
1784 	if (sset != ETH_SS_STATS)
1785 		return 0;
1786 
1787 	return ARRAY_SIZE(mxl862xx_mib);
1788 }
1789 
1790 static int mxl862xx_read_rmon(struct dsa_switch *ds, int port,
1791 			      struct mxl862xx_rmon_port_cnt *cnt)
1792 {
1793 	memset(cnt, 0, sizeof(*cnt));
1794 	cnt->port_type = cpu_to_le32(MXL862XX_CTP_PORT);
1795 	cnt->port_id = cpu_to_le16(port);
1796 
1797 	return MXL862XX_API_READ(ds->priv, MXL862XX_RMON_PORT_GET, *cnt);
1798 }
1799 
1800 static void mxl862xx_get_ethtool_stats(struct dsa_switch *ds, int port,
1801 				       u64 *data)
1802 {
1803 	const struct mxl862xx_mib_desc *mib;
1804 	struct mxl862xx_rmon_port_cnt cnt;
1805 	int ret, i;
1806 	void *field;
1807 
1808 	ret = mxl862xx_read_rmon(ds, port, &cnt);
1809 	if (ret) {
1810 		dev_err(ds->dev, "failed to read RMON stats on port %d\n", port);
1811 		return;
1812 	}
1813 
1814 	for (i = 0; i < ARRAY_SIZE(mxl862xx_mib); i++) {
1815 		mib = &mxl862xx_mib[i];
1816 		field = (u8 *)&cnt + mib->offset;
1817 
1818 		if (mib->size == 1)
1819 			*data++ = le32_to_cpu(*(__le32 *)field);
1820 		else
1821 			*data++ = le64_to_cpu(*(__le64 *)field);
1822 	}
1823 }
1824 
1825 static void mxl862xx_get_eth_mac_stats(struct dsa_switch *ds, int port,
1826 				       struct ethtool_eth_mac_stats *mac_stats)
1827 {
1828 	struct mxl862xx_rmon_port_cnt cnt;
1829 
1830 	if (mxl862xx_read_rmon(ds, port, &cnt))
1831 		return;
1832 
1833 	mac_stats->FramesTransmittedOK = le32_to_cpu(cnt.tx_good_pkts);
1834 	mac_stats->SingleCollisionFrames = le32_to_cpu(cnt.tx_single_coll_count);
1835 	mac_stats->MultipleCollisionFrames = le32_to_cpu(cnt.tx_mult_coll_count);
1836 	mac_stats->FramesReceivedOK = le32_to_cpu(cnt.rx_good_pkts);
1837 	mac_stats->FrameCheckSequenceErrors = le32_to_cpu(cnt.rx_fcserror_pkts);
1838 	mac_stats->AlignmentErrors = le32_to_cpu(cnt.rx_align_error_pkts);
1839 	mac_stats->OctetsTransmittedOK = le64_to_cpu(cnt.tx_good_bytes);
1840 	mac_stats->LateCollisions = le32_to_cpu(cnt.tx_late_coll_count);
1841 	mac_stats->FramesAbortedDueToXSColls = le32_to_cpu(cnt.tx_excess_coll_count);
1842 	mac_stats->OctetsReceivedOK = le64_to_cpu(cnt.rx_good_bytes);
1843 	mac_stats->MulticastFramesXmittedOK = le32_to_cpu(cnt.tx_multicast_pkts);
1844 	mac_stats->BroadcastFramesXmittedOK = le32_to_cpu(cnt.tx_broadcast_pkts);
1845 	mac_stats->MulticastFramesReceivedOK = le32_to_cpu(cnt.rx_multicast_pkts);
1846 	mac_stats->BroadcastFramesReceivedOK = le32_to_cpu(cnt.rx_broadcast_pkts);
1847 	mac_stats->FrameTooLongErrors = le32_to_cpu(cnt.rx_oversize_error_pkts);
1848 }
1849 
1850 static void mxl862xx_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
1851 					struct ethtool_eth_ctrl_stats *ctrl_stats)
1852 {
1853 	struct mxl862xx_rmon_port_cnt cnt;
1854 
1855 	if (mxl862xx_read_rmon(ds, port, &cnt))
1856 		return;
1857 
1858 	ctrl_stats->MACControlFramesTransmitted = le32_to_cpu(cnt.tx_pause_count);
1859 	ctrl_stats->MACControlFramesReceived = le32_to_cpu(cnt.rx_good_pause_pkts);
1860 }
1861 
1862 static void mxl862xx_get_pause_stats(struct dsa_switch *ds, int port,
1863 				     struct ethtool_pause_stats *pause_stats)
1864 {
1865 	struct mxl862xx_rmon_port_cnt cnt;
1866 
1867 	if (mxl862xx_read_rmon(ds, port, &cnt))
1868 		return;
1869 
1870 	pause_stats->tx_pause_frames = le32_to_cpu(cnt.tx_pause_count);
1871 	pause_stats->rx_pause_frames = le32_to_cpu(cnt.rx_good_pause_pkts);
1872 }
1873 
1874 static void mxl862xx_get_rmon_stats(struct dsa_switch *ds, int port,
1875 				    struct ethtool_rmon_stats *rmon_stats,
1876 				    const struct ethtool_rmon_hist_range **ranges)
1877 {
1878 	struct mxl862xx_rmon_port_cnt cnt;
1879 
1880 	if (mxl862xx_read_rmon(ds, port, &cnt))
1881 		return;
1882 
1883 	rmon_stats->undersize_pkts = le32_to_cpu(cnt.rx_under_size_good_pkts);
1884 	rmon_stats->oversize_pkts = le32_to_cpu(cnt.rx_oversize_good_pkts);
1885 	rmon_stats->fragments = le32_to_cpu(cnt.rx_under_size_error_pkts);
1886 	rmon_stats->jabbers = le32_to_cpu(cnt.rx_oversize_error_pkts);
1887 
1888 	rmon_stats->hist[0] = le32_to_cpu(cnt.rx64byte_pkts);
1889 	rmon_stats->hist[1] = le32_to_cpu(cnt.rx127byte_pkts);
1890 	rmon_stats->hist[2] = le32_to_cpu(cnt.rx255byte_pkts);
1891 	rmon_stats->hist[3] = le32_to_cpu(cnt.rx511byte_pkts);
1892 	rmon_stats->hist[4] = le32_to_cpu(cnt.rx1023byte_pkts);
1893 	rmon_stats->hist[5] = le32_to_cpu(cnt.rx_max_byte_pkts);
1894 
1895 	rmon_stats->hist_tx[0] = le32_to_cpu(cnt.tx64byte_pkts);
1896 	rmon_stats->hist_tx[1] = le32_to_cpu(cnt.tx127byte_pkts);
1897 	rmon_stats->hist_tx[2] = le32_to_cpu(cnt.tx255byte_pkts);
1898 	rmon_stats->hist_tx[3] = le32_to_cpu(cnt.tx511byte_pkts);
1899 	rmon_stats->hist_tx[4] = le32_to_cpu(cnt.tx1023byte_pkts);
1900 	rmon_stats->hist_tx[5] = le32_to_cpu(cnt.tx_max_byte_pkts);
1901 
1902 	*ranges = mxl862xx_rmon_ranges;
1903 }
1904 
1905 /* Compute the delta between two 32-bit free-running counter snapshots,
1906  * handling a single wrap-around correctly via unsigned subtraction.
1907  */
1908 static u64 mxl862xx_delta32(u32 cur, u32 prev)
1909 {
1910 	return (u32)(cur - prev);
1911 }
1912 
1913 /**
1914  * mxl862xx_stats_poll - Read RMON counters and accumulate into 64-bit stats
1915  * @ds: DSA switch
1916  * @port: port index
1917  *
1918  * The firmware RMON counters are free-running 32-bit values (64-bit for
1919  * byte counters). This function reads the hardware via MDIO (may sleep),
1920  * computes deltas from the previous snapshot, and accumulates them into
1921  * 64-bit per-port stats under a spinlock.
1922  *
1923  * Called only from the stats polling workqueue -- serialized by the
1924  * single-threaded delayed_work, so no MDIO locking is needed here.
1925  */
1926 static void mxl862xx_stats_poll(struct dsa_switch *ds, int port)
1927 {
1928 	struct mxl862xx_priv *priv = ds->priv;
1929 	struct mxl862xx_port_stats *s = &priv->ports[port].stats;
1930 	u32 rx_fcserr, rx_under, rx_over, rx_align, tx_drop;
1931 	u32 rx_drop, rx_evlan, mtu_exc, tx_acm;
1932 	struct mxl862xx_rmon_port_cnt cnt;
1933 	u64 rx_bytes, tx_bytes;
1934 	u32 rx_mcast, tx_coll;
1935 	u32 rx_pkts, tx_pkts;
1936 
1937 	/* MDIO read -- may sleep, done outside the spinlock. */
1938 	if (mxl862xx_read_rmon(ds, port, &cnt))
1939 		return;
1940 
1941 	rx_pkts   = le32_to_cpu(cnt.rx_good_pkts);
1942 	tx_pkts   = le32_to_cpu(cnt.tx_good_pkts);
1943 	rx_bytes  = le64_to_cpu(cnt.rx_good_bytes);
1944 	tx_bytes  = le64_to_cpu(cnt.tx_good_bytes);
1945 	rx_fcserr = le32_to_cpu(cnt.rx_fcserror_pkts);
1946 	rx_under  = le32_to_cpu(cnt.rx_under_size_error_pkts);
1947 	rx_over   = le32_to_cpu(cnt.rx_oversize_error_pkts);
1948 	rx_align  = le32_to_cpu(cnt.rx_align_error_pkts);
1949 	tx_drop   = le32_to_cpu(cnt.tx_dropped_pkts);
1950 	rx_drop   = le32_to_cpu(cnt.rx_dropped_pkts);
1951 	rx_evlan  = le32_to_cpu(cnt.rx_extended_vlan_discard_pkts);
1952 	mtu_exc   = le32_to_cpu(cnt.mtu_exceed_discard_pkts);
1953 	tx_acm    = le32_to_cpu(cnt.tx_acm_dropped_pkts);
1954 	rx_mcast  = le32_to_cpu(cnt.rx_multicast_pkts);
1955 	tx_coll   = le32_to_cpu(cnt.tx_coll_count);
1956 
1957 	/* Accumulate deltas under spinlock -- .get_stats64 reads these. */
1958 	spin_lock_bh(&priv->ports[port].stats_lock);
1959 
1960 	s->rx_packets += mxl862xx_delta32(rx_pkts, s->prev_rx_good_pkts);
1961 	s->tx_packets += mxl862xx_delta32(tx_pkts, s->prev_tx_good_pkts);
1962 	s->rx_bytes   += rx_bytes - s->prev_rx_good_bytes;
1963 	s->tx_bytes   += tx_bytes - s->prev_tx_good_bytes;
1964 
1965 	s->rx_errors +=
1966 		mxl862xx_delta32(rx_fcserr, s->prev_rx_fcserror_pkts) +
1967 		mxl862xx_delta32(rx_under, s->prev_rx_under_size_error_pkts) +
1968 		mxl862xx_delta32(rx_over, s->prev_rx_oversize_error_pkts) +
1969 		mxl862xx_delta32(rx_align, s->prev_rx_align_error_pkts);
1970 	s->tx_errors +=
1971 		mxl862xx_delta32(tx_drop, s->prev_tx_dropped_pkts);
1972 
1973 	s->rx_dropped +=
1974 		mxl862xx_delta32(rx_drop, s->prev_rx_dropped_pkts) +
1975 		mxl862xx_delta32(rx_evlan, s->prev_rx_evlan_discard_pkts) +
1976 		mxl862xx_delta32(mtu_exc, s->prev_mtu_exceed_discard_pkts);
1977 	s->tx_dropped +=
1978 		mxl862xx_delta32(tx_drop, s->prev_tx_dropped_pkts) +
1979 		mxl862xx_delta32(tx_acm, s->prev_tx_acm_dropped_pkts);
1980 
1981 	s->multicast  += mxl862xx_delta32(rx_mcast, s->prev_rx_multicast_pkts);
1982 	s->collisions += mxl862xx_delta32(tx_coll, s->prev_tx_coll_count);
1983 
1984 	s->rx_length_errors +=
1985 		mxl862xx_delta32(rx_under, s->prev_rx_under_size_error_pkts) +
1986 		mxl862xx_delta32(rx_over, s->prev_rx_oversize_error_pkts);
1987 	s->rx_crc_errors +=
1988 		mxl862xx_delta32(rx_fcserr, s->prev_rx_fcserror_pkts);
1989 	s->rx_frame_errors +=
1990 		mxl862xx_delta32(rx_align, s->prev_rx_align_error_pkts);
1991 
1992 	s->prev_rx_good_pkts             = rx_pkts;
1993 	s->prev_tx_good_pkts             = tx_pkts;
1994 	s->prev_rx_good_bytes            = rx_bytes;
1995 	s->prev_tx_good_bytes            = tx_bytes;
1996 	s->prev_rx_fcserror_pkts         = rx_fcserr;
1997 	s->prev_rx_under_size_error_pkts = rx_under;
1998 	s->prev_rx_oversize_error_pkts   = rx_over;
1999 	s->prev_rx_align_error_pkts      = rx_align;
2000 	s->prev_tx_dropped_pkts          = tx_drop;
2001 	s->prev_rx_dropped_pkts          = rx_drop;
2002 	s->prev_rx_evlan_discard_pkts    = rx_evlan;
2003 	s->prev_mtu_exceed_discard_pkts  = mtu_exc;
2004 	s->prev_tx_acm_dropped_pkts      = tx_acm;
2005 	s->prev_rx_multicast_pkts        = rx_mcast;
2006 	s->prev_tx_coll_count            = tx_coll;
2007 
2008 	spin_unlock_bh(&priv->ports[port].stats_lock);
2009 }
2010 
2011 static void mxl862xx_stats_work_fn(struct work_struct *work)
2012 {
2013 	struct mxl862xx_priv *priv =
2014 		container_of(work, struct mxl862xx_priv, stats_work.work);
2015 	struct dsa_switch *ds = priv->ds;
2016 	struct dsa_port *dp;
2017 
2018 	dsa_switch_for_each_available_port(dp, ds)
2019 		mxl862xx_stats_poll(ds, dp->index);
2020 
2021 	if (!test_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags))
2022 		schedule_delayed_work(&priv->stats_work,
2023 				      MXL862XX_STATS_POLL_INTERVAL);
2024 }
2025 
2026 static void mxl862xx_get_stats64(struct dsa_switch *ds, int port,
2027 				 struct rtnl_link_stats64 *s)
2028 {
2029 	struct mxl862xx_priv *priv = ds->priv;
2030 	struct mxl862xx_port_stats *ps = &priv->ports[port].stats;
2031 
2032 	spin_lock_bh(&priv->ports[port].stats_lock);
2033 
2034 	s->rx_packets = ps->rx_packets;
2035 	s->tx_packets = ps->tx_packets;
2036 	s->rx_bytes = ps->rx_bytes;
2037 	s->tx_bytes = ps->tx_bytes;
2038 	s->rx_errors = ps->rx_errors;
2039 	s->tx_errors = ps->tx_errors;
2040 	s->rx_dropped = ps->rx_dropped;
2041 	s->tx_dropped = ps->tx_dropped;
2042 	s->multicast = ps->multicast;
2043 	s->collisions = ps->collisions;
2044 	s->rx_length_errors = ps->rx_length_errors;
2045 	s->rx_crc_errors = ps->rx_crc_errors;
2046 	s->rx_frame_errors = ps->rx_frame_errors;
2047 
2048 	spin_unlock_bh(&priv->ports[port].stats_lock);
2049 
2050 	/* Trigger a fresh poll so the next read sees up-to-date counters.
2051 	 * No-op if the work is already pending, running, or teardown started.
2052 	 */
2053 	if (!test_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags))
2054 		schedule_delayed_work(&priv->stats_work, 0);
2055 }
2056 
2057 static const struct dsa_switch_ops mxl862xx_switch_ops = {
2058 	.get_tag_protocol = mxl862xx_get_tag_protocol,
2059 	.setup = mxl862xx_setup,
2060 	.port_setup = mxl862xx_port_setup,
2061 	.port_teardown = mxl862xx_port_teardown,
2062 	.phylink_get_caps = mxl862xx_phylink_get_caps,
2063 	.port_enable = mxl862xx_port_enable,
2064 	.port_disable = mxl862xx_port_disable,
2065 	.port_fast_age = mxl862xx_port_fast_age,
2066 	.set_ageing_time = mxl862xx_set_ageing_time,
2067 	.port_bridge_join = mxl862xx_port_bridge_join,
2068 	.port_bridge_leave = mxl862xx_port_bridge_leave,
2069 	.port_pre_bridge_flags = mxl862xx_port_pre_bridge_flags,
2070 	.port_bridge_flags = mxl862xx_port_bridge_flags,
2071 	.port_stp_state_set = mxl862xx_port_stp_state_set,
2072 	.port_set_host_flood = mxl862xx_port_set_host_flood,
2073 	.port_fdb_add = mxl862xx_port_fdb_add,
2074 	.port_fdb_del = mxl862xx_port_fdb_del,
2075 	.port_fdb_dump = mxl862xx_port_fdb_dump,
2076 	.port_mdb_add = mxl862xx_port_mdb_add,
2077 	.port_mdb_del = mxl862xx_port_mdb_del,
2078 	.port_vlan_filtering = mxl862xx_port_vlan_filtering,
2079 	.port_vlan_add = mxl862xx_port_vlan_add,
2080 	.port_vlan_del = mxl862xx_port_vlan_del,
2081 	.get_strings = mxl862xx_get_strings,
2082 	.get_sset_count = mxl862xx_get_sset_count,
2083 	.get_ethtool_stats = mxl862xx_get_ethtool_stats,
2084 	.get_eth_mac_stats = mxl862xx_get_eth_mac_stats,
2085 	.get_eth_ctrl_stats = mxl862xx_get_eth_ctrl_stats,
2086 	.get_pause_stats = mxl862xx_get_pause_stats,
2087 	.get_rmon_stats = mxl862xx_get_rmon_stats,
2088 	.get_stats64 = mxl862xx_get_stats64,
2089 };
2090 
2091 static int mxl862xx_probe(struct mdio_device *mdiodev)
2092 {
2093 	struct device *dev = &mdiodev->dev;
2094 	struct mxl862xx_priv *priv;
2095 	struct dsa_switch *ds;
2096 	int err, i;
2097 
2098 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
2099 	if (!priv)
2100 		return -ENOMEM;
2101 
2102 	priv->mdiodev = mdiodev;
2103 
2104 	ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
2105 	if (!ds)
2106 		return -ENOMEM;
2107 
2108 	priv->ds = ds;
2109 	ds->dev = dev;
2110 	ds->priv = priv;
2111 	ds->ops = &mxl862xx_switch_ops;
2112 	ds->phylink_mac_ops = &mxl862xx_phylink_mac_ops;
2113 	ds->num_ports = MXL862XX_MAX_PORTS;
2114 	ds->fdb_isolation = true;
2115 	ds->max_num_bridges = MXL862XX_MAX_BRIDGES;
2116 
2117 	mxl862xx_host_init(priv);
2118 
2119 	for (i = 0; i < MXL862XX_MAX_PORTS; i++) {
2120 		priv->ports[i].priv = priv;
2121 		INIT_WORK(&priv->ports[i].host_flood_work,
2122 			  mxl862xx_host_flood_work_fn);
2123 		spin_lock_init(&priv->ports[i].stats_lock);
2124 	}
2125 
2126 	INIT_DELAYED_WORK(&priv->stats_work, mxl862xx_stats_work_fn);
2127 
2128 	dev_set_drvdata(dev, ds);
2129 
2130 	err = dsa_register_switch(ds);
2131 	if (err) {
2132 		set_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags);
2133 		cancel_delayed_work_sync(&priv->stats_work);
2134 		mxl862xx_host_shutdown(priv);
2135 		for (i = 0; i < MXL862XX_MAX_PORTS; i++)
2136 			cancel_work_sync(&priv->ports[i].host_flood_work);
2137 	}
2138 
2139 	return err;
2140 }
2141 
2142 static void mxl862xx_remove(struct mdio_device *mdiodev)
2143 {
2144 	struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
2145 	struct mxl862xx_priv *priv;
2146 	int i;
2147 
2148 	if (!ds)
2149 		return;
2150 
2151 	priv = ds->priv;
2152 
2153 	set_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags);
2154 	cancel_delayed_work_sync(&priv->stats_work);
2155 
2156 	dsa_unregister_switch(ds);
2157 
2158 	mxl862xx_host_shutdown(priv);
2159 
2160 	/* Cancel any pending host flood work. dsa_unregister_switch()
2161 	 * has already called port_teardown (which sets setup_done=false),
2162 	 * but a worker could still be blocked on rtnl_lock(). Since we
2163 	 * are now outside RTNL, cancel_work_sync() will not deadlock.
2164 	 */
2165 	for (i = 0; i < MXL862XX_MAX_PORTS; i++)
2166 		cancel_work_sync(&priv->ports[i].host_flood_work);
2167 }
2168 
2169 static void mxl862xx_shutdown(struct mdio_device *mdiodev)
2170 {
2171 	struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
2172 	struct mxl862xx_priv *priv;
2173 	int i;
2174 
2175 	if (!ds)
2176 		return;
2177 
2178 	priv = ds->priv;
2179 
2180 	dsa_switch_shutdown(ds);
2181 
2182 	set_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags);
2183 	cancel_delayed_work_sync(&priv->stats_work);
2184 
2185 	mxl862xx_host_shutdown(priv);
2186 
2187 	for (i = 0; i < MXL862XX_MAX_PORTS; i++)
2188 		cancel_work_sync(&priv->ports[i].host_flood_work);
2189 
2190 	dev_set_drvdata(&mdiodev->dev, NULL);
2191 }
2192 
2193 static const struct of_device_id mxl862xx_of_match[] = {
2194 	{ .compatible = "maxlinear,mxl86282" },
2195 	{ .compatible = "maxlinear,mxl86252" },
2196 	{ /* sentinel */ }
2197 };
2198 MODULE_DEVICE_TABLE(of, mxl862xx_of_match);
2199 
2200 static struct mdio_driver mxl862xx_driver = {
2201 	.probe  = mxl862xx_probe,
2202 	.remove = mxl862xx_remove,
2203 	.shutdown = mxl862xx_shutdown,
2204 	.mdiodrv.driver = {
2205 		.name = "mxl862xx",
2206 		.of_match_table = mxl862xx_of_match,
2207 	},
2208 };
2209 
2210 mdio_module_driver(mxl862xx_driver);
2211 
2212 MODULE_DESCRIPTION("Driver for MaxLinear MxL862xx switch family");
2213 MODULE_LICENSE("GPL");
2214