diff options
Diffstat (limited to 'net/dsa/mv88e6131.c')
-rw-r--r-- | net/dsa/mv88e6131.c | 78 |
1 files changed, 50 insertions, 28 deletions
diff --git a/net/dsa/mv88e6131.c b/net/dsa/mv88e6131.c index 002995721ecf..bb2b41bc854e 100644 --- a/net/dsa/mv88e6131.c +++ b/net/dsa/mv88e6131.c | |||
@@ -102,17 +102,17 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
102 | REG_WRITE(REG_GLOBAL, 0x19, 0x8100); | 102 | REG_WRITE(REG_GLOBAL, 0x19, 0x8100); |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Disable ARP mirroring, and configure the cpu port as the | 105 | * Disable ARP mirroring, and configure the upstream port as |
106 | * port to which ingress and egress monitor frames are to be | 106 | * the port to which ingress and egress monitor frames are to |
107 | * sent. | 107 | * be sent. |
108 | */ | 108 | */ |
109 | REG_WRITE(REG_GLOBAL, 0x1a, (ds->cpu_port * 0x1100) | 0x00f0); | 109 | REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1100) | 0x00f0); |
110 | 110 | ||
111 | /* | 111 | /* |
112 | * Disable cascade port functionality, and set the switch's | 112 | * Disable cascade port functionality, and set the switch's |
113 | * DSA device number to zero. | 113 | * DSA device number. |
114 | */ | 114 | */ |
115 | REG_WRITE(REG_GLOBAL, 0x1c, 0xe000); | 115 | REG_WRITE(REG_GLOBAL, 0x1c, 0xe000 | (ds->index & 0x1f)); |
116 | 116 | ||
117 | /* | 117 | /* |
118 | * Send all frames with destination addresses matching | 118 | * Send all frames with destination addresses matching |
@@ -129,10 +129,17 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
129 | REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff); | 129 | REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff); |
130 | 130 | ||
131 | /* | 131 | /* |
132 | * Map all DSA device IDs to the CPU port. | 132 | * Program the DSA routing table. |
133 | */ | 133 | */ |
134 | for (i = 0; i < 32; i++) | 134 | for (i = 0; i < 32; i++) { |
135 | REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | ds->cpu_port); | 135 | int nexthop; |
136 | |||
137 | nexthop = 0x1f; | ||
138 | if (i != ds->index && i < ds->dst->pd->nr_chips) | ||
139 | nexthop = ds->pd->rtable[i] & 0x1f; | ||
140 | |||
141 | REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop); | ||
142 | } | ||
136 | 143 | ||
137 | /* | 144 | /* |
138 | * Clear all trunk masks. | 145 | * Clear all trunk masks. |
@@ -158,13 +165,15 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
158 | static int mv88e6131_setup_port(struct dsa_switch *ds, int p) | 165 | static int mv88e6131_setup_port(struct dsa_switch *ds, int p) |
159 | { | 166 | { |
160 | int addr = REG_PORT(p); | 167 | int addr = REG_PORT(p); |
168 | u16 val; | ||
161 | 169 | ||
162 | /* | 170 | /* |
163 | * MAC Forcing register: don't force link, speed, duplex | 171 | * MAC Forcing register: don't force link, speed, duplex |
164 | * or flow control state to any particular values on physical | 172 | * or flow control state to any particular values on physical |
165 | * ports, but force the CPU port to 1000 Mb/s full duplex. | 173 | * ports, but force the CPU port and all DSA ports to 1000 Mb/s |
174 | * full duplex. | ||
166 | */ | 175 | */ |
167 | if (p == ds->cpu_port) | 176 | if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p)) |
168 | REG_WRITE(addr, 0x01, 0x003e); | 177 | REG_WRITE(addr, 0x01, 0x003e); |
169 | else | 178 | else |
170 | REG_WRITE(addr, 0x01, 0x0003); | 179 | REG_WRITE(addr, 0x01, 0x0003); |
@@ -175,29 +184,40 @@ static int mv88e6131_setup_port(struct dsa_switch *ds, int p) | |||
175 | * enable IGMP/MLD snoop, disable DoubleTag, disable VLAN | 184 | * enable IGMP/MLD snoop, disable DoubleTag, disable VLAN |
176 | * tunneling, determine priority by looking at 802.1p and | 185 | * tunneling, determine priority by looking at 802.1p and |
177 | * IP priority fields (IP prio has precedence), and set STP | 186 | * IP priority fields (IP prio has precedence), and set STP |
178 | * state to Forwarding. Finally, if this is the CPU port, | 187 | * state to Forwarding. |
179 | * additionally enable DSA tagging and forwarding of unknown | 188 | * |
180 | * unicast addresses. | 189 | * If this is the upstream port for this switch, enable |
190 | * forwarding of unknown unicasts, and enable DSA tagging | ||
191 | * mode. | ||
192 | * | ||
193 | * If this is the link to another switch, use DSA tagging | ||
194 | * mode, but do not enable forwarding of unknown unicasts. | ||
181 | */ | 195 | */ |
182 | REG_WRITE(addr, 0x04, (p == ds->cpu_port) ? 0x0537 : 0x0433); | 196 | val = 0x0433; |
197 | if (p == dsa_upstream_port(ds)) | ||
198 | val |= 0x0104; | ||
199 | if (ds->dsa_port_mask & (1 << p)) | ||
200 | val |= 0x0100; | ||
201 | REG_WRITE(addr, 0x04, val); | ||
183 | 202 | ||
184 | /* | 203 | /* |
185 | * Port Control 1: disable trunking. Also, if this is the | 204 | * Port Control 1: disable trunking. Also, if this is the |
186 | * CPU port, enable learn messages to be sent to this port. | 205 | * CPU port, enable learn messages to be sent to this port. |
187 | */ | 206 | */ |
188 | REG_WRITE(addr, 0x05, (p == ds->cpu_port) ? 0x8000 : 0x0000); | 207 | REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000); |
189 | 208 | ||
190 | /* | 209 | /* |
191 | * Port based VLAN map: give each port its own address | 210 | * Port based VLAN map: give each port its own address |
192 | * database, allow the CPU port to talk to each of the 'real' | 211 | * database, allow the CPU port to talk to each of the 'real' |
193 | * ports, and allow each of the 'real' ports to only talk to | 212 | * ports, and allow each of the 'real' ports to only talk to |
194 | * the CPU port. | 213 | * the upstream port. |
195 | */ | 214 | */ |
196 | REG_WRITE(addr, 0x06, | 215 | val = (p & 0xf) << 12; |
197 | ((p & 0xf) << 12) | | 216 | if (dsa_is_cpu_port(ds, p)) |
198 | ((p == ds->cpu_port) ? | 217 | val |= ds->phys_port_mask; |
199 | ds->valid_port_mask : | 218 | else |
200 | (1 << ds->cpu_port))); | 219 | val |= 1 << dsa_upstream_port(ds); |
220 | REG_WRITE(addr, 0x06, val); | ||
201 | 221 | ||
202 | /* | 222 | /* |
203 | * Default VLAN ID and priority: don't set a default VLAN | 223 | * Default VLAN ID and priority: don't set a default VLAN |
@@ -213,13 +233,15 @@ static int mv88e6131_setup_port(struct dsa_switch *ds, int p) | |||
213 | * untagged frames on this port, do a destination address | 233 | * untagged frames on this port, do a destination address |
214 | * lookup on received packets as usual, don't send a copy | 234 | * lookup on received packets as usual, don't send a copy |
215 | * of all transmitted/received frames on this port to the | 235 | * of all transmitted/received frames on this port to the |
216 | * CPU, and configure the CPU port number. Also, if this | 236 | * CPU, and configure the upstream port number. |
217 | * is the CPU port, enable forwarding of unknown multicast | 237 | * |
218 | * addresses. | 238 | * If this is the upstream port for this switch, enable |
239 | * forwarding of unknown multicast addresses. | ||
219 | */ | 240 | */ |
220 | REG_WRITE(addr, 0x08, | 241 | val = 0x0080 | dsa_upstream_port(ds); |
221 | ((p == ds->cpu_port) ? 0x00c0 : 0x0080) | | 242 | if (p == dsa_upstream_port(ds)) |
222 | ds->cpu_port); | 243 | val |= 0x0040; |
244 | REG_WRITE(addr, 0x08, val); | ||
223 | 245 | ||
224 | /* | 246 | /* |
225 | * Rate Control: disable ingress rate limiting. | 247 | * Rate Control: disable ingress rate limiting. |