GNU Linux-libre 4.19.211-gnu1
[releases.git] / drivers / net / dsa / mv88e6xxx / global1_vtu.c
1 /*
2  * Marvell 88E6xxx VLAN [Spanning Tree] Translation Unit (VTU [STU]) support
3  *
4  * Copyright (c) 2008 Marvell Semiconductor
5  * Copyright (c) 2015 CMC Electronics, Inc.
6  * Copyright (c) 2017 Savoir-faire Linux, Inc.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13
14 #include <linux/interrupt.h>
15 #include <linux/irqdomain.h>
16
17 #include "chip.h"
18 #include "global1.h"
19
20 /* Offset 0x02: VTU FID Register */
21
22 static int mv88e6xxx_g1_vtu_fid_read(struct mv88e6xxx_chip *chip,
23                                      struct mv88e6xxx_vtu_entry *entry)
24 {
25         u16 val;
26         int err;
27
28         err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_FID, &val);
29         if (err)
30                 return err;
31
32         entry->fid = val & MV88E6352_G1_VTU_FID_MASK;
33
34         return 0;
35 }
36
37 static int mv88e6xxx_g1_vtu_fid_write(struct mv88e6xxx_chip *chip,
38                                       struct mv88e6xxx_vtu_entry *entry)
39 {
40         u16 val = entry->fid & MV88E6352_G1_VTU_FID_MASK;
41
42         return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_FID, val);
43 }
44
45 /* Offset 0x03: VTU SID Register */
46
47 static int mv88e6xxx_g1_vtu_sid_read(struct mv88e6xxx_chip *chip,
48                                      struct mv88e6xxx_vtu_entry *entry)
49 {
50         u16 val;
51         int err;
52
53         err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_SID, &val);
54         if (err)
55                 return err;
56
57         entry->sid = val & MV88E6352_G1_VTU_SID_MASK;
58
59         return 0;
60 }
61
62 static int mv88e6xxx_g1_vtu_sid_write(struct mv88e6xxx_chip *chip,
63                                       struct mv88e6xxx_vtu_entry *entry)
64 {
65         u16 val = entry->sid & MV88E6352_G1_VTU_SID_MASK;
66
67         return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_SID, val);
68 }
69
70 /* Offset 0x05: VTU Operation Register */
71
72 static int mv88e6xxx_g1_vtu_op_wait(struct mv88e6xxx_chip *chip)
73 {
74         return mv88e6xxx_g1_wait(chip, MV88E6XXX_G1_VTU_OP,
75                                  MV88E6XXX_G1_VTU_OP_BUSY);
76 }
77
78 static int mv88e6xxx_g1_vtu_op(struct mv88e6xxx_chip *chip, u16 op)
79 {
80         int err;
81
82         err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_OP,
83                                  MV88E6XXX_G1_VTU_OP_BUSY | op);
84         if (err)
85                 return err;
86
87         return mv88e6xxx_g1_vtu_op_wait(chip);
88 }
89
90 /* Offset 0x06: VTU VID Register */
91
92 static int mv88e6xxx_g1_vtu_vid_read(struct mv88e6xxx_chip *chip,
93                                      struct mv88e6xxx_vtu_entry *entry)
94 {
95         u16 val;
96         int err;
97
98         err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_VID, &val);
99         if (err)
100                 return err;
101
102         entry->vid = val & 0xfff;
103
104         if (val & MV88E6390_G1_VTU_VID_PAGE)
105                 entry->vid |= 0x1000;
106
107         entry->valid = !!(val & MV88E6XXX_G1_VTU_VID_VALID);
108
109         return 0;
110 }
111
112 static int mv88e6xxx_g1_vtu_vid_write(struct mv88e6xxx_chip *chip,
113                                       struct mv88e6xxx_vtu_entry *entry)
114 {
115         u16 val = entry->vid & 0xfff;
116
117         if (entry->vid & 0x1000)
118                 val |= MV88E6390_G1_VTU_VID_PAGE;
119
120         if (entry->valid)
121                 val |= MV88E6XXX_G1_VTU_VID_VALID;
122
123         return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_VID, val);
124 }
125
126 /* Offset 0x07: VTU/STU Data Register 1
127  * Offset 0x08: VTU/STU Data Register 2
128  * Offset 0x09: VTU/STU Data Register 3
129  */
130 static int mv88e6185_g1_vtu_stu_data_read(struct mv88e6xxx_chip *chip,
131                                           u16 *regs)
132 {
133         int i;
134
135         /* Read all 3 VTU/STU Data registers */
136         for (i = 0; i < 3; ++i) {
137                 u16 *reg = &regs[i];
138                 int err;
139
140                 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
141                 if (err)
142                         return err;
143         }
144
145         return 0;
146 }
147
148 static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip,
149                                       struct mv88e6xxx_vtu_entry *entry)
150 {
151         u16 regs[3];
152         int err;
153         int i;
154
155         err = mv88e6185_g1_vtu_stu_data_read(chip, regs);
156         if (err)
157                 return err;
158
159         /* Extract MemberTag data */
160         for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
161                 unsigned int member_offset = (i % 4) * 4;
162
163                 entry->member[i] = (regs[i / 4] >> member_offset) & 0x3;
164         }
165
166         return 0;
167 }
168
169 static int mv88e6185_g1_stu_data_read(struct mv88e6xxx_chip *chip,
170                                       struct mv88e6xxx_vtu_entry *entry)
171 {
172         u16 regs[3];
173         int err;
174         int i;
175
176         err = mv88e6185_g1_vtu_stu_data_read(chip, regs);
177         if (err)
178                 return err;
179
180         /* Extract PortState data */
181         for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
182                 unsigned int state_offset = (i % 4) * 4 + 2;
183
184                 entry->state[i] = (regs[i / 4] >> state_offset) & 0x3;
185         }
186
187         return 0;
188 }
189
190 static int mv88e6185_g1_vtu_data_write(struct mv88e6xxx_chip *chip,
191                                        struct mv88e6xxx_vtu_entry *entry)
192 {
193         u16 regs[3] = { 0 };
194         int i;
195
196         /* Insert MemberTag and PortState data */
197         for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
198                 unsigned int member_offset = (i % 4) * 4;
199                 unsigned int state_offset = member_offset + 2;
200
201                 regs[i / 4] |= (entry->member[i] & 0x3) << member_offset;
202                 regs[i / 4] |= (entry->state[i] & 0x3) << state_offset;
203         }
204
205         /* Write all 3 VTU/STU Data registers */
206         for (i = 0; i < 3; ++i) {
207                 u16 reg = regs[i];
208                 int err;
209
210                 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
211                 if (err)
212                         return err;
213         }
214
215         return 0;
216 }
217
218 static int mv88e6390_g1_vtu_data_read(struct mv88e6xxx_chip *chip, u8 *data)
219 {
220         u16 regs[2];
221         int i;
222
223         /* Read the 2 VTU/STU Data registers */
224         for (i = 0; i < 2; ++i) {
225                 u16 *reg = &regs[i];
226                 int err;
227
228                 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
229                 if (err)
230                         return err;
231         }
232
233         /* Extract data */
234         for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
235                 unsigned int offset = (i % 8) * 2;
236
237                 data[i] = (regs[i / 8] >> offset) & 0x3;
238         }
239
240         return 0;
241 }
242
243 static int mv88e6390_g1_vtu_data_write(struct mv88e6xxx_chip *chip, u8 *data)
244 {
245         u16 regs[2] = { 0 };
246         int i;
247
248         /* Insert data */
249         for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
250                 unsigned int offset = (i % 8) * 2;
251
252                 regs[i / 8] |= (data[i] & 0x3) << offset;
253         }
254
255         /* Write the 2 VTU/STU Data registers */
256         for (i = 0; i < 2; ++i) {
257                 u16 reg = regs[i];
258                 int err;
259
260                 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg);
261                 if (err)
262                         return err;
263         }
264
265         return 0;
266 }
267
268 /* VLAN Translation Unit Operations */
269
270 static int mv88e6xxx_g1_vtu_stu_getnext(struct mv88e6xxx_chip *chip,
271                                         struct mv88e6xxx_vtu_entry *entry)
272 {
273         int err;
274
275         err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
276         if (err)
277                 return err;
278
279         err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_GET_NEXT);
280         if (err)
281                 return err;
282
283         err = mv88e6xxx_g1_vtu_sid_read(chip, entry);
284         if (err)
285                 return err;
286
287         return mv88e6xxx_g1_vtu_vid_read(chip, entry);
288 }
289
290 static int mv88e6xxx_g1_vtu_stu_get(struct mv88e6xxx_chip *chip,
291                                     struct mv88e6xxx_vtu_entry *vtu)
292 {
293         struct mv88e6xxx_vtu_entry stu;
294         int err;
295
296         err = mv88e6xxx_g1_vtu_sid_read(chip, vtu);
297         if (err)
298                 return err;
299
300         stu.sid = vtu->sid - 1;
301
302         err = mv88e6xxx_g1_vtu_stu_getnext(chip, &stu);
303         if (err)
304                 return err;
305
306         if (stu.sid != vtu->sid || !stu.valid)
307                 return -EINVAL;
308
309         return 0;
310 }
311
312 static int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
313                                     struct mv88e6xxx_vtu_entry *entry)
314 {
315         int err;
316
317         err = mv88e6xxx_g1_vtu_op_wait(chip);
318         if (err)
319                 return err;
320
321         /* To get the next higher active VID, the VTU GetNext operation can be
322          * started again without setting the VID registers since it already
323          * contains the last VID.
324          *
325          * To save a few hardware accesses and abstract this to the caller,
326          * write the VID only once, when the entry is given as invalid.
327          */
328         if (!entry->valid) {
329                 err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
330                 if (err)
331                         return err;
332         }
333
334         err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT);
335         if (err)
336                 return err;
337
338         return mv88e6xxx_g1_vtu_vid_read(chip, entry);
339 }
340
341 int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
342                              struct mv88e6xxx_vtu_entry *entry)
343 {
344         u16 val;
345         int err;
346
347         err = mv88e6xxx_g1_vtu_getnext(chip, entry);
348         if (err)
349                 return err;
350
351         if (entry->valid) {
352                 err = mv88e6185_g1_vtu_data_read(chip, entry);
353                 if (err)
354                         return err;
355
356                 err = mv88e6185_g1_stu_data_read(chip, entry);
357                 if (err)
358                         return err;
359
360                 /* VTU DBNum[3:0] are located in VTU Operation 3:0
361                  * VTU DBNum[7:4] are located in VTU Operation 11:8
362                  */
363                 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
364                 if (err)
365                         return err;
366
367                 entry->fid = val & 0x000f;
368                 entry->fid |= (val & 0x0f00) >> 4;
369         }
370
371         return 0;
372 }
373
374 int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
375                              struct mv88e6xxx_vtu_entry *entry)
376 {
377         int err;
378
379         /* Fetch VLAN MemberTag data from the VTU */
380         err = mv88e6xxx_g1_vtu_getnext(chip, entry);
381         if (err)
382                 return err;
383
384         if (entry->valid) {
385                 err = mv88e6185_g1_vtu_data_read(chip, entry);
386                 if (err)
387                         return err;
388
389                 err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
390                 if (err)
391                         return err;
392
393                 /* Fetch VLAN PortState data from the STU */
394                 err = mv88e6xxx_g1_vtu_stu_get(chip, entry);
395                 if (err)
396                         return err;
397
398                 err = mv88e6185_g1_stu_data_read(chip, entry);
399                 if (err)
400                         return err;
401         }
402
403         return 0;
404 }
405
406 int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
407                              struct mv88e6xxx_vtu_entry *entry)
408 {
409         int err;
410
411         /* Fetch VLAN MemberTag data from the VTU */
412         err = mv88e6xxx_g1_vtu_getnext(chip, entry);
413         if (err)
414                 return err;
415
416         if (entry->valid) {
417                 err = mv88e6390_g1_vtu_data_read(chip, entry->member);
418                 if (err)
419                         return err;
420
421                 /* Fetch VLAN PortState data from the STU */
422                 err = mv88e6xxx_g1_vtu_stu_get(chip, entry);
423                 if (err)
424                         return err;
425
426                 err = mv88e6390_g1_vtu_data_read(chip, entry->state);
427                 if (err)
428                         return err;
429
430                 err = mv88e6xxx_g1_vtu_fid_read(chip, entry);
431                 if (err)
432                         return err;
433         }
434
435         return 0;
436 }
437
438 int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
439                                struct mv88e6xxx_vtu_entry *entry)
440 {
441         u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE;
442         int err;
443
444         err = mv88e6xxx_g1_vtu_op_wait(chip);
445         if (err)
446                 return err;
447
448         err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
449         if (err)
450                 return err;
451
452         if (entry->valid) {
453                 err = mv88e6185_g1_vtu_data_write(chip, entry);
454                 if (err)
455                         return err;
456
457                 /* VTU DBNum[3:0] are located in VTU Operation 3:0
458                  * VTU DBNum[7:4] are located in VTU Operation 11:8
459                  */
460                 op |= entry->fid & 0x000f;
461                 op |= (entry->fid & 0x00f0) << 4;
462         }
463
464         return mv88e6xxx_g1_vtu_op(chip, op);
465 }
466
467 int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
468                                struct mv88e6xxx_vtu_entry *entry)
469 {
470         int err;
471
472         err = mv88e6xxx_g1_vtu_op_wait(chip);
473         if (err)
474                 return err;
475
476         err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
477         if (err)
478                 return err;
479
480         if (entry->valid) {
481                 /* Write MemberTag and PortState data */
482                 err = mv88e6185_g1_vtu_data_write(chip, entry);
483                 if (err)
484                         return err;
485
486                 err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
487                 if (err)
488                         return err;
489
490                 /* Load STU entry */
491                 err = mv88e6xxx_g1_vtu_op(chip,
492                                           MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
493                 if (err)
494                         return err;
495
496                 err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
497                 if (err)
498                         return err;
499         }
500
501         /* Load/Purge VTU entry */
502         return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
503 }
504
505 int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
506                                struct mv88e6xxx_vtu_entry *entry)
507 {
508         int err;
509
510         err = mv88e6xxx_g1_vtu_op_wait(chip);
511         if (err)
512                 return err;
513
514         err = mv88e6xxx_g1_vtu_vid_write(chip, entry);
515         if (err)
516                 return err;
517
518         if (entry->valid) {
519                 /* Write PortState data */
520                 err = mv88e6390_g1_vtu_data_write(chip, entry->state);
521                 if (err)
522                         return err;
523
524                 err = mv88e6xxx_g1_vtu_sid_write(chip, entry);
525                 if (err)
526                         return err;
527
528                 /* Load STU entry */
529                 err = mv88e6xxx_g1_vtu_op(chip,
530                                           MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE);
531                 if (err)
532                         return err;
533
534                 /* Write MemberTag data */
535                 err = mv88e6390_g1_vtu_data_write(chip, entry->member);
536                 if (err)
537                         return err;
538
539                 err = mv88e6xxx_g1_vtu_fid_write(chip, entry);
540                 if (err)
541                         return err;
542         }
543
544         /* Load/Purge VTU entry */
545         return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE);
546 }
547
548 int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip)
549 {
550         int err;
551
552         err = mv88e6xxx_g1_vtu_op_wait(chip);
553         if (err)
554                 return err;
555
556         return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_FLUSH_ALL);
557 }
558
559 static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id)
560 {
561         struct mv88e6xxx_chip *chip = dev_id;
562         struct mv88e6xxx_vtu_entry entry;
563         int spid;
564         int err;
565         u16 val;
566
567         mutex_lock(&chip->reg_lock);
568
569         err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION);
570         if (err)
571                 goto out;
572
573         err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val);
574         if (err)
575                 goto out;
576
577         err = mv88e6xxx_g1_vtu_vid_read(chip, &entry);
578         if (err)
579                 goto out;
580
581         spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;
582
583         if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) {
584                 dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n",
585                                     entry.vid, spid);
586                 chip->ports[spid].vtu_member_violation++;
587         }
588
589         if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) {
590                 dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n",
591                                     entry.vid, spid);
592                 chip->ports[spid].vtu_miss_violation++;
593         }
594
595         mutex_unlock(&chip->reg_lock);
596
597         return IRQ_HANDLED;
598
599 out:
600         mutex_unlock(&chip->reg_lock);
601
602         dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n",
603                 err);
604
605         return IRQ_HANDLED;
606 }
607
608 int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip)
609 {
610         int err;
611
612         chip->vtu_prob_irq = irq_find_mapping(chip->g1_irq.domain,
613                                               MV88E6XXX_G1_STS_IRQ_VTU_PROB);
614         if (chip->vtu_prob_irq < 0)
615                 return chip->vtu_prob_irq;
616
617         err = request_threaded_irq(chip->vtu_prob_irq, NULL,
618                                    mv88e6xxx_g1_vtu_prob_irq_thread_fn,
619                                    IRQF_ONESHOT, "mv88e6xxx-g1-vtu-prob",
620                                    chip);
621         if (err)
622                 irq_dispose_mapping(chip->vtu_prob_irq);
623
624         return err;
625 }
626
627 void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip)
628 {
629         free_irq(chip->vtu_prob_irq, chip);
630         irq_dispose_mapping(chip->vtu_prob_irq);
631 }