~ubuntu-branches/ubuntu/lucid/linux-rt/lucid

« back to all changes in this revision

Viewing changes to net/dsa/mv88e6123_61_65.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2009-08-05 23:00:52 UTC
  • Revision ID: james.westby@ubuntu.com-20090805230052-7xedvqcyk9dnnxb2
Tags: 2.6.31-1.1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support
3
 
 * Copyright (c) 2008 Marvell Semiconductor
 
3
 * Copyright (c) 2008-2009 Marvell Semiconductor
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify
6
6
 * it under the terms of the GNU General Public License as published by
98
98
                return ret;
99
99
 
100
100
        /*
101
 
         * Configure the cpu port, and configure the cpu port as the
102
 
         * port to which ingress and egress monitor frames are to be
103
 
         * sent.
 
101
         * Configure the upstream port, and configure the upstream
 
102
         * port as the port to which ingress and egress monitor frames
 
103
         * are to be sent.
104
104
         */
105
 
        REG_WRITE(REG_GLOBAL, 0x1a, (ds->cpu_port * 0x1110));
 
105
        REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1110));
106
106
 
107
107
        /*
108
108
         * Disable remote management for now, and set the switch's
109
 
         * DSA device number to zero.
 
109
         * DSA device number.
110
110
         */
111
 
        REG_WRITE(REG_GLOBAL, 0x1c, 0x0000);
 
111
        REG_WRITE(REG_GLOBAL, 0x1c, ds->index & 0x1f);
112
112
 
113
113
        /*
114
114
         * Send all frames with destination addresses matching
133
133
        REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff);
134
134
 
135
135
        /*
136
 
         * Map all DSA device IDs to the CPU port.
 
136
         * Program the DSA routing table.
137
137
         */
138
 
        for (i = 0; i < 32; i++)
139
 
                REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | ds->cpu_port);
 
138
        for (i = 0; i < 32; i++) {
 
139
                int nexthop;
 
140
 
 
141
                nexthop = 0x1f;
 
142
                if (i != ds->index && i < ds->dst->pd->nr_chips)
 
143
                        nexthop = ds->pd->rtable[i] & 0x1f;
 
144
 
 
145
                REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop);
 
146
        }
140
147
 
141
148
        /*
142
149
         * Clear all trunk masks.
176
183
static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p)
177
184
{
178
185
        int addr = REG_PORT(p);
 
186
        u16 val;
179
187
 
180
188
        /*
181
189
         * MAC Forcing register: don't force link, speed, duplex
182
 
         * or flow control state to any particular values.
 
190
         * or flow control state to any particular values on physical
 
191
         * ports, but force the CPU port and all DSA ports to 1000 Mb/s
 
192
         * full duplex.
183
193
         */
184
 
        REG_WRITE(addr, 0x01, 0x0003);
 
194
        if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
 
195
                REG_WRITE(addr, 0x01, 0x003e);
 
196
        else
 
197
                REG_WRITE(addr, 0x01, 0x0003);
185
198
 
186
199
        /*
187
200
         * Do not limit the period of time that this port can be
192
205
 
193
206
        /*
194
207
         * Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
195
 
         * configure the requested (DSA/EDSA) tagging mode if this is
196
 
         * the CPU port, disable Header mode, enable IGMP/MLD snooping,
197
 
         * disable VLAN tunneling, determine priority by looking at
198
 
         * 802.1p and IP priority fields (IP prio has precedence), and
199
 
         * set STP state to Forwarding.  Finally, if this is the CPU
200
 
         * port, additionally enable forwarding of unknown unicast and
201
 
         * multicast addresses.
 
208
         * disable Header mode, enable IGMP/MLD snooping, disable VLAN
 
209
         * tunneling, determine priority by looking at 802.1p and IP
 
210
         * priority fields (IP prio has precedence), and set STP state
 
211
         * to Forwarding.
 
212
         *
 
213
         * If this is the CPU link, use DSA or EDSA tagging depending
 
214
         * on which tagging mode was configured.
 
215
         *
 
216
         * If this is a link to another switch, use DSA tagging mode.
 
217
         *
 
218
         * If this is the upstream port for this switch, enable
 
219
         * forwarding of unknown unicasts and multicasts.
202
220
         */
203
 
        REG_WRITE(addr, 0x04,
204
 
                        (p == ds->cpu_port) ?
205
 
                         (ds->tag_protocol == htons(ETH_P_DSA)) ?
206
 
                          0x053f : 0x373f :
207
 
                         0x0433);
 
221
        val = 0x0433;
 
222
        if (dsa_is_cpu_port(ds, p)) {
 
223
                if (ds->dst->tag_protocol == htons(ETH_P_EDSA))
 
224
                        val |= 0x3300;
 
225
                else
 
226
                        val |= 0x0100;
 
227
        }
 
228
        if (ds->dsa_port_mask & (1 << p))
 
229
                val |= 0x0100;
 
230
        if (p == dsa_upstream_port(ds))
 
231
                val |= 0x000c;
 
232
        REG_WRITE(addr, 0x04, val);
208
233
 
209
234
        /*
210
235
         * Port Control 1: disable trunking.  Also, if this is the
211
236
         * CPU port, enable learn messages to be sent to this port.
212
237
         */
213
 
        REG_WRITE(addr, 0x05, (p == ds->cpu_port) ? 0x8000 : 0x0000);
 
238
        REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
214
239
 
215
240
        /*
216
241
         * Port based VLAN map: give each port its own address
217
242
         * database, allow the CPU port to talk to each of the 'real'
218
243
         * ports, and allow each of the 'real' ports to only talk to
219
 
         * the CPU port.
 
244
         * the upstream port.
220
245
         */
221
 
        REG_WRITE(addr, 0x06,
222
 
                        ((p & 0xf) << 12) |
223
 
                         ((p == ds->cpu_port) ?
224
 
                                ds->valid_port_mask :
225
 
                                (1 << ds->cpu_port)));
 
246
        val = (p & 0xf) << 12;
 
247
        if (dsa_is_cpu_port(ds, p))
 
248
                val |= ds->phys_port_mask;
 
249
        else
 
250
                val |= 1 << dsa_upstream_port(ds);
 
251
        REG_WRITE(addr, 0x06, val);
226
252
 
227
253
        /*
228
254
         * Default VLAN ID and priority: don't set a default VLAN
394
420
}
395
421
 
396
422
static struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
397
 
        .tag_protocol           = __constant_htons(ETH_P_EDSA),
 
423
        .tag_protocol           = cpu_to_be16(ETH_P_EDSA),
398
424
        .priv_size              = sizeof(struct mv88e6xxx_priv_state),
399
425
        .probe                  = mv88e6123_61_65_probe,
400
426
        .setup                  = mv88e6123_61_65_setup,