~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise-security

« back to all changes in this revision

Viewing changes to drivers/net/ethernet/xscale/ixp2000/ixp2400_rx.uc

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati
  • Date: 2011-12-06 15:56:07 UTC
  • Revision ID: package-import@ubuntu.com-20111206155607-pcf44kv5fmhk564f
Tags: 3.2.0-1401.1
[ Paolo Pisati ]

* Rebased on top of Ubuntu-3.2.0-3.8
* Tilt-tracking @ ef2487af4bb15bdd0689631774b5a5e3a59f74e2
* Delete debian.ti-omap4/control, it shoudln't be tracked
* Fix architecture spelling (s/armel/armhf/)
* [Config] Update configs following 3.2 import
* [Config] Fix compilation: disable CODA and ARCH_OMAP3
* [Config] Fix compilation: disable Ethernet Faraday
* Update series to precise

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * RX ucode for the Intel IXP2400 in POS-PHY mode.
 
3
 * Copyright (C) 2004, 2005 Lennert Buytenhek
 
4
 * Dedicated to Marija Kulikova.
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * Assumptions made in this code:
 
12
 * - The IXP2400 MSF is configured for POS-PHY mode, in a mode where
 
13
 *   only one full element list is used.  This includes, for example,
 
14
 *   1x32 SPHY and 1x32 MPHY32, but not 4x8 SPHY or 1x32 MPHY4.  (This
 
15
 *   is not an exhaustive list.)
 
16
 * - The RBUF uses 64-byte mpackets.
 
17
 * - RX descriptors reside in SRAM, and have the following format:
 
18
 *      struct rx_desc
 
19
 *      {
 
20
 *      // to uengine
 
21
 *              u32     buf_phys_addr;
 
22
 *              u32     buf_length;
 
23
 *
 
24
 *      // from uengine
 
25
 *              u32     channel;
 
26
 *              u32     pkt_length;
 
27
 *      };
 
28
 * - Packet data resides in DRAM.
 
29
 * - Packet buffer addresses are 8-byte aligned.
 
30
 * - Scratch ring 0 is rx_pending.
 
31
 * - Scratch ring 1 is rx_done, and has status condition 'full'.
 
32
 * - The host triggers rx_done flush and rx_pending refill on seeing INTA.
 
33
 * - This code is run on all eight threads of the microengine it runs on.
 
34
 *
 
35
 * Local memory is used for per-channel RX state.
 
36
 */
 
37
 
 
38
#define RX_THREAD_FREELIST_0            0x0030
 
39
#define RBUF_ELEMENT_DONE               0x0044
 
40
 
 
41
#define CHANNEL_FLAGS                   *l$index0[0]
 
42
#define CHANNEL_FLAG_RECEIVING          1
 
43
#define PACKET_LENGTH                   *l$index0[1]
 
44
#define PACKET_CHECKSUM                 *l$index0[2]
 
45
#define BUFFER_HANDLE                   *l$index0[3]
 
46
#define BUFFER_START                    *l$index0[4]
 
47
#define BUFFER_LENGTH                   *l$index0[5]
 
48
 
 
49
#define CHANNEL_STATE_SIZE              24      // in bytes
 
50
#define CHANNEL_STATE_SHIFT             5       // ceil(log2(state size))
 
51
 
 
52
 
 
53
        .sig volatile sig1
 
54
        .sig volatile sig2
 
55
        .sig volatile sig3
 
56
 
 
57
        .sig mpacket_arrived
 
58
        .reg add_to_rx_freelist
 
59
        .reg read $rsw0, $rsw1
 
60
        .xfer_order $rsw0 $rsw1
 
61
 
 
62
        .reg zero
 
63
 
 
64
        /*
 
65
         * Initialise add_to_rx_freelist.
 
66
         */
 
67
        .begin
 
68
                .reg temp
 
69
                .reg temp2
 
70
 
 
71
                immed[add_to_rx_freelist, RX_THREAD_FREELIST_0]
 
72
                immed_w1[add_to_rx_freelist, (&$rsw0 | (&mpacket_arrived << 12))]
 
73
 
 
74
                local_csr_rd[ACTIVE_CTX_STS]
 
75
                immed[temp, 0]
 
76
                alu[temp2, temp, and, 0x1f]
 
77
                alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<20]
 
78
                alu[temp2, temp, and, 0x80]
 
79
                alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<18]
 
80
        .end
 
81
 
 
82
        immed[zero, 0]
 
83
 
 
84
        /*
 
85
         * Skip context 0 initialisation?
 
86
         */
 
87
        .begin
 
88
                br!=ctx[0, mpacket_receive_loop#]
 
89
        .end
 
90
 
 
91
        /*
 
92
         * Initialise local memory.
 
93
         */
 
94
        .begin
 
95
                .reg addr
 
96
                .reg temp
 
97
 
 
98
                immed[temp, 0]
 
99
        init_local_mem_loop#:
 
100
                alu_shf[addr, --, b, temp, <<CHANNEL_STATE_SHIFT]
 
101
                local_csr_wr[ACTIVE_LM_ADDR_0, addr]
 
102
                nop
 
103
                nop
 
104
                nop
 
105
 
 
106
                immed[CHANNEL_FLAGS, 0]
 
107
 
 
108
                alu[temp, temp, +, 1]
 
109
                alu[--, temp, and, 0x20]
 
110
                beq[init_local_mem_loop#]
 
111
        .end
 
112
 
 
113
        /*
 
114
         * Initialise signal pipeline.
 
115
         */
 
116
        .begin
 
117
                local_csr_wr[SAME_ME_SIGNAL, (&sig1 << 3)]
 
118
                .set_sig sig1
 
119
 
 
120
                local_csr_wr[SAME_ME_SIGNAL, (&sig2 << 3)]
 
121
                .set_sig sig2
 
122
 
 
123
                local_csr_wr[SAME_ME_SIGNAL, (&sig3 << 3)]
 
124
                .set_sig sig3
 
125
        .end
 
126
 
 
127
mpacket_receive_loop#:
 
128
        /*
 
129
         * Synchronise and wait for mpacket.
 
130
         */
 
131
        .begin
 
132
                ctx_arb[sig1]
 
133
                local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig1 << 3))]
 
134
 
 
135
                msf[fast_wr, --, add_to_rx_freelist, 0]
 
136
                .set_sig mpacket_arrived
 
137
                ctx_arb[mpacket_arrived]
 
138
                .set $rsw0 $rsw1
 
139
        .end
 
140
 
 
141
        /*
 
142
         * We halt if we see {inbparerr,parerr,null,soperror}.
 
143
         */
 
144
        .begin
 
145
                alu_shf[--, 0x1b, and, $rsw0, >>8]
 
146
                bne[abort_rswerr#]
 
147
        .end
 
148
 
 
149
        /*
 
150
         * Point local memory pointer to this channel's state area.
 
151
         */
 
152
        .begin
 
153
                .reg chanaddr
 
154
 
 
155
                alu[chanaddr, $rsw0, and, 0x1f]
 
156
                alu_shf[chanaddr, --, b, chanaddr, <<CHANNEL_STATE_SHIFT]
 
157
                local_csr_wr[ACTIVE_LM_ADDR_0, chanaddr]
 
158
                nop
 
159
                nop
 
160
                nop
 
161
        .end
 
162
 
 
163
        /*
 
164
         * Check whether we received a SOP mpacket while we were already
 
165
         * working on a packet, or a non-SOP mpacket while there was no
 
166
         * packet pending.  (SOP == RECEIVING -> abort)  If everything's
 
167
         * okay, update the RECEIVING flag to reflect our new state.
 
168
         */
 
169
        .begin
 
170
                .reg temp
 
171
                .reg eop
 
172
 
 
173
                #if CHANNEL_FLAG_RECEIVING != 1
 
174
                #error CHANNEL_FLAG_RECEIVING is not 1
 
175
                #endif
 
176
 
 
177
                alu_shf[temp, 1, and, $rsw0, >>15]
 
178
                alu[temp, temp, xor, CHANNEL_FLAGS]
 
179
                alu[--, temp, and, CHANNEL_FLAG_RECEIVING]
 
180
                beq[abort_proterr#]
 
181
 
 
182
                alu_shf[eop, 1, and, $rsw0, >>14]
 
183
                alu[CHANNEL_FLAGS, temp, xor, eop]
 
184
        .end
 
185
 
 
186
        /*
 
187
         * Copy the mpacket into the right spot, and in case of EOP,
 
188
         * write back the descriptor and pass the packet on.
 
189
         */
 
190
        .begin
 
191
                .reg buffer_offset
 
192
                .reg _packet_length
 
193
                .reg _packet_checksum
 
194
                .reg _buffer_handle
 
195
                .reg _buffer_start
 
196
                .reg _buffer_length
 
197
 
 
198
                /*
 
199
                 * Determine buffer_offset, _packet_length and
 
200
                 * _packet_checksum.
 
201
                 */
 
202
                .begin
 
203
                        .reg temp
 
204
 
 
205
                        alu[--, 1, and, $rsw0, >>15]
 
206
                        beq[not_sop#]
 
207
 
 
208
                        immed[PACKET_LENGTH, 0]
 
209
                        immed[PACKET_CHECKSUM, 0]
 
210
 
 
211
                not_sop#:
 
212
                        alu[buffer_offset, --, b, PACKET_LENGTH]
 
213
                        alu_shf[temp, 0xff, and, $rsw0, >>16]
 
214
                        alu[_packet_length, buffer_offset, +, temp]
 
215
                        alu[PACKET_LENGTH, --, b, _packet_length]
 
216
 
 
217
                        immed[temp, 0xffff]
 
218
                        alu[temp, $rsw1, and, temp]
 
219
                        alu[_packet_checksum, PACKET_CHECKSUM, +, temp]
 
220
                        alu[PACKET_CHECKSUM, --, b, _packet_checksum]
 
221
                .end
 
222
 
 
223
                /*
 
224
                 * Allocate buffer in case of SOP.
 
225
                 */
 
226
                .begin
 
227
                        .reg temp
 
228
 
 
229
                        alu[temp, 1, and, $rsw0, >>15]
 
230
                        beq[skip_buffer_alloc#]
 
231
 
 
232
                        .begin
 
233
                                .sig zzz
 
234
                                .reg read $stemp $stemp2
 
235
                                .xfer_order $stemp $stemp2
 
236
 
 
237
                        rx_nobufs#:
 
238
                                scratch[get, $stemp, zero, 0, 1], ctx_swap[zzz]
 
239
                                alu[_buffer_handle, --, b, $stemp]
 
240
                                beq[rx_nobufs#]
 
241
 
 
242
                                sram[read, $stemp, _buffer_handle, 0, 2],
 
243
                                                                ctx_swap[zzz]
 
244
                                alu[_buffer_start, --, b, $stemp]
 
245
                                alu[_buffer_length, --, b, $stemp2]
 
246
                        .end
 
247
 
 
248
                skip_buffer_alloc#:
 
249
                .end
 
250
 
 
251
                /*
 
252
                 * Resynchronise.
 
253
                 */
 
254
                .begin
 
255
                        ctx_arb[sig2]
 
256
                        local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig2 << 3))]
 
257
                .end
 
258
 
 
259
                /*
 
260
                 * Synchronise buffer state.
 
261
                 */
 
262
                .begin
 
263
                        .reg temp
 
264
 
 
265
                        alu[temp, 1, and, $rsw0, >>15]
 
266
                        beq[copy_from_local_mem#]
 
267
 
 
268
                        alu[BUFFER_HANDLE, --, b, _buffer_handle]
 
269
                        alu[BUFFER_START, --, b, _buffer_start]
 
270
                        alu[BUFFER_LENGTH, --, b, _buffer_length]
 
271
                        br[sync_state_done#]
 
272
 
 
273
                copy_from_local_mem#:
 
274
                        alu[_buffer_handle, --, b, BUFFER_HANDLE]
 
275
                        alu[_buffer_start, --, b, BUFFER_START]
 
276
                        alu[_buffer_length, --, b, BUFFER_LENGTH]
 
277
 
 
278
                sync_state_done#:
 
279
                .end
 
280
 
 
281
#if 0
 
282
                /*
 
283
                 * Debug buffer state management.
 
284
                 */
 
285
                .begin
 
286
                        .reg temp
 
287
 
 
288
                        alu[temp, 1, and, $rsw0, >>14]
 
289
                        beq[no_poison#]
 
290
                        immed[BUFFER_HANDLE, 0xdead]
 
291
                        immed[BUFFER_START, 0xdead]
 
292
                        immed[BUFFER_LENGTH, 0xdead]
 
293
                no_poison#:
 
294
 
 
295
                        immed[temp, 0xdead]
 
296
                        alu[--, _buffer_handle, -, temp]
 
297
                        beq[state_corrupted#]
 
298
                        alu[--, _buffer_start, -, temp]
 
299
                        beq[state_corrupted#]
 
300
                        alu[--, _buffer_length, -, temp]
 
301
                        beq[state_corrupted#]
 
302
                .end
 
303
#endif
 
304
 
 
305
                /*
 
306
                 * Check buffer length.
 
307
                 */
 
308
                .begin
 
309
                        alu[--, _buffer_length, -, _packet_length]
 
310
                        blo[buffer_overflow#]
 
311
                .end
 
312
 
 
313
                /*
 
314
                 * Copy the mpacket and give back the RBUF element.
 
315
                 */
 
316
                .begin
 
317
                        .reg element
 
318
                        .reg xfer_size
 
319
                        .reg temp
 
320
                        .sig copy_sig
 
321
 
 
322
                        alu_shf[element, 0x7f, and, $rsw0, >>24]
 
323
                        alu_shf[xfer_size, 0xff, and, $rsw0, >>16]
 
324
 
 
325
                        alu[xfer_size, xfer_size, -, 1]
 
326
                        alu_shf[xfer_size, 0x10, or, xfer_size, >>3]
 
327
                        alu_shf[temp, 0x10, or, xfer_size, <<21]
 
328
                        alu_shf[temp, temp, or, element, <<11]
 
329
                        alu_shf[--, temp, or, 1, <<18]
 
330
 
 
331
                        dram[rbuf_rd, --, _buffer_start, buffer_offset, max_8],
 
332
                                                indirect_ref, sig_done[copy_sig]
 
333
                        ctx_arb[copy_sig]
 
334
 
 
335
                        alu[temp, RBUF_ELEMENT_DONE, or, element, <<16]
 
336
                        msf[fast_wr, --, temp, 0]
 
337
                .end
 
338
 
 
339
                /*
 
340
                 * If EOP, write back the packet descriptor.
 
341
                 */
 
342
                .begin
 
343
                        .reg write $stemp $stemp2
 
344
                        .xfer_order $stemp $stemp2
 
345
                        .sig zzz
 
346
 
 
347
                        alu_shf[--, 1, and, $rsw0, >>14]
 
348
                        beq[no_writeback#]
 
349
 
 
350
                        alu[$stemp, $rsw0, and, 0x1f]
 
351
                        alu[$stemp2, --, b, _packet_length]
 
352
                        sram[write, $stemp, _buffer_handle, 8, 2], ctx_swap[zzz]
 
353
 
 
354
                no_writeback#:
 
355
                .end
 
356
 
 
357
                /*
 
358
                 * Resynchronise.
 
359
                 */
 
360
                .begin
 
361
                        ctx_arb[sig3]
 
362
                        local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig3 << 3))]
 
363
                .end
 
364
 
 
365
                /*
 
366
                 * If EOP, put the buffer back onto the scratch ring.
 
367
                 */
 
368
                .begin
 
369
                        .reg write $stemp
 
370
                        .sig zzz
 
371
 
 
372
                        br_inp_state[SCR_Ring1_Status, rx_done_ring_overflow#]
 
373
 
 
374
                        alu_shf[--, 1, and, $rsw0, >>14]
 
375
                        beq[mpacket_receive_loop#]
 
376
 
 
377
                        alu[--, 1, and, $rsw0, >>10]
 
378
                        bne[rxerr#]
 
379
 
 
380
                        alu[$stemp, --, b, _buffer_handle]
 
381
                        scratch[put, $stemp, zero, 4, 1], ctx_swap[zzz]
 
382
                        cap[fast_wr, 0, XSCALE_INT_A]
 
383
                        br[mpacket_receive_loop#]
 
384
 
 
385
                rxerr#:
 
386
                        alu[$stemp, --, b, _buffer_handle]
 
387
                        scratch[put, $stemp, zero, 0, 1], ctx_swap[zzz]
 
388
                        br[mpacket_receive_loop#]
 
389
                .end
 
390
        .end
 
391
 
 
392
 
 
393
abort_rswerr#:
 
394
        halt
 
395
 
 
396
abort_proterr#:
 
397
        halt
 
398
 
 
399
state_corrupted#:
 
400
        halt
 
401
 
 
402
buffer_overflow#:
 
403
        halt
 
404
 
 
405
rx_done_ring_overflow#:
 
406
        halt
 
407
 
 
408