]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/devs/eth/arm/netarm/v2_0/src/netarm_eth_drv.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / eth / arm / netarm / v2_0 / src / netarm_eth_drv.c
1 //==========================================================================
2 //
3 //      netarm_eth_drv.c
4 //
5 //      NetSilion NET+ARM Ethernet Driver (DMA driven)
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System
11 // Copyright (C) 2005 eCosCentric Ltd.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // -------------------------------------------
37 //####ECOSGPLCOPYRIGHTEND####
38 //==========================================================================
39 //#####DESCRIPTIONBEGIN####
40 //
41 // Author(s):           Harald Brandl (harald.brandl@fh-joanneum.at)
42 // Contributors:        Harald Brandl
43 // Date:                01.08.2004
44 // Purpose:             NET+ARM Ethernet Driver (DMA driven)
45 // Description:
46 //
47 //####DESCRIPTIONEND####
48 //
49 //==========================================================================
50
51 #include <cyg/infra/cyg_type.h>
52 #include <cyg/hal/hal_arch.h>
53 #include <cyg/infra/diag.h>
54 #include <cyg/hal/drv_api.h>
55 #include <cyg/io/eth/netdev.h>
56 #include <cyg/io/eth/eth_drv.h>
57
58 #include <pkgconf/devs_eth_arm_netarm.h>
59 #include <cyg/hal/hal_platform_ints.h>
60 #include <cyg/hal/plf_mmap.h>
61 #include "eth_regs.h"
62 #include "MII.h"
63 #include "netarm_eth_drv.h"
64 #include "eeprom.h"
65
66
67 #define BufferSizeA 128
68 #define BufferSizeB 512
69 #define BufferSizeC 1524
70
71 #define NumA 16
72 #define NumB 8
73 #define NumC 8
74
75 #define EEPROM_MAC 0    // location of MAC address inside eeprom
76
77
78 static cyg_mutex_t Key_Mutex;
79 static private_data_t driver_private;
80
81 static unsigned char RxBufferA[NumA][BufferSizeA] __attribute__ ((aligned (4)));
82 static unsigned char RxBufferB[NumB][BufferSizeB] __attribute__ ((aligned (4)));
83 static unsigned char RxBufferC[NumC][BufferSizeC] __attribute__ ((aligned (4)));
84
85 static unsigned char TxBuffer[1518] __attribute__ ((aligned (4)));
86
87 static BDP_t RxBDP_A[NumA];
88 static BDP_t RxBDP_B[NumB];
89 static BDP_t RxBDP_C[NumC];
90
91 static BDP_t TxBDP;
92
93 // relocation pointer for data accessed by DMA to enable caching
94 static unsigned char *pRxBufferA = (unsigned char *)RxBufferA,
95                                          *pRxBufferB = (unsigned char *)RxBufferB,
96                                          *pRxBufferC = (unsigned char *)RxBufferC;
97 static unsigned char *pTxBuffer = TxBuffer;
98
99 static BDP_t *pRxBDP_A = RxBDP_A, *pRxBDP_B = RxBDP_B, *pRxBDP_C = RxBDP_C;
100 static BDP_t *pTxBDP = &TxBDP;
101
102
103 ETH_DRV_SC(netarm_sc,
104            (void *)&driver_private,     // driver specific data
105            "eth0",                              // name for this interface
106            netarm_start,
107            netarm_stop,
108            netarm_control,
109            netarm_can_send,
110            netarm_send,
111            netarm_recv,
112            netarm_deliver,
113            netarm_poll,
114            netarm_int_vector);
115
116
117 NETDEVTAB_ENTRY(netarm_netdev,
118                 "ETH_DRV",
119                 netarm_init,
120                 &netarm_sc);
121
122
123 #ifdef __thumb__
124         #define fastcopy memcpy
125 #else
126 static void
127 fastcopy(void *buf, void *data, unsigned long len)
128 {
129         asm volatile(
130
131                 "STMDB SP!, {R11};"
132
133                 "TST R1, #2;"                   // test if aligned
134                 "LDRNEH R3, [R1], #2;"
135                 "STRNEH R3, [R0], #2;"
136                 "SUBNE R2, R2, #2;"
137                 "TST R1, #1;"
138                 "LDRNEB R3, [R1], #1;"
139                 "STRNEB R3, [R0], #1;"
140                 "SUBNE R2, R2, #1;"
141
142                 ".START%=:"
143
144                 "CMP R2, #44;"
145                 "BLT .LASTBYTES%=;"
146                 "LDMIA R1!, {R3 - R12, R14};"
147                 "STMIA R0!, {R3 - R12, R14};"
148                 "SUB R2, R2, #44;"
149
150                 "CMP R2, #44;"
151                 "BLT .LASTBYTES%=;"
152                 "LDMIA R1!, {R3 - R12, R14};"
153                 "STMIA R0!, {R3 - R12, R14};"
154                 "SUB R2, R2, #44;"
155
156                 "CMP R2, #44;"
157                 "BLT .LASTBYTES%=;"
158                 "LDMIA R1!, {R3 - R12, R14};"
159                 "STMIA R0!, {R3 - R12, R14};"
160                 "SUB R2, R2, #44;"
161
162                 "CMP R2, #44;"
163                 "BLT .LASTBYTES%=;"
164                 "LDMIA R1!, {R3 - R12, R14};"
165                 "STMIA R0!, {R3 - R12, R14};"
166                 "SUB R2, R2, #44;"
167
168                 "CMP R2, #44;"
169                 "BLT .LASTBYTES%=;"
170                 "LDMIA R1!, {R3 - R12, R14};"
171                 "STMIA R0!, {R3 - R12, R14};"
172                 "SUB R2, R2, #44;"
173
174                 "CMP R2, #44;"
175                 "BLT .LASTBYTES%=;"
176                 "LDMIA R1!, {R3 - R12, R14};"
177                 "STMIA R0!, {R3 - R12, R14};"
178                 "SUB R2, R2, #44;"
179
180                 "CMP R2, #44;"
181                 "BLT .LASTBYTES%=;"
182                 "LDMIA R1!, {R3 - R12, R14};"
183                 "STMIA R0!, {R3 - R12, R14};"
184                 "SUB R2, R2, #44;"
185
186                 "CMP R2, #44;"
187                 "BLT .LASTBYTES%=;"
188                 "LDMIA R1!, {R3 - R12, R14};"
189                 "STMIA R0!, {R3 - R12, R14};"
190                 "SUB R2, R2, #44;"
191
192                 "CMP R2, #44;"
193                 "BLT .LASTBYTES%=;"
194                 "LDMIA R1!, {R3 - R12, R14};"
195                 "STMIA R0!, {R3 - R12, R14};"
196                 "SUB R2, R2, #44;"
197
198                 "CMP R2, #44;"
199                 "BLT .LASTBYTES%=;"
200                 "LDMIA R1!, {R3 - R12, R14};"
201                 "STMIA R0!, {R3 - R12, R14};"
202                 "SUB R2, R2, #44;"
203
204                 "BGE .START%=;"
205
206
207                 ".LASTBYTES%=:"
208
209                 "AND R14, R2, #0xfffffffc;"
210                 "LDR PC, [PC, R14];"
211                 "NOP;"
212
213                 ".SWITCH%=:"
214                 ".word  .CASE0%=;"
215                 ".word  .CASE1%=;"
216                 ".word  .CASE2%=;"
217                 ".word  .CASE3%=;"
218                 ".word  .CASE4%=;"
219                 ".word  .CASE5%=;"
220                 ".word  .CASE6%=;"
221                 ".word  .CASE7%=;"
222                 ".word  .CASE8%=;"
223                 ".word  .CASE9%=;"
224                 ".word  .CASE10%=;"
225
226                 ".CASE0%=:"
227                 "B .END%=;"
228
229                 ".CASE1%=:"
230                 "LDMIA R1!, {R3};"
231                 "STMIA R0!, {R3};"
232                 "B .END%=;"
233
234                 ".CASE2%=:"
235                 "LDMIA R1!, {R3, R4};"
236                 "STMIA R0!, {R3, R4};"
237                 "B .END%=;"
238
239                 ".CASE3%=:"
240                 "LDMIA R1!, {R3 - R5};"
241                 "STMIA R0!, {R3 - R5};"
242                 "B .END%=;"
243
244                 ".CASE4%=:"
245                 "LDMIA R1!, {R3 - R6};"
246                 "STMIA R0!, {R3 - R6};"
247                 "B .END%=;"
248
249                 ".CASE5%=:"
250                 "LDMIA R1!, {R3 - R7};"
251                 "STMIA R0!, {R3 - R7};"
252                 "B .END%=;"
253
254                 ".CASE6%=:"
255                 "LDMIA R1!, {R3 - R8};"
256                 "STMIA R0!, {R3 - R8};"
257                 "B .END%=;"
258
259                 ".CASE7%=:"
260                 "LDMIA R1!, {R3 - R9};"
261                 "STMIA R0!, {R3 - R9};"
262                 "B .END%=;"
263
264                 ".CASE8%=:"
265                 "LDMIA R1!, {R3 - R10};"
266                 "STMIA R0!, {R3 - R10};"
267                 "B .END%=;"
268
269                 ".CASE9%=:"
270                 "LDMIA R1!, {R3 - R11};"
271                 "STMIA R0!, {R3 - R11};"
272                 "B .END%=;"
273
274                 ".CASE10%=:"
275                 "LDMIA R1!, {R3 - R12};"
276                 "STMIA R0!, {R3 - R12};"
277
278                 ".END%=:"
279                 "TST R2, #2;"
280                 "LDRNEH R3, [R1], #2;"
281                 "STRNEH R3, [R0], #2;"
282                 "TST R2, #1;"
283                 "LDRNEB R3, [R1], #1;"
284                 "STRNEB R3, [R0], #1;"
285
286                 "LDMIA SP!, {R11};"
287
288                 :
289                 : "r" (buf), "r" (data), "r" (len)
290                 : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14"
291                 );
292 }
293 #endif
294
295 static bool
296 KeyBufferFull(private_data_t *pd)
297 {
298         int tmp = 0;
299
300         cyg_drv_mutex_lock(&Key_Mutex);
301
302         if((pd->key_head + 1) % MaxKeys == pd->key_tail)
303         {
304                 tmp = 1;
305         }
306
307         cyg_drv_mutex_unlock(&Key_Mutex);
308
309         return tmp;
310 }
311
312
313 static void
314 AddKey(unsigned long key, private_data_t *pd)
315 {
316
317         cyg_drv_mutex_lock(&Key_Mutex);
318
319         pd->KeyBuffer[pd->key_head] = key;
320         pd->key_head = (pd->key_head + 1) % MaxKeys;
321
322         cyg_drv_mutex_unlock(&Key_Mutex);
323 }
324
325 static unsigned
326 GetKey(private_data_t *pd)
327 {
328         unsigned key = 0;
329
330         cyg_drv_mutex_lock(&Key_Mutex);
331
332         if(pd->key_tail != pd->key_head)
333         {
334                 key = pd->KeyBuffer[pd->key_tail];
335                 pd->key_tail = (pd->key_tail + 1) % MaxKeys;
336         }
337
338         cyg_drv_mutex_unlock(&Key_Mutex);
339
340         return key;
341 }
342
343
344 static cyg_uint32
345 dma_rx_isr(cyg_vector_t vector, cyg_addrword_t data)
346 {
347
348         // block this interrupt until the dsr completes
349         cyg_drv_interrupt_mask(vector);
350
351         // tell ecos to allow further interrupt processing
352         cyg_drv_interrupt_acknowledge(vector);
353
354         return CYG_ISR_CALL_DSR;        // call the dsr
355 }
356
357 static void
358 dma_rx_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
359 {
360
361         eth_drv_dsr( vector, count, data );
362
363         HAL_WRITE_UINT32(DMA1A_SR, 0x80000000);         // acknowledge and mask interrupts
364         HAL_WRITE_UINT32(DMA1B_SR, 0x80000000);
365         HAL_WRITE_UINT32(DMA1C_SR, 0x80000000);
366
367         cyg_drv_interrupt_unmask(vector);
368 }
369
370 static cyg_uint32
371 dma_tx_isr(cyg_vector_t vector, cyg_addrword_t data)
372 {
373
374         // block this interrupt until the dsr completes
375         cyg_drv_interrupt_mask(vector);
376
377         // tell ecos to allow further interrupt processing
378         cyg_drv_interrupt_acknowledge(vector);
379
380         return CYG_ISR_CALL_DSR;        // invoke the dsr
381 }
382
383 static void
384 dma_tx_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
385 {
386
387         eth_drv_dsr( vector, count, data );
388
389         HAL_OR_UINT32(DMA2_SR, 0x80000000); // acknowledge interrupt
390
391         cyg_drv_interrupt_unmask(vector);
392 }
393
394 static void
395 setupDMA(void)
396 {
397         int i;
398
399         /* map DMA shared data to non-cached ram */
400 #ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
401         HAL_CACHED_TO_UNCACHED_ADDRESS(RxBufferA, pRxBufferA, unsigned char *);
402         HAL_CACHED_TO_UNCACHED_ADDRESS(RxBufferB, pRxBufferB, unsigned char *);
403         HAL_CACHED_TO_UNCACHED_ADDRESS(RxBufferC, pRxBufferC, unsigned char *);
404
405         HAL_CACHED_TO_UNCACHED_ADDRESS(TxBuffer, pTxBuffer, unsigned char *);
406
407         HAL_CACHED_TO_UNCACHED_ADDRESS(RxBDP_A, pRxBDP_A, BDP_t *);
408         HAL_CACHED_TO_UNCACHED_ADDRESS(RxBDP_B, pRxBDP_B, BDP_t *);
409         HAL_CACHED_TO_UNCACHED_ADDRESS(RxBDP_C, pRxBDP_C, BDP_t *);
410
411         HAL_CACHED_TO_UNCACHED_ADDRESS(TxBDP, pTxBDP, BDP_t * );
412 #endif
413
414         HAL_OR_UINT32(SYSCON, 0x40);            // reset DMA module
415
416         for(i = 0; i < NumA; i++)
417         {
418                 pRxBDP_A[i].lo = ((unsigned)(pRxBufferA + i*BufferSizeA)) & 0x3fffffff;
419                 pRxBDP_A[i].hi = BufferSizeA;
420         }
421
422         pRxBDP_A[i - 1].lo |= 0x80000000; // set W bit
423
424         for(i = 0; i < NumB; i++)
425         {
426                 pRxBDP_B[i].lo = ((unsigned)(pRxBufferB + i*BufferSizeB)) & 0x3fffffff;
427                 pRxBDP_B[i].hi = BufferSizeB;
428         }
429
430         pRxBDP_B[i - 1].lo |= 0x80000000;
431
432         for(i = 0; i < NumC; i++)
433         {
434                 pRxBDP_C[i].lo = ((unsigned)(pRxBufferC + i*BufferSizeC)) & 0x3fffffff;
435                 pRxBDP_C[i].hi = BufferSizeC;
436         }
437
438         pRxBDP_C[i - 1].lo |= 0x80000000;
439
440         HAL_AND_UINT32(SYSCON, ~0x40);
441
442         HAL_WRITE_UINT32(DMA1A_BDP, (unsigned)pRxBDP_A);
443         HAL_WRITE_UINT32(DMA1A_CR, 0x82000000);         //burst transfer
444         HAL_WRITE_UINT32(DMA1A_SR, 0xa00000);
445
446         HAL_WRITE_UINT32(DMA1B_BDP, (unsigned)pRxBDP_B);
447         HAL_WRITE_UINT32(DMA1B_CR, 0x82000000);         //burst transfer
448         HAL_WRITE_UINT32(DMA1B_SR, 0xa00000);
449
450         HAL_WRITE_UINT32(DMA1C_BDP, (unsigned)pRxBDP_C);
451         HAL_WRITE_UINT32(DMA1C_CR, 0x82000000);         //burst transfer
452         HAL_WRITE_UINT32(DMA1C_SR, 0xa00000);
453
454
455         pTxBDP->lo = ((unsigned)pTxBuffer) & 0x3fffffff;
456         pTxBDP->lo |= 0xa0000000;                                       // set W and L bit
457
458         HAL_WRITE_UINT32(DMA2_BDP, (unsigned)pTxBDP);
459         HAL_WRITE_UINT32(DMA2_CR, 0x86000000);          //burst transfer
460         HAL_WRITE_UINT32(DMA2_SR, 0x800000);
461 }
462
463
464 static bool
465 netarm_init(struct cyg_netdevtab_entry *tab)
466 {
467         struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
468         cyg_bool duplex;
469         static cyg_interrupt dma_rx_int_object, dma_tx_int_object;
470         static cyg_handle_t dma_rx_int_handle, dma_tx_int_handle;
471
472 #ifdef CYGSEM_DEVS_ETH_ARM_NETARM_ETH0_SET_ESA
473
474         unsigned char esa[6] = CYGDAT_DEVS_ETH_ARM_NETARM_ETH0_ESA;
475 #else
476         unsigned char esa[6];
477
478         cyg_netarm_initI2C();
479         cyg_netarm_eepromRead(0x50, EEPROM_MAC, esa, 6);
480 #endif
481
482         // setup dma receiver
483         setupDMA();
484
485         cyg_netarm_mii_reset();
486         cyg_netarm_mii_negotiate();                             // initialize PHY
487         duplex = cyg_netarm_mii_check_duplex();
488
489         // Ethernet Controller Initializatition
490
491         // auto CRC, late collision retry
492         HAL_WRITE_UINT32(MACCR, 0x1c | (duplex << 1));
493         // insert MAC source address into ethernet frame
494         HAL_WRITE_UINT32(STLCR, 0x3);
495         HAL_WRITE_UINT32(BtBIPGGapTimerR, 0x14);                                // standard values
496         HAL_WRITE_UINT32(NonBtBIPGGapTimerR, (0x9 << 7) | 0x11);// standard values
497         HAL_WRITE_UINT32(CollWinR, (0x37 << 8) | 0xf);                  // standard values
498         HAL_WRITE_UINT32(SAFR, 0x1);                                                    // broadcast mode
499         // dma mode, full duplex, enable pNA mode(needed for alignment)
500         HAL_WRITE_UINT32(EthGenCR, 0x40400400 | (duplex << 16));
501
502         cyg_drv_interrupt_create(
503                 CYGNUM_HAL_INTERRUPT_DMA1,              // Interrupt Vector
504                 0,                                                              // Interrupt Priority
505                 (cyg_addrword_t)&netarm_sc,             // Reference to Driver Instance
506                 dma_rx_isr,
507                 dma_rx_dsr,
508                 &dma_rx_int_handle,
509                 &dma_rx_int_object);
510
511         cyg_drv_interrupt_create(
512                 CYGNUM_HAL_INTERRUPT_DMA2,              // Interrupt Vector
513                 0,                                                              // Interrupt Priority
514                 (cyg_addrword_t)&netarm_sc,             // Reference to Driver Instance
515                 dma_tx_isr,
516                 dma_tx_dsr,
517                 &dma_tx_int_handle,
518                 &dma_tx_int_object);
519
520         cyg_drv_interrupt_attach(dma_rx_int_handle);
521
522         cyg_drv_interrupt_attach(dma_tx_int_handle);
523
524         cyg_mutex_init(&Key_Mutex);
525
526         sc->funs->eth_drv->init(sc, esa);
527
528         return true;
529 }
530
531
532 static void
533 netarm_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
534 {
535     int i, len;
536     private_data_t *pd = (private_data_t *)(sc->driver_private);
537     unsigned char *data, *buf = pd->RxBuffer;
538
539     for (i = 0;  i < sg_len;  i++) {
540         data = (unsigned char *)(sg_list[i].buf);
541         len = sg_list[i].len;
542         if(len)
543         {
544                         if(i == 1)
545                         {
546                                 buf += 2;
547                         }
548
549             fastcopy(data, buf, len);
550             buf += len;
551         }
552     }
553 }
554
555
556 static void
557 netarm_deliver(struct eth_drv_sc *sc)
558 {
559         static int a = 0, b = 0, c = 0;
560         unsigned key, rega, regb, regc;
561         private_data_t *pd = (private_data_t *)(sc->driver_private);
562
563
564         while((key = GetKey(pd)))
565         {
566                 sc->funs->eth_drv->tx_done(sc, key, 0);
567         }
568
569         while(pRxBDP_A[a].hi & 0x8000)
570         {
571                 pd->RxBuffer = (unsigned char *)(pRxBDP_A[a].lo & 0x1FFFFFFF);
572         HAL_REORDER_BARRIER();
573                 sc->funs->eth_drv->recv(sc, pRxBDP_A[a].hi & 0x7FFF);
574         HAL_REORDER_BARRIER();
575                 pRxBDP_A[a].hi = BufferSizeA;
576         HAL_REORDER_BARRIER();
577                 a = (a + 1) % NumA;
578         }
579
580         while(pRxBDP_B[b].hi & 0x8000)
581         {
582                 pd->RxBuffer = (unsigned char *)(pRxBDP_B[b].lo & 0x1FFFFFFF);
583         HAL_REORDER_BARRIER();
584                 sc->funs->eth_drv->recv(sc, pRxBDP_B[b].hi & 0x7FFF);
585         HAL_REORDER_BARRIER();
586                 pRxBDP_B[b].hi = BufferSizeB;
587         HAL_REORDER_BARRIER();
588                 b = (b + 1) % NumB;
589         }
590
591         while(pRxBDP_C[c].hi & 0x8000)
592         {
593                 pd->RxBuffer = (unsigned char *)(pRxBDP_C[c].lo & 0x1FFFFFFF);
594         HAL_REORDER_BARRIER();
595                 sc->funs->eth_drv->recv(sc, pRxBDP_C[c].hi & 0x7FFF);
596         HAL_REORDER_BARRIER();
597                 pRxBDP_C[c].hi = BufferSizeC;
598         HAL_REORDER_BARRIER();
599                 c = (c + 1) % NumC;
600         }
601
602         HAL_READ_UINT32(DMA1A_SR, rega);
603         HAL_READ_UINT32(DMA1B_SR, regb);
604         HAL_READ_UINT32(DMA1C_SR, regc);
605
606         if((rega & 0x20000000) || (regb & 0x20000000) || (regc & 0x20000000))
607         {
608                 HAL_AND_UINT32(EthGenCR, ~0xc0000000);          // reset Rx FIFO
609                 HAL_OR_UINT32(EthGenCR, 0xc0000000);
610         }
611
612         HAL_WRITE_UINT32(DMA1A_SR, 0x20a00000);
613         HAL_WRITE_UINT32(DMA1B_SR, 0x20a00000);
614         HAL_WRITE_UINT32(DMA1C_SR, 0x20a00000);
615 }
616
617
618 static int
619 netarm_can_send(struct eth_drv_sc *sc)
620 {
621         private_data_t *pd = (private_data_t *)(sc->driver_private);
622
623         if((pTxBDP->hi & 0x8000) || KeyBufferFull(pd))
624                 return 0;
625
626         return 1;
627 }
628
629 static void
630 netarm_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
631                         int sg_len, int total_len, unsigned long key)
632 {
633         private_data_t *pd = (private_data_t *)(sc->driver_private);
634     int i, len;
635     unsigned char *data, *buf = pTxBuffer;
636
637         AddKey(key, pd);
638
639     // Put data into buffer
640     for(i = 0;  i < sg_len;  i++) {
641         data = (unsigned char *)sg_list[i].buf;
642         len = sg_list[i].len;
643
644                 if(len)
645                 {
646                         if(((unsigned)buf & 0x3) != ((unsigned)data & 0x3))
647                         {
648                                 memcpy(buf, data, len);
649                         }
650                         else
651                         {
652                                 fastcopy(buf, data, len);
653                         }
654
655                         buf += len;
656                 }
657     }
658
659 cyg_drv_dsr_lock();
660         pTxBDP->hi = total_len | 0x8000;
661 HAL_REORDER_BARRIER();
662         HAL_OR_UINT32(DMA2_SR, 0xf0000000);
663 cyg_drv_dsr_unlock();
664 }
665
666
667 static void
668 netarm_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
669 {
670         setMAC(enaddr);                                                 // set MAC address
671 HAL_REORDER_BARRIER();
672         HAL_OR_UINT32(EthGenCR, 0x80800000);    // enable Rx und Tx FIFO
673 HAL_REORDER_BARRIER();
674         cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_DMA1);
675         cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_DMA2);
676 }
677
678 static void
679 netarm_stop(struct eth_drv_sc *sc)
680 {
681         HAL_AND_UINT32(EthGenCR, 0x7f7fffff);
682 HAL_REORDER_BARRIER();
683         cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_DMA1);
684         cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_DMA2);
685 }
686
687 static int
688 netarm_control(struct eth_drv_sc *sc, unsigned long key, void *data, int len)
689 {
690     return -1;
691 }
692
693 static void
694 netarm_poll(struct eth_drv_sc *sc)
695 {
696 }
697
698 static int
699 netarm_int_vector(struct eth_drv_sc *sc)
700 {
701         return CYGNUM_HAL_INTERRUPT_DMA1;
702 }
703
704 static void
705 setMAC(unsigned char *esa)
706 {
707         HAL_WRITE_UINT32(SAR1, (esa[1] << 8) | esa[0]); // set MAC address
708         HAL_WRITE_UINT32(SAR2, (esa[3] << 8) | esa[2]);
709         HAL_WRITE_UINT32(SAR3, (esa[5] << 8) | esa[4]);
710 }