xref: /linux/drivers/net/dsa/mxl862xx/mxl862xx.c (revision b5a051f6b840d48f159166ef073d3021989bfb50)
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 
mxl862xx_get_tag_protocol(struct dsa_switch * ds,int port,enum dsa_tag_protocol m)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 */
mxl862xx_phy_read_mmd(struct mxl862xx_priv * priv,int addr,int devadd,int regnum)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 
mxl862xx_phy_write_mmd(struct mxl862xx_priv * priv,int addr,int devadd,int regnum,u16 data)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 
mxl862xx_phy_read_mii_bus(struct mii_bus * bus,int addr,int regnum)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 
mxl862xx_phy_write_mii_bus(struct mii_bus * bus,int addr,int regnum,u16 val)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 
mxl862xx_phy_read_c45_mii_bus(struct mii_bus * bus,int addr,int devadd,int regnum)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 
mxl862xx_phy_write_c45_mii_bus(struct mii_bus * bus,int addr,int devadd,int regnum,u16 val)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 
mxl862xx_wait_ready(struct dsa_switch * ds)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 
mxl862xx_setup_mdio(struct dsa_switch * ds)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 
mxl862xx_bridge_config_fwd(struct dsa_switch * ds,u16 bridge_id,bool ucast_flood,bool mcast_flood,bool bcast_flood)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  */
mxl862xx_setup_drop_meter(struct dsa_switch * ds)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 
mxl862xx_set_bridge_port(struct dsa_switch * ds,int port)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 
mxl862xx_sync_bridge_members(struct dsa_switch * ds,const struct dsa_bridge * bridge)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 
mxl862xx_evlan_block_alloc(struct mxl862xx_priv * priv,struct mxl862xx_evlan_block * blk)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 
mxl862xx_vf_block_alloc(struct mxl862xx_priv * priv,u16 size,u16 * block_id)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 
mxl862xx_vf_entry_discard(struct mxl862xx_priv * priv,u16 block_id,u16 index)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 
mxl862xx_vf_alloc(struct mxl862xx_priv * priv,struct mxl862xx_vf_block * vf)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 
mxl862xx_allocate_bridge(struct mxl862xx_priv * priv)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 
mxl862xx_free_bridge(struct dsa_switch * ds,const struct dsa_bridge * bridge)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 
mxl862xx_setup(struct dsa_switch * ds)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 	ret = mxl862xx_setup_mdio(ds);
689 	if (ret)
690 		return ret;
691 
692 	schedule_delayed_work(&priv->stats_work,
693 			      MXL862XX_STATS_POLL_INTERVAL);
694 
695 	return 0;
696 }
697 
mxl862xx_teardown(struct dsa_switch * ds)698 static void mxl862xx_teardown(struct dsa_switch *ds)
699 {
700 	struct mxl862xx_priv *priv = ds->priv;
701 
702 	set_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags);
703 	disable_delayed_work_sync(&priv->stats_work);
704 }
705 
mxl862xx_port_state(struct dsa_switch * ds,int port,bool enable)706 static int mxl862xx_port_state(struct dsa_switch *ds, int port, bool enable)
707 {
708 	struct mxl862xx_register_mod sdma = {
709 		.addr = cpu_to_le16(MXL862XX_SDMA_PCTRLP(port)),
710 		.data = cpu_to_le16(enable ? MXL862XX_SDMA_PCTRL_EN : 0),
711 		.mask = cpu_to_le16(MXL862XX_SDMA_PCTRL_EN),
712 	};
713 	struct mxl862xx_register_mod fdma = {
714 		.addr = cpu_to_le16(MXL862XX_FDMA_PCTRLP(port)),
715 		.data = cpu_to_le16(enable ? MXL862XX_FDMA_PCTRL_EN : 0),
716 		.mask = cpu_to_le16(MXL862XX_FDMA_PCTRL_EN),
717 	};
718 	int ret;
719 
720 	ret = MXL862XX_API_WRITE(ds->priv, MXL862XX_COMMON_REGISTERMOD, sdma);
721 	if (ret)
722 		return ret;
723 
724 	return MXL862XX_API_WRITE(ds->priv, MXL862XX_COMMON_REGISTERMOD, fdma);
725 }
726 
mxl862xx_port_enable(struct dsa_switch * ds,int port,struct phy_device * phydev)727 static int mxl862xx_port_enable(struct dsa_switch *ds, int port,
728 				struct phy_device *phydev)
729 {
730 	return mxl862xx_port_state(ds, port, true);
731 }
732 
mxl862xx_port_disable(struct dsa_switch * ds,int port)733 static void mxl862xx_port_disable(struct dsa_switch *ds, int port)
734 {
735 	if (mxl862xx_port_state(ds, port, false))
736 		dev_err(ds->dev, "failed to disable port %d\n", port);
737 }
738 
mxl862xx_port_fast_age(struct dsa_switch * ds,int port)739 static void mxl862xx_port_fast_age(struct dsa_switch *ds, int port)
740 {
741 	struct mxl862xx_mac_table_clear param = {
742 		.type = MXL862XX_MAC_CLEAR_PHY_PORT,
743 		.port_id = port,
744 	};
745 
746 	if (MXL862XX_API_WRITE(ds->priv, MXL862XX_MAC_TABLECLEARCOND, param))
747 		dev_err(ds->dev, "failed to clear fdb on port %d\n", port);
748 }
749 
mxl862xx_configure_ctp_port(struct dsa_switch * ds,int port,u16 first_ctp_port_id,u16 number_of_ctp_ports)750 static int mxl862xx_configure_ctp_port(struct dsa_switch *ds, int port,
751 				       u16 first_ctp_port_id,
752 				       u16 number_of_ctp_ports)
753 {
754 	struct mxl862xx_ctp_port_assignment ctp_assign = {
755 		.logical_port_id = port,
756 		.first_ctp_port_id = cpu_to_le16(first_ctp_port_id),
757 		.number_of_ctp_port = cpu_to_le16(number_of_ctp_ports),
758 		.mode = cpu_to_le32(MXL862XX_LOGICAL_PORT_ETHERNET),
759 	};
760 
761 	return MXL862XX_API_WRITE(ds->priv, MXL862XX_CTP_PORTASSIGNMENTSET,
762 				  ctp_assign);
763 }
764 
mxl862xx_configure_sp_tag_proto(struct dsa_switch * ds,int port,bool enable)765 static int mxl862xx_configure_sp_tag_proto(struct dsa_switch *ds, int port,
766 					   bool enable)
767 {
768 	struct mxl862xx_ss_sp_tag tag = {
769 		.pid = port,
770 		.mask = MXL862XX_SS_SP_TAG_MASK_RX | MXL862XX_SS_SP_TAG_MASK_TX,
771 		.rx = enable ? MXL862XX_SS_SP_TAG_RX_TAG_NO_INSERT :
772 			       MXL862XX_SS_SP_TAG_RX_NO_TAG_INSERT,
773 		.tx = enable ? MXL862XX_SS_SP_TAG_TX_TAG_NO_REMOVE :
774 			       MXL862XX_SS_SP_TAG_TX_TAG_REMOVE,
775 	};
776 
777 	return MXL862XX_API_WRITE(ds->priv, MXL862XX_SS_SPTAG_SET, tag);
778 }
779 
mxl862xx_evlan_write_rule(struct mxl862xx_priv * priv,u16 block_id,u16 entry_index,const struct mxl862xx_evlan_rule_desc * desc,u16 vid,bool untagged,u16 pvid)780 static int mxl862xx_evlan_write_rule(struct mxl862xx_priv *priv,
781 				     u16 block_id, u16 entry_index,
782 				     const struct mxl862xx_evlan_rule_desc *desc,
783 				     u16 vid, bool untagged, u16 pvid)
784 {
785 	struct mxl862xx_extendedvlan_config cfg = {};
786 	struct mxl862xx_extendedvlan_filter_vlan *fv;
787 
788 	cfg.extended_vlan_block_id = cpu_to_le16(block_id);
789 	cfg.entry_index = cpu_to_le16(entry_index);
790 
791 	/* Populate filter */
792 	cfg.filter.outer_vlan.type = cpu_to_le32(desc->outer_type);
793 	cfg.filter.inner_vlan.type = cpu_to_le32(desc->inner_type);
794 	cfg.filter.outer_vlan.tpid = cpu_to_le32(desc->outer_tpid);
795 	cfg.filter.inner_vlan.tpid = cpu_to_le32(desc->inner_tpid);
796 
797 	if (desc->match_vid) {
798 		/* For egress unaware: outer=NO_FILTER, match on inner tag */
799 		if (desc->outer_type == FT_NO_FILTER)
800 			fv = &cfg.filter.inner_vlan;
801 		else
802 			fv = &cfg.filter.outer_vlan;
803 
804 		fv->vid_enable = 1;
805 		fv->vid_val = cpu_to_le32(vid);
806 	}
807 
808 	/* Populate treatment based on action */
809 	switch (desc->action) {
810 	case EVLAN_ACCEPT:
811 		cfg.treatment.remove_tag =
812 			cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG);
813 		break;
814 
815 	case EVLAN_STRIP_IF_UNTAGGED:
816 		cfg.treatment.remove_tag = cpu_to_le32(untagged ?
817 			MXL862XX_EXTENDEDVLAN_TREATMENT_REMOVE_1_TAG :
818 			MXL862XX_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG);
819 		break;
820 
821 	case EVLAN_PVID_OR_DISCARD:
822 		if (pvid) {
823 			cfg.treatment.remove_tag =
824 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_NOT_REMOVE_TAG);
825 			cfg.treatment.add_outer_vlan = 1;
826 			cfg.treatment.outer_vlan.vid_mode =
827 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_VID_VAL);
828 			cfg.treatment.outer_vlan.vid_val = cpu_to_le32(pvid);
829 			cfg.treatment.outer_vlan.tpid =
830 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_8021Q);
831 		} else {
832 			cfg.treatment.remove_tag =
833 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM);
834 		}
835 		break;
836 
837 	case EVLAN_STRIP1_AND_PVID_OR_DISCARD:
838 		if (pvid) {
839 			cfg.treatment.remove_tag =
840 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_REMOVE_1_TAG);
841 			cfg.treatment.add_outer_vlan = 1;
842 			cfg.treatment.outer_vlan.vid_mode =
843 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_VID_VAL);
844 			cfg.treatment.outer_vlan.vid_val = cpu_to_le32(pvid);
845 			cfg.treatment.outer_vlan.tpid =
846 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_8021Q);
847 		} else {
848 			cfg.treatment.remove_tag =
849 				cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM);
850 		}
851 		break;
852 	}
853 
854 	return MXL862XX_API_WRITE(priv, MXL862XX_EXTENDEDVLAN_SET, cfg);
855 }
856 
mxl862xx_evlan_deactivate_entry(struct mxl862xx_priv * priv,u16 block_id,u16 entry_index)857 static int mxl862xx_evlan_deactivate_entry(struct mxl862xx_priv *priv,
858 					   u16 block_id, u16 entry_index)
859 {
860 	struct mxl862xx_extendedvlan_config cfg = {};
861 
862 	cfg.extended_vlan_block_id = cpu_to_le16(block_id);
863 	cfg.entry_index = cpu_to_le16(entry_index);
864 
865 	/* Use an unreachable filter (DEFAULT+DEFAULT) with DISCARD treatment.
866 	 * A zeroed entry would have NORMAL+NORMAL filter which matches
867 	 * real double-tagged traffic and passes it through.
868 	 */
869 	cfg.filter.outer_vlan.type =
870 		cpu_to_le32(MXL862XX_EXTENDEDVLAN_FILTER_TYPE_DEFAULT);
871 	cfg.filter.inner_vlan.type =
872 		cpu_to_le32(MXL862XX_EXTENDEDVLAN_FILTER_TYPE_DEFAULT);
873 	cfg.treatment.remove_tag =
874 		cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM);
875 
876 	return MXL862XX_API_WRITE(priv, MXL862XX_EXTENDEDVLAN_SET, cfg);
877 }
878 
mxl862xx_evlan_write_final_rules(struct mxl862xx_priv * priv,struct mxl862xx_evlan_block * blk,const struct mxl862xx_evlan_rule_desc * rules,int n_rules,u16 pvid)879 static int mxl862xx_evlan_write_final_rules(struct mxl862xx_priv *priv,
880 					    struct mxl862xx_evlan_block *blk,
881 					    const struct mxl862xx_evlan_rule_desc *rules,
882 					    int n_rules, u16 pvid)
883 {
884 	u16 start_idx = blk->block_size - n_rules;
885 	int i, ret;
886 
887 	for (i = 0; i < n_rules; i++) {
888 		ret = mxl862xx_evlan_write_rule(priv, blk->block_id,
889 						start_idx + i, &rules[i],
890 						0, false, pvid);
891 		if (ret)
892 			return ret;
893 	}
894 
895 	return 0;
896 }
897 
mxl862xx_vf_entry_set(struct mxl862xx_priv * priv,u16 block_id,u16 index,u16 vid)898 static int mxl862xx_vf_entry_set(struct mxl862xx_priv *priv,
899 				 u16 block_id, u16 index, u16 vid)
900 {
901 	struct mxl862xx_vlanfilter_config cfg = {};
902 
903 	cfg.vlan_filter_block_id = cpu_to_le16(block_id);
904 	cfg.entry_index = cpu_to_le16(index);
905 	cfg.vlan_filter_mask = cpu_to_le32(MXL862XX_VLAN_FILTER_TCI_MASK_VID);
906 	cfg.val = cpu_to_le32(vid);
907 	cfg.discard_matched = 0;
908 
909 	return MXL862XX_API_WRITE(priv, MXL862XX_VLANFILTER_SET, cfg);
910 }
911 
mxl862xx_vf_find_vid(struct mxl862xx_vf_block * vf,u16 vid)912 static struct mxl862xx_vf_vid *mxl862xx_vf_find_vid(struct mxl862xx_vf_block *vf,
913 						    u16 vid)
914 {
915 	struct mxl862xx_vf_vid *ve;
916 
917 	list_for_each_entry(ve, &vf->vids, list)
918 		if (ve->vid == vid)
919 			return ve;
920 
921 	return NULL;
922 }
923 
mxl862xx_vf_add_vid(struct mxl862xx_priv * priv,struct mxl862xx_vf_block * vf,u16 vid,bool untagged)924 static int mxl862xx_vf_add_vid(struct mxl862xx_priv *priv,
925 			       struct mxl862xx_vf_block *vf,
926 			       u16 vid, bool untagged)
927 {
928 	struct mxl862xx_vf_vid *ve;
929 	int ret;
930 
931 	ve = mxl862xx_vf_find_vid(vf, vid);
932 	if (ve) {
933 		ve->untagged = untagged;
934 		return 0;
935 	}
936 
937 	if (vf->active_count >= vf->block_size)
938 		return -ENOSPC;
939 
940 	ve = kzalloc_obj(*ve);
941 	if (!ve)
942 		return -ENOMEM;
943 
944 	ve->vid = vid;
945 	ve->index = vf->active_count;
946 	ve->untagged = untagged;
947 
948 	ret = mxl862xx_vf_entry_set(priv, vf->block_id, ve->index, vid);
949 	if (ret) {
950 		kfree(ve);
951 		return ret;
952 	}
953 
954 	list_add_tail(&ve->list, &vf->vids);
955 	vf->active_count++;
956 
957 	return 0;
958 }
959 
mxl862xx_vf_del_vid(struct mxl862xx_priv * priv,struct mxl862xx_vf_block * vf,u16 vid)960 static int mxl862xx_vf_del_vid(struct mxl862xx_priv *priv,
961 			       struct mxl862xx_vf_block *vf, u16 vid)
962 {
963 	struct mxl862xx_vf_vid *ve, *last_ve;
964 	u16 gap, last;
965 	int ret;
966 
967 	ve = mxl862xx_vf_find_vid(vf, vid);
968 	if (!ve)
969 		return 0;
970 
971 	if (!vf->allocated) {
972 		/* Software-only state -- just remove the tracking entry */
973 		list_del(&ve->list);
974 		kfree(ve);
975 		vf->active_count--;
976 		return 0;
977 	}
978 
979 	gap = ve->index;
980 	last = vf->active_count - 1;
981 
982 	if (vf->active_count == 1) {
983 		/* Last VID -- restore DISCARD sentinel at index 0 */
984 		ret = mxl862xx_vf_entry_discard(priv, vf->block_id, 0);
985 		if (ret)
986 			return ret;
987 	} else if (gap < last) {
988 		/* Swap: move the last ALLOW entry into the gap */
989 		list_for_each_entry(last_ve, &vf->vids, list)
990 			if (last_ve->index == last)
991 				break;
992 
993 		if (WARN_ON(list_entry_is_head(last_ve, &vf->vids, list)))
994 			return -EINVAL;
995 
996 		ret = mxl862xx_vf_entry_set(priv, vf->block_id,
997 					    gap, last_ve->vid);
998 		if (ret)
999 			return ret;
1000 
1001 		last_ve->index = gap;
1002 	}
1003 
1004 	list_del(&ve->list);
1005 	kfree(ve);
1006 	vf->active_count--;
1007 
1008 	return 0;
1009 }
1010 
mxl862xx_evlan_program_ingress(struct mxl862xx_priv * priv,int port)1011 static int mxl862xx_evlan_program_ingress(struct mxl862xx_priv *priv, int port)
1012 {
1013 	struct mxl862xx_port *p = &priv->ports[port];
1014 	struct mxl862xx_evlan_block *blk = &p->ingress_evlan;
1015 
1016 	if (!p->vlan_filtering)
1017 		return 0;
1018 
1019 	blk->in_use = true;
1020 	blk->n_active = blk->block_size;
1021 
1022 	return mxl862xx_evlan_write_final_rules(priv, blk,
1023 						ingress_aware_final,
1024 						ARRAY_SIZE(ingress_aware_final),
1025 						p->pvid);
1026 }
1027 
mxl862xx_evlan_program_egress(struct mxl862xx_priv * priv,int port)1028 static int mxl862xx_evlan_program_egress(struct mxl862xx_priv *priv, int port)
1029 {
1030 	struct mxl862xx_port *p = &priv->ports[port];
1031 	struct mxl862xx_evlan_block *blk = &p->egress_evlan;
1032 	const struct mxl862xx_evlan_rule_desc *vid_rules;
1033 	struct mxl862xx_vf_vid *vfv;
1034 	u16 old_active = blk->n_active;
1035 	u16 idx = 0, i;
1036 	int n_vid, ret;
1037 
1038 	if (p->vlan_filtering) {
1039 		vid_rules = vid_accept_standard;
1040 		n_vid = ARRAY_SIZE(vid_accept_standard);
1041 	} else {
1042 		vid_rules = vid_accept_egress_unaware;
1043 		n_vid = ARRAY_SIZE(vid_accept_egress_unaware);
1044 	}
1045 
1046 	list_for_each_entry(vfv, &p->vf.vids, list) {
1047 		if (!vfv->untagged)
1048 			continue;
1049 
1050 		if (idx + n_vid > blk->block_size)
1051 			return -ENOSPC;
1052 
1053 		ret = mxl862xx_evlan_write_rule(priv, blk->block_id,
1054 						idx++, &vid_rules[0],
1055 						vfv->vid, vfv->untagged,
1056 						p->pvid);
1057 		if (ret)
1058 			return ret;
1059 
1060 		if (n_vid > 1) {
1061 			ret = mxl862xx_evlan_write_rule(priv, blk->block_id,
1062 							idx++, &vid_rules[1],
1063 							vfv->vid,
1064 							vfv->untagged,
1065 							p->pvid);
1066 			if (ret)
1067 				return ret;
1068 		}
1069 	}
1070 
1071 	/* Deactivate stale entries that are no longer needed.
1072 	 * This closes the brief window between writing the new rules
1073 	 * and set_bridge_port narrowing the scan window.
1074 	 */
1075 	for (i = idx; i < old_active; i++) {
1076 		ret = mxl862xx_evlan_deactivate_entry(priv,
1077 						      blk->block_id,
1078 						      i);
1079 		if (ret)
1080 			return ret;
1081 	}
1082 
1083 	blk->n_active = idx;
1084 	blk->in_use = idx > 0;
1085 
1086 	return 0;
1087 }
1088 
mxl862xx_port_vlan_filtering(struct dsa_switch * ds,int port,bool vlan_filtering,struct netlink_ext_ack * extack)1089 static int mxl862xx_port_vlan_filtering(struct dsa_switch *ds, int port,
1090 					bool vlan_filtering,
1091 					struct netlink_ext_ack *extack)
1092 {
1093 	struct mxl862xx_priv *priv = ds->priv;
1094 	struct mxl862xx_port *p = &priv->ports[port];
1095 	bool old_vlan_filtering = p->vlan_filtering;
1096 	bool old_in_use = p->ingress_evlan.in_use;
1097 	bool changed = (p->vlan_filtering != vlan_filtering);
1098 	int ret;
1099 
1100 	p->vlan_filtering = vlan_filtering;
1101 
1102 	if (changed) {
1103 		/* When leaving VLAN-aware mode, release the ingress HW
1104 		 * block. The firmware passes frames through unchanged
1105 		 * when no ingress EVLAN block is assigned, so the block
1106 		 * is unnecessary in unaware mode.
1107 		 */
1108 		if (!vlan_filtering)
1109 			p->ingress_evlan.in_use = false;
1110 
1111 		ret = mxl862xx_evlan_program_ingress(priv, port);
1112 		if (ret)
1113 			goto err_restore;
1114 
1115 		ret = mxl862xx_evlan_program_egress(priv, port);
1116 		if (ret)
1117 			goto err_restore;
1118 	}
1119 
1120 	return mxl862xx_set_bridge_port(ds, port);
1121 
1122 	/* No HW rollback -- restoring SW state is sufficient for a correct retry. */
1123 err_restore:
1124 	p->vlan_filtering = old_vlan_filtering;
1125 	p->ingress_evlan.in_use = old_in_use;
1126 	return ret;
1127 }
1128 
mxl862xx_port_vlan_add(struct dsa_switch * ds,int port,const struct switchdev_obj_port_vlan * vlan,struct netlink_ext_ack * extack)1129 static int mxl862xx_port_vlan_add(struct dsa_switch *ds, int port,
1130 				  const struct switchdev_obj_port_vlan *vlan,
1131 				  struct netlink_ext_ack *extack)
1132 {
1133 	struct mxl862xx_priv *priv = ds->priv;
1134 	struct mxl862xx_port *p = &priv->ports[port];
1135 	bool untagged = !!(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED);
1136 	u16 vid = vlan->vid;
1137 	u16 old_pvid = p->pvid;
1138 	bool pvid_changed = false;
1139 	int ret;
1140 
1141 	/* CPU port is VLAN-transparent: the SP tag handles port
1142 	 * identification and the host-side DSA tagger manages VLAN
1143 	 * delivery. Egress EVLAN catchalls are set up once in
1144 	 * setup_cpu_bridge; no per-VID VF/EVLAN programming needed.
1145 	 */
1146 	if (dsa_is_cpu_port(ds, port))
1147 		return 0;
1148 
1149 	/* Update PVID tracking */
1150 	if (vlan->flags & BRIDGE_VLAN_INFO_PVID) {
1151 		if (p->pvid != vid) {
1152 			p->pvid = vid;
1153 			pvid_changed = true;
1154 		}
1155 	} else if (p->pvid == vid) {
1156 		p->pvid = 0;
1157 		pvid_changed = true;
1158 	}
1159 
1160 	/* Add/update VID in this port's VLAN Filter block.
1161 	 * VF must be updated before programming egress EVLAN because
1162 	 * evlan_program_egress walks the VF VID list.
1163 	 */
1164 	ret = mxl862xx_vf_add_vid(priv, &p->vf, vid, untagged);
1165 	if (ret)
1166 		goto err_pvid;
1167 
1168 	/* Reprogram ingress finals if PVID changed */
1169 	if (pvid_changed) {
1170 		ret = mxl862xx_evlan_program_ingress(priv, port);
1171 		if (ret)
1172 			goto err_rollback;
1173 	}
1174 
1175 	/* Reprogram egress tag-stripping rules (walks VF VID list) */
1176 	ret = mxl862xx_evlan_program_egress(priv, port);
1177 	if (ret)
1178 		goto err_rollback;
1179 
1180 	/* Apply VLAN block IDs and MAC learning flags to bridge port */
1181 	ret = mxl862xx_set_bridge_port(ds, port);
1182 	if (ret)
1183 		goto err_rollback;
1184 
1185 	return 0;
1186 
1187 err_rollback:
1188 	/* Best-effort: undo VF add and restore consistent hardware state.
1189 	 * A retry of port_vlan_add will converge since vf_add_vid is
1190 	 * idempotent.
1191 	 */
1192 	p->pvid = old_pvid;
1193 	mxl862xx_vf_del_vid(priv, &p->vf, vid);
1194 	mxl862xx_evlan_program_ingress(priv, port);
1195 	mxl862xx_evlan_program_egress(priv, port);
1196 	mxl862xx_set_bridge_port(ds, port);
1197 	return ret;
1198 err_pvid:
1199 	p->pvid = old_pvid;
1200 	return ret;
1201 }
1202 
mxl862xx_port_vlan_del(struct dsa_switch * ds,int port,const struct switchdev_obj_port_vlan * vlan)1203 static int mxl862xx_port_vlan_del(struct dsa_switch *ds, int port,
1204 				  const struct switchdev_obj_port_vlan *vlan)
1205 {
1206 	struct mxl862xx_priv *priv = ds->priv;
1207 	struct mxl862xx_port *p = &priv->ports[port];
1208 	struct mxl862xx_vf_vid *ve;
1209 	bool pvid_changed = false;
1210 	u16 vid = vlan->vid;
1211 	bool old_untagged;
1212 	u16 old_pvid;
1213 	int ret;
1214 
1215 	if (dsa_is_cpu_port(ds, port))
1216 		return 0;
1217 
1218 	ve = mxl862xx_vf_find_vid(&p->vf, vid);
1219 	if (!ve)
1220 		return 0;
1221 	old_untagged = ve->untagged;
1222 	old_pvid = p->pvid;
1223 
1224 	/* Clear PVID if we're deleting it */
1225 	if (p->pvid == vid) {
1226 		p->pvid = 0;
1227 		pvid_changed = true;
1228 	}
1229 
1230 	/* Remove VID from this port's VLAN Filter block.
1231 	 * Must happen before egress reprogram so the VID is no
1232 	 * longer in the list that evlan_program_egress walks.
1233 	 */
1234 	ret = mxl862xx_vf_del_vid(priv, &p->vf, vid);
1235 	if (ret)
1236 		goto err_pvid;
1237 
1238 	/* Reprogram egress tag-stripping rules (VID is now gone) */
1239 	ret = mxl862xx_evlan_program_egress(priv, port);
1240 	if (ret)
1241 		goto err_rollback;
1242 
1243 	/* If PVID changed, reprogram ingress finals */
1244 	if (pvid_changed) {
1245 		ret = mxl862xx_evlan_program_ingress(priv, port);
1246 		if (ret)
1247 			goto err_rollback;
1248 	}
1249 
1250 	ret = mxl862xx_set_bridge_port(ds, port);
1251 	if (ret)
1252 		goto err_rollback;
1253 
1254 	return 0;
1255 
1256 err_rollback:
1257 	/* Best-effort: re-add the VID and restore consistent hardware
1258 	 * state. A retry of port_vlan_del will converge.
1259 	 */
1260 	p->pvid = old_pvid;
1261 	mxl862xx_vf_add_vid(priv, &p->vf, vid, old_untagged);
1262 	mxl862xx_evlan_program_egress(priv, port);
1263 	mxl862xx_evlan_program_ingress(priv, port);
1264 	mxl862xx_set_bridge_port(ds, port);
1265 	return ret;
1266 err_pvid:
1267 	p->pvid = old_pvid;
1268 	return ret;
1269 }
1270 
mxl862xx_setup_cpu_bridge(struct dsa_switch * ds,int port)1271 static int mxl862xx_setup_cpu_bridge(struct dsa_switch *ds, int port)
1272 {
1273 	struct mxl862xx_priv *priv = ds->priv;
1274 	struct mxl862xx_port *p = &priv->ports[port];
1275 
1276 	p->fid = MXL862XX_DEFAULT_BRIDGE;
1277 	p->learning = true;
1278 
1279 	/* EVLAN is left disabled on CPU ports -- frames pass through
1280 	 * without EVLAN processing. Only the portmap and bridge
1281 	 * assignment need to be configured.
1282 	 */
1283 
1284 	return mxl862xx_set_bridge_port(ds, port);
1285 }
1286 
mxl862xx_port_bridge_join(struct dsa_switch * ds,int port,const struct dsa_bridge bridge,bool * tx_fwd_offload,struct netlink_ext_ack * extack)1287 static int mxl862xx_port_bridge_join(struct dsa_switch *ds, int port,
1288 				     const struct dsa_bridge bridge,
1289 				     bool *tx_fwd_offload,
1290 				     struct netlink_ext_ack *extack)
1291 {
1292 	struct mxl862xx_priv *priv = ds->priv;
1293 	int ret;
1294 
1295 	if (!priv->bridges[bridge.num]) {
1296 		ret = mxl862xx_allocate_bridge(priv);
1297 		if (ret < 0)
1298 			return ret;
1299 
1300 		priv->bridges[bridge.num] = ret;
1301 
1302 		/* Free bridge here on error, DSA rollback won't. */
1303 		ret = mxl862xx_sync_bridge_members(ds, &bridge);
1304 		if (ret) {
1305 			mxl862xx_free_bridge(ds, &bridge);
1306 			return ret;
1307 		}
1308 
1309 		return 0;
1310 	}
1311 
1312 	return mxl862xx_sync_bridge_members(ds, &bridge);
1313 }
1314 
mxl862xx_port_bridge_leave(struct dsa_switch * ds,int port,const struct dsa_bridge bridge)1315 static void mxl862xx_port_bridge_leave(struct dsa_switch *ds, int port,
1316 				       const struct dsa_bridge bridge)
1317 {
1318 	struct mxl862xx_priv *priv = ds->priv;
1319 	struct mxl862xx_port *p = &priv->ports[port];
1320 	int err;
1321 
1322 	err = mxl862xx_sync_bridge_members(ds, &bridge);
1323 	if (err)
1324 		dev_err(ds->dev,
1325 			"failed to sync bridge members after port %d left: %pe\n",
1326 			port, ERR_PTR(err));
1327 
1328 	/* Revert leaving port, omitted by the sync above, to its
1329 	 * single-port bridge
1330 	 */
1331 	p->pvid = 0;
1332 	p->ingress_evlan.in_use = false;
1333 	p->egress_evlan.in_use = false;
1334 
1335 	err = mxl862xx_set_bridge_port(ds, port);
1336 	if (err)
1337 		dev_err(ds->dev,
1338 			"failed to update bridge port %d state: %pe\n", port,
1339 			ERR_PTR(err));
1340 
1341 	if (!dsa_bridge_ports(ds, bridge.dev))
1342 		mxl862xx_free_bridge(ds, &bridge);
1343 }
1344 
mxl862xx_port_setup(struct dsa_switch * ds,int port)1345 static int mxl862xx_port_setup(struct dsa_switch *ds, int port)
1346 {
1347 	struct mxl862xx_priv *priv = ds->priv;
1348 	struct dsa_port *dp = dsa_to_port(ds, port);
1349 	bool is_cpu_port = dsa_port_is_cpu(dp);
1350 	int ret;
1351 
1352 	ret = mxl862xx_port_state(ds, port, false);
1353 	if (ret)
1354 		return ret;
1355 
1356 	mxl862xx_port_fast_age(ds, port);
1357 
1358 	if (dsa_port_is_unused(dp))
1359 		return 0;
1360 
1361 	if (dsa_port_is_dsa(dp)) {
1362 		dev_err(ds->dev, "port %d: DSA links not supported\n", port);
1363 		return -EOPNOTSUPP;
1364 	}
1365 
1366 	ret = mxl862xx_configure_sp_tag_proto(ds, port, is_cpu_port);
1367 	if (ret)
1368 		return ret;
1369 
1370 	ret = mxl862xx_configure_ctp_port(ds, port, port,
1371 					  is_cpu_port ? 32 - port : 1);
1372 	if (ret)
1373 		return ret;
1374 
1375 	if (is_cpu_port)
1376 		return mxl862xx_setup_cpu_bridge(ds, port);
1377 
1378 	/* setup single-port bridge for user ports.
1379 	 * If this fails, the FID is leaked -- but the port then transitions
1380 	 * to unused, and the FID pool is sized to tolerate this.
1381 	 */
1382 	ret = mxl862xx_allocate_bridge(priv);
1383 	if (ret < 0) {
1384 		dev_err(ds->dev, "failed to allocate a bridge for port %d\n", port);
1385 		return ret;
1386 	}
1387 	priv->ports[port].fid = ret;
1388 	/* Standalone ports should not flood unknown unicast or multicast
1389 	 * towards the CPU by default; only broadcast is needed initially.
1390 	 */
1391 	ret = mxl862xx_bridge_config_fwd(ds, priv->ports[port].fid,
1392 					 false, false, true);
1393 	if (ret)
1394 		return ret;
1395 	ret = mxl862xx_set_bridge_port(ds, port);
1396 	if (ret)
1397 		return ret;
1398 
1399 	priv->ports[port].ingress_evlan.block_size = priv->evlan_ingress_size;
1400 	ret = mxl862xx_evlan_block_alloc(priv, &priv->ports[port].ingress_evlan);
1401 	if (ret)
1402 		return ret;
1403 
1404 	priv->ports[port].egress_evlan.block_size = priv->evlan_egress_size;
1405 	ret = mxl862xx_evlan_block_alloc(priv, &priv->ports[port].egress_evlan);
1406 	if (ret)
1407 		return ret;
1408 
1409 	priv->ports[port].vf.block_size = priv->vf_block_size;
1410 	INIT_LIST_HEAD(&priv->ports[port].vf.vids);
1411 	ret = mxl862xx_vf_alloc(priv, &priv->ports[port].vf);
1412 	if (ret)
1413 		return ret;
1414 
1415 	priv->ports[port].setup_done = true;
1416 
1417 	return 0;
1418 }
1419 
mxl862xx_port_teardown(struct dsa_switch * ds,int port)1420 static void mxl862xx_port_teardown(struct dsa_switch *ds, int port)
1421 {
1422 	struct mxl862xx_priv *priv = ds->priv;
1423 	struct dsa_port *dp = dsa_to_port(ds, port);
1424 
1425 	if (dsa_port_is_unused(dp))
1426 		return;
1427 
1428 	/* Prevent deferred host_flood_work from acting on stale state.
1429 	 * The flag is checked under rtnl_lock() by the worker; since
1430 	 * teardown also runs under RTNL, this is race-free.
1431 	 *
1432 	 * HW EVLAN/VF blocks are not freed here -- the firmware receives
1433 	 * a full reset on the next probe, which reclaims all resources.
1434 	 */
1435 	priv->ports[port].setup_done = false;
1436 }
1437 
mxl862xx_get_fid(struct dsa_switch * ds,struct dsa_db db)1438 static int mxl862xx_get_fid(struct dsa_switch *ds, struct dsa_db db)
1439 {
1440 	struct mxl862xx_priv *priv = ds->priv;
1441 
1442 	switch (db.type) {
1443 	case DSA_DB_PORT:
1444 		return priv->ports[db.dp->index].fid;
1445 
1446 	case DSA_DB_BRIDGE:
1447 		if (!priv->bridges[db.bridge.num])
1448 			return -ENOENT;
1449 		return priv->bridges[db.bridge.num];
1450 
1451 	default:
1452 		return -EOPNOTSUPP;
1453 	}
1454 }
1455 
mxl862xx_port_fdb_add(struct dsa_switch * ds,int port,const unsigned char * addr,u16 vid,struct dsa_db db)1456 static int mxl862xx_port_fdb_add(struct dsa_switch *ds, int port,
1457 				 const unsigned char *addr, u16 vid, struct dsa_db db)
1458 {
1459 	struct mxl862xx_mac_table_add param = {};
1460 	int fid = mxl862xx_get_fid(ds, db), ret;
1461 	struct mxl862xx_priv *priv = ds->priv;
1462 
1463 	if (fid < 0)
1464 		return fid;
1465 
1466 	param.port_id = cpu_to_le32(port);
1467 	param.static_entry = true;
1468 	param.fid = cpu_to_le16(fid);
1469 	param.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, vid));
1470 	ether_addr_copy(param.mac, addr);
1471 
1472 	ret = MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYADD, param);
1473 	if (ret)
1474 		dev_err(ds->dev, "failed to add FDB entry on port %d\n", port);
1475 
1476 	return ret;
1477 }
1478 
mxl862xx_port_fdb_del(struct dsa_switch * ds,int port,const unsigned char * addr,u16 vid,const struct dsa_db db)1479 static int mxl862xx_port_fdb_del(struct dsa_switch *ds, int port,
1480 				 const unsigned char *addr, u16 vid, const struct dsa_db db)
1481 {
1482 	struct mxl862xx_mac_table_remove param = {};
1483 	int fid = mxl862xx_get_fid(ds, db), ret;
1484 	struct mxl862xx_priv *priv = ds->priv;
1485 
1486 	if (fid < 0)
1487 		return fid;
1488 
1489 	param.fid = cpu_to_le16(fid);
1490 	param.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, vid));
1491 	ether_addr_copy(param.mac, addr);
1492 
1493 	ret = MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYREMOVE, param);
1494 	if (ret)
1495 		dev_err(ds->dev, "failed to remove FDB entry on port %d\n", port);
1496 
1497 	return ret;
1498 }
1499 
mxl862xx_port_fdb_dump(struct dsa_switch * ds,int port,dsa_fdb_dump_cb_t * cb,void * data)1500 static int mxl862xx_port_fdb_dump(struct dsa_switch *ds, int port,
1501 				  dsa_fdb_dump_cb_t *cb, void *data)
1502 {
1503 	struct mxl862xx_mac_table_read param = { .initial = 1 };
1504 	struct mxl862xx_priv *priv = ds->priv;
1505 	u32 entry_port_id;
1506 	int ret;
1507 
1508 	while (true) {
1509 		ret = MXL862XX_API_READ(priv, MXL862XX_MAC_TABLEENTRYREAD, param);
1510 		if (ret)
1511 			return ret;
1512 
1513 		if (param.last)
1514 			break;
1515 
1516 		entry_port_id = le32_to_cpu(param.port_id);
1517 
1518 		if (entry_port_id == port) {
1519 			ret = cb(param.mac, FIELD_GET(MXL862XX_TCI_VLAN_ID,
1520 						      le16_to_cpu(param.tci)),
1521 				 param.static_entry, data);
1522 			if (ret)
1523 				return ret;
1524 		}
1525 
1526 		memset(&param, 0, sizeof(param));
1527 	}
1528 
1529 	return 0;
1530 }
1531 
mxl862xx_port_mdb_add(struct dsa_switch * ds,int port,const struct switchdev_obj_port_mdb * mdb,const struct dsa_db db)1532 static int mxl862xx_port_mdb_add(struct dsa_switch *ds, int port,
1533 				 const struct switchdev_obj_port_mdb *mdb,
1534 				 const struct dsa_db db)
1535 {
1536 	struct mxl862xx_mac_table_query qparam = {};
1537 	struct mxl862xx_mac_table_add aparam = {};
1538 	struct mxl862xx_priv *priv = ds->priv;
1539 	int fid, ret;
1540 
1541 	fid = mxl862xx_get_fid(ds, db);
1542 	if (fid < 0)
1543 		return fid;
1544 
1545 	ether_addr_copy(qparam.mac, mdb->addr);
1546 	qparam.fid = cpu_to_le16(fid);
1547 	qparam.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, mdb->vid));
1548 
1549 	ret = MXL862XX_API_READ(priv, MXL862XX_MAC_TABLEENTRYQUERY, qparam);
1550 	if (ret)
1551 		return ret;
1552 
1553 	/* Build the ADD command using portmap mode */
1554 	ether_addr_copy(aparam.mac, mdb->addr);
1555 	aparam.fid = cpu_to_le16(fid);
1556 	aparam.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, mdb->vid));
1557 	aparam.static_entry = true;
1558 	aparam.port_id = cpu_to_le32(MXL862XX_PORTMAP_FLAG);
1559 
1560 	if (qparam.found)
1561 		memcpy(aparam.port_map, qparam.port_map,
1562 		       sizeof(aparam.port_map));
1563 
1564 	mxl862xx_fw_portmap_set_bit(aparam.port_map, port);
1565 
1566 	return MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYADD, aparam);
1567 }
1568 
mxl862xx_port_mdb_del(struct dsa_switch * ds,int port,const struct switchdev_obj_port_mdb * mdb,const struct dsa_db db)1569 static int mxl862xx_port_mdb_del(struct dsa_switch *ds, int port,
1570 				 const struct switchdev_obj_port_mdb *mdb,
1571 				 const struct dsa_db db)
1572 {
1573 	struct mxl862xx_mac_table_remove rparam = {};
1574 	struct mxl862xx_mac_table_query qparam = {};
1575 	struct mxl862xx_mac_table_add aparam = {};
1576 	int fid = mxl862xx_get_fid(ds, db), ret;
1577 	struct mxl862xx_priv *priv = ds->priv;
1578 
1579 	if (fid < 0)
1580 		return fid;
1581 
1582 	qparam.fid = cpu_to_le16(fid);
1583 	qparam.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, mdb->vid));
1584 	ether_addr_copy(qparam.mac, mdb->addr);
1585 
1586 	ret = MXL862XX_API_READ(priv, MXL862XX_MAC_TABLEENTRYQUERY, qparam);
1587 	if (ret)
1588 		return ret;
1589 
1590 	if (!qparam.found)
1591 		return 0;
1592 
1593 	mxl862xx_fw_portmap_clear_bit(qparam.port_map, port);
1594 
1595 	if (mxl862xx_fw_portmap_is_empty(qparam.port_map)) {
1596 		rparam.fid = cpu_to_le16(fid);
1597 		rparam.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, mdb->vid));
1598 		ether_addr_copy(rparam.mac, mdb->addr);
1599 		ret = MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYREMOVE, rparam);
1600 	} else {
1601 		/* Write back with reduced portmap */
1602 		aparam.fid = cpu_to_le16(fid);
1603 		aparam.tci = cpu_to_le16(FIELD_PREP(MXL862XX_TCI_VLAN_ID, mdb->vid));
1604 		ether_addr_copy(aparam.mac, mdb->addr);
1605 		aparam.static_entry = true;
1606 		aparam.port_id = cpu_to_le32(MXL862XX_PORTMAP_FLAG);
1607 		memcpy(aparam.port_map, qparam.port_map, sizeof(aparam.port_map));
1608 		ret = MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYADD, aparam);
1609 	}
1610 
1611 	return ret;
1612 }
1613 
mxl862xx_set_ageing_time(struct dsa_switch * ds,unsigned int msecs)1614 static int mxl862xx_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
1615 {
1616 	struct mxl862xx_cfg param = {};
1617 	int ret;
1618 
1619 	ret = MXL862XX_API_READ(ds->priv, MXL862XX_COMMON_CFGGET, param);
1620 	if (ret) {
1621 		dev_err(ds->dev, "failed to read switch config\n");
1622 		return ret;
1623 	}
1624 
1625 	param.mac_table_age_timer = cpu_to_le32(MXL862XX_AGETIMER_CUSTOM);
1626 	param.age_timer = cpu_to_le32(msecs / 1000);
1627 	ret = MXL862XX_API_WRITE(ds->priv, MXL862XX_COMMON_CFGSET, param);
1628 	if (ret)
1629 		dev_err(ds->dev, "failed to set ageing\n");
1630 
1631 	return ret;
1632 }
1633 
mxl862xx_port_stp_state_set(struct dsa_switch * ds,int port,u8 state)1634 static void mxl862xx_port_stp_state_set(struct dsa_switch *ds, int port,
1635 					u8 state)
1636 {
1637 	struct mxl862xx_stp_port_cfg param = {
1638 		.port_id = cpu_to_le16(port),
1639 	};
1640 	struct mxl862xx_priv *priv = ds->priv;
1641 	int ret;
1642 
1643 	switch (state) {
1644 	case BR_STATE_DISABLED:
1645 		param.port_state = cpu_to_le32(MXL862XX_STP_PORT_STATE_DISABLE);
1646 		break;
1647 	case BR_STATE_BLOCKING:
1648 	case BR_STATE_LISTENING:
1649 		param.port_state = cpu_to_le32(MXL862XX_STP_PORT_STATE_BLOCKING);
1650 		break;
1651 	case BR_STATE_LEARNING:
1652 		param.port_state = cpu_to_le32(MXL862XX_STP_PORT_STATE_LEARNING);
1653 		break;
1654 	case BR_STATE_FORWARDING:
1655 		param.port_state = cpu_to_le32(MXL862XX_STP_PORT_STATE_FORWARD);
1656 		break;
1657 	default:
1658 		dev_err(ds->dev, "invalid STP state: %d\n", state);
1659 		return;
1660 	}
1661 
1662 	ret = MXL862XX_API_WRITE(priv, MXL862XX_STP_PORTCFGSET, param);
1663 	if (ret) {
1664 		dev_err(ds->dev, "failed to set STP state on port %d\n", port);
1665 		return;
1666 	}
1667 
1668 	/* The firmware may re-enable MAC learning as a side-effect of entering
1669 	 * LEARNING or FORWARDING state (per 802.1D defaults).
1670 	 * Re-apply the driver's intended learning and metering config so that
1671 	 * standalone ports keep learning disabled.
1672 	 */
1673 	ret = mxl862xx_set_bridge_port(ds, port);
1674 	if (ret)
1675 		dev_err(ds->dev, "failed to reapply brport flags on port %d\n",
1676 			port);
1677 
1678 	mxl862xx_port_fast_age(ds, port);
1679 }
1680 
1681 /* Deferred work handler for host flood configuration.
1682  *
1683  * port_set_host_flood is called from atomic context (under
1684  * netif_addr_lock), so firmware calls must be deferred. The worker
1685  * acquires rtnl_lock() to serialize with DSA callbacks that access the
1686  * same driver state.
1687  */
mxl862xx_host_flood_work_fn(struct work_struct * work)1688 static void mxl862xx_host_flood_work_fn(struct work_struct *work)
1689 {
1690 	struct mxl862xx_port *p = container_of(work, struct mxl862xx_port,
1691 					       host_flood_work);
1692 	struct mxl862xx_priv *priv = p->priv;
1693 	struct dsa_switch *ds = priv->ds;
1694 
1695 	rtnl_lock();
1696 
1697 	/* Port may have been torn down between scheduling and now. */
1698 	if (!p->setup_done) {
1699 		rtnl_unlock();
1700 		return;
1701 	}
1702 
1703 	/* Always write to the standalone FID. When standalone it takes effect
1704 	 * immediately; when bridged the port uses the shared bridge FID so the
1705 	 * write is a no-op for current forwarding, but the state is preserved
1706 	 * in hardware and is ready once the port returns to standalone.
1707 	 */
1708 	mxl862xx_bridge_config_fwd(ds, p->fid, p->host_flood_uc,
1709 				   p->host_flood_mc, true);
1710 
1711 	rtnl_unlock();
1712 }
1713 
mxl862xx_port_set_host_flood(struct dsa_switch * ds,int port,bool uc,bool mc)1714 static void mxl862xx_port_set_host_flood(struct dsa_switch *ds, int port,
1715 					 bool uc, bool mc)
1716 {
1717 	struct mxl862xx_priv *priv = ds->priv;
1718 	struct mxl862xx_port *p = &priv->ports[port];
1719 
1720 	p->host_flood_uc = uc;
1721 	p->host_flood_mc = mc;
1722 	schedule_work(&p->host_flood_work);
1723 }
1724 
mxl862xx_port_pre_bridge_flags(struct dsa_switch * ds,int port,const struct switchdev_brport_flags flags,struct netlink_ext_ack * extack)1725 static int mxl862xx_port_pre_bridge_flags(struct dsa_switch *ds, int port,
1726 					  const struct switchdev_brport_flags flags,
1727 					  struct netlink_ext_ack *extack)
1728 {
1729 	if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD |
1730 			   BR_LEARNING))
1731 		return -EINVAL;
1732 
1733 	return 0;
1734 }
1735 
mxl862xx_port_bridge_flags(struct dsa_switch * ds,int port,const struct switchdev_brport_flags flags,struct netlink_ext_ack * extack)1736 static int mxl862xx_port_bridge_flags(struct dsa_switch *ds, int port,
1737 				      const struct switchdev_brport_flags flags,
1738 				      struct netlink_ext_ack *extack)
1739 {
1740 	struct mxl862xx_priv *priv = ds->priv;
1741 	unsigned long old_block = priv->ports[port].flood_block;
1742 	unsigned long block = old_block;
1743 	int ret;
1744 
1745 	if (flags.mask & BR_FLOOD) {
1746 		if (flags.val & BR_FLOOD)
1747 			block &= ~BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC);
1748 		else
1749 			block |= BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_UC);
1750 	}
1751 
1752 	if (flags.mask & BR_MCAST_FLOOD) {
1753 		if (flags.val & BR_MCAST_FLOOD) {
1754 			block &= ~BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP);
1755 			block &= ~BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP);
1756 		} else {
1757 			block |= BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_IP);
1758 			block |= BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_UNKNOWN_MC_NON_IP);
1759 		}
1760 	}
1761 
1762 	if (flags.mask & BR_BCAST_FLOOD) {
1763 		if (flags.val & BR_BCAST_FLOOD)
1764 			block &= ~BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_BROADCAST);
1765 		else
1766 			block |= BIT(MXL862XX_BRIDGE_PORT_EGRESS_METER_BROADCAST);
1767 	}
1768 
1769 	if (flags.mask & BR_LEARNING)
1770 		priv->ports[port].learning = !!(flags.val & BR_LEARNING);
1771 
1772 	if (block != old_block || (flags.mask & BR_LEARNING)) {
1773 		priv->ports[port].flood_block = block;
1774 		ret = mxl862xx_set_bridge_port(ds, port);
1775 		if (ret)
1776 			return ret;
1777 	}
1778 
1779 	return 0;
1780 }
1781 
mxl862xx_get_strings(struct dsa_switch * ds,int port,u32 stringset,u8 * data)1782 static void mxl862xx_get_strings(struct dsa_switch *ds, int port,
1783 				 u32 stringset, u8 *data)
1784 {
1785 	int i;
1786 
1787 	if (stringset != ETH_SS_STATS)
1788 		return;
1789 
1790 	for (i = 0; i < ARRAY_SIZE(mxl862xx_mib); i++)
1791 		ethtool_puts(&data, mxl862xx_mib[i].name);
1792 }
1793 
mxl862xx_get_sset_count(struct dsa_switch * ds,int port,int sset)1794 static int mxl862xx_get_sset_count(struct dsa_switch *ds, int port, int sset)
1795 {
1796 	if (sset != ETH_SS_STATS)
1797 		return 0;
1798 
1799 	return ARRAY_SIZE(mxl862xx_mib);
1800 }
1801 
mxl862xx_read_rmon(struct dsa_switch * ds,int port,struct mxl862xx_rmon_port_cnt * cnt)1802 static int mxl862xx_read_rmon(struct dsa_switch *ds, int port,
1803 			      struct mxl862xx_rmon_port_cnt *cnt)
1804 {
1805 	memset(cnt, 0, sizeof(*cnt));
1806 	cnt->port_type = cpu_to_le32(MXL862XX_CTP_PORT);
1807 	cnt->port_id = cpu_to_le16(port);
1808 
1809 	return MXL862XX_API_READ(ds->priv, MXL862XX_RMON_PORT_GET, *cnt);
1810 }
1811 
mxl862xx_get_ethtool_stats(struct dsa_switch * ds,int port,u64 * data)1812 static void mxl862xx_get_ethtool_stats(struct dsa_switch *ds, int port,
1813 				       u64 *data)
1814 {
1815 	const struct mxl862xx_mib_desc *mib;
1816 	struct mxl862xx_rmon_port_cnt cnt;
1817 	int ret, i;
1818 	void *field;
1819 
1820 	ret = mxl862xx_read_rmon(ds, port, &cnt);
1821 	if (ret) {
1822 		dev_err(ds->dev, "failed to read RMON stats on port %d\n", port);
1823 		return;
1824 	}
1825 
1826 	for (i = 0; i < ARRAY_SIZE(mxl862xx_mib); i++) {
1827 		mib = &mxl862xx_mib[i];
1828 		field = (u8 *)&cnt + mib->offset;
1829 
1830 		if (mib->size == 1)
1831 			*data++ = le32_to_cpu(*(__le32 *)field);
1832 		else
1833 			*data++ = le64_to_cpu(*(__le64 *)field);
1834 	}
1835 }
1836 
mxl862xx_get_eth_mac_stats(struct dsa_switch * ds,int port,struct ethtool_eth_mac_stats * mac_stats)1837 static void mxl862xx_get_eth_mac_stats(struct dsa_switch *ds, int port,
1838 				       struct ethtool_eth_mac_stats *mac_stats)
1839 {
1840 	struct mxl862xx_rmon_port_cnt cnt;
1841 
1842 	if (mxl862xx_read_rmon(ds, port, &cnt))
1843 		return;
1844 
1845 	mac_stats->FramesTransmittedOK = le32_to_cpu(cnt.tx_good_pkts);
1846 	mac_stats->SingleCollisionFrames = le32_to_cpu(cnt.tx_single_coll_count);
1847 	mac_stats->MultipleCollisionFrames = le32_to_cpu(cnt.tx_mult_coll_count);
1848 	mac_stats->FramesReceivedOK = le32_to_cpu(cnt.rx_good_pkts);
1849 	mac_stats->FrameCheckSequenceErrors = le32_to_cpu(cnt.rx_fcserror_pkts);
1850 	mac_stats->AlignmentErrors = le32_to_cpu(cnt.rx_align_error_pkts);
1851 	mac_stats->OctetsTransmittedOK = le64_to_cpu(cnt.tx_good_bytes);
1852 	mac_stats->LateCollisions = le32_to_cpu(cnt.tx_late_coll_count);
1853 	mac_stats->FramesAbortedDueToXSColls = le32_to_cpu(cnt.tx_excess_coll_count);
1854 	mac_stats->OctetsReceivedOK = le64_to_cpu(cnt.rx_good_bytes);
1855 	mac_stats->MulticastFramesXmittedOK = le32_to_cpu(cnt.tx_multicast_pkts);
1856 	mac_stats->BroadcastFramesXmittedOK = le32_to_cpu(cnt.tx_broadcast_pkts);
1857 	mac_stats->MulticastFramesReceivedOK = le32_to_cpu(cnt.rx_multicast_pkts);
1858 	mac_stats->BroadcastFramesReceivedOK = le32_to_cpu(cnt.rx_broadcast_pkts);
1859 	mac_stats->FrameTooLongErrors = le32_to_cpu(cnt.rx_oversize_error_pkts);
1860 }
1861 
mxl862xx_get_eth_ctrl_stats(struct dsa_switch * ds,int port,struct ethtool_eth_ctrl_stats * ctrl_stats)1862 static void mxl862xx_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
1863 					struct ethtool_eth_ctrl_stats *ctrl_stats)
1864 {
1865 	struct mxl862xx_rmon_port_cnt cnt;
1866 
1867 	if (mxl862xx_read_rmon(ds, port, &cnt))
1868 		return;
1869 
1870 	ctrl_stats->MACControlFramesTransmitted = le32_to_cpu(cnt.tx_pause_count);
1871 	ctrl_stats->MACControlFramesReceived = le32_to_cpu(cnt.rx_good_pause_pkts);
1872 }
1873 
mxl862xx_get_pause_stats(struct dsa_switch * ds,int port,struct ethtool_pause_stats * pause_stats)1874 static void mxl862xx_get_pause_stats(struct dsa_switch *ds, int port,
1875 				     struct ethtool_pause_stats *pause_stats)
1876 {
1877 	struct mxl862xx_rmon_port_cnt cnt;
1878 
1879 	if (mxl862xx_read_rmon(ds, port, &cnt))
1880 		return;
1881 
1882 	pause_stats->tx_pause_frames = le32_to_cpu(cnt.tx_pause_count);
1883 	pause_stats->rx_pause_frames = le32_to_cpu(cnt.rx_good_pause_pkts);
1884 }
1885 
mxl862xx_get_rmon_stats(struct dsa_switch * ds,int port,struct ethtool_rmon_stats * rmon_stats,const struct ethtool_rmon_hist_range ** ranges)1886 static void mxl862xx_get_rmon_stats(struct dsa_switch *ds, int port,
1887 				    struct ethtool_rmon_stats *rmon_stats,
1888 				    const struct ethtool_rmon_hist_range **ranges)
1889 {
1890 	struct mxl862xx_rmon_port_cnt cnt;
1891 
1892 	if (mxl862xx_read_rmon(ds, port, &cnt))
1893 		return;
1894 
1895 	rmon_stats->undersize_pkts = le32_to_cpu(cnt.rx_under_size_good_pkts);
1896 	rmon_stats->oversize_pkts = le32_to_cpu(cnt.rx_oversize_good_pkts);
1897 	rmon_stats->fragments = le32_to_cpu(cnt.rx_under_size_error_pkts);
1898 	rmon_stats->jabbers = le32_to_cpu(cnt.rx_oversize_error_pkts);
1899 
1900 	rmon_stats->hist[0] = le32_to_cpu(cnt.rx64byte_pkts);
1901 	rmon_stats->hist[1] = le32_to_cpu(cnt.rx127byte_pkts);
1902 	rmon_stats->hist[2] = le32_to_cpu(cnt.rx255byte_pkts);
1903 	rmon_stats->hist[3] = le32_to_cpu(cnt.rx511byte_pkts);
1904 	rmon_stats->hist[4] = le32_to_cpu(cnt.rx1023byte_pkts);
1905 	rmon_stats->hist[5] = le32_to_cpu(cnt.rx_max_byte_pkts);
1906 
1907 	rmon_stats->hist_tx[0] = le32_to_cpu(cnt.tx64byte_pkts);
1908 	rmon_stats->hist_tx[1] = le32_to_cpu(cnt.tx127byte_pkts);
1909 	rmon_stats->hist_tx[2] = le32_to_cpu(cnt.tx255byte_pkts);
1910 	rmon_stats->hist_tx[3] = le32_to_cpu(cnt.tx511byte_pkts);
1911 	rmon_stats->hist_tx[4] = le32_to_cpu(cnt.tx1023byte_pkts);
1912 	rmon_stats->hist_tx[5] = le32_to_cpu(cnt.tx_max_byte_pkts);
1913 
1914 	*ranges = mxl862xx_rmon_ranges;
1915 }
1916 
1917 /* Compute the delta between two 32-bit free-running counter snapshots,
1918  * handling a single wrap-around correctly via unsigned subtraction.
1919  */
mxl862xx_delta32(u32 cur,u32 prev)1920 static u64 mxl862xx_delta32(u32 cur, u32 prev)
1921 {
1922 	return (u32)(cur - prev);
1923 }
1924 
1925 /**
1926  * mxl862xx_stats_poll - Read RMON counters and accumulate into 64-bit stats
1927  * @ds: DSA switch
1928  * @port: port index
1929  *
1930  * The firmware RMON counters are free-running 32-bit values (64-bit for
1931  * byte counters). This function reads the hardware via MDIO (may sleep),
1932  * computes deltas from the previous snapshot, and accumulates them into
1933  * 64-bit per-port stats under a spinlock.
1934  *
1935  * Called only from the stats polling workqueue -- serialized by the
1936  * single-threaded delayed_work, so no MDIO locking is needed here.
1937  */
mxl862xx_stats_poll(struct dsa_switch * ds,int port)1938 static void mxl862xx_stats_poll(struct dsa_switch *ds, int port)
1939 {
1940 	struct mxl862xx_priv *priv = ds->priv;
1941 	struct mxl862xx_port_stats *s = &priv->ports[port].stats;
1942 	u32 rx_fcserr, rx_under, rx_over, rx_align, tx_drop;
1943 	u32 rx_drop, rx_evlan, mtu_exc, tx_acm;
1944 	struct mxl862xx_rmon_port_cnt cnt;
1945 	u64 rx_bytes, tx_bytes;
1946 	u32 rx_mcast, tx_coll;
1947 	u32 rx_pkts, tx_pkts;
1948 
1949 	/* MDIO read -- may sleep, done outside the spinlock. */
1950 	if (mxl862xx_read_rmon(ds, port, &cnt))
1951 		return;
1952 
1953 	rx_pkts   = le32_to_cpu(cnt.rx_good_pkts);
1954 	tx_pkts   = le32_to_cpu(cnt.tx_good_pkts);
1955 	rx_bytes  = le64_to_cpu(cnt.rx_good_bytes);
1956 	tx_bytes  = le64_to_cpu(cnt.tx_good_bytes);
1957 	rx_fcserr = le32_to_cpu(cnt.rx_fcserror_pkts);
1958 	rx_under  = le32_to_cpu(cnt.rx_under_size_error_pkts);
1959 	rx_over   = le32_to_cpu(cnt.rx_oversize_error_pkts);
1960 	rx_align  = le32_to_cpu(cnt.rx_align_error_pkts);
1961 	tx_drop   = le32_to_cpu(cnt.tx_dropped_pkts);
1962 	rx_drop   = le32_to_cpu(cnt.rx_dropped_pkts);
1963 	rx_evlan  = le32_to_cpu(cnt.rx_extended_vlan_discard_pkts);
1964 	mtu_exc   = le32_to_cpu(cnt.mtu_exceed_discard_pkts);
1965 	tx_acm    = le32_to_cpu(cnt.tx_acm_dropped_pkts);
1966 	rx_mcast  = le32_to_cpu(cnt.rx_multicast_pkts);
1967 	tx_coll   = le32_to_cpu(cnt.tx_coll_count);
1968 
1969 	/* Accumulate deltas under spinlock -- .get_stats64 reads these. */
1970 	spin_lock_bh(&priv->ports[port].stats_lock);
1971 
1972 	s->rx_packets += mxl862xx_delta32(rx_pkts, s->prev_rx_good_pkts);
1973 	s->tx_packets += mxl862xx_delta32(tx_pkts, s->prev_tx_good_pkts);
1974 	s->rx_bytes   += rx_bytes - s->prev_rx_good_bytes;
1975 	s->tx_bytes   += tx_bytes - s->prev_tx_good_bytes;
1976 
1977 	s->rx_errors +=
1978 		mxl862xx_delta32(rx_fcserr, s->prev_rx_fcserror_pkts) +
1979 		mxl862xx_delta32(rx_under, s->prev_rx_under_size_error_pkts) +
1980 		mxl862xx_delta32(rx_over, s->prev_rx_oversize_error_pkts) +
1981 		mxl862xx_delta32(rx_align, s->prev_rx_align_error_pkts);
1982 	s->tx_errors +=
1983 		mxl862xx_delta32(tx_drop, s->prev_tx_dropped_pkts);
1984 
1985 	s->rx_dropped +=
1986 		mxl862xx_delta32(rx_drop, s->prev_rx_dropped_pkts) +
1987 		mxl862xx_delta32(rx_evlan, s->prev_rx_evlan_discard_pkts) +
1988 		mxl862xx_delta32(mtu_exc, s->prev_mtu_exceed_discard_pkts);
1989 	s->tx_dropped +=
1990 		mxl862xx_delta32(tx_drop, s->prev_tx_dropped_pkts) +
1991 		mxl862xx_delta32(tx_acm, s->prev_tx_acm_dropped_pkts);
1992 
1993 	s->multicast  += mxl862xx_delta32(rx_mcast, s->prev_rx_multicast_pkts);
1994 	s->collisions += mxl862xx_delta32(tx_coll, s->prev_tx_coll_count);
1995 
1996 	s->rx_length_errors +=
1997 		mxl862xx_delta32(rx_under, s->prev_rx_under_size_error_pkts) +
1998 		mxl862xx_delta32(rx_over, s->prev_rx_oversize_error_pkts);
1999 	s->rx_crc_errors +=
2000 		mxl862xx_delta32(rx_fcserr, s->prev_rx_fcserror_pkts);
2001 	s->rx_frame_errors +=
2002 		mxl862xx_delta32(rx_align, s->prev_rx_align_error_pkts);
2003 
2004 	s->prev_rx_good_pkts             = rx_pkts;
2005 	s->prev_tx_good_pkts             = tx_pkts;
2006 	s->prev_rx_good_bytes            = rx_bytes;
2007 	s->prev_tx_good_bytes            = tx_bytes;
2008 	s->prev_rx_fcserror_pkts         = rx_fcserr;
2009 	s->prev_rx_under_size_error_pkts = rx_under;
2010 	s->prev_rx_oversize_error_pkts   = rx_over;
2011 	s->prev_rx_align_error_pkts      = rx_align;
2012 	s->prev_tx_dropped_pkts          = tx_drop;
2013 	s->prev_rx_dropped_pkts          = rx_drop;
2014 	s->prev_rx_evlan_discard_pkts    = rx_evlan;
2015 	s->prev_mtu_exceed_discard_pkts  = mtu_exc;
2016 	s->prev_tx_acm_dropped_pkts      = tx_acm;
2017 	s->prev_rx_multicast_pkts        = rx_mcast;
2018 	s->prev_tx_coll_count            = tx_coll;
2019 
2020 	spin_unlock_bh(&priv->ports[port].stats_lock);
2021 }
2022 
mxl862xx_stats_work_fn(struct work_struct * work)2023 static void mxl862xx_stats_work_fn(struct work_struct *work)
2024 {
2025 	struct mxl862xx_priv *priv =
2026 		container_of(work, struct mxl862xx_priv, stats_work.work);
2027 	struct dsa_switch *ds = priv->ds;
2028 	struct dsa_port *dp;
2029 
2030 	dsa_switch_for_each_available_port(dp, ds)
2031 		mxl862xx_stats_poll(ds, dp->index);
2032 
2033 	if (!test_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags))
2034 		schedule_delayed_work(&priv->stats_work,
2035 				      MXL862XX_STATS_POLL_INTERVAL);
2036 }
2037 
mxl862xx_get_stats64(struct dsa_switch * ds,int port,struct rtnl_link_stats64 * s)2038 static void mxl862xx_get_stats64(struct dsa_switch *ds, int port,
2039 				 struct rtnl_link_stats64 *s)
2040 {
2041 	struct mxl862xx_priv *priv = ds->priv;
2042 	struct mxl862xx_port_stats *ps = &priv->ports[port].stats;
2043 
2044 	spin_lock_bh(&priv->ports[port].stats_lock);
2045 
2046 	s->rx_packets = ps->rx_packets;
2047 	s->tx_packets = ps->tx_packets;
2048 	s->rx_bytes = ps->rx_bytes;
2049 	s->tx_bytes = ps->tx_bytes;
2050 	s->rx_errors = ps->rx_errors;
2051 	s->tx_errors = ps->tx_errors;
2052 	s->rx_dropped = ps->rx_dropped;
2053 	s->tx_dropped = ps->tx_dropped;
2054 	s->multicast = ps->multicast;
2055 	s->collisions = ps->collisions;
2056 	s->rx_length_errors = ps->rx_length_errors;
2057 	s->rx_crc_errors = ps->rx_crc_errors;
2058 	s->rx_frame_errors = ps->rx_frame_errors;
2059 
2060 	spin_unlock_bh(&priv->ports[port].stats_lock);
2061 
2062 	/* Trigger a fresh poll so the next read sees up-to-date counters. */
2063 	if (!test_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags))
2064 		schedule_delayed_work(&priv->stats_work, 0);
2065 }
2066 
2067 static const struct dsa_switch_ops mxl862xx_switch_ops = {
2068 	.get_tag_protocol = mxl862xx_get_tag_protocol,
2069 	.setup = mxl862xx_setup,
2070 	.teardown = mxl862xx_teardown,
2071 	.port_setup = mxl862xx_port_setup,
2072 	.port_teardown = mxl862xx_port_teardown,
2073 	.phylink_get_caps = mxl862xx_phylink_get_caps,
2074 	.port_enable = mxl862xx_port_enable,
2075 	.port_disable = mxl862xx_port_disable,
2076 	.port_fast_age = mxl862xx_port_fast_age,
2077 	.set_ageing_time = mxl862xx_set_ageing_time,
2078 	.port_bridge_join = mxl862xx_port_bridge_join,
2079 	.port_bridge_leave = mxl862xx_port_bridge_leave,
2080 	.port_pre_bridge_flags = mxl862xx_port_pre_bridge_flags,
2081 	.port_bridge_flags = mxl862xx_port_bridge_flags,
2082 	.port_stp_state_set = mxl862xx_port_stp_state_set,
2083 	.port_set_host_flood = mxl862xx_port_set_host_flood,
2084 	.port_fdb_add = mxl862xx_port_fdb_add,
2085 	.port_fdb_del = mxl862xx_port_fdb_del,
2086 	.port_fdb_dump = mxl862xx_port_fdb_dump,
2087 	.port_mdb_add = mxl862xx_port_mdb_add,
2088 	.port_mdb_del = mxl862xx_port_mdb_del,
2089 	.port_vlan_filtering = mxl862xx_port_vlan_filtering,
2090 	.port_vlan_add = mxl862xx_port_vlan_add,
2091 	.port_vlan_del = mxl862xx_port_vlan_del,
2092 	.get_strings = mxl862xx_get_strings,
2093 	.get_sset_count = mxl862xx_get_sset_count,
2094 	.get_ethtool_stats = mxl862xx_get_ethtool_stats,
2095 	.get_eth_mac_stats = mxl862xx_get_eth_mac_stats,
2096 	.get_eth_ctrl_stats = mxl862xx_get_eth_ctrl_stats,
2097 	.get_pause_stats = mxl862xx_get_pause_stats,
2098 	.get_rmon_stats = mxl862xx_get_rmon_stats,
2099 	.get_stats64 = mxl862xx_get_stats64,
2100 };
2101 
mxl862xx_probe(struct mdio_device * mdiodev)2102 static int mxl862xx_probe(struct mdio_device *mdiodev)
2103 {
2104 	struct device *dev = &mdiodev->dev;
2105 	struct mxl862xx_priv *priv;
2106 	struct dsa_switch *ds;
2107 	int err, i;
2108 
2109 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
2110 	if (!priv)
2111 		return -ENOMEM;
2112 
2113 	priv->mdiodev = mdiodev;
2114 
2115 	ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
2116 	if (!ds)
2117 		return -ENOMEM;
2118 
2119 	priv->ds = ds;
2120 	ds->dev = dev;
2121 	ds->priv = priv;
2122 	ds->ops = &mxl862xx_switch_ops;
2123 	ds->phylink_mac_ops = &mxl862xx_phylink_mac_ops;
2124 	ds->num_ports = MXL862XX_MAX_PORTS;
2125 	ds->assisted_learning_on_cpu_port = true;
2126 	ds->fdb_isolation = true;
2127 	ds->max_num_bridges = MXL862XX_MAX_BRIDGES;
2128 
2129 	mxl862xx_host_init(priv);
2130 
2131 	for (i = 0; i < MXL862XX_MAX_PORTS; i++) {
2132 		priv->ports[i].priv = priv;
2133 		INIT_WORK(&priv->ports[i].host_flood_work,
2134 			  mxl862xx_host_flood_work_fn);
2135 		spin_lock_init(&priv->ports[i].stats_lock);
2136 	}
2137 
2138 	INIT_DELAYED_WORK(&priv->stats_work, mxl862xx_stats_work_fn);
2139 
2140 	dev_set_drvdata(dev, ds);
2141 
2142 	err = dsa_register_switch(ds);
2143 	if (err) {
2144 		set_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags);
2145 		mxl862xx_host_shutdown(priv);
2146 		for (i = 0; i < MXL862XX_MAX_PORTS; i++)
2147 			cancel_work_sync(&priv->ports[i].host_flood_work);
2148 	}
2149 
2150 	return err;
2151 }
2152 
mxl862xx_remove(struct mdio_device * mdiodev)2153 static void mxl862xx_remove(struct mdio_device *mdiodev)
2154 {
2155 	struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
2156 	struct mxl862xx_priv *priv;
2157 	int i;
2158 
2159 	if (!ds)
2160 		return;
2161 
2162 	priv = ds->priv;
2163 
2164 	set_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags);
2165 
2166 	dsa_unregister_switch(ds);
2167 
2168 	mxl862xx_host_shutdown(priv);
2169 
2170 	/* Cancel any pending host flood work. dsa_unregister_switch()
2171 	 * has already called port_teardown (which sets setup_done=false),
2172 	 * but a worker could still be blocked on rtnl_lock(). Since we
2173 	 * are now outside RTNL, cancel_work_sync() will not deadlock.
2174 	 */
2175 	for (i = 0; i < MXL862XX_MAX_PORTS; i++)
2176 		cancel_work_sync(&priv->ports[i].host_flood_work);
2177 }
2178 
mxl862xx_shutdown(struct mdio_device * mdiodev)2179 static void mxl862xx_shutdown(struct mdio_device *mdiodev)
2180 {
2181 	struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
2182 	struct mxl862xx_priv *priv;
2183 	int i;
2184 
2185 	if (!ds)
2186 		return;
2187 
2188 	priv = ds->priv;
2189 
2190 	dsa_switch_shutdown(ds);
2191 
2192 	set_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags);
2193 	disable_delayed_work_sync(&priv->stats_work);
2194 
2195 	mxl862xx_host_shutdown(priv);
2196 
2197 	for (i = 0; i < MXL862XX_MAX_PORTS; i++)
2198 		cancel_work_sync(&priv->ports[i].host_flood_work);
2199 
2200 	dev_set_drvdata(&mdiodev->dev, NULL);
2201 }
2202 
2203 static const struct of_device_id mxl862xx_of_match[] = {
2204 	{ .compatible = "maxlinear,mxl86282" },
2205 	{ .compatible = "maxlinear,mxl86252" },
2206 	{ /* sentinel */ }
2207 };
2208 MODULE_DEVICE_TABLE(of, mxl862xx_of_match);
2209 
2210 static struct mdio_driver mxl862xx_driver = {
2211 	.probe  = mxl862xx_probe,
2212 	.remove = mxl862xx_remove,
2213 	.shutdown = mxl862xx_shutdown,
2214 	.mdiodrv.driver = {
2215 		.name = "mxl862xx",
2216 		.of_match_table = mxl862xx_of_match,
2217 	},
2218 };
2219 
2220 mdio_module_driver(mxl862xx_driver);
2221 
2222 MODULE_DESCRIPTION("Driver for MaxLinear MxL862xx switch family");
2223 MODULE_LICENSE("GPL");
2224