OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [eth/] [cortexm/] [a2fxxx/] [current/] [src/] [if_a2fxxx.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      if_a2fxxx.c
4
//
5
//      Ethernet driver for Actel A2Fxxx device family
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 2011 Free Software Foundation, Inc.
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
16
// version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
// for more details.
22
//
23
// You should have received a copy of the GNU General Public License
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26
//
27
// As a special exception, if other files instantiate templates or use
28
// macros or inline functions from this file, or you compile this file
29
// and link it with other works to produce a work based on this file,
30
// this file does not by itself cause the resulting work to be covered by
31
// the GNU General Public License. However the source code for this file
32
// must still be made available in accordance with section (3) of the GNU
33
// General Public License v2.
34
//
35
// This exception does not invalidate any other reasons why a work based
36
// on this file might be covered by the GNU General Public License.
37
// -------------------------------------------
38
// ####ECOSGPLCOPYRIGHTEND####
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    ccoutand
43
// Contributors:
44
// Date:         2011-05-05
45
// Purpose:      Ethernet driver for Actel A2Fxxx device family
46
// Description:
47
//
48
//####DESCRIPTIONEND####
49
//
50
//========================================================================*/
51
 
52
#include <pkgconf/system.h>
53
#include <pkgconf/devs_eth_cortexm_a2fxxx.h>
54
 
55
#ifdef CYGDAT_DEVS_CORTEXM_A2FXXX_ETH_CDL
56
# include CYGDAT_DEVS_CORTEXM_A2FXXX_ETH_CDL
57
#endif
58
 
59
#include <pkgconf/io_eth_drivers.h>
60
 
61
#ifdef CYGPKG_NET
62
# include <pkgconf/net.h>
63
#endif
64
 
65
#include <cyg/infra/cyg_type.h>
66
 
67
#include <cyg/hal/hal_arch.h>
68
#include <cyg/hal/hal_cache.h>
69
#include <cyg/hal/hal_intr.h>
70
#include <cyg/hal/drv_api.h>
71
#include <cyg/hal/hal_if.h>
72
#include <cyg/hal/var_io.h>
73
 
74
#include <cyg/io/eth/netdev.h>
75
#include <cyg/io/eth/eth_drv.h>
76
 
77
#ifdef CYGPKG_DEVS_ETH_PHY
78
# include <cyg/io/eth_phy.h>
79
#endif
80
 
81
#include <errno.h>
82
#include <string.h>
83
 
84
static unsigned char enaddr[6];
85
 
86
// Buffer descriptor
87
struct a2fxxx_bd {
88
    cyg_uint32     des0;
89
    cyg_uint32     des1;
90
    cyg_uint32     des2;
91
    cyg_uint32     des3;
92
    cyg_uint32     private;
93
};
94
 
95
// Some statistics
96
#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
97
typedef struct {
98
    cyg_uint32     rx_mcast;
99
    cyg_uint32     rx_des_err;
100
    cyg_uint32     rx_collision;
101
    cyg_uint32     rx_crc_err;
102
    cyg_uint32     rx_too_long;
103
    cyg_uint32     tx_fifo_underflow;
104
    cyg_uint32     tx_frame_deferred;
105
    cyg_uint32     tx_late_collision;
106
    cyg_uint32     tx_no_carrier;
107
    cyg_uint32     tx_loss_carrier;
108
} a2fxxx_eth_stats;
109
#endif
110
 
111
// Internal data structure
112
struct a2fxxx_eth_info {
113
    volatile struct    a2fxxx_bd *txbd,
114
                      *rxbd;                   // Next Tx,Rx descriptor to use
115
    volatile struct    a2fxxx_bd *tbase,
116
                      *rbase;                  // First Tx,Rx descriptor
117
    volatile struct    a2fxxx_bd *tnext,
118
                      *rnext;                  // Next descriptor to check for interrupt
119
    cyg_uint8          txactive;               // Count of active Tx buffers
120
    unsigned long      txkey[CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_TxNUM];
121
    cyg_uint8          mac_address[6];         // mac (hardware) address
122
    cyg_uint8          *init_rxbufs;           // Initial base pointer of RX buffers
123
    cyg_uint8          *init_txbufs;           // Initial base pointer of TX buffers
124
    volatile struct    a2fxxx_bd *init_rxring; // Initial base pointer of RX ring
125
    volatile struct    a2fxxx_bd *init_txring; // Initial base pointer of TX ring
126
    cyg_uint32         rx_mac[48];             // Setup frame (192) bytes
127
    cyg_uint32         valid_mac;
128
#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
129
    a2fxxx_eth_stats   stats;                  // MAC statistics
130
#endif
131
    cyg_uint32         base;                   // MAC base address
132
    cyg_uint32         base_bb;                // MAC base address (bit-band)
133
    cyg_uint8          if_num;
134
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
135
    cyg_uint8          vector;
136
    cyg_interrupt      interrupt;
137
    cyg_handle_t       interrupt_handle;
138
#endif
139
#ifdef CYGPKG_DEVS_ETH_PHY
140
    eth_phy_access_t   *phy;
141
#endif
142
};
143
 
144
static void     a2fxxx_phy_init(void);
145
static bool     a2fxxx_mdio_read(cyg_int32, cyg_int32, cyg_uint16 *);
146
static void     a2fxxx_mdio_write(cyg_int32, cyg_int32, cyg_uint16);
147
 
148
static void     a2fxxx_eth_int(struct eth_drv_sc *data);
149
 
150
#ifdef CYGDAT_DEVS_CORTEXM_A2FXXX_ETH_INL
151
# include CYGDAT_DEVS_CORTEXM_A2FXXX_ETH_INL
152
#endif
153
 
154
#include <cyg/infra/diag.h>
155
 
156
#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_CHATTER
157
# define a2fxxx_eth_printf(args...)   diag_printf(args)
158
#else
159
# define a2fxxx_eth_printf(args...)    /* NOOP */
160
#endif
161
 
162
// For fetching the ESA from RedBoot
163
#include <cyg/hal/hal_if.h>
164
#ifndef CONFIG_ESA
165
# define CONFIG_ESA 6
166
#endif
167
 
168
// ----------------------------------------------------------------
169
// Definition
170
//
171
//
172
 
173
#define RESET_FULL_DUPLEX                     0x00000001
174
#define RESET_100MB                           0x00000002
175
 
176
#define MDIO_PREAMBLE_SEQ                     0xffffffff
177
#define MDIO_START_SEQ                        0x01
178
#define MDIO_WRITE_SEQ                        0x01
179
#define MDIO_READ_SEQ                         0x02
180
#define MDIO_STOP_WRITE_SEQ                   0x02
181
#define MDIO_STOP_READ_SEQ                    0x00
182
 
183
#define CYGHWR_HAL_A2FXXX_MAC_CSR5_TI_BB(_base_)  \
184
    ( _base_ + ( CYGHWR_HAL_A2FXXX_MAC_CSR5 << 5 ) + (  0*sizeof(cyg_uint32) ) )
185
#define CYGHWR_HAL_A2FXXX_MAC_CSR5_RI_BB(_base_)  \
186
    ( _base_ + ( CYGHWR_HAL_A2FXXX_MAC_CSR5 << 5 ) + (  6*sizeof(cyg_uint32) ) )
187
#define CYGHWR_HAL_A2FXXX_MAC_CSR5_NIS_BB(_base_) \
188
    ( _base_ + ( CYGHWR_HAL_A2FXXX_MAC_CSR5 << 5 ) + ( 16*sizeof(cyg_uint32) ) )
189
 
190
#define CYGHWR_HAL_A2FXXX_MAC_PRIVATE_SENT    BIT_(0)
191
 
192
#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
193
# define A2FXXX_INC_STATS(_x_)                 (qi->stats._x_++)
194
#endif
195
 
196
// ----------------------------------------------------------------
197
// MDIO API
198
//
199
//
200
 
201
#define MDIO_XFER_BITS( reg, reg_val, sequence, length )      \
202
{                                                             \
203
    cyg_uint32 i;                                             \
204
    for (i = (1 << (length-1)); i != 0; ) {                   \
205
        reg_val &= ~CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC;           \
206
        HAL_WRITE_UINT32( reg, reg_val );                     \
207
        HAL_DELAY_US(1);                                      \
208
        if( i & sequence )                                    \
209
            reg_val |= (  CYGHWR_HAL_A2FXXX_MAC_CSR9_MDO );   \
210
        else                                                  \
211
            reg_val &= ( ~CYGHWR_HAL_A2FXXX_MAC_CSR9_MDO );   \
212
        HAL_WRITE_UINT32( reg, reg_val );                     \
213
        reg_val |= CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC;            \
214
        HAL_WRITE_UINT32( reg, reg_val );                     \
215
        HAL_DELAY_US(1);                                      \
216
        i = i >> 1;                                           \
217
    }                                                         \
218
}
219
 
220
//
221
// Setup IOs
222
//
223
static void
224
a2fxxx_phy_init(void)
225
{
226
    a2fxxx_eth_printf("ETH A2Fxxx - PHY Init\n");
227
    CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_MDIO);
228
    CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_MDC);
229
}
230
 
231
//
232
// Start MDIO transfer -> 32 bits of preamble ('1'), start bits,
233
// transfer type bits, phy address and register address bits
234
//
235
static void
236
a2fxxx_mdio_xfer_start(cyg_bool rd, cyg_uint8 phy_addr, cyg_uint8 addr)
237
{
238
    cyg_uint32      csr9_reg =
239
        (CYGHWR_HAL_A2FXXX_MAC + CYGHWR_HAL_A2FXXX_MAC_CSR9);
240
    cyg_uint32      csr9_data,
241
                    bit_sequence;
242
 
243
    // Enable MDIO write
244
    HAL_READ_UINT32(csr9_reg, csr9_data);
245
    csr9_data |=
246
        (CYGHWR_HAL_A2FXXX_MAC_CSR9_MDEN | CYGHWR_HAL_A2FXXX_MAC_CSR9_MDO |
247
         CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC);
248
    HAL_WRITE_UINT32(csr9_reg, csr9_data);
249
    HAL_DELAY_US(1);
250
 
251
    // Send preamble bits
252
    bit_sequence = MDIO_PREAMBLE_SEQ;
253
    MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 32);
254
 
255
    // Send 2 start bits
256
    bit_sequence = MDIO_START_SEQ;
257
    MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 2);
258
 
259
    // Send transfer type bits
260
    bit_sequence = (rd == true) ? MDIO_READ_SEQ : MDIO_WRITE_SEQ;
261
    MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 2);
262
 
263
    // Send PHY address
264
    bit_sequence = (cyg_uint32)phy_addr;
265
    MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 5);
266
 
267
    // Send register address
268
    bit_sequence = (cyg_uint32)addr;
269
    MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 5);
270
 
271
    // Send TA sequence
272
    if (rd == true) {
273
        bit_sequence = MDIO_STOP_READ_SEQ;
274
        csr9_data &= ~(CYGHWR_HAL_A2FXXX_MAC_CSR9_MDEN);
275
        HAL_WRITE_UINT32(csr9_reg, csr9_data);
276
    } else {
277
        bit_sequence = MDIO_STOP_WRITE_SEQ;
278
    }
279
    MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 2);
280
 
281
    // now we can read or write the 16 bits data ...
282
}
283
 
284
//
285
// Read 16 bits data from MDIO interface
286
//
287
static cyg_bool
288
a2fxxx_mdio_xfer_read(cyg_uint16 *data)
289
{
290
    cyg_uint32      csr9_reg =
291
        (CYGHWR_HAL_A2FXXX_MAC + CYGHWR_HAL_A2FXXX_MAC_CSR9);
292
    cyg_uint32      csr9_data;
293
    *data = 0;
294
    int             i;
295
 
296
    // Read MDIO register
297
    HAL_READ_UINT32(csr9_reg, csr9_data);
298
 
299
    // Clock in the RX data
300
    for (i = (1 << 15); i != 0;) {
301
        csr9_data &= ~CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC;
302
        HAL_WRITE_UINT32(csr9_reg, csr9_data);
303
        HAL_DELAY_US(1);
304
        HAL_READ_UINT32(csr9_reg, csr9_data);
305
        if (csr9_data & CYGHWR_HAL_A2FXXX_MAC_CSR9_MDI)
306
            *data |= i;
307
        csr9_data |= CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC;
308
        HAL_WRITE_UINT32(csr9_reg, csr9_data);
309
        HAL_DELAY_US(1);
310
        i = i >> 1;
311
    }
312
 
313
    return true;
314
}
315
 
316
//
317
// Write 16 bits data to MDIO interface
318
//
319
static bool
320
a2fxxx_mdio_xfer_write(cyg_uint16 data)
321
{
322
    cyg_uint32      csr9_reg =
323
        (CYGHWR_HAL_A2FXXX_MAC + CYGHWR_HAL_A2FXXX_MAC_CSR9);
324
    cyg_uint32      csr9_data,
325
                    bit_sequence;
326
 
327
    // Read MDIO register
328
    HAL_READ_UINT32(csr9_reg, csr9_data);
329
 
330
    // Write data
331
    bit_sequence = (cyg_uint32)data;
332
    MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 16);
333
 
334
    // Set back clock to low
335
    csr9_data &= ~CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC;
336
    HAL_WRITE_UINT32(csr9_reg, csr9_data);
337
 
338
    return true;
339
}
340
 
341
//
342
// MDIO read register
343
//
344
static bool
345
a2fxxx_mdio_read(cyg_int32 addr, cyg_int32 phy_addr, cyg_uint16 *data)
346
{
347
    bool            res;
348
    a2fxxx_mdio_xfer_start(true, phy_addr, addr);
349
    res = a2fxxx_mdio_xfer_read(data);
350
    a2fxxx_eth_printf("ETH A2Fxxx - PHY %x(%x) - RX data %x\n", phy_addr, addr,
351
                      *data);
352
    return res;
353
}
354
 
355
//
356
// MDIO write register
357
//
358
static void
359
a2fxxx_mdio_write(cyg_int32 addr, cyg_int32 phy_addr, cyg_uint16 data)
360
{
361
    a2fxxx_mdio_xfer_start(false, phy_addr, addr);
362
    a2fxxx_eth_printf("ETH A2Fxxx - PHY %x(%x) - TX data %x\n", phy_addr, addr,
363
                      data);
364
    a2fxxx_mdio_xfer_write(data);
365
}
366
 
367
 
368
// ----------------------------------------------------------------
369
// Ethernet driver
370
//
371
//
372
#define A2FXXX_RESET_MAC( qi )                                \
373
{                                                             \
374
    cyg_uint32      swr_addr =                                \
375
          qi->base_bb + (CYGHWR_HAL_A2FXXX_MAC_CSR0 << 5);    \
376
    cyg_uint32      swr_data = 0x1;                           \
377
    HAL_WRITE_UINT32(swr_addr, swr_data);                     \
378
    do {                                                      \
379
        HAL_READ_UINT32(swr_addr, swr_data);                  \
380
    } while (swr_data);                                       \
381
}
382
 
383
//
384
// Deliver function (ex-DSR) handles the Ethernet [logical] processing
385
//
386
static void
387
a2fxxx_eth_deliver(struct eth_drv_sc *sc)
388
{
389
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
390
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *)sc->driver_private;
391
#endif
392
    a2fxxx_eth_int(sc);
393
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
394
    // Allow interrupts to happen again
395
    cyg_drv_interrupt_unmask(qi->vector);
396
#endif
397
}
398
 
399
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
400
//
401
// This ISR is called when the Ethernet interrupt occurs
402
//
403
static int
404
a2fxxx_eth_isr(cyg_vector_t vector, cyg_addrword_t data,
405
               HAL_SavedRegisters * regs)
406
{
407
    a2fxxx_eth_printf("ETH A2Fxxx - ISR\n");
408
    cyg_drv_interrupt_mask(vector);
409
    cyg_drv_interrupt_acknowledge(vector);
410
 
411
    return (CYG_ISR_HANDLED | CYG_ISR_CALL_DSR);        // Run the DSR
412
}
413
 
414
void
415
a2fxxx_eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
416
{
417
    a2fxxx_eth_deliver((struct eth_drv_sc *)data);
418
    // Allow interrupts to happen again
419
    cyg_drv_interrupt_unmask(vector);
420
}
421
#endif
422
 
423
//
424
// This function add MAC address to the list of allowed MAC address
425
// that the MAC layer can deliver to the application layer
426
//
427
static bool
428
a2fxxx_eth_add_mac ( struct eth_drv_sc *sc, cyg_uint8 *mac )
429
{
430
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *)sc->driver_private;
431
    cyg_uint8 idx = 12;
432
    struct a2fxxx_bd setup_bd;
433
    cyg_uint32 i, csr4, csr5, csr6, csr7;
434
 
435
    // If no MAC to be added, just re-send the setup frame
436
    if( mac != NULL )
437
    {
438
        // no more room
439
        if( qi->valid_mac == (cyg_uint32) -1 )
440
            return false;
441
 
442
        // Search empty spot
443
        while( qi->valid_mac & i ){
444
            i = i << 1;
445
            idx += 12;
446
        }
447
 
448
        qi->rx_mac[idx+0] = mac[0];
449
        qi->rx_mac[idx+1] = mac[1];
450
        qi->rx_mac[idx+4] = mac[2];
451
        qi->rx_mac[idx+5] = mac[3];
452
        qi->rx_mac[idx+8] = mac[4];
453
        qi->rx_mac[idx+9] = mac[6];
454
    }
455
 
456
    a2fxxx_eth_printf("ETH A2Fxxx - Send setup frame for %s\n", sc->dev_name);
457
 
458
    // Stop TX
459
    HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
460
    csr6 &= ~( CYGHWR_HAL_A2FXXX_MAC_CSR6_ST );
461
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
462
 
463
    // Wait until controller is halted
464
    do {
465
        HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR5), csr5);
466
    } while( ((csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_MASK)
467
                                     != CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_STOP) );
468
 
469
    // Backup the current BD / interrupt mask
470
    HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR4), csr4);
471
    HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR7), csr7);
472
 
473
    // Disable interrupt
474
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR7), 0);
475
 
476
    // Setup descriptor for setup frame
477
    setup_bd.des0 = CYGHWR_HAL_A2FXXX_MAC_TDES0_OWN;
478
    setup_bd.des1 = CYGHWR_HAL_A2FXXX_MAC_TDES1_TER |
479
                         CYGHWR_HAL_A2FXXX_MAC_TDES1_SET |
480
                         CYGHWR_HAL_A2FXXX_MAC_TDES1_TBS1(192);
481
    setup_bd.des2 = (cyg_uint32) &qi->rx_mac[0];
482
    setup_bd.des3 = (cyg_uint32) NULL;
483
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR4),
484
                      (cyg_uint32) &setup_bd);
485
 
486
    // Start transmission
487
    csr6 |= ( CYGHWR_HAL_A2FXXX_MAC_CSR6_ST );
488
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
489
 
490
    // Poll for transmission completed
491
    do {
492
        HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR5), csr5);
493
    } while( ((csr5 & A2FXXX_MAC_TX_STATE_MASK) != A2FXXX_MAC_TX_STATE(SUSPEND)) );
494
 
495
    // Stop transmission
496
    csr6 &= ~( CYGHWR_HAL_A2FXXX_MAC_CSR6_ST );
497
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
498
 
499
    // Wait until controller is halted
500
    do {
501
        HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR5), csr5);
502
    } while( ((csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_MASK)
503
                                    != CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_STOP) );
504
 
505
    // Restore BD
506
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR4), csr4);
507
 
508
    HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_TI_BB(qi->base_bb), 1);
509
 
510
    // Restore interrupt mask
511
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR7), csr7);
512
 
513
    return true;
514
}
515
 
516
//
517
// [re]Initialize the Ethernet controller
518
//   Done separately since shutting down the device requires a
519
//   full reconfiguration when re-enabling.
520
//   when
521
static bool
522
a2fxxx_eth_setup(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
523
{
524
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
525
    volatile struct a2fxxx_bd *rxbd, *txbd;
526
    cyg_uint8 *RxBUF, *TxBUF;
527
    cyg_uint32 csr0, csr6 = 0, csr11;
528
    int i = 0;
529
 
530
    qi->valid_mac = 0;
531
    qi->rx_mac[5] = enaddr[0];
532
    qi->rx_mac[4] = enaddr[1];
533
    qi->rx_mac[3] = enaddr[2];
534
    qi->rx_mac[2] = enaddr[3];
535
    qi->rx_mac[1] = enaddr[4];
536
    qi->rx_mac[0] = enaddr[5];
537
 
538
    txbd = qi->init_txring;
539
    rxbd = qi->init_rxring;
540
 
541
    /* Init Rx / Tx ring base */
542
    qi->tbase = qi->txbd = qi->tnext = txbd;
543
    qi->rbase = qi->rxbd = qi->rnext = rxbd;
544
    qi->txactive = 0;
545
 
546
    RxBUF = qi->init_rxbufs;
547
    TxBUF = qi->init_txbufs;
548
 
549
    /* Initialize Rx BDs */
550
    for (i = 0; i < CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_RxNUM; i++)
551
    {
552
        rxbd->des0 = CYGHWR_HAL_A2FXXX_MAC_RDES0_OWN;
553
        rxbd->des1 =
554
          CYGHWR_HAL_A2FXXX_MAC_RDES1_RBS1(CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ALIGN_BUFSIZE_RX);
555
        rxbd->des2 = (cyg_uint32) RxBUF;
556
        rxbd->des3 = (cyg_uint32) NULL;
557
        RxBUF += CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ALIGN_BUFSIZE_RX;
558
        rxbd++;
559
    }
560
    rxbd--;
561
    rxbd->des1 |= CYGHWR_HAL_A2FXXX_MAC_RDES1_RER; // Last buffer
562
 
563
    /* Initialize Tx BDs */
564
    for (i = 0; i < CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_TxNUM; i++)
565
    {
566
        txbd->des1 = 0;
567
        txbd->des2 = (cyg_uint32) TxBUF;
568
        rxbd->des3 = (cyg_uint32) NULL;
569
        txbd->private = 0;
570
        TxBUF += CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ALIGN_BUFSIZE_TX;
571
        txbd++;
572
    }
573
    txbd--;
574
    txbd->des1 |= CYGHWR_HAL_A2FXXX_MAC_TDES1_TER; // Last buffer
575
 
576
    // Setup automatic polling
577
    csr0 = CYGHWR_HAL_A2FXXX_MAC_CSR0_CLEAR | CYGHWR_HAL_A2FXXX_MAC_CSR0_TAP(3) |
578
           CYGHWR_HAL_A2FXXX_MAC_CSR0_DSL(1);
579
 
580
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR0),
581
                      (cyg_uint32) csr0);
582
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR3),
583
                      (cyg_uint32) (qi->rbase));
584
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR4),
585
                      (cyg_uint32) (qi->tbase));
586
 
587
    csr11 = CYGHWR_HAL_A2FXXX_MAC_CSR11_TT(7) |
588
            CYGHWR_HAL_A2FXXX_MAC_CSR11_NTP(1) |
589
            CYGHWR_HAL_A2FXXX_MAC_CSR11_RT(7) |
590
            CYGHWR_HAL_A2FXXX_MAC_CSR11_NRP(1);
591
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR11), (cyg_uint32) csr11);
592
 
593
    HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
594
    csr6 |= CYGHWR_HAL_A2FXXX_MAC_CSR6_CLEAR;
595
 
596
    csr6 |= ((flags & RESET_100MB) ? CYGHWR_HAL_A2FXXX_MAC_CSR6_TTM : 0x0) |
597
           ((flags & RESET_FULL_DUPLEX) ? CYGHWR_HAL_A2FXXX_MAC_CSR6_FD : 0x0);
598
 
599
#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_PROMISCUOUS
600
    csr6 |= CYGHWR_HAL_A2FXXX_MAC_CSR6_PR;
601
#endif
602
 
603
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
604
 
605
    return true;
606
}
607
 
608
//
609
// This function is called to shut down the interface.
610
//
611
static void
612
a2fxxx_eth_stop(struct eth_drv_sc *sc)
613
{
614
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *)sc->driver_private;
615
    cyg_uint32 csr6, csr5;
616
 
617
    a2fxxx_eth_printf("ETH A2Fxxx - Stop\n");
618
 
619
    // Stop RX / TX
620
    HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
621
    csr6 &= ~( CYGHWR_HAL_A2FXXX_MAC_CSR6_SR | CYGHWR_HAL_A2FXXX_MAC_CSR6_ST );
622
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
623
 
624
    // Stall until controller is halted
625
    do {
626
        HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR5), csr5);
627
    } while( ((csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_MASK) != CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_STOP) &&
628
             ((csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_RS_MASK) != CYGHWR_HAL_A2FXXX_MAC_CSR5_RS_STOP));
629
 
630
}
631
 
632
//
633
// Setup Ethernet IOs.
634
//
635
static void
636
a2fxxx_eth_io(void)
637
{
638
    CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_TXD0);
639
    CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_TXD1);
640
    CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_RXD0);
641
    CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_RXD1);
642
    CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_TXEN);
643
    CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_CRSDV);
644
    CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_RXER);
645
}
646
 
647
//
648
// Initialize the interface - performed at system startup
649
// This function must set up the interface, including arranging to
650
// handle interrupts, etc, so that it may be "started" cheaply later.
651
//
652
static bool
653
a2fxxx_eth_init(struct cyg_netdevtab_entry *tab)
654
{
655
    struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
656
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *)sc->driver_private;
657
    cyg_uint32      speed100 = 0, full_duplex = 0;
658
    bool            esa_ok;
659
    cyg_uint16      phy_state = 0;
660
    cyg_uint32      istate, csr7;
661
    bool            ret = true;
662
 
663
    a2fxxx_eth_printf("ETH A2Fxxx - Initialization for %s\n", sc->dev_name);
664
 
665
    // Release MAC controller
666
    CYGHWR_HAL_A2FXXX_PERIPH_RELEASE(CYGHWR_HAL_A2FXXX_PERIPH_SOFTRST(MAC));
667
 
668
    // Setup IOs
669
    a2fxxx_eth_io();
670
 
671
    // Reset MAC
672
    A2FXXX_RESET_MAC( qi );
673
 
674
    HAL_DISABLE_INTERRUPTS(istate);
675
 
676
    a2fxxx_eth_stop(sc);
677
 
678
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
679
    cyg_drv_interrupt_create(qi->vector,
680
                             CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ISR_PRIORITY,
681
                             (cyg_addrword_t)sc,    //  Data item passed to interrupt handler
682
                             (cyg_ISR_t *)a2fxxx_eth_isr,
683
                             (cyg_DSR_t *)eth_drv_dsr,
684
                             &qi->interrupt_handle, &qi->interrupt);
685
    cyg_drv_interrupt_attach(qi->interrupt_handle);
686
    cyg_drv_interrupt_unmask(qi->vector);
687
#endif
688
 
689
    esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
690
                                         "a2fxxx_esa", enaddr, CONFIG_ESA);
691
 
692
    if (!esa_ok) {
693
        a2fxxx_eth_printf("ETH A2Fxxx - Warning! ESA unknown for %s\n", sc->dev_name);
694
        memcpy(&enaddr, &qi->mac_address, sizeof(enaddr));
695
    }
696
 
697
#ifdef CYGPKG_DEVS_ETH_PHY
698
    if (!_eth_phy_init(qi->phy)) {
699
        a2fxxx_eth_printf("ETH A2Fxxx - Failed to initialize PHY of %s\n",
700
                          sc->dev_name);
701
        ret = false;
702
        goto exit;
703
    }
704
    phy_state = _eth_phy_state(qi->phy);
705
 
706
    if (phy_state & ETH_PHY_STAT_100MB)
707
        speed100 = 1;
708
    if (phy_state & ETH_PHY_STAT_FDX)
709
        full_duplex = 1;
710
    if (phy_state & ETH_PHY_STAT_LINK) {
711
        a2fxxx_eth_printf("Ethernet Mode (%s): %sMbps/%s\n",
712
                          sc->dev_name,
713
                          (speed100 ? "100" : "10"),
714
                          (full_duplex ? "Full" : "Half"));
715
    } else {
716
        a2fxxx_eth_printf("ETH A2Fxxx - NO LINK on %s\n", sc->dev_name);
717
    }
718
#else
719
    a2fxxx_eth_printf("ETH A2Fxxx - No PHY interface specified for %s\n",
720
                      sc->dev_name);
721
    ret = false;
722
    goto exit;
723
#endif
724
 
725
    if (!a2fxxx_eth_setup(sc, enaddr, (full_duplex ? RESET_FULL_DUPLEX
726
                         : 0x00000000) | (speed100 ? RESET_100MB : 0x00000000)))
727
    {
728
      ret = false;
729
      goto exit;
730
    }
731
 
732
    a2fxxx_eth_add_mac( sc, NULL );
733
 
734
    HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_RI_BB(qi->base_bb), 1);
735
    HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_TI_BB(qi->base_bb), 1);
736
 
737
    csr7 = ( CYGHWR_HAL_A2FXXX_MAC_CSR7_TIE | CYGHWR_HAL_A2FXXX_MAC_CSR7_RIE |
738
                    CYGHWR_HAL_A2FXXX_MAC_CSR7_NIE);
739
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR7), csr7);
740
 
741
    HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_NIS_BB(qi->base_bb),
742
                                                           (cyg_uint32) 0x1);
743
 
744
    // Call upper layer initialization
745
    (sc->funs->eth_drv->init)(sc, (unsigned char *) &enaddr);
746
 
747
exit:
748
    HAL_RESTORE_INTERRUPTS(istate);
749
    return ret;
750
}
751
 
752
//
753
// This function is called to "start up" the interface.  It may be called
754
// multiple times, even when the hardware is already running.  It will be
755
// called whenever something "hardware oriented" changes and should leave
756
// the hardware ready to send/receive packets.
757
//
758
static void
759
a2fxxx_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
760
{
761
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *)sc->driver_private;
762
    cyg_uint32 csr6;
763
 
764
    a2fxxx_eth_printf("ETH A2Fxxx - Start\n");
765
 
766
    // Stop RX / TX
767
    HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
768
    csr6 |= ( CYGHWR_HAL_A2FXXX_MAC_CSR6_SR | CYGHWR_HAL_A2FXXX_MAC_CSR6_ST );
769
    HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
770
}
771
 
772
//
773
// This function is called for low level "control" operations
774
//
775
static int
776
a2fxxx_eth_control(struct eth_drv_sc *sc, unsigned long key,
777
                   void *data, int length)
778
{
779
    switch (key)
780
    {
781
    case ETH_DRV_SET_MAC_ADDRESS:
782
        return 0;
783
        break;
784
#ifdef ETH_DRV_SET_MC_ALL
785
    case ETH_DRV_SET_MC_ALL:
786
    case ETH_DRV_SET_MC_LIST:
787
        // TODO
788
        return 0;
789
        break;
790
#endif
791
    default:
792
        return 1;
793
        break;
794
    }
795
}
796
 
797
//
798
// This function is called to see if another packet can be sent.
799
// It should return the number of packets which can be handled.
800
// Zero should be returned if the interface is busy and can not send any more.
801
//
802
static int
803
a2fxxx_eth_can_send(struct eth_drv_sc *sc)
804
{
805
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
806
 
807
    return (qi->txactive < CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_TxNUM);
808
}
809
 
810
//
811
// This routine is called to send data to the hardware.
812
static void
813
a2fxxx_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
814
                int sg_len, int total_len, unsigned long key)
815
{
816
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
817
    volatile struct a2fxxx_bd *txbd, *txfirst;
818
    cyg_uint32 des1 = CYGHWR_HAL_A2FXXX_MAC_TDES1_TBS1(total_len);
819
    volatile cyg_uint8 *bp;
820
    cyg_int32 i, txindex, istate;
821
 
822
    a2fxxx_eth_printf("ETH A2Fxxx - transmit pkt, length %d\n", total_len);
823
 
824
    // Continue from current descriptor
825
    txbd = txfirst = qi->txbd;
826
 
827
    if ( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_OWN) == CYGHWR_HAL_A2FXXX_MAC_TDES0_OWN ) {
828
        a2fxxx_eth_printf("ETH A2Fxxx - Fatal error, no free BD for %s\n",
829
            sc->dev_name);
830
        a2fxxx_eth_printf("ETH A2Fxxx - Cannot transmit packet, active pkt in queue:%d\n",
831
            qi->txactive);
832
        return;
833
    }
834
 
835
    // Set up buffer
836
    bp = (cyg_uint8 *) txbd->des2;
837
    for (i = 0; i < sg_len; i++) {
838
        memcpy((void *) bp, (void *) sg_list[i].buf, sg_list[i].len);
839
        bp += sg_list[i].len;
840
    }
841
 
842
    if (txbd->des1 & CYGHWR_HAL_A2FXXX_MAC_TDES1_TER) {
843
        des1 |= CYGHWR_HAL_A2FXXX_MAC_TDES1_TER;
844
    }
845
    txbd->des1 =
846
      ( des1 | CYGHWR_HAL_A2FXXX_MAC_TDES1_LS | CYGHWR_HAL_A2FXXX_MAC_TDES1_FS |
847
        CYGHWR_HAL_A2FXXX_MAC_TDES1_IC );
848
    txindex = ((unsigned long) txbd - (unsigned long) qi->tbase)
849
                / sizeof(*txbd);
850
    qi->txkey[txindex] = key;
851
 
852
    qi->txactive++;
853
 
854
    HAL_DISABLE_INTERRUPTS(istate);
855
    // Give ownership to the MAC
856
    txbd->des0    = CYGHWR_HAL_A2FXXX_MAC_TDES0_OWN;
857
    txbd->private = CYGHWR_HAL_A2FXXX_MAC_PRIVATE_SENT;
858
 
859
    // Remember the next buffer to try
860
    if (qi->txbd->des1 & CYGHWR_HAL_A2FXXX_MAC_TDES1_TER){
861
        qi->txbd = qi->tbase;
862
    }
863
    else {
864
        qi->txbd++;
865
    }
866
    HAL_RESTORE_INTERRUPTS(istate);
867
}
868
 
869
//
870
// This function is called for low level "control" operations
871
//
872
static void
873
a2fxxx_eth_TxEvent(struct eth_drv_sc *sc)
874
{
875
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
876
    volatile struct a2fxxx_bd *txbd;
877
    int key, txindex;
878
 
879
    txbd = qi->tnext;
880
 
881
    while ( ( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_OWN ) == 0) &&
882
              (txbd->private & CYGHWR_HAL_A2FXXX_MAC_PRIVATE_SENT) )
883
    {
884
        txindex = ((unsigned long) txbd - (unsigned long) qi->tbase)
885
                / sizeof(*txbd);
886
        if ((key = qi->txkey[txindex]) != 0)
887
        {
888
            qi->txkey[txindex] = 0;
889
            (sc->funs->eth_drv->tx_done)(sc, key, 0);
890
        }
891
        qi->txactive--;
892
#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
893
        if( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_LC) ) {
894
            A2FXXX_INC_STATS(tx_late_collision);
895
        }
896
        if( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_NC) ) {
897
            A2FXXX_INC_STATS(tx_no_carrier);
898
        }
899
        if( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_LO) ) {
900
            A2FXXX_INC_STATS(tx_loss_carrier);
901
        }
902
        if( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_DE) ) {
903
            A2FXXX_INC_STATS(tx_frame_deferred);
904
        }
905
        if( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_UF) ) {
906
            A2FXXX_INC_STATS(tx_fifo_underflow);
907
        }
908
#endif
909
        txbd->private &= ~CYGHWR_HAL_A2FXXX_MAC_PRIVATE_SENT;
910
        if (txbd->des1 & CYGHWR_HAL_A2FXXX_MAC_TDES1_TER){
911
            txbd = qi->tbase;
912
        } else {
913
            txbd++;
914
        }
915
    }
916
    // Remember where we left off
917
    qi->tnext = (struct a2fxxx_bd *) txbd;
918
}
919
 
920
//
921
// Interrupt vector
922
//
923
static int
924
a2fxxx_eth_int_vector(struct eth_drv_sc *sc)
925
{
926
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
927
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
928
    return (qi->vector);
929
#else
930
    return 0;
931
#endif
932
}
933
 
934
//
935
// This function is called when a packet has been received.  It's job is
936
// to prepare to unload the packet from the hardware.  Once the length of
937
// the packet is known, the upper layer of the driver can be told.  When
938
// the upper layer is ready to unload the packet, the internal function
939
// 'fec_eth_recv' will be called to actually fetch it from the hardware.
940
//
941
static void
942
a2fxxx_eth_RxEvent(struct eth_drv_sc *sc)
943
{
944
  struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
945
  volatile struct a2fxxx_bd *rxbd, *rxfirst;
946
  int cnt_bd = 0;
947
  cyg_int32 len;
948
 
949
  rxbd = rxfirst = qi->rnext;
950
  while ((rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_OWN) == 0)
951
  {
952
    cnt_bd++;
953
    qi->rxbd = rxbd; // Save for callback
954
 
955
#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
956
    if( (rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_CE) ) {
957
        A2FXXX_INC_STATS(rx_crc_err);
958
    }
959
    if( (rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_CS) ) {
960
        A2FXXX_INC_STATS(rx_collision);
961
    }
962
    if( (rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_TL) ) {
963
        A2FXXX_INC_STATS(rx_too_long);
964
    }
965
    if( (rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_MF) ) {
966
        A2FXXX_INC_STATS(rx_mcast);
967
    }
968
    if( (rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_DE) ) {
969
        A2FXXX_INC_STATS(rx_des_err);
970
    }
971
#endif
972
 
973
    len = (rxbd->des0 >> 16) & 0x3fff;
974
    a2fxxx_eth_printf("ETH A2Fxxx - Receive pkt, length %d\n", len);
975
 
976
    (sc->funs->eth_drv->recv)(sc, len - 4);
977
    if (rxbd->des1 & CYGHWR_HAL_A2FXXX_MAC_RDES1_RER){
978
        rxbd = qi->rbase;
979
    } else {
980
        rxbd++;
981
    }
982
  }
983
  // Remember where we left off
984
  qi->rnext = (struct a2fxxx_bd *) rxbd;
985
}
986
 
987
//
988
// Interrupt processing
989
//
990
static void
991
a2fxxx_eth_int(struct eth_drv_sc *sc)
992
{
993
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
994
    cyg_uint32 csr5;
995
 
996
     // Check interrupt status
997
     HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR5), csr5);
998
 
999
     if (( csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_TI ) != 0)
1000
     {
1001
         a2fxxx_eth_printf("%s - Transmit packet irq\n", sc->dev_name);
1002
         a2fxxx_eth_TxEvent(sc);
1003
         HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_TI_BB(qi->base_bb), 1);
1004
     }
1005
 
1006
     if (( csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_RI ) != 0)
1007
     {
1008
         a2fxxx_eth_printf("%s - Receive packet irq\n", sc->dev_name);
1009
         a2fxxx_eth_RxEvent(sc);
1010
         HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_RI_BB(qi->base_bb), 1);
1011
     }
1012
}
1013
 
1014
//
1015
// Polling function
1016
//
1017
static void
1018
a2fxxx_eth_poll(struct eth_drv_sc *sc)
1019
{
1020
     a2fxxx_eth_int(sc);
1021
     CYGACC_CALL_IF_DELAY_US(500);
1022
}
1023
 
1024
static void
1025
a2fxxx_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
1026
{
1027
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
1028
    cyg_uint8 *bp;
1029
    int i;
1030
 
1031
    bp = (cyg_uint8 *) qi->rxbd->des2;
1032
    for (i = 0; i < sg_len; i++)
1033
    {
1034
        if (sg_list[i].buf != 0)
1035
        {
1036
            memcpy((void *) sg_list[i].buf, bp, sg_list[i].len);
1037
            bp += sg_list[i].len;
1038
        }
1039
    }
1040
    qi->rxbd->des0 |= CYGHWR_HAL_A2FXXX_MAC_RDES0_OWN;
1041
}
1042
 
1043
 
1044
//
1045
// Display ETH statistics
1046
//
1047
#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
1048
externC void
1049
a2fxxx_disp_stats(struct eth_drv_sc *sc , char flag )
1050
{
1051
    struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
1052
 
1053
    diag_printf("Ethernet Statistics\n");
1054
 
1055
    diag_printf("%17s %10d\n",
1056
        "RX MCAST",
1057
        qi->stats.rx_mcast);
1058
    diag_printf("%17s %10d\n",
1059
        "RX DESC ERR",
1060
        qi->stats.rx_des_err);
1061
    diag_printf("%17s %10d\n",
1062
        "RX COLLISION",
1063
        qi->stats.rx_collision);
1064
    diag_printf("%17s %10d\n",
1065
        "RX CRC ERR",
1066
        qi->stats.rx_crc_err);
1067
    diag_printf("%17s %10d\n",
1068
        "RX TOO LONG",
1069
        qi->stats.rx_too_long);
1070
    diag_printf("%17s %10d\n",
1071
        "TX FIFO UNDERFLOW",
1072
        qi->stats.tx_fifo_underflow);
1073
    diag_printf("%17s %10d\n",
1074
        "TX FRAME DEFERRED",
1075
        qi->stats.tx_frame_deferred);
1076
    diag_printf("%17s %10d\n",
1077
        "TX LATE COLLISION",
1078
        qi->stats.tx_late_collision);
1079
    diag_printf("%17s %10d\n",
1080
        "TX NO CARRIER",
1081
        qi->stats.tx_no_carrier);
1082
    diag_printf("%17s %10d\n",
1083
        "TX LOSS CARRIER",
1084
        qi->stats.tx_loss_carrier);
1085
}
1086
#endif
1087
 
1088
// EOF if_a2fxxx.c

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.