1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Microchip switch driver main logic
4  *
5  * Copyright (C) 2017-2019 Microchip Technology Inc.
6  */
7 
8 #include <linux/delay.h>
9 #include <linux/export.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/platform_data/microchip-ksz.h>
14 #include <linux/phy.h>
15 #include <linux/etherdevice.h>
16 #include <linux/if_bridge.h>
17 #include <linux/of_net.h>
18 #include <net/dsa.h>
19 #include <net/switchdev.h>
20 
21 #include "ksz_common.h"
22 
23 void ksz_update_port_member(struct ksz_device *dev, int port)
24 {
25 	struct ksz_port *p;
26 	int i;
27 
28 	for (i = 0; i < dev->port_cnt; i++) {
29 		if (i == port || i == dev->cpu_port)
30 			continue;
31 		p = &dev->ports[i];
32 		if (!(dev->member & (1 << i)))
33 			continue;
34 
35 		/* Port is a member of the bridge and is forwarding. */
36 		if (p->stp_state == BR_STATE_FORWARDING &&
37 		    p->member != dev->member)
38 			dev->dev_ops->cfg_port_member(dev, i, dev->member);
39 	}
40 }
41 EXPORT_SYMBOL_GPL(ksz_update_port_member);
42 
43 static void port_r_cnt(struct ksz_device *dev, int port)
44 {
45 	struct ksz_port_mib *mib = &dev->ports[port].mib;
46 	u64 *dropped;
47 
48 	/* Some ports may not have MIB counters before SWITCH_COUNTER_NUM. */
49 	while (mib->cnt_ptr < dev->reg_mib_cnt) {
50 		dev->dev_ops->r_mib_cnt(dev, port, mib->cnt_ptr,
51 					&mib->counters[mib->cnt_ptr]);
52 		++mib->cnt_ptr;
53 	}
54 
55 	/* last one in storage */
56 	dropped = &mib->counters[dev->mib_cnt];
57 
58 	/* Some ports may not have MIB counters after SWITCH_COUNTER_NUM. */
59 	while (mib->cnt_ptr < dev->mib_cnt) {
60 		dev->dev_ops->r_mib_pkt(dev, port, mib->cnt_ptr,
61 					dropped, &mib->counters[mib->cnt_ptr]);
62 		++mib->cnt_ptr;
63 	}
64 	mib->cnt_ptr = 0;
65 }
66 
67 static void ksz_mib_read_work(struct work_struct *work)
68 {
69 	struct ksz_device *dev = container_of(work, struct ksz_device,
70 					      mib_read.work);
71 	struct ksz_port_mib *mib;
72 	struct ksz_port *p;
73 	int i;
74 
75 	for (i = 0; i < dev->mib_port_cnt; i++) {
76 		if (dsa_is_unused_port(dev->ds, i))
77 			continue;
78 
79 		p = &dev->ports[i];
80 		mib = &p->mib;
81 		mutex_lock(&mib->cnt_mutex);
82 
83 		/* Only read MIB counters when the port is told to do.
84 		 * If not, read only dropped counters when link is not up.
85 		 */
86 		if (!p->read) {
87 			const struct dsa_port *dp = dsa_to_port(dev->ds, i);
88 
89 			if (!netif_carrier_ok(dp->slave))
90 				mib->cnt_ptr = dev->reg_mib_cnt;
91 		}
92 		port_r_cnt(dev, i);
93 		p->read = false;
94 		mutex_unlock(&mib->cnt_mutex);
95 	}
96 
97 	schedule_delayed_work(&dev->mib_read, dev->mib_read_interval);
98 }
99 
100 void ksz_init_mib_timer(struct ksz_device *dev)
101 {
102 	int i;
103 
104 	INIT_DELAYED_WORK(&dev->mib_read, ksz_mib_read_work);
105 
106 	/* Read MIB counters every 30 seconds to avoid overflow. */
107 	dev->mib_read_interval = msecs_to_jiffies(30000);
108 
109 	for (i = 0; i < dev->mib_port_cnt; i++)
110 		dev->dev_ops->port_init_cnt(dev, i);
111 
112 	/* Start the timer 2 seconds later. */
113 	schedule_delayed_work(&dev->mib_read, msecs_to_jiffies(2000));
114 }
115 EXPORT_SYMBOL_GPL(ksz_init_mib_timer);
116 
117 int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg)
118 {
119 	struct ksz_device *dev = ds->priv;
120 	u16 val = 0xffff;
121 
122 	dev->dev_ops->r_phy(dev, addr, reg, &val);
123 
124 	return val;
125 }
126 EXPORT_SYMBOL_GPL(ksz_phy_read16);
127 
128 int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)
129 {
130 	struct ksz_device *dev = ds->priv;
131 
132 	dev->dev_ops->w_phy(dev, addr, reg, val);
133 
134 	return 0;
135 }
136 EXPORT_SYMBOL_GPL(ksz_phy_write16);
137 
138 void ksz_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
139 		       phy_interface_t interface)
140 {
141 	struct ksz_device *dev = ds->priv;
142 	struct ksz_port *p = &dev->ports[port];
143 
144 	/* Read all MIB counters when the link is going down. */
145 	p->read = true;
146 	schedule_delayed_work(&dev->mib_read, 0);
147 }
148 EXPORT_SYMBOL_GPL(ksz_mac_link_down);
149 
150 int ksz_sset_count(struct dsa_switch *ds, int port, int sset)
151 {
152 	struct ksz_device *dev = ds->priv;
153 
154 	if (sset != ETH_SS_STATS)
155 		return 0;
156 
157 	return dev->mib_cnt;
158 }
159 EXPORT_SYMBOL_GPL(ksz_sset_count);
160 
161 void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf)
162 {
163 	const struct dsa_port *dp = dsa_to_port(ds, port);
164 	struct ksz_device *dev = ds->priv;
165 	struct ksz_port_mib *mib;
166 
167 	mib = &dev->ports[port].mib;
168 	mutex_lock(&mib->cnt_mutex);
169 
170 	/* Only read dropped counters if no link. */
171 	if (!netif_carrier_ok(dp->slave))
172 		mib->cnt_ptr = dev->reg_mib_cnt;
173 	port_r_cnt(dev, port);
174 	memcpy(buf, mib->counters, dev->mib_cnt * sizeof(u64));
175 	mutex_unlock(&mib->cnt_mutex);
176 }
177 EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats);
178 
179 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
180 			 struct net_device *br)
181 {
182 	struct ksz_device *dev = ds->priv;
183 
184 	mutex_lock(&dev->dev_mutex);
185 	dev->br_member |= (1 << port);
186 	mutex_unlock(&dev->dev_mutex);
187 
188 	/* port_stp_state_set() will be called after to put the port in
189 	 * appropriate state so there is no need to do anything.
190 	 */
191 
192 	return 0;
193 }
194 EXPORT_SYMBOL_GPL(ksz_port_bridge_join);
195 
196 void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
197 			   struct net_device *br)
198 {
199 	struct ksz_device *dev = ds->priv;
200 
201 	mutex_lock(&dev->dev_mutex);
202 	dev->br_member &= ~(1 << port);
203 	dev->member &= ~(1 << port);
204 	mutex_unlock(&dev->dev_mutex);
205 
206 	/* port_stp_state_set() will be called after to put the port in
207 	 * forwarding state so there is no need to do anything.
208 	 */
209 }
210 EXPORT_SYMBOL_GPL(ksz_port_bridge_leave);
211 
212 void ksz_port_fast_age(struct dsa_switch *ds, int port)
213 {
214 	struct ksz_device *dev = ds->priv;
215 
216 	dev->dev_ops->flush_dyn_mac_table(dev, port);
217 }
218 EXPORT_SYMBOL_GPL(ksz_port_fast_age);
219 
220 int ksz_port_vlan_prepare(struct dsa_switch *ds, int port,
221 			  const struct switchdev_obj_port_vlan *vlan)
222 {
223 	/* nothing needed */
224 
225 	return 0;
226 }
227 EXPORT_SYMBOL_GPL(ksz_port_vlan_prepare);
228 
229 int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
230 		      void *data)
231 {
232 	struct ksz_device *dev = ds->priv;
233 	int ret = 0;
234 	u16 i = 0;
235 	u16 entries = 0;
236 	u8 timestamp = 0;
237 	u8 fid;
238 	u8 member;
239 	struct alu_struct alu;
240 
241 	do {
242 		alu.is_static = false;
243 		ret = dev->dev_ops->r_dyn_mac_table(dev, i, alu.mac, &fid,
244 						    &member, &timestamp,
245 						    &entries);
246 		if (!ret && (member & BIT(port))) {
247 			ret = cb(alu.mac, alu.fid, alu.is_static, data);
248 			if (ret)
249 				break;
250 		}
251 		i++;
252 	} while (i < entries);
253 	if (i >= entries)
254 		ret = 0;
255 
256 	return ret;
257 }
258 EXPORT_SYMBOL_GPL(ksz_port_fdb_dump);
259 
260 int ksz_port_mdb_prepare(struct dsa_switch *ds, int port,
261 			 const struct switchdev_obj_port_mdb *mdb)
262 {
263 	/* nothing to do */
264 	return 0;
265 }
266 EXPORT_SYMBOL_GPL(ksz_port_mdb_prepare);
267 
268 void ksz_port_mdb_add(struct dsa_switch *ds, int port,
269 		      const struct switchdev_obj_port_mdb *mdb)
270 {
271 	struct ksz_device *dev = ds->priv;
272 	struct alu_struct alu;
273 	int index;
274 	int empty = 0;
275 
276 	alu.port_forward = 0;
277 	for (index = 0; index < dev->num_statics; index++) {
278 		if (!dev->dev_ops->r_sta_mac_table(dev, index, &alu)) {
279 			/* Found one already in static MAC table. */
280 			if (!memcmp(alu.mac, mdb->addr, ETH_ALEN) &&
281 			    alu.fid == mdb->vid)
282 				break;
283 		/* Remember the first empty entry. */
284 		} else if (!empty) {
285 			empty = index + 1;
286 		}
287 	}
288 
289 	/* no available entry */
290 	if (index == dev->num_statics && !empty)
291 		return;
292 
293 	/* add entry */
294 	if (index == dev->num_statics) {
295 		index = empty - 1;
296 		memset(&alu, 0, sizeof(alu));
297 		memcpy(alu.mac, mdb->addr, ETH_ALEN);
298 		alu.is_static = true;
299 	}
300 	alu.port_forward |= BIT(port);
301 	if (mdb->vid) {
302 		alu.is_use_fid = true;
303 
304 		/* Need a way to map VID to FID. */
305 		alu.fid = mdb->vid;
306 	}
307 	dev->dev_ops->w_sta_mac_table(dev, index, &alu);
308 }
309 EXPORT_SYMBOL_GPL(ksz_port_mdb_add);
310 
311 int ksz_port_mdb_del(struct dsa_switch *ds, int port,
312 		     const struct switchdev_obj_port_mdb *mdb)
313 {
314 	struct ksz_device *dev = ds->priv;
315 	struct alu_struct alu;
316 	int index;
317 	int ret = 0;
318 
319 	for (index = 0; index < dev->num_statics; index++) {
320 		if (!dev->dev_ops->r_sta_mac_table(dev, index, &alu)) {
321 			/* Found one already in static MAC table. */
322 			if (!memcmp(alu.mac, mdb->addr, ETH_ALEN) &&
323 			    alu.fid == mdb->vid)
324 				break;
325 		}
326 	}
327 
328 	/* no available entry */
329 	if (index == dev->num_statics)
330 		goto exit;
331 
332 	/* clear port */
333 	alu.port_forward &= ~BIT(port);
334 	if (!alu.port_forward)
335 		alu.is_static = false;
336 	dev->dev_ops->w_sta_mac_table(dev, index, &alu);
337 
338 exit:
339 	return ret;
340 }
341 EXPORT_SYMBOL_GPL(ksz_port_mdb_del);
342 
343 int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
344 {
345 	struct ksz_device *dev = ds->priv;
346 
347 	if (!dsa_is_user_port(ds, port))
348 		return 0;
349 
350 	/* setup slave port */
351 	dev->dev_ops->port_setup(dev, port, false);
352 
353 	/* port_stp_state_set() will be called after to enable the port so
354 	 * there is no need to do anything.
355 	 */
356 
357 	return 0;
358 }
359 EXPORT_SYMBOL_GPL(ksz_enable_port);
360 
361 struct ksz_device *ksz_switch_alloc(struct device *base, void *priv)
362 {
363 	struct dsa_switch *ds;
364 	struct ksz_device *swdev;
365 
366 	ds = devm_kzalloc(base, sizeof(*ds), GFP_KERNEL);
367 	if (!ds)
368 		return NULL;
369 
370 	ds->dev = base;
371 	ds->num_ports = DSA_MAX_PORTS;
372 
373 	swdev = devm_kzalloc(base, sizeof(*swdev), GFP_KERNEL);
374 	if (!swdev)
375 		return NULL;
376 
377 	ds->priv = swdev;
378 	swdev->dev = base;
379 
380 	swdev->ds = ds;
381 	swdev->priv = priv;
382 
383 	return swdev;
384 }
385 EXPORT_SYMBOL(ksz_switch_alloc);
386 
387 int ksz_switch_register(struct ksz_device *dev,
388 			const struct ksz_dev_ops *ops)
389 {
390 	phy_interface_t interface;
391 	int ret;
392 
393 	if (dev->pdata)
394 		dev->chip_id = dev->pdata->chip_id;
395 
396 	dev->reset_gpio = devm_gpiod_get_optional(dev->dev, "reset",
397 						  GPIOD_OUT_LOW);
398 	if (IS_ERR(dev->reset_gpio))
399 		return PTR_ERR(dev->reset_gpio);
400 
401 	if (dev->reset_gpio) {
402 		gpiod_set_value_cansleep(dev->reset_gpio, 1);
403 		mdelay(10);
404 		gpiod_set_value_cansleep(dev->reset_gpio, 0);
405 	}
406 
407 	mutex_init(&dev->dev_mutex);
408 	mutex_init(&dev->regmap_mutex);
409 	mutex_init(&dev->alu_mutex);
410 	mutex_init(&dev->vlan_mutex);
411 
412 	dev->dev_ops = ops;
413 
414 	if (dev->dev_ops->detect(dev))
415 		return -EINVAL;
416 
417 	ret = dev->dev_ops->init(dev);
418 	if (ret)
419 		return ret;
420 
421 	/* Host port interface will be self detected, or specifically set in
422 	 * device tree.
423 	 */
424 	if (dev->dev->of_node) {
425 		ret = of_get_phy_mode(dev->dev->of_node, &interface);
426 		if (ret == 0)
427 			dev->interface = interface;
428 		dev->synclko_125 = of_property_read_bool(dev->dev->of_node,
429 							 "microchip,synclko-125");
430 	}
431 
432 	ret = dsa_register_switch(dev->ds);
433 	if (ret) {
434 		dev->dev_ops->exit(dev);
435 		return ret;
436 	}
437 
438 	return 0;
439 }
440 EXPORT_SYMBOL(ksz_switch_register);
441 
442 void ksz_switch_remove(struct ksz_device *dev)
443 {
444 	/* timer started */
445 	if (dev->mib_read_interval)
446 		cancel_delayed_work_sync(&dev->mib_read);
447 
448 	dev->dev_ops->exit(dev);
449 	dsa_unregister_switch(dev->ds);
450 
451 	if (dev->reset_gpio)
452 		gpiod_set_value_cansleep(dev->reset_gpio, 1);
453 
454 }
455 EXPORT_SYMBOL(ksz_switch_remove);
456 
457 MODULE_AUTHOR("Woojung Huh <Woojung.Huh@microchip.com>");
458 MODULE_DESCRIPTION("Microchip KSZ Series Switch DSA Driver");
459 MODULE_LICENSE("GPL");
460