treewide: replace nbd@openwrt.org with nbd@nbd.name
[openwrt/staging/lynxis/omap.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_SPEED_10 = 0x00,
53 MV_PORT_STATUS_SPEED_100 = 0x01,
54 MV_PORT_STATUS_SPEED_1000 = 0x02,
55 };
56 #define MV_PORT_STATUS_SPEED_SHIFT 8
57 #define MV_PORT_STATUS_SPEED_MASK (3 << 8)
58
59 enum {
60 MV_PORTCTRL_DISABLED = (0 << 0),
61 MV_PORTCTRL_BLOCKING = (1 << 0),
62 MV_PORTCTRL_LEARNING = (2 << 0),
63 MV_PORTCTRL_FORWARDING = (3 << 0),
64 MV_PORTCTRL_VLANTUN = (1 << 7),
65 MV_PORTCTRL_EGRESS = (1 << 12),
66 };
67
68 #define MV_PHYCTL_FC_MASK (3 << 6)
69
70 enum {
71 MV_PHYCTL_FC_ENABLE = (3 << 6),
72 MV_PHYCTL_FC_DISABLE = (1 << 6),
73 };
74
75 enum {
76 MV_8021Q_EGRESS_UNMODIFIED = 0x00,
77 MV_8021Q_EGRESS_UNTAGGED = 0x01,
78 MV_8021Q_EGRESS_TAGGED = 0x02,
79 MV_8021Q_EGRESS_ADDTAG = 0x03,
80 };
81
82 #define MV_8021Q_MODE_SHIFT 10
83 #define MV_8021Q_MODE_MASK (0x3 << MV_8021Q_MODE_SHIFT)
84
85 enum {
86 MV_8021Q_MODE_DISABLE = 0x00,
87 MV_8021Q_MODE_FALLBACK = 0x01,
88 MV_8021Q_MODE_CHECK = 0x02,
89 MV_8021Q_MODE_SECURE = 0x03,
90 };
91
92 enum {
93 MV_8021Q_VLAN_ONLY = (1 << 15),
94 };
95
96 #define MV_PORTASSOC_MONITOR (1 << 15)
97
98 enum {
99 MV_SWITCH_ATU_FID0 = 0x01,
100 MV_SWITCH_ATU_FID1 = 0x02,
101 MV_SWITCH_ATU_SID = 0x03,
102 MV_SWITCH_CTRL = 0x04,
103 MV_SWITCH_ATU_CTRL = 0x0a,
104 MV_SWITCH_ATU_OP = 0x0b,
105 MV_SWITCH_ATU_DATA = 0x0c,
106 MV_SWITCH_ATU_MAC0 = 0x0d,
107 MV_SWITCH_ATU_MAC1 = 0x0e,
108 MV_SWITCH_ATU_MAC2 = 0x0f,
109 MV_SWITCH_GLOBAL = 0x1b,
110 MV_SWITCH_GLOBAL2 = 0x1c,
111 };
112 #define MV_SWITCHREG(_type) MV_SWITCHREGS, MV_SWITCH_##_type
113
114 enum {
115 MV_SWITCHCTL_EEIE = (1 << 0),
116 MV_SWITCHCTL_PHYIE = (1 << 1),
117 MV_SWITCHCTL_ATUDONE = (1 << 2),
118 MV_SWITCHCTL_ATUIE = (1 << 3),
119 MV_SWITCHCTL_CTRMODE = (1 << 8),
120 MV_SWITCHCTL_RELOAD = (1 << 9),
121 MV_SWITCHCTL_MSIZE = (1 << 10),
122 MV_SWITCHCTL_DROP = (1 << 13),
123 };
124
125 enum {
126 #define MV_ATUCTL_AGETIME_MIN 16
127 #define MV_ATUCTL_AGETIME_MAX 4080
128 #define MV_ATUCTL_AGETIME(_n) ((((_n) / 16) & 0xff) << 4)
129 MV_ATUCTL_ATU_256 = (0 << 12),
130 MV_ATUCTL_ATU_512 = (1 << 12),
131 MV_ATUCTL_ATU_1K = (2 << 12),
132 MV_ATUCTL_ATUMASK = (3 << 12),
133 MV_ATUCTL_NO_LEARN = (1 << 14),
134 MV_ATUCTL_RESET = (1 << 15),
135 };
136
137 enum {
138 #define MV_ATUOP_DBNUM(_n) ((_n) & 0x0f)
139 MV_ATUOP_NOOP = (0 << 12),
140 MV_ATUOP_FLUSH_ALL = (1 << 12),
141 MV_ATUOP_FLUSH_U = (2 << 12),
142 MV_ATUOP_LOAD_DB = (3 << 12),
143 MV_ATUOP_GET_NEXT = (4 << 12),
144 MV_ATUOP_FLUSH_DB = (5 << 12),
145 MV_ATUOP_FLUSH_DB_UU = (6 << 12),
146 MV_ATUOP_INPROGRESS = (1 << 15),
147 };
148
149 enum {
150 MV_GLOBAL_STATUS = 0x00,
151 MV_GLOBAL_ATU_FID = 0x01,
152 MV_GLOBAL_VTU_FID = 0x02,
153 MV_GLOBAL_VTU_SID = 0x03,
154 MV_GLOBAL_CONTROL = 0x04,
155 MV_GLOBAL_VTU_OP = 0x05,
156 MV_GLOBAL_VTU_VID = 0x06,
157 MV_GLOBAL_VTU_DATA1 = 0x07,
158 MV_GLOBAL_VTU_DATA2 = 0x08,
159 MV_GLOBAL_VTU_DATA3 = 0x09,
160 MV_GLOBAL_CONTROL2 = 0x1c,
161 };
162 #define MV_GLOBALREG(_type) MV_SWITCH_GLOBAL, MV_GLOBAL_##_type
163
164 enum {
165 MV_GLOBAL2_SDET_POLARITY = 0x1d,
166 };
167 #define MV_GLOBAL2REG(_type) MV_SWITCH_GLOBAL2, MV_GLOBAL2_##_type
168
169 enum {
170 MV_VTU_VID_VALID = (1 << 12),
171 };
172
173 enum {
174 MV_VTUOP_PURGE = (1 << 12),
175 MV_VTUOP_LOAD = (3 << 12),
176 MV_VTUOP_INPROGRESS = (1 << 15),
177 MV_VTUOP_STULOAD = (5 << 12),
178 MV_VTUOP_VTU_GET_NEXT = (4 << 12),
179 MV_VTUOP_STU_GET_NEXT = (6 << 12),
180 MV_VTUOP_GET_VIOLATION = (7 << 12),
181 };
182
183 enum {
184 MV_CONTROL_RESET = (1 << 15),
185 MV_CONTROL_PPU_ENABLE = (1 << 14),
186 };
187
188 enum {
189 MV_VTUCTL_EGRESS_UNMODIFIED = (0 << 0),
190 MV_VTUCTL_EGRESS_UNTAGGED = (1 << 0),
191 MV_VTUCTL_EGRESS_TAGGED = (2 << 0),
192 MV_VTUCTL_DISCARD = (3 << 0),
193 };
194
195 enum {
196 MV_STUCTL_STATE_DISABLED = (0 << 0),
197 MV_STUCTL_STATE_BLOCKING = (1 << 0),
198 MV_STUCTL_STATE_LEARNING = (2 << 0),
199 MV_STUCTL_STATE_FORWARDING = (3 << 0),
200 };
201
202 enum {
203 MV_INDIRECT_REG_CMD = 0,
204 MV_INDIRECT_REG_DATA = 1,
205 };
206
207 enum {
208 MV_INDIRECT_INPROGRESS = 0x8000,
209 MV_INDIRECT_WRITE = 0x9400,
210 MV_INDIRECT_READ = 0x9800,
211 };
212 #define MV_INDIRECT_ADDR_S 5
213
214 #define MV_IDENT_MASK 0xfff0
215
216 #define MV_IDENT_VALUE_6171 0x1710
217 #define MV_IDENT_STR_6171 "MV88E6171"
218
219 #define MV_IDENT_VALUE_6172 0x1720
220 #define MV_IDENT_STR_6172 "MV88E6172"
221
222 #define MV_IDENT_VALUE_6176 0x1760
223 #define MV_IDENT_STR_6176 "MV88E6176"
224
225 #define MV_PVID_MASK 0x0fff
226
227 #define MV_FDB_HI_MASK 0x00ff
228 #define MV_FDB_LO_MASK 0xf000
229 #define MV_FDB_HI_SHIFT 4
230 #define MV_FDB_LO_SHIFT 12
231
232 struct mvsw61xx_state {
233 struct switch_dev dev;
234 struct mii_bus *bus;
235 int base_addr;
236 u16 model;
237
238 bool registered;
239 bool is_indirect;
240
241 int cpu_port0;
242 int cpu_port1;
243
244 int vlan_enabled;
245 struct port_state {
246 u16 fdb;
247 u16 pvid;
248 u16 mask;
249 u8 qmode;
250 } ports[MV_PORTS];
251
252 struct vlan_state {
253 bool port_based;
254
255 u16 mask;
256 u16 vid;
257 u32 port_mode;
258 u32 port_sstate;
259 } vlans[MV_VLANS];
260
261 char buf[128];
262 };
263
264 #define get_state(_dev) container_of((_dev), struct mvsw61xx_state, dev)
265
266 #endif