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