First git repo commit for the libreCMC project
[librecmc/librecmc.git] / target / linux / generic / files / drivers / net / phy / mvsw61xx.h
1 /*
2  * Marvell 88E61xx switch driver
3  *
4  * Copyright (c) 2014 Claudio Leite <leitec@staticky.com>
5  * Copyright (c) 2014 Nikita Nazarenko <nnazarenko@radiofid.com>
6  *
7  * Based on code (c) 2008 Felix Fietkau <nbd@nbd.name>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License v2 as published by the
11  * Free Software Foundation
12  */
13
14 #ifndef __MVSW61XX_H
15 #define __MVSW61XX_H
16
17 #define MV_PORTS                        7
18 #define MV_PORTS_MASK                   ((1 << MV_PORTS) - 1)
19
20 #define MV_BASE                         0x10
21
22 #define MV_SWITCHPORT_BASE              0x10
23 #define MV_SWITCHPORT(_n)               (MV_SWITCHPORT_BASE + (_n))
24 #define MV_SWITCHREGS                   (MV_BASE + 0xb)
25
26 #define MV_VLANS                        64
27
28 enum {
29         MV_PORT_STATUS                  = 0x00,
30         MV_PORT_PHYCTL                  = 0x01,
31         MV_PORT_JAMCTL                  = 0x02,
32         MV_PORT_IDENT                   = 0x03,
33         MV_PORT_CONTROL                 = 0x04,
34         MV_PORT_CONTROL1                = 0x05,
35         MV_PORT_VLANMAP                 = 0x06,
36         MV_PORT_VLANID                  = 0x07,
37         MV_PORT_CONTROL2                = 0x08,
38         MV_PORT_ASSOC                   = 0x0b,
39         MV_PORT_RX_DISCARD_LOW          = 0x10,
40         MV_PORT_RX_DISCARD_HIGH         = 0x11,
41         MV_PORT_IN_FILTERED             = 0x12,
42         MV_PORT_OUT_ACCEPTED            = 0x13,
43 };
44 #define MV_PORTREG(_type, _port) MV_SWITCHPORT(_port), MV_PORT_##_type
45
46 enum {
47         MV_PORT_STATUS_FDX              = (1 << 10),
48         MV_PORT_STATUS_LINK             = (1 << 11),
49 };
50
51 enum {
52         MV_PORT_STATUS_CMODE_100BASE_X  = 0x8,
53         MV_PORT_STATUS_CMODE_1000BASE_X = 0x9,
54         MV_PORT_STATUS_CMODE_SGMII      = 0xa,
55 };
56
57 #define MV_PORT_STATUS_CMODE_MASK       0xf
58
59 enum {
60         MV_PORT_STATUS_SPEED_10         = 0x00,
61         MV_PORT_STATUS_SPEED_100        = 0x01,
62         MV_PORT_STATUS_SPEED_1000       = 0x02,
63 };
64 #define MV_PORT_STATUS_SPEED_SHIFT      8
65 #define MV_PORT_STATUS_SPEED_MASK       (3 << 8)
66
67 enum {
68         MV_PORTCTRL_DISABLED            = (0 << 0),
69         MV_PORTCTRL_BLOCKING            = (1 << 0),
70         MV_PORTCTRL_LEARNING            = (2 << 0),
71         MV_PORTCTRL_FORWARDING          = (3 << 0),
72         MV_PORTCTRL_VLANTUN             = (1 << 7),
73         MV_PORTCTRL_EGRESS              = (1 << 12),
74 };
75
76 #define MV_PHYCTL_FC_MASK               (3 << 6)
77
78 enum {
79         MV_PHYCTL_FC_ENABLE             = (3 << 6),
80         MV_PHYCTL_FC_DISABLE            = (1 << 6),
81 };
82
83 enum {
84         MV_8021Q_EGRESS_UNMODIFIED      = 0x00,
85         MV_8021Q_EGRESS_UNTAGGED        = 0x01,
86         MV_8021Q_EGRESS_TAGGED          = 0x02,
87         MV_8021Q_EGRESS_ADDTAG          = 0x03,
88 };
89
90 #define MV_8021Q_MODE_SHIFT             10
91 #define MV_8021Q_MODE_MASK              (0x3 << MV_8021Q_MODE_SHIFT)
92
93 enum {
94         MV_8021Q_MODE_DISABLE           = 0x00,
95         MV_8021Q_MODE_FALLBACK          = 0x01,
96         MV_8021Q_MODE_CHECK             = 0x02,
97         MV_8021Q_MODE_SECURE            = 0x03,
98 };
99
100 enum {
101         MV_8021Q_VLAN_ONLY              = (1 << 15),
102 };
103
104 #define MV_PORTASSOC_MONITOR            (1 << 15)
105
106 enum {
107         MV_SWITCH_ATU_FID0              = 0x01,
108         MV_SWITCH_ATU_FID1              = 0x02,
109         MV_SWITCH_ATU_SID               = 0x03,
110         MV_SWITCH_CTRL                  = 0x04,
111         MV_SWITCH_ATU_CTRL              = 0x0a,
112         MV_SWITCH_ATU_OP                = 0x0b,
113         MV_SWITCH_ATU_DATA              = 0x0c,
114         MV_SWITCH_ATU_MAC0              = 0x0d,
115         MV_SWITCH_ATU_MAC1              = 0x0e,
116         MV_SWITCH_ATU_MAC2              = 0x0f,
117         MV_SWITCH_GLOBAL                = 0x1b,
118         MV_SWITCH_GLOBAL2               = 0x1c,
119 };
120 #define MV_SWITCHREG(_type) MV_SWITCHREGS, MV_SWITCH_##_type
121
122 enum {
123         MV_SWITCHCTL_EEIE               = (1 << 0),
124         MV_SWITCHCTL_PHYIE              = (1 << 1),
125         MV_SWITCHCTL_ATUDONE            = (1 << 2),
126         MV_SWITCHCTL_ATUIE              = (1 << 3),
127         MV_SWITCHCTL_CTRMODE            = (1 << 8),
128         MV_SWITCHCTL_RELOAD             = (1 << 9),
129         MV_SWITCHCTL_MSIZE              = (1 << 10),
130         MV_SWITCHCTL_DROP               = (1 << 13),
131 };
132
133 enum {
134 #define MV_ATUCTL_AGETIME_MIN           16
135 #define MV_ATUCTL_AGETIME_MAX           4080
136 #define MV_ATUCTL_AGETIME(_n)           ((((_n) / 16) & 0xff) << 4)
137         MV_ATUCTL_ATU_256               = (0 << 12),
138         MV_ATUCTL_ATU_512               = (1 << 12),
139         MV_ATUCTL_ATU_1K                = (2 << 12),
140         MV_ATUCTL_ATUMASK               = (3 << 12),
141         MV_ATUCTL_NO_LEARN              = (1 << 14),
142         MV_ATUCTL_RESET                 = (1 << 15),
143 };
144
145 enum {
146 #define MV_ATUOP_DBNUM(_n)              ((_n) & 0x0f)
147         MV_ATUOP_NOOP                   = (0 << 12),
148         MV_ATUOP_FLUSH_ALL              = (1 << 12),
149         MV_ATUOP_FLUSH_U                = (2 << 12),
150         MV_ATUOP_LOAD_DB                = (3 << 12),
151         MV_ATUOP_GET_NEXT               = (4 << 12),
152         MV_ATUOP_FLUSH_DB               = (5 << 12),
153         MV_ATUOP_FLUSH_DB_UU            = (6 << 12),
154         MV_ATUOP_INPROGRESS             = (1 << 15),
155 };
156
157 enum {
158         MV_GLOBAL_STATUS                = 0x00,
159         MV_GLOBAL_ATU_FID               = 0x01,
160         MV_GLOBAL_VTU_FID               = 0x02,
161         MV_GLOBAL_VTU_SID               = 0x03,
162         MV_GLOBAL_CONTROL               = 0x04,
163         MV_GLOBAL_VTU_OP                = 0x05,
164         MV_GLOBAL_VTU_VID               = 0x06,
165         MV_GLOBAL_VTU_DATA1             = 0x07,
166         MV_GLOBAL_VTU_DATA2             = 0x08,
167         MV_GLOBAL_VTU_DATA3             = 0x09,
168         MV_GLOBAL_CONTROL2              = 0x1c,
169 };
170 #define MV_GLOBALREG(_type) MV_SWITCH_GLOBAL, MV_GLOBAL_##_type
171
172 enum {
173         MV_GLOBAL2_SMI_OP               = 0x18,
174         MV_GLOBAL2_SMI_DATA             = 0x19,
175         MV_GLOBAL2_SDET_POLARITY        = 0x1d,
176 };
177 #define MV_GLOBAL2REG(_type) MV_SWITCH_GLOBAL2, MV_GLOBAL2_##_type
178
179 enum {
180         MV_VTU_VID_VALID                = (1 << 12),
181 };
182
183 enum {
184         MV_VTUOP_PURGE                  = (1 << 12),
185         MV_VTUOP_LOAD                   = (3 << 12),
186         MV_VTUOP_INPROGRESS             = (1 << 15),
187         MV_VTUOP_STULOAD                = (5 << 12),
188         MV_VTUOP_VTU_GET_NEXT           = (4 << 12),
189         MV_VTUOP_STU_GET_NEXT           = (6 << 12),
190         MV_VTUOP_GET_VIOLATION          = (7 << 12),
191 };
192
193 enum {
194         MV_CONTROL_RESET                = (1 << 15),
195         MV_CONTROL_PPU_ENABLE           = (1 << 14),
196 };
197
198 enum {
199         MV_VTUCTL_EGRESS_UNMODIFIED     = (0 << 0),
200         MV_VTUCTL_EGRESS_UNTAGGED       = (1 << 0),
201         MV_VTUCTL_EGRESS_TAGGED         = (2 << 0),
202         MV_VTUCTL_DISCARD               = (3 << 0),
203 };
204
205 enum {
206         MV_STUCTL_STATE_DISABLED        = (0 << 0),
207         MV_STUCTL_STATE_BLOCKING        = (1 << 0),
208         MV_STUCTL_STATE_LEARNING        = (2 << 0),
209         MV_STUCTL_STATE_FORWARDING      = (3 << 0),
210 };
211
212 enum {
213         MV_INDIRECT_REG_CMD             = 0,
214         MV_INDIRECT_REG_DATA            = 1,
215 };
216
217 enum {
218         MV_INDIRECT_INPROGRESS          = 0x8000,
219         MV_INDIRECT_WRITE               = 0x9400,
220         MV_INDIRECT_READ                = 0x9800,
221 };
222 #define MV_INDIRECT_ADDR_S              5
223
224 #define MV_IDENT_MASK                   0xfff0
225
226 #define MV_IDENT_VALUE_6171             0x1710
227 #define MV_IDENT_STR_6171               "MV88E6171"
228
229 #define MV_IDENT_VALUE_6172             0x1720
230 #define MV_IDENT_STR_6172               "MV88E6172"
231
232 #define MV_IDENT_VALUE_6176             0x1760
233 #define MV_IDENT_STR_6176               "MV88E6176"
234
235 #define MV_PVID_MASK                    0x0fff
236
237 #define MV_FDB_HI_MASK                  0x00ff
238 #define MV_FDB_LO_MASK                  0xf000
239 #define MV_FDB_HI_SHIFT                 4
240 #define MV_FDB_LO_SHIFT                 12
241
242 /* Marvell Specific PHY register */
243 #define MII_MV_SPEC_CTRL                16
244 enum {
245         MV_SPEC_MDI_CROSS_AUTO          = (0x6 << 4),
246         MV_SPEC_ENERGY_DETECT           = (0x3 << 8),
247         MV_SPEC_DOWNSHIFT_COUNTER       = (0x3 << 12),
248 };
249
250 #define MII_MV_PAGE                     22
251
252 #define MV_REG_FIBER_SERDES             0xf
253 #define MV_PAGE_FIBER_SERDES            0x1
254
255 struct mvsw61xx_state {
256         struct switch_dev dev;
257         struct mii_bus *bus;
258         int base_addr;
259         u16 model;
260
261         bool registered;
262         bool is_indirect;
263
264         int cpu_port0;
265         int cpu_port1;
266
267         int vlan_enabled;
268         struct port_state {
269                 u16 fdb;
270                 u16 pvid;
271                 u16 mask;
272                 u8 qmode;
273         } ports[MV_PORTS];
274
275         struct vlan_state {
276                 bool port_based;
277
278                 u16 mask;
279                 u16 vid;
280                 u32 port_mode;
281                 u32 port_sstate;
282         } vlans[MV_VLANS];
283
284         char buf[128];
285 };
286
287 #define get_state(_dev) container_of((_dev), struct mvsw61xx_state, dev)
288
289 #endif