bd9d60a8a77d3f83386918608cef5ad6461b55a5
[openwrt.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  *
6  * Based on code (c) 2008 Felix Fietkau <nbd@openwrt.org>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License v2 as published by the
10  * Free Software Foundation
11  */
12
13 #ifndef __MVSW61XX_H
14 #define __MVSW61XX_H
15
16 #define MV_PORTS                        7
17 #define MV_PORTS_MASK                   ((1 << MV_PORTS) - 1)
18
19 #define MV_CPUPORT                      6
20
21 #define MV_BASE                         0x10
22
23 #define MV_SWITCHPORT_BASE              0x10
24 #define MV_SWITCHPORT(_n)               (MV_SWITCHPORT_BASE + (_n))
25 #define MV_SWITCHREGS                   (MV_BASE + 0xb)
26
27 #define MV_VLANS                        64
28
29 enum {
30         MV_PORT_STATUS                  = 0x00,
31         MV_PORT_FORCE                   = 0x01,
32         MV_PORT_PAUSE                   = 0x02,
33         MV_PORT_IDENT                   = 0x03,
34         MV_PORT_CONTROL                 = 0x04,
35         MV_PORT_CONTROL1                = 0x05,
36         MV_PORT_VLANMAP                 = 0x06,
37         MV_PORT_VLANID                  = 0x07,
38         MV_PORT_CONTROL2                = 0x08,
39         MV_PORT_ASSOC                   = 0x0b,
40         MV_PORT_RXCOUNT                 = 0x10,
41         MV_PORT_TXCOUNT                 = 0x11,
42 };
43 #define MV_PORTREG(_type, _port) MV_SWITCHPORT(_port), MV_PORT_##_type
44
45 enum {
46         MV_PORT_STATUS_FDX              = (1 << 10),
47         MV_PORT_STATUS_LINK             = (1 << 11),
48 };
49
50 enum {
51         MV_PORT_STATUS_SPEED_10         = 0x00,
52         MV_PORT_STATUS_SPEED_100        = 0x01,
53         MV_PORT_STATUS_SPEED_1000       = 0x02,
54 };
55 #define MV_PORT_STATUS_SPEED_SHIFT      8
56 #define MV_PORT_STATUS_SPEED_MASK       (3 << 8)
57
58 enum {
59         MV_PORTCTRL_BLOCK               = (1 << 0),
60         MV_PORTCTRL_LEARN               = (2 << 0),
61         MV_PORTCTRL_ENABLED             = (3 << 0),
62         MV_PORTCTRL_VLANTUN             = (1 << 7),
63         MV_PORTCTRL_EGRESS              = (1 << 12),
64 };
65
66 #define MV_FORCE_FC_MASK                (3 << 6)
67
68 enum {
69         MV_FORCE_FC_ENABLE              = (3 << 6),
70         MV_FORCE_FC_DISABLE             = (1 << 6),
71 };
72
73 enum {
74         MV_8021Q_EGRESS_UNMODIFIED      = 0x00,
75         MV_8021Q_EGRESS_UNTAGGED        = 0x01,
76         MV_8021Q_EGRESS_TAGGED          = 0x02,
77         MV_8021Q_EGRESS_ADDTAG          = 0x03,
78 };
79
80 #define MV_8021Q_MODE_SHIFT             10
81 #define MV_8021Q_MODE_MASK              (0x3 << MV_8021Q_MODE_SHIFT)
82
83 enum {
84         MV_8021Q_MODE_DISABLE           = 0x00,
85         MV_8021Q_MODE_FALLBACK          = 0x01,
86         MV_8021Q_MODE_CHECK             = 0x02,
87         MV_8021Q_MODE_SECURE            = 0x03,
88 };
89
90 #define MV_PORTASSOC_MONITOR            (1 << 15)
91
92 enum {
93         MV_SWITCH_MAC0                  = 0x01,
94         MV_SWITCH_MAC1                  = 0x02,
95         MV_SWITCH_MAC2                  = 0x03,
96         MV_SWITCH_CTRL                  = 0x04,
97         MV_SWITCH_ATU_CTRL              = 0x0a,
98         MV_SWITCH_ATU_OP                = 0x0b,
99         MV_SWITCH_ATU_DATA              = 0x0c,
100         MV_SWITCH_ATU_MAC0              = 0x0d,
101         MV_SWITCH_ATU_MAC1              = 0x0e,
102         MV_SWITCH_ATU_MAC2              = 0x0f,
103         MV_SWITCH_GLOBAL                = 0x1b,
104         MV_SWITCH_GLOBAL2               = 0x1c,
105 };
106 #define MV_SWITCHREG(_type) MV_SWITCHREGS, MV_SWITCH_##_type
107
108 enum {
109         MV_SWITCHCTL_EEIE               = (1 << 0),
110         MV_SWITCHCTL_PHYIE              = (1 << 1),
111         MV_SWITCHCTL_ATUDONE            = (1 << 2),
112         MV_SWITCHCTL_ATUIE              = (1 << 3),
113         MV_SWITCHCTL_CTRMODE            = (1 << 8),
114         MV_SWITCHCTL_RELOAD             = (1 << 9),
115         MV_SWITCHCTL_MSIZE              = (1 << 10),
116         MV_SWITCHCTL_DROP               = (1 << 13),
117 };
118
119 enum {
120 #define MV_ATUCTL_AGETIME_MIN           16
121 #define MV_ATUCTL_AGETIME_MAX           4080
122 #define MV_ATUCTL_AGETIME(_n)           ((((_n) / 16) & 0xff) << 4)
123         MV_ATUCTL_ATU_256               = (0 << 12),
124         MV_ATUCTL_ATU_512               = (1 << 12),
125         MV_ATUCTL_ATU_1K                = (2 << 12),
126         MV_ATUCTL_ATUMASK               = (3 << 12),
127         MV_ATUCTL_NO_LEARN              = (1 << 14),
128         MV_ATUCTL_RESET                 = (1 << 15),
129 };
130
131 enum {
132 #define MV_ATUOP_DBNUM(_n)              ((_n) & 0x0f)
133         MV_ATUOP_NOOP                   = (0 << 12),
134         MV_ATUOP_FLUSH_ALL              = (1 << 12),
135         MV_ATUOP_FLUSH_U                = (2 << 12),
136         MV_ATUOP_LOAD_DB                = (3 << 12),
137         MV_ATUOP_GET_NEXT               = (4 << 12),
138         MV_ATUOP_FLUSH_DB               = (5 << 12),
139         MV_ATUOP_FLUSH_DB_UU            = (6 << 12),
140         MV_ATUOP_INPROGRESS             = (1 << 15),
141 };
142
143 enum {
144         MV_GLOBAL_STATUS                = 0x00,
145         MV_GLOBAL_CONTROL               = 0x04,
146         MV_GLOBAL_VTU_OP                = 0x05,
147         MV_GLOBAL_VTU_VID               = 0x06,
148         MV_GLOBAL_VTU_DATA1             = 0x07,
149         MV_GLOBAL_VTU_DATA2             = 0x08,
150         MV_GLOBAL_VTU_DATA3             = 0x09,
151 };
152 #define MV_GLOBALREG(_type) MV_SWITCH_GLOBAL, MV_GLOBAL_##_type
153
154 enum {
155         MV_GLOBAL2_SDET_POLARITY        = 0x1D,
156 };
157 #define MV_GLOBAL2REG(_type) MV_SWITCH_GLOBAL2, MV_GLOBAL2_##_type
158
159 enum {
160         MV_VTUOP_VALID                  = (1 << 12),
161         MV_VTUOP_LOAD                   = (3 << 12),
162         MV_VTUOP_INPROGRESS             = (1 << 15),
163 };
164
165 enum {
166         MV_CONTROL_RESET                = (1 << 15),
167         MV_CONTROL_PPU_ENABLE           = (1 << 14),
168 };
169
170 enum {
171         MV_VTUCTL_EGRESS_UNMODIFIED     = 0x00,
172         MV_VTUCTL_EGRESS_UNTAGGED       = 0x01,
173         MV_VTUCTL_EGRESS_TAGGED         = 0x02,
174         MV_VTUCTL_DISCARD               = 0x03,
175 };
176
177 enum {
178         MV_8021Q_VLAN_ONLY              = (1 << 15),
179 };
180
181 enum {
182         MV_INDIRECT_REG_CMD             = 0,
183         MV_INDIRECT_REG_DATA            = 1,
184 };
185
186 enum {
187         MV_INDIRECT_INPROGRESS          = 0x8000,
188         MV_INDIRECT_WRITE               = 0x9400,
189         MV_INDIRECT_READ                = 0x9800,
190 };
191 #define MV_INDIRECT_ADDR_S              5
192
193 #define MV_IDENT_MASK                   0xffc0
194 #define MV_IDENT_VALUE                  0x1700
195 #define MV_IDENT_STR                    "MV88E617x"
196
197 #define MV_PVID_MASK                    0x0fff
198
199 struct mvsw61xx_state {
200         struct switch_dev dev;
201         struct mii_bus *bus;
202         int base_addr;
203
204         bool registered;
205         bool is_indirect;
206
207         int cpu_port0;
208         int cpu_port1;
209
210         int vlan_enabled;
211         struct port_state {
212                 u16 pvid;
213                 u16 mask;
214                 u8 qmode;
215         } ports[MV_PORTS];
216
217         struct vlan_state {
218                 bool port_based;
219
220                 u16 mask;
221                 u16 vid;
222                 u32 port_mode;
223         } vlans[MV_VLANS];
224
225         char buf[128];
226 };
227
228 #define get_state(_dev) container_of((_dev), struct mvsw61xx_state, dev)
229
230 #endif