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