1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Microchip switch driver main logic
4  *
5  * Copyright (C) 2017-2018 Microchip Technology Inc.
6  */
7 
8 #include <linux/delay.h>
9 #include <linux/export.h>
10 #include <linux/gpio.h>
11 #include <linux/gpio/consumer.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/platform_data/microchip-ksz.h>
15 #include <linux/phy.h>
16 #include <linux/etherdevice.h>
17 #include <linux/if_bridge.h>
18 #include <linux/of_gpio.h>
19 #include <linux/of_net.h>
20 #include <net/dsa.h>
21 #include <net/switchdev.h>
22 
23 #include "ksz_priv.h"
24 
25 void ksz_update_port_member(struct ksz_device *dev, int port)
26 {
27 	struct ksz_port *p;
28 	int i;
29 
30 	for (i = 0; i < dev->port_cnt; i++) {
31 		if (i == port || i == dev->cpu_port)
32 			continue;
33 		p = &dev->ports[i];
34 		if (!(dev->member & (1 << i)))
35 			continue;
36 
37 		/* Port is a member of the bridge and is forwarding. */
38 		if (p->stp_state == BR_STATE_FORWARDING &&
39 		    p->member != dev->member)
40 			dev->dev_ops->cfg_port_member(dev, i, dev->member);
41 	}
42 }
43 EXPORT_SYMBOL_GPL(ksz_update_port_member);
44 
45 int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg)
46 {
47 	struct ksz_device *dev = ds->priv;
48 	u16 val = 0xffff;
49 
50 	dev->dev_ops->r_phy(dev, addr, reg, &val);
51 
52 	return val;
53 }
54 EXPORT_SYMBOL_GPL(ksz_phy_read16);
55 
56 int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)
57 {
58 	struct ksz_device *dev = ds->priv;
59 
60 	dev->dev_ops->w_phy(dev, addr, reg, val);
61 
62 	return 0;
63 }
64 EXPORT_SYMBOL_GPL(ksz_phy_write16);
65 
66 int ksz_sset_count(struct dsa_switch *ds, int port, int sset)
67 {
68 	struct ksz_device *dev = ds->priv;
69 
70 	if (sset != ETH_SS_STATS)
71 		return 0;
72 
73 	return dev->mib_cnt;
74 }
75 EXPORT_SYMBOL_GPL(ksz_sset_count);
76 
77 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
78 			 struct net_device *br)
79 {
80 	struct ksz_device *dev = ds->priv;
81 
82 	dev->br_member |= (1 << port);
83 
84 	/* port_stp_state_set() will be called after to put the port in
85 	 * appropriate state so there is no need to do anything.
86 	 */
87 
88 	return 0;
89 }
90 EXPORT_SYMBOL_GPL(ksz_port_bridge_join);
91 
92 void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
93 			   struct net_device *br)
94 {
95 	struct ksz_device *dev = ds->priv;
96 
97 	dev->br_member &= ~(1 << port);
98 	dev->member &= ~(1 << port);
99 
100 	/* port_stp_state_set() will be called after to put the port in
101 	 * forwarding state so there is no need to do anything.
102 	 */
103 }
104 EXPORT_SYMBOL_GPL(ksz_port_bridge_leave);
105 
106 void ksz_port_fast_age(struct dsa_switch *ds, int port)
107 {
108 	struct ksz_device *dev = ds->priv;
109 
110 	dev->dev_ops->flush_dyn_mac_table(dev, port);
111 }
112 EXPORT_SYMBOL_GPL(ksz_port_fast_age);
113 
114 int ksz_port_vlan_prepare(struct dsa_switch *ds, int port,
115 			  const struct switchdev_obj_port_vlan *vlan)
116 {
117 	/* nothing needed */
118 
119 	return 0;
120 }
121 EXPORT_SYMBOL_GPL(ksz_port_vlan_prepare);
122 
123 int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
124 		      void *data)
125 {
126 	struct ksz_device *dev = ds->priv;
127 	int ret = 0;
128 	u16 i = 0;
129 	u16 entries = 0;
130 	u8 timestamp = 0;
131 	u8 fid;
132 	u8 member;
133 	struct alu_struct alu;
134 
135 	do {
136 		alu.is_static = false;
137 		ret = dev->dev_ops->r_dyn_mac_table(dev, i, alu.mac, &fid,
138 						    &member, &timestamp,
139 						    &entries);
140 		if (!ret && (member & BIT(port))) {
141 			ret = cb(alu.mac, alu.fid, alu.is_static, data);
142 			if (ret)
143 				break;
144 		}
145 		i++;
146 	} while (i < entries);
147 	if (i >= entries)
148 		ret = 0;
149 
150 	return ret;
151 }
152 EXPORT_SYMBOL_GPL(ksz_port_fdb_dump);
153 
154 int ksz_port_mdb_prepare(struct dsa_switch *ds, int port,
155 			 const struct switchdev_obj_port_mdb *mdb)
156 {
157 	/* nothing to do */
158 	return 0;
159 }
160 EXPORT_SYMBOL_GPL(ksz_port_mdb_prepare);
161 
162 void ksz_port_mdb_add(struct dsa_switch *ds, int port,
163 		      const struct switchdev_obj_port_mdb *mdb)
164 {
165 	struct ksz_device *dev = ds->priv;
166 	struct alu_struct alu;
167 	int index;
168 	int empty = 0;
169 
170 	alu.port_forward = 0;
171 	for (index = 0; index < dev->num_statics; index++) {
172 		if (!dev->dev_ops->r_sta_mac_table(dev, index, &alu)) {
173 			/* Found one already in static MAC table. */
174 			if (!memcmp(alu.mac, mdb->addr, ETH_ALEN) &&
175 			    alu.fid == mdb->vid)
176 				break;
177 		/* Remember the first empty entry. */
178 		} else if (!empty) {
179 			empty = index + 1;
180 		}
181 	}
182 
183 	/* no available entry */
184 	if (index == dev->num_statics && !empty)
185 		return;
186 
187 	/* add entry */
188 	if (index == dev->num_statics) {
189 		index = empty - 1;
190 		memset(&alu, 0, sizeof(alu));
191 		memcpy(alu.mac, mdb->addr, ETH_ALEN);
192 		alu.is_static = true;
193 	}
194 	alu.port_forward |= BIT(port);
195 	if (mdb->vid) {
196 		alu.is_use_fid = true;
197 
198 		/* Need a way to map VID to FID. */
199 		alu.fid = mdb->vid;
200 	}
201 	dev->dev_ops->w_sta_mac_table(dev, index, &alu);
202 }
203 EXPORT_SYMBOL_GPL(ksz_port_mdb_add);
204 
205 int ksz_port_mdb_del(struct dsa_switch *ds, int port,
206 		     const struct switchdev_obj_port_mdb *mdb)
207 {
208 	struct ksz_device *dev = ds->priv;
209 	struct alu_struct alu;
210 	int index;
211 	int ret = 0;
212 
213 	for (index = 0; index < dev->num_statics; index++) {
214 		if (!dev->dev_ops->r_sta_mac_table(dev, index, &alu)) {
215 			/* Found one already in static MAC table. */
216 			if (!memcmp(alu.mac, mdb->addr, ETH_ALEN) &&
217 			    alu.fid == mdb->vid)
218 				break;
219 		}
220 	}
221 
222 	/* no available entry */
223 	if (index == dev->num_statics)
224 		goto exit;
225 
226 	/* clear port */
227 	alu.port_forward &= ~BIT(port);
228 	if (!alu.port_forward)
229 		alu.is_static = false;
230 	dev->dev_ops->w_sta_mac_table(dev, index, &alu);
231 
232 exit:
233 	return ret;
234 }
235 EXPORT_SYMBOL_GPL(ksz_port_mdb_del);
236 
237 int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
238 {
239 	struct ksz_device *dev = ds->priv;
240 
241 	/* setup slave port */
242 	dev->dev_ops->port_setup(dev, port, false);
243 
244 	/* port_stp_state_set() will be called after to enable the port so
245 	 * there is no need to do anything.
246 	 */
247 
248 	return 0;
249 }
250 EXPORT_SYMBOL_GPL(ksz_enable_port);
251 
252 void ksz_disable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
253 {
254 	struct ksz_device *dev = ds->priv;
255 
256 	dev->on_ports &= ~(1 << port);
257 	dev->live_ports &= ~(1 << port);
258 
259 	/* port_stp_state_set() will be called after to disable the port so
260 	 * there is no need to do anything.
261 	 */
262 }
263 EXPORT_SYMBOL_GPL(ksz_disable_port);
264 
265 struct ksz_device *ksz_switch_alloc(struct device *base,
266 				    const struct ksz_io_ops *ops,
267 				    void *priv)
268 {
269 	struct dsa_switch *ds;
270 	struct ksz_device *swdev;
271 
272 	ds = dsa_switch_alloc(base, DSA_MAX_PORTS);
273 	if (!ds)
274 		return NULL;
275 
276 	swdev = devm_kzalloc(base, sizeof(*swdev), GFP_KERNEL);
277 	if (!swdev)
278 		return NULL;
279 
280 	ds->priv = swdev;
281 	swdev->dev = base;
282 
283 	swdev->ds = ds;
284 	swdev->priv = priv;
285 	swdev->ops = ops;
286 
287 	return swdev;
288 }
289 EXPORT_SYMBOL(ksz_switch_alloc);
290 
291 int ksz_switch_register(struct ksz_device *dev,
292 			const struct ksz_dev_ops *ops)
293 {
294 	int ret;
295 
296 	if (dev->pdata)
297 		dev->chip_id = dev->pdata->chip_id;
298 
299 	dev->reset_gpio = devm_gpiod_get_optional(dev->dev, "reset",
300 						  GPIOD_OUT_LOW);
301 	if (IS_ERR(dev->reset_gpio))
302 		return PTR_ERR(dev->reset_gpio);
303 
304 	if (dev->reset_gpio) {
305 		gpiod_set_value(dev->reset_gpio, 1);
306 		mdelay(10);
307 		gpiod_set_value(dev->reset_gpio, 0);
308 	}
309 
310 	mutex_init(&dev->reg_mutex);
311 	mutex_init(&dev->stats_mutex);
312 	mutex_init(&dev->alu_mutex);
313 	mutex_init(&dev->vlan_mutex);
314 
315 	dev->dev_ops = ops;
316 
317 	if (dev->dev_ops->detect(dev))
318 		return -EINVAL;
319 
320 	ret = dev->dev_ops->init(dev);
321 	if (ret)
322 		return ret;
323 
324 	dev->interface = PHY_INTERFACE_MODE_MII;
325 	if (dev->dev->of_node) {
326 		ret = of_get_phy_mode(dev->dev->of_node);
327 		if (ret >= 0)
328 			dev->interface = ret;
329 	}
330 
331 	ret = dsa_register_switch(dev->ds);
332 	if (ret) {
333 		dev->dev_ops->exit(dev);
334 		return ret;
335 	}
336 
337 	return 0;
338 }
339 EXPORT_SYMBOL(ksz_switch_register);
340 
341 void ksz_switch_remove(struct ksz_device *dev)
342 {
343 	dev->dev_ops->exit(dev);
344 	dsa_unregister_switch(dev->ds);
345 
346 	if (dev->reset_gpio)
347 		gpiod_set_value(dev->reset_gpio, 1);
348 
349 }
350 EXPORT_SYMBOL(ksz_switch_remove);
351 
352 MODULE_AUTHOR("Woojung Huh <Woojung.Huh@microchip.com>");
353 MODULE_DESCRIPTION("Microchip KSZ Series Switch DSA Driver");
354 MODULE_LICENSE("GPL");
355