Merge tag 'iio-fixes-for-3.19a' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / net / dsa / mv88e6352.c
1 /*
2  * net/dsa/mv88e6352.c - Marvell 88e6352 switch chip support
3  *
4  * Copyright (c) 2014 Guenter Roeck
5  *
6  * Derived from mv88e6123_61_65.c
7  * Copyright (c) 2008-2009 Marvell Semiconductor
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  */
14
15 #include <linux/delay.h>
16 #include <linux/jiffies.h>
17 #include <linux/list.h>
18 #include <linux/module.h>
19 #include <linux/netdevice.h>
20 #include <linux/platform_device.h>
21 #include <linux/phy.h>
22 #include <net/dsa.h>
23 #include "mv88e6xxx.h"
24
25 static int mv88e6352_wait(struct dsa_switch *ds, int reg, u16 mask)
26 {
27         unsigned long timeout = jiffies + HZ / 10;
28
29         while (time_before(jiffies, timeout)) {
30                 int ret;
31
32                 ret = REG_READ(REG_GLOBAL2, reg);
33                 if (ret < 0)
34                         return ret;
35
36                 if (!(ret & mask))
37                         return 0;
38
39                 usleep_range(1000, 2000);
40         }
41         return -ETIMEDOUT;
42 }
43
44 static inline int mv88e6352_phy_wait(struct dsa_switch *ds)
45 {
46         return mv88e6352_wait(ds, 0x18, 0x8000);
47 }
48
49 static inline int mv88e6352_eeprom_load_wait(struct dsa_switch *ds)
50 {
51         return mv88e6352_wait(ds, 0x14, 0x0800);
52 }
53
54 static inline int mv88e6352_eeprom_busy_wait(struct dsa_switch *ds)
55 {
56         return mv88e6352_wait(ds, 0x14, 0x8000);
57 }
58
59 static int __mv88e6352_phy_read(struct dsa_switch *ds, int addr, int regnum)
60 {
61         int ret;
62
63         REG_WRITE(REG_GLOBAL2, 0x18, 0x9800 | (addr << 5) | regnum);
64
65         ret = mv88e6352_phy_wait(ds);
66         if (ret < 0)
67                 return ret;
68
69         return REG_READ(REG_GLOBAL2, 0x19);
70 }
71
72 static int __mv88e6352_phy_write(struct dsa_switch *ds, int addr, int regnum,
73                                  u16 val)
74 {
75         REG_WRITE(REG_GLOBAL2, 0x19, val);
76         REG_WRITE(REG_GLOBAL2, 0x18, 0x9400 | (addr << 5) | regnum);
77
78         return mv88e6352_phy_wait(ds);
79 }
80
81 static char *mv88e6352_probe(struct device *host_dev, int sw_addr)
82 {
83         struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
84         int ret;
85
86         if (bus == NULL)
87                 return NULL;
88
89         ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
90         if (ret >= 0) {
91                 if ((ret & 0xfff0) == 0x1760)
92                         return "Marvell 88E6176";
93                 if (ret == 0x3521)
94                         return "Marvell 88E6352 (A0)";
95                 if (ret == 0x3522)
96                         return "Marvell 88E6352 (A1)";
97                 if ((ret & 0xfff0) == 0x3520)
98                         return "Marvell 88E6352";
99         }
100
101         return NULL;
102 }
103
104 static int mv88e6352_switch_reset(struct dsa_switch *ds)
105 {
106         unsigned long timeout;
107         int ret;
108         int i;
109
110         /* Set all ports to the disabled state. */
111         for (i = 0; i < 7; i++) {
112                 ret = REG_READ(REG_PORT(i), 0x04);
113                 REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
114         }
115
116         /* Wait for transmit queues to drain. */
117         usleep_range(2000, 4000);
118
119         /* Reset the switch. Keep PPU active (bit 14, undocumented).
120          * The PPU needs to be active to support indirect phy register
121          * accesses through global registers 0x18 and 0x19.
122          */
123         REG_WRITE(REG_GLOBAL, 0x04, 0xc000);
124
125         /* Wait up to one second for reset to complete. */
126         timeout = jiffies + 1 * HZ;
127         while (time_before(jiffies, timeout)) {
128                 ret = REG_READ(REG_GLOBAL, 0x00);
129                 if ((ret & 0x8800) == 0x8800)
130                         break;
131                 usleep_range(1000, 2000);
132         }
133         if (time_after(jiffies, timeout))
134                 return -ETIMEDOUT;
135
136         return 0;
137 }
138
139 static int mv88e6352_setup_global(struct dsa_switch *ds)
140 {
141         int ret;
142         int i;
143
144         /* Discard packets with excessive collisions,
145          * mask all interrupt sources, enable PPU (bit 14, undocumented).
146          */
147         REG_WRITE(REG_GLOBAL, 0x04, 0x6000);
148
149         /* Set the default address aging time to 5 minutes, and
150          * enable address learn messages to be sent to all message
151          * ports.
152          */
153         REG_WRITE(REG_GLOBAL, 0x0a, 0x0148);
154
155         /* Configure the priority mapping registers. */
156         ret = mv88e6xxx_config_prio(ds);
157         if (ret < 0)
158                 return ret;
159
160         /* Configure the upstream port, and configure the upstream
161          * port as the port to which ingress and egress monitor frames
162          * are to be sent.
163          */
164         REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1110));
165
166         /* Disable remote management for now, and set the switch's
167          * DSA device number.
168          */
169         REG_WRITE(REG_GLOBAL, 0x1c, ds->index & 0x1f);
170
171         /* Send all frames with destination addresses matching
172          * 01:80:c2:00:00:2x to the CPU port.
173          */
174         REG_WRITE(REG_GLOBAL2, 0x02, 0xffff);
175
176         /* Send all frames with destination addresses matching
177          * 01:80:c2:00:00:0x to the CPU port.
178          */
179         REG_WRITE(REG_GLOBAL2, 0x03, 0xffff);
180
181         /* Disable the loopback filter, disable flow control
182          * messages, disable flood broadcast override, disable
183          * removing of provider tags, disable ATU age violation
184          * interrupts, disable tag flow control, force flow
185          * control priority to the highest, and send all special
186          * multicast frames to the CPU at the highest priority.
187          */
188         REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff);
189
190         /* Program the DSA routing table. */
191         for (i = 0; i < 32; i++) {
192                 int nexthop = 0x1f;
193
194                 if (i != ds->index && i < ds->dst->pd->nr_chips)
195                         nexthop = ds->pd->rtable[i] & 0x1f;
196
197                 REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop);
198         }
199
200         /* Clear all trunk masks. */
201         for (i = 0; i < 8; i++)
202                 REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0x7f);
203
204         /* Clear all trunk mappings. */
205         for (i = 0; i < 16; i++)
206                 REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11));
207
208         /* Disable ingress rate limiting by resetting all ingress
209          * rate limit registers to their initial state.
210          */
211         for (i = 0; i < 7; i++)
212                 REG_WRITE(REG_GLOBAL2, 0x09, 0x9000 | (i << 8));
213
214         /* Initialise cross-chip port VLAN table to reset defaults. */
215         REG_WRITE(REG_GLOBAL2, 0x0b, 0x9000);
216
217         /* Clear the priority override table. */
218         for (i = 0; i < 16; i++)
219                 REG_WRITE(REG_GLOBAL2, 0x0f, 0x8000 | (i << 8));
220
221         /* @@@ initialise AVB (22/23) watchdog (27) sdet (29) registers */
222
223         return 0;
224 }
225
226 static int mv88e6352_setup_port(struct dsa_switch *ds, int p)
227 {
228         int addr = REG_PORT(p);
229         u16 val;
230
231         /* MAC Forcing register: don't force link, speed, duplex
232          * or flow control state to any particular values on physical
233          * ports, but force the CPU port and all DSA ports to 1000 Mb/s
234          * full duplex.
235          */
236         if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
237                 REG_WRITE(addr, 0x01, 0x003e);
238         else
239                 REG_WRITE(addr, 0x01, 0x0003);
240
241         /* Do not limit the period of time that this port can be
242          * paused for by the remote end or the period of time that
243          * this port can pause the remote end.
244          */
245         REG_WRITE(addr, 0x02, 0x0000);
246
247         /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
248          * disable Header mode, enable IGMP/MLD snooping, disable VLAN
249          * tunneling, determine priority by looking at 802.1p and IP
250          * priority fields (IP prio has precedence), and set STP state
251          * to Forwarding.
252          *
253          * If this is the CPU link, use DSA or EDSA tagging depending
254          * on which tagging mode was configured.
255          *
256          * If this is a link to another switch, use DSA tagging mode.
257          *
258          * If this is the upstream port for this switch, enable
259          * forwarding of unknown unicasts and multicasts.
260          */
261         val = 0x0433;
262         if (dsa_is_cpu_port(ds, p)) {
263                 if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA)
264                         val |= 0x3300;
265                 else
266                         val |= 0x0100;
267         }
268         if (ds->dsa_port_mask & (1 << p))
269                 val |= 0x0100;
270         if (p == dsa_upstream_port(ds))
271                 val |= 0x000c;
272         REG_WRITE(addr, 0x04, val);
273
274         /* Port Control 1: disable trunking.  Also, if this is the
275          * CPU port, enable learn messages to be sent to this port.
276          */
277         REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
278
279         /* Port based VLAN map: give each port its own address
280          * database, allow the CPU port to talk to each of the 'real'
281          * ports, and allow each of the 'real' ports to only talk to
282          * the upstream port.
283          */
284         val = (p & 0xf) << 12;
285         if (dsa_is_cpu_port(ds, p))
286                 val |= ds->phys_port_mask;
287         else
288                 val |= 1 << dsa_upstream_port(ds);
289         REG_WRITE(addr, 0x06, val);
290
291         /* Default VLAN ID and priority: don't set a default VLAN
292          * ID, and set the default packet priority to zero.
293          */
294         REG_WRITE(addr, 0x07, 0x0000);
295
296         /* Port Control 2: don't force a good FCS, set the maximum
297          * frame size to 10240 bytes, don't let the switch add or
298          * strip 802.1q tags, don't discard tagged or untagged frames
299          * on this port, do a destination address lookup on all
300          * received packets as usual, disable ARP mirroring and don't
301          * send a copy of all transmitted/received frames on this port
302          * to the CPU.
303          */
304         REG_WRITE(addr, 0x08, 0x2080);
305
306         /* Egress rate control: disable egress rate control. */
307         REG_WRITE(addr, 0x09, 0x0001);
308
309         /* Egress rate control 2: disable egress rate control. */
310         REG_WRITE(addr, 0x0a, 0x0000);
311
312         /* Port Association Vector: when learning source addresses
313          * of packets, add the address to the address database using
314          * a port bitmap that has only the bit for this port set and
315          * the other bits clear.
316          */
317         REG_WRITE(addr, 0x0b, 1 << p);
318
319         /* Port ATU control: disable limiting the number of address
320          * database entries that this port is allowed to use.
321          */
322         REG_WRITE(addr, 0x0c, 0x0000);
323
324         /* Priority Override: disable DA, SA and VTU priority override. */
325         REG_WRITE(addr, 0x0d, 0x0000);
326
327         /* Port Ethertype: use the Ethertype DSA Ethertype value. */
328         REG_WRITE(addr, 0x0f, ETH_P_EDSA);
329
330         /* Tag Remap: use an identity 802.1p prio -> switch prio
331          * mapping.
332          */
333         REG_WRITE(addr, 0x18, 0x3210);
334
335         /* Tag Remap 2: use an identity 802.1p prio -> switch prio
336          * mapping.
337          */
338         REG_WRITE(addr, 0x19, 0x7654);
339
340         return 0;
341 }
342
343 #ifdef CONFIG_NET_DSA_HWMON
344
345 static int mv88e6352_phy_page_read(struct dsa_switch *ds,
346                                    int port, int page, int reg)
347 {
348         struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
349         int ret;
350
351         mutex_lock(&ps->phy_mutex);
352         ret = __mv88e6352_phy_write(ds, port, 0x16, page);
353         if (ret < 0)
354                 goto error;
355         ret = __mv88e6352_phy_read(ds, port, reg);
356 error:
357         __mv88e6352_phy_write(ds, port, 0x16, 0x0);
358         mutex_unlock(&ps->phy_mutex);
359         return ret;
360 }
361
362 static int mv88e6352_phy_page_write(struct dsa_switch *ds,
363                                     int port, int page, int reg, int val)
364 {
365         struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
366         int ret;
367
368         mutex_lock(&ps->phy_mutex);
369         ret = __mv88e6352_phy_write(ds, port, 0x16, page);
370         if (ret < 0)
371                 goto error;
372
373         ret = __mv88e6352_phy_write(ds, port, reg, val);
374 error:
375         __mv88e6352_phy_write(ds, port, 0x16, 0x0);
376         mutex_unlock(&ps->phy_mutex);
377         return ret;
378 }
379
380 static int mv88e6352_get_temp(struct dsa_switch *ds, int *temp)
381 {
382         int ret;
383
384         *temp = 0;
385
386         ret = mv88e6352_phy_page_read(ds, 0, 6, 27);
387         if (ret < 0)
388                 return ret;
389
390         *temp = (ret & 0xff) - 25;
391
392         return 0;
393 }
394
395 static int mv88e6352_get_temp_limit(struct dsa_switch *ds, int *temp)
396 {
397         int ret;
398
399         *temp = 0;
400
401         ret = mv88e6352_phy_page_read(ds, 0, 6, 26);
402         if (ret < 0)
403                 return ret;
404
405         *temp = (((ret >> 8) & 0x1f) * 5) - 25;
406
407         return 0;
408 }
409
410 static int mv88e6352_set_temp_limit(struct dsa_switch *ds, int temp)
411 {
412         int ret;
413
414         ret = mv88e6352_phy_page_read(ds, 0, 6, 26);
415         if (ret < 0)
416                 return ret;
417         temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f);
418         return mv88e6352_phy_page_write(ds, 0, 6, 26,
419                                         (ret & 0xe0ff) | (temp << 8));
420 }
421
422 static int mv88e6352_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
423 {
424         int ret;
425
426         *alarm = false;
427
428         ret = mv88e6352_phy_page_read(ds, 0, 6, 26);
429         if (ret < 0)
430                 return ret;
431
432         *alarm = !!(ret & 0x40);
433
434         return 0;
435 }
436 #endif /* CONFIG_NET_DSA_HWMON */
437
438 static int mv88e6352_setup(struct dsa_switch *ds)
439 {
440         struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
441         int ret;
442         int i;
443
444         mutex_init(&ps->smi_mutex);
445         mutex_init(&ps->stats_mutex);
446         mutex_init(&ps->phy_mutex);
447         mutex_init(&ps->eeprom_mutex);
448
449         ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0;
450
451         ret = mv88e6352_switch_reset(ds);
452         if (ret < 0)
453                 return ret;
454
455         /* @@@ initialise vtu and atu */
456
457         ret = mv88e6352_setup_global(ds);
458         if (ret < 0)
459                 return ret;
460
461         for (i = 0; i < 7; i++) {
462                 ret = mv88e6352_setup_port(ds, i);
463                 if (ret < 0)
464                         return ret;
465         }
466
467         return 0;
468 }
469
470 static int mv88e6352_port_to_phy_addr(int port)
471 {
472         if (port >= 0 && port <= 4)
473                 return port;
474         return -EINVAL;
475 }
476
477 static int
478 mv88e6352_phy_read(struct dsa_switch *ds, int port, int regnum)
479 {
480         struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
481         int addr = mv88e6352_port_to_phy_addr(port);
482         int ret;
483
484         if (addr < 0)
485                 return addr;
486
487         mutex_lock(&ps->phy_mutex);
488         ret = __mv88e6352_phy_read(ds, addr, regnum);
489         mutex_unlock(&ps->phy_mutex);
490
491         return ret;
492 }
493
494 static int
495 mv88e6352_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
496 {
497         struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
498         int addr = mv88e6352_port_to_phy_addr(port);
499         int ret;
500
501         if (addr < 0)
502                 return addr;
503
504         mutex_lock(&ps->phy_mutex);
505         ret = __mv88e6352_phy_write(ds, addr, regnum, val);
506         mutex_unlock(&ps->phy_mutex);
507
508         return ret;
509 }
510
511 static struct mv88e6xxx_hw_stat mv88e6352_hw_stats[] = {
512         { "in_good_octets", 8, 0x00, },
513         { "in_bad_octets", 4, 0x02, },
514         { "in_unicast", 4, 0x04, },
515         { "in_broadcasts", 4, 0x06, },
516         { "in_multicasts", 4, 0x07, },
517         { "in_pause", 4, 0x16, },
518         { "in_undersize", 4, 0x18, },
519         { "in_fragments", 4, 0x19, },
520         { "in_oversize", 4, 0x1a, },
521         { "in_jabber", 4, 0x1b, },
522         { "in_rx_error", 4, 0x1c, },
523         { "in_fcs_error", 4, 0x1d, },
524         { "out_octets", 8, 0x0e, },
525         { "out_unicast", 4, 0x10, },
526         { "out_broadcasts", 4, 0x13, },
527         { "out_multicasts", 4, 0x12, },
528         { "out_pause", 4, 0x15, },
529         { "excessive", 4, 0x11, },
530         { "collisions", 4, 0x1e, },
531         { "deferred", 4, 0x05, },
532         { "single", 4, 0x14, },
533         { "multiple", 4, 0x17, },
534         { "out_fcs_error", 4, 0x03, },
535         { "late", 4, 0x1f, },
536         { "hist_64bytes", 4, 0x08, },
537         { "hist_65_127bytes", 4, 0x09, },
538         { "hist_128_255bytes", 4, 0x0a, },
539         { "hist_256_511bytes", 4, 0x0b, },
540         { "hist_512_1023bytes", 4, 0x0c, },
541         { "hist_1024_max_bytes", 4, 0x0d, },
542         { "sw_in_discards", 4, 0x110, },
543         { "sw_in_filtered", 2, 0x112, },
544         { "sw_out_filtered", 2, 0x113, },
545 };
546
547 static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr)
548 {
549         struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
550         int ret;
551
552         mutex_lock(&ps->eeprom_mutex);
553
554         ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, 0x14,
555                                   0xc000 | (addr & 0xff));
556         if (ret < 0)
557                 goto error;
558
559         ret = mv88e6352_eeprom_busy_wait(ds);
560         if (ret < 0)
561                 goto error;
562
563         ret = mv88e6xxx_reg_read(ds, REG_GLOBAL2, 0x15);
564 error:
565         mutex_unlock(&ps->eeprom_mutex);
566         return ret;
567 }
568
569 static int mv88e6352_get_eeprom(struct dsa_switch *ds,
570                                 struct ethtool_eeprom *eeprom, u8 *data)
571 {
572         int offset;
573         int len;
574         int ret;
575
576         offset = eeprom->offset;
577         len = eeprom->len;
578         eeprom->len = 0;
579
580         eeprom->magic = 0xc3ec4951;
581
582         ret = mv88e6352_eeprom_load_wait(ds);
583         if (ret < 0)
584                 return ret;
585
586         if (offset & 1) {
587                 int word;
588
589                 word = mv88e6352_read_eeprom_word(ds, offset >> 1);
590                 if (word < 0)
591                         return word;
592
593                 *data++ = (word >> 8) & 0xff;
594
595                 offset++;
596                 len--;
597                 eeprom->len++;
598         }
599
600         while (len >= 2) {
601                 int word;
602
603                 word = mv88e6352_read_eeprom_word(ds, offset >> 1);
604                 if (word < 0)
605                         return word;
606
607                 *data++ = word & 0xff;
608                 *data++ = (word >> 8) & 0xff;
609
610                 offset += 2;
611                 len -= 2;
612                 eeprom->len += 2;
613         }
614
615         if (len) {
616                 int word;
617
618                 word = mv88e6352_read_eeprom_word(ds, offset >> 1);
619                 if (word < 0)
620                         return word;
621
622                 *data++ = word & 0xff;
623
624                 offset++;
625                 len--;
626                 eeprom->len++;
627         }
628
629         return 0;
630 }
631
632 static int mv88e6352_eeprom_is_readonly(struct dsa_switch *ds)
633 {
634         int ret;
635
636         ret = mv88e6xxx_reg_read(ds, REG_GLOBAL2, 0x14);
637         if (ret < 0)
638                 return ret;
639
640         if (!(ret & 0x0400))
641                 return -EROFS;
642
643         return 0;
644 }
645
646 static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr,
647                                        u16 data)
648 {
649         struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
650         int ret;
651
652         mutex_lock(&ps->eeprom_mutex);
653
654         ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, 0x15, data);
655         if (ret < 0)
656                 goto error;
657
658         ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, 0x14,
659                                   0xb000 | (addr & 0xff));
660         if (ret < 0)
661                 goto error;
662
663         ret = mv88e6352_eeprom_busy_wait(ds);
664 error:
665         mutex_unlock(&ps->eeprom_mutex);
666         return ret;
667 }
668
669 static int mv88e6352_set_eeprom(struct dsa_switch *ds,
670                                 struct ethtool_eeprom *eeprom, u8 *data)
671 {
672         int offset;
673         int ret;
674         int len;
675
676         if (eeprom->magic != 0xc3ec4951)
677                 return -EINVAL;
678
679         ret = mv88e6352_eeprom_is_readonly(ds);
680         if (ret)
681                 return ret;
682
683         offset = eeprom->offset;
684         len = eeprom->len;
685         eeprom->len = 0;
686
687         ret = mv88e6352_eeprom_load_wait(ds);
688         if (ret < 0)
689                 return ret;
690
691         if (offset & 1) {
692                 int word;
693
694                 word = mv88e6352_read_eeprom_word(ds, offset >> 1);
695                 if (word < 0)
696                         return word;
697
698                 word = (*data++ << 8) | (word & 0xff);
699
700                 ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
701                 if (ret < 0)
702                         return ret;
703
704                 offset++;
705                 len--;
706                 eeprom->len++;
707         }
708
709         while (len >= 2) {
710                 int word;
711
712                 word = *data++;
713                 word |= *data++ << 8;
714
715                 ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
716                 if (ret < 0)
717                         return ret;
718
719                 offset += 2;
720                 len -= 2;
721                 eeprom->len += 2;
722         }
723
724         if (len) {
725                 int word;
726
727                 word = mv88e6352_read_eeprom_word(ds, offset >> 1);
728                 if (word < 0)
729                         return word;
730
731                 word = (word & 0xff00) | *data++;
732
733                 ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
734                 if (ret < 0)
735                         return ret;
736
737                 offset++;
738                 len--;
739                 eeprom->len++;
740         }
741
742         return 0;
743 }
744
745 static void
746 mv88e6352_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
747 {
748         mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6352_hw_stats),
749                               mv88e6352_hw_stats, port, data);
750 }
751
752 static void
753 mv88e6352_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data)
754 {
755         mv88e6xxx_get_ethtool_stats(ds, ARRAY_SIZE(mv88e6352_hw_stats),
756                                     mv88e6352_hw_stats, port, data);
757 }
758
759 static int mv88e6352_get_sset_count(struct dsa_switch *ds)
760 {
761         return ARRAY_SIZE(mv88e6352_hw_stats);
762 }
763
764 struct dsa_switch_driver mv88e6352_switch_driver = {
765         .tag_protocol           = DSA_TAG_PROTO_EDSA,
766         .priv_size              = sizeof(struct mv88e6xxx_priv_state),
767         .probe                  = mv88e6352_probe,
768         .setup                  = mv88e6352_setup,
769         .set_addr               = mv88e6xxx_set_addr_indirect,
770         .phy_read               = mv88e6352_phy_read,
771         .phy_write              = mv88e6352_phy_write,
772         .poll_link              = mv88e6xxx_poll_link,
773         .get_strings            = mv88e6352_get_strings,
774         .get_ethtool_stats      = mv88e6352_get_ethtool_stats,
775         .get_sset_count         = mv88e6352_get_sset_count,
776 #ifdef CONFIG_NET_DSA_HWMON
777         .get_temp               = mv88e6352_get_temp,
778         .get_temp_limit         = mv88e6352_get_temp_limit,
779         .set_temp_limit         = mv88e6352_set_temp_limit,
780         .get_temp_alarm         = mv88e6352_get_temp_alarm,
781 #endif
782         .get_eeprom             = mv88e6352_get_eeprom,
783         .set_eeprom             = mv88e6352_set_eeprom,
784         .get_regs_len           = mv88e6xxx_get_regs_len,
785         .get_regs               = mv88e6xxx_get_regs,
786 };
787
788 MODULE_ALIAS("platform:mv88e6352");