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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [eth/] [mips/] [atlas/] [v2_0/] [src/] [if_atlas.c] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      dev/if_atlas.c
4
//
5
//      Ethernet device driver for MIPS Atlas using Philips SAA9730
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
13
//
14
// eCos is free software; you can redistribute it and/or modify it under
15
// the terms of the GNU General Public License as published by the Free
16
// Software Foundation; either version 2 or (at your option) any later version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19
// 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 along
24
// with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26
//
27
// As a special exception, if other files instantiate templates or use macros
28
// or inline functions from this file, or you compile this file and link it
29
// with other works to produce a work based on this file, this file does not
30
// by itself cause the resulting work to be covered by the GNU General Public
31
// License. However the source code for this file must still be made available
32
// in accordance with section (3) of the GNU General Public License.
33
//
34
// This exception does not invalidate any other reasons why a work based on
35
// this file might be covered by the GNU General Public License.
36
//
37
// Alternative licenses for eCos may be arranged by contacting the copyright
38
// holders.
39
// -------------------------------------------
40
//####ECOSGPLCOPYRIGHTEND####
41
//####BSDCOPYRIGHTBEGIN####
42
//
43
// -------------------------------------------
44
//
45
// Portions of this software may have been derived from OpenBSD or other sources,
46
// and are covered by the appropriate copyright disclaimers included herein.
47
//
48
// -------------------------------------------
49
//
50
//####BSDCOPYRIGHTEND####
51
//==========================================================================
52
//#####DESCRIPTIONBEGIN####
53
//
54
// Author(s):    msalter
55
// Contributors: msalter, nickg
56
// Date:         2000-12-06
57
// Purpose:      
58
// Description:  hardware driver for SAA9730 ethernet
59
//              
60
//
61
//####DESCRIPTIONEND####
62
//
63
//==========================================================================
64
 
65
// Ethernet device driver for MIPS Atlas
66
// Based on SAA9730
67
 
68
#include <pkgconf/system.h>
69
#include <pkgconf/devs_eth_mips_atlas.h>
70
#include <pkgconf/io_eth_drivers.h>
71
 
72
#ifdef CYGPKG_NET
73
#include <pkgconf/net.h>
74
#include <cyg/kernel/kapi.h>
75
#endif
76
#include <cyg/infra/cyg_type.h>
77
#include <cyg/hal/hal_arch.h>
78
#include <cyg/hal/hal_endian.h>
79
#include <cyg/hal/hal_intr.h>
80
#include <cyg/hal/hal_cache.h>
81
#include <cyg/hal/hal_if.h>
82
#include <cyg/infra/diag.h>
83
#include <cyg/hal/drv_api.h>
84
#include <cyg/io/eth/netdev.h>
85
#include <cyg/io/eth/eth_drv.h>
86
 
87
#ifdef CYGPKG_IO_PCI
88
#include <cyg/io/pci.h>
89
// So we can check the validity of the PCI window against the MLTs opinion,
90
// and thereby what the malloc heap consumes willy-nilly:
91
#include CYGHWR_MEMORY_LAYOUT_H
92
#else
93
#error "Need PCI package here"
94
#endif
95
 
96
#ifndef CYGSEM_MIPS_ATLAS_SET_ESA
97
#ifdef CYGPKG_REDBOOT
98
#include <pkgconf/redboot.h>
99
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
100
#include <redboot.h>
101
#include <flash_config.h>
102
RedBoot_config_option("Network hardware address [MAC]",
103
                      atlas_esa,
104
                      ALWAYS_ENABLED, true,
105
                      CONFIG_ESA, 0
106
    );
107
#endif
108
#endif
109
#endif
110
 
111
// SAA9730 LAN definitions
112
#include "saa9730.h"
113
 
114
// Exported statistics and the like
115
#include <cyg/io/eth/eth_drv_stats.h>
116
 
117
#ifndef CYGPKG_REDBOOT
118
//#define DEBUG
119
#endif
120
#define db_printf diag_printf
121
 
122
#define ETHER_ADDR_LEN 6
123
 
124
static unsigned poll_count = 0;  // for bug workaround
125
static void __tx_poll(struct eth_drv_sc *sc);
126
 
127
struct saa9730_priv_data {
128
    int                 active;
129
    cyg_uint32          vector;
130
    cyg_handle_t        interrupt_handle;
131
    cyg_interrupt       interrupt_object;
132
    cyg_uint32          devid;             // PCI device id
133
    cyg_uint32          base;              // PCI memory map base
134
    void                *ndp;
135
 
136
    // index of next RX buffer
137
    cyg_uint8           next_rx_bindex;
138
 
139
    // index of next packet within RX buffer
140
    cyg_uint8           next_rx_pindex;
141
 
142
    // index of next TX buffer
143
    cyg_uint8           next_tx_bindex;
144
 
145
    // index of next packet within TX buffer
146
    cyg_uint8           next_tx_pindex;
147
 
148
    cyg_uint32          *tx_buffer[SAA9730_BUFFERS][SAA9730_TXPKTS_PER_BUFFER];
149
    cyg_uint32          *rx_buffer[SAA9730_BUFFERS][SAA9730_RXPKTS_PER_BUFFER];
150
 
151
    int                 tx_busy;
152
    unsigned long       tx_key[SAA9730_BUFFERS][SAA9730_TXPKTS_PER_BUFFER];
153
    int                 tx_used[SAA9730_BUFFERS];
154
 
155
} saa9730_priv_data;
156
 
157
ETH_DRV_SC(atlas_sc,
158
           &saa9730_priv_data, // Driver specific data
159
           "eth0",             // Name for this interface
160
           saa9730_start,
161
           saa9730_stop,
162
           saa9730_control,
163
           saa9730_can_send,
164
           saa9730_send,
165
           saa9730_recv,
166
           saa9730_deliver,     // "pseudoDSR" called from fast net thread
167
           saa9730_poll,
168
           saa9730_int_vector);
169
 
170
NETDEVTAB_ENTRY(atlas_netdev,
171
                "atlas",
172
                atlas_saa9730_init,
173
                &atlas_sc);
174
 
175
#ifdef CYGSEM_MIPS_ATLAS_SET_ESA
176
static unsigned char enaddr[] = CYGDAT_MIPS_ATLAS_ESA;
177
#else
178
static unsigned char enaddr[ETHER_ADDR_LEN];
179
#endif
180
 
181
static void saa9730_poll(struct eth_drv_sc *sc);
182
 
183
// This ISR is called when the ethernet interrupt occurs
184
static int
185
saa9730_isr(cyg_vector_t vector, cyg_addrword_t data)
186
{
187
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)data;
188
    unsigned long __base = spd->base;
189
 
190
#ifndef CYGPKG_REDBOOT    
191
    SAA9730_EVM_IER_SW &= ~(SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
192
    SAA9730_EVM_ISR = SAA9730_EVM_LAN_INT;
193
    cyg_drv_interrupt_mask(vector);
194
#endif
195
#ifdef DEBUG
196
    db_printf("saa9730_isr\n");
197
#endif
198
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
199
}
200
 
201
#ifndef CYGPKG_REDBOOT
202
static
203
void saa9730_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
204
{
205
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)data;
206
    struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(spd->ndp);
207
    struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
208
#ifdef DEBUG
209
    db_printf("saa9730_dsr\n");
210
#endif
211
 
212
    eth_drv_dsr(vector, count, (cyg_addrword_t)sc);
213
}
214
#endif
215
 
216
static int
217
saa9730_int_vector(struct eth_drv_sc *sc)
218
{
219
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
220
 
221
    return spd->vector;
222
}
223
 
224
static void
225
__init_buffers(struct saa9730_priv_data *spd)
226
{
227
    extern char cyg_io_atlas_2kbuffers[];
228
    cyg_uint32 *bufp = (cyg_uint32 *)CYGARC_UNCACHED_ADDRESS((unsigned)cyg_io_atlas_2kbuffers);
229
    int i, j;
230
 
231
    for (i = 0; i < SAA9730_BUFFERS; i++) {
232
        for (j = 0; j < SAA9730_RXPKTS_PER_BUFFER; j++) {
233
            memset(bufp, 0, 2048);
234
            spd->rx_buffer[i][j]   = bufp;
235
            bufp += SAA9730_PACKET_SIZE/sizeof(*bufp);
236
        }
237
    }
238
    for (i = 0; i < SAA9730_BUFFERS; i++) {
239
        for (j = 0; j < SAA9730_TXPKTS_PER_BUFFER; j++) {
240
            memset(bufp, 0, 2048);
241
            *bufp = CYG_CPU_TO_LE32(TX_EMPTY);
242
            spd->tx_buffer[i][j] = bufp;
243
            bufp += SAA9730_PACKET_SIZE/sizeof(*bufp);
244
        }
245
    }
246
 
247
    spd->next_rx_pindex = 0;
248
    spd->next_rx_bindex = 0;
249
    spd->next_tx_pindex = 0;
250
    spd->next_tx_bindex = 0;
251
}
252
 
253
static void
254
__select_buffer(struct saa9730_priv_data *spd, int buf_nr)
255
{
256
    unsigned long __base = spd->base;
257
    cyg_uint32 *p;
258
    int i;
259
 
260
    // Enable RX buffer
261
    for (i = 0; i < SAA9730_RXPKTS_PER_BUFFER; i++) {
262
        p = spd->rx_buffer[buf_nr][i];
263
        *p = CYG_CPU_TO_LE32(RX_READY);
264
    }
265
 
266
    if (buf_nr)
267
        SAA9730_OK2USE |= SAA9730_OK2USE_RXB;
268
    else
269
        SAA9730_OK2USE |= SAA9730_OK2USE_RXA;
270
 
271
}
272
 
273
static void
274
__init_cam(struct saa9730_priv_data *spd)
275
{
276
    unsigned long __base = spd->base;
277
    cyg_uint32 abuf[3];  // room for 2 copies of mac address
278
    int i,j,cam_offset;
279
 
280
    // make 2 contiguous copies of mac addr
281
    memcpy((char *)abuf, enaddr, 6);
282
    memcpy((char *)abuf + 6, enaddr, 6);
283
 
284
    // Setting up the address compare regs is weird because you have
285
    // to access by word addresses even though addresses don't have
286
    // an integral number of words.
287
    cam_offset = 0;
288
    for (i = 0; i < SAA9730_CAM_ENTRIES; i++) {
289
        for (j = 0; j < 3; j++, cam_offset++) {
290
            SAA9730_CAMADR = cam_offset;
291
            SAA9730_CAMDAT = CYG_CPU_TO_BE32(abuf[j]);
292
        }
293
    }
294
}
295
 
296
static void
297
__stop_dma(struct saa9730_priv_data *spd)
298
{
299
    unsigned long __base = spd->base;
300
 
301
    // Stop DMA
302
    SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX);
303
 
304
    // Stop tx/rx
305
    SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX;
306
    SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX;
307
 
308
    // Set DMA and MAC reset bits
309
    SAA9730_DMATST |= SAA9730_DMATST_RESET;
310
    SAA9730_MACCTL |= SAA9730_MACCTL_RESET;
311
}
312
 
313
 
314
static void
315
__init_dma(struct saa9730_priv_data *spd)
316
{
317
    unsigned long __base = spd->base;
318
 
319
    __stop_dma(spd);
320
 
321
    // reset DMA engine
322
    SAA9730_DMATST |= SAA9730_DMATST_RESET;
323
 
324
    // setup buffers
325
    SAA9730_TXBUFA = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->tx_buffer[0][0]);
326
    SAA9730_TXBUFB = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->tx_buffer[1][0]);
327
    SAA9730_RXBUFA = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->rx_buffer[0][0]);
328
    SAA9730_RXBUFB = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->rx_buffer[1][0]);
329
 
330
    SAA9730_PKTCNT = ((SAA9730_TXPKTS_PER_BUFFER << 24) |
331
                      (SAA9730_TXPKTS_PER_BUFFER << 16) |
332
                      (SAA9730_RXPKTS_PER_BUFFER <<  8) |
333
                      (SAA9730_RXPKTS_PER_BUFFER <<  0));
334
 
335
    SAA9730_OK2USE = 0;
336
 
337
    __select_buffer(spd, 0);
338
 
339
    // initialize DMA control register
340
    SAA9730_DMACTL = SAA9730_DMACTL_BLKINT |
341
                     SAA9730_DMACTL_MAXXFER_ANY |
342
                     SAA9730_DMACTL_ENDIAN_LITTLE;
343
 
344
    SAA9730_DMACTL |= SAA9730_DMACTL_RXINT;
345
    SAA9730_DMACTL |= (1<<SAA9730_DMACTL_RXINTCNT_SHIFT);
346
    SAA9730_DMACTL &= ~SAA9730_DMACTL_BLKINT;
347
 
348
#ifndef CYGPKG_REDBOOT
349
    SAA9730_DMACTL |= SAA9730_DMACTL_TXINT;
350
#endif
351
 
352
    SAA9730_TIMOUT = 200;
353
 
354
    // accept broadcast packets */
355
    SAA9730_CAMCTL = SAA9730_CAMCTL_BROADCAST |
356
                     SAA9730_CAMCTL_COMPARE;
357
 
358
    SAA9730_TXCTL = 0;
359
    SAA9730_RXCTL |= SAA9730_RXCTL_STRIPCRC;
360
 
361
    SAA9730_CAMENA = 1;
362
 
363
}
364
 
365
static void
366
__check_mii(struct saa9730_priv_data *spd)
367
{
368
    unsigned long __base = spd->base;
369
    cyg_uint32 opmode;
370
 
371
#ifdef DEBUG
372
    db_printf("__check_mii\n");
373
#endif
374
 
375
    // spin till station is not busy
376
    while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY)
377
        ;
378
 
379
    // set PHY address = 'STATUS'
380
    SAA9730_MDCTL = SAA9730_MDCTL_BUSY |
381
                    (PHY_ADDRESS << SAA9730_MDCTL_PHY_SHIFT)  |
382
                    PHY_STATUS;
383
 
384
    // spin till station is not busy
385
    while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY)
386
        ;
387
 
388
    hal_delay_us(1000);
389
 
390
    // check the link status
391
    if (SAA9730_MDDATA & PHY_STATUS_LINK_UP) {
392
 
393
        SAA9730_MDCTL = SAA9730_MDCTL_BUSY |
394
                        (PHY_ADDRESS << SAA9730_MDCTL_PHY_SHIFT)  |
395
                        PHY_REG31;
396
 
397
        // spin till station is not busy
398
        while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY)
399
            ;
400
 
401
        hal_delay_us(1000);
402
 
403
        opmode = (SAA9730_MDDATA & PHY_REG31_OPMODE_MSK) >> PHY_REG31_OPMODE_SHIFT;
404
 
405
#ifdef DEBUG
406
        db_printf("MII mode %d\n", opmode);
407
#endif
408
 
409
        if ((opmode == OPMODE_10BASET_FULLDUPLEX) ||
410
            (opmode == OPMODE_100BASEX_FULLDUPLEX))
411
            SAA9730_MACCTL = SAA9730_MACCTL_CONMODE_FORCE_MII | SAA9730_MACCTL_FULLDUP;
412
        else
413
            SAA9730_MACCTL = SAA9730_MACCTL_CONMODE_FORCE_MII;
414
    }
415
#ifdef DEBUG
416
    else
417
        db_printf("Link is down\n");
418
#endif
419
}
420
 
421
 
422
static void
423
saa9730_reset(struct saa9730_priv_data *spd)
424
{
425
    unsigned long __base = spd->base;
426
 
427
    __init_buffers(spd);
428
 
429
    __base = spd->base;
430
 
431
    // Stop DMA
432
    SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX);
433
 
434
    // Stop tx/rx
435
    SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX;
436
    SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX;
437
 
438
    // Set DMA and MAC reset bits
439
    SAA9730_DMATST |= SAA9730_DMATST_RESET;
440
    SAA9730_MACCTL |= SAA9730_MACCTL_RESET;
441
 
442
    __init_cam(spd);
443
    __init_dma(spd);
444
    __check_mii(spd);
445
 
446
    spd->tx_busy = 0;
447
}
448
 
449
 
450
static bool
451
atlas_saa9730_init(struct cyg_netdevtab_entry *tab)
452
{
453
    static int initialized = 0; // only probe PCI et al *once*
454
    struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
455
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
456
 
457
#ifdef DEBUG
458
    db_printf("atlas_saa9730_init\n");
459
#endif
460
 
461
    if (0 == initialized) {
462
        cyg_pci_device_id devid;
463
        cyg_pci_device dev_info;
464
 
465
        cyg_pci_init();
466
 
467
        devid = CYG_PCI_NULL_DEVID;
468
 
469
        if (cyg_pci_find_device(CYG_PCI_VENDOR_PHILIPS, 0x9730, &devid) ) {
470
 
471
            spd->devid = devid;
472
 
473
            cyg_pci_get_device_info(devid, &dev_info);
474
 
475
            if (!cyg_pci_configure_device(&dev_info)) {
476
#ifdef DEBUG
477
                db_printf("Failed to configure eth device\n");
478
#endif
479
                return false;
480
            }
481
 
482
            //  Philips SAA9730 implements only one function memory mapped
483
            //  into a single contigous memory region.
484
            //
485
            //  According to spec. the BAR#1 is to be used for memory mapped IO.
486
            spd->base = dev_info.base_map[1];
487
 
488
            // FIXME! All IO units share an interrupt
489
            spd->vector = CYGNUM_HAL_INTERRUPT_INTB;
490
 
491
            // Setup timing stuff
492
            cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid),
493
                                           CYG_PCI_DEV_GET_DEVFN(devid),
494
                                           CYG_PCI_CFG_LATENCY_TIMER, 0x20);
495
            cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid),
496
                                           CYG_PCI_DEV_GET_DEVFN(devid),
497
                                           CYG_PCI_CFG_MIN_GNT, 9);
498
            cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid),
499
                                           CYG_PCI_DEV_GET_DEVFN(devid),
500
                                           CYG_PCI_CFG_MAX_LAT, 24);
501
 
502
#ifdef DEBUG
503
            db_printf("eth0 found: bus[%d] dev[%d] base[%x] vector[%d]\n",
504
                      CYG_PCI_DEV_GET_BUS(devid),
505
                      CYG_PCI_DEV_GET_DEV(CYG_PCI_DEV_GET_DEVFN(devid)),
506
                      spd->base, spd->vector);
507
#endif
508
 
509
            spd->ndp = tab;
510
 
511
#ifndef CYGPKG_REDBOOT
512
            cyg_drv_interrupt_create(
513
                    spd->vector,
514
                    0,                  // Priority - unused
515
                    (CYG_ADDRWORD)spd,  // Data item passed to ISR & DSR
516
                    saa9730_isr,            // ISR
517
                    saa9730_dsr,            // DSR
518
                    &spd->interrupt_handle, // handle to intr obj
519
                    &spd->interrupt_object ); // space for int obj
520
 
521
            cyg_drv_interrupt_attach(spd->interrupt_handle);
522
            cyg_drv_interrupt_acknowledge(spd->vector);
523
            cyg_drv_interrupt_unmask(spd->vector);
524
#endif
525
            {
526
                // When in Redboot we want to get RX interrupts. These
527
                // will be picked up by the default interrupt handler and
528
                // checked for ^C.
529
                unsigned long __base = spd->base;
530
                SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
531
                SAA9730_EVM_IER |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
532
                SAA9730_EVM_ISR |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
533
            }
534
 
535
#ifdef DEBUG
536
            db_printf(" **** Device enabled for I/O and Memory and Bus Master\n");
537
#endif
538
 
539
        } else {
540
#ifdef DEBUG
541
            db_printf("eth0 not found\n");
542
#endif
543
        }
544
 
545
        saa9730_stop(sc);
546
 
547
        spd->active = 0;
548
 
549
        initialized = 1;
550
    }
551
 
552
    // Fetch hardware address
553
#if defined(CYGPKG_REDBOOT) && \
554
    defined(CYGSEM_REDBOOT_FLASH_CONFIG) && \
555
    !defined(CYGSEM_MIPS_ATLAS_SET_ESA)
556
    flash_get_config("atlas_esa", enaddr, CONFIG_ESA);
557
#else
558
#define CONFIG_ESA     6
559
    CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
560
                                 "atlas_esa", enaddr, CONFIG_ESA );
561
#ifdef DEBUG
562
    db_printf("ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
563
              enaddr[0],enaddr[1],enaddr[2],enaddr[3],enaddr[4],enaddr[5]);
564
#endif
565
#endif
566
 
567
    saa9730_reset(spd);
568
 
569
    // Initialize upper level driver
570
    (sc->funs->eth_drv->init)(sc, enaddr);
571
 
572
    return true;
573
}
574
 
575
static void
576
saa9730_stop(struct eth_drv_sc *sc)
577
{
578
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
579
    unsigned long __base = spd->base;
580
 
581
    // Stop DMA
582
    SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX);
583
 
584
    // Stop tx/rx
585
    SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX;
586
    SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX;
587
 
588
    // Set DMA and MAC reset bits
589
    SAA9730_DMATST |= SAA9730_DMATST_RESET;
590
    SAA9730_MACCTL |= SAA9730_MACCTL_RESET;
591
 
592
    spd->active = 0;
593
}
594
 
595
static void
596
__do_start(struct saa9730_priv_data *spd)
597
{
598
    unsigned long __base = spd->base;
599
    int i;
600
 
601
    spd->active = 1;
602
    spd->tx_busy = 0;
603
 
604
    for (i = 0; i < SAA9730_BUFFERS; i++)
605
        spd->tx_used[i] = 0;
606
 
607
    // for tx, turn on MAC first
608
    SAA9730_TXCTL |= SAA9730_TXCTL_ENTX;
609
    SAA9730_DMACTL |= SAA9730_DMACTL_ENTX;
610
 
611
    // for rx, turn on DMA first
612
    SAA9730_DMACTL |= SAA9730_DMACTL_ENRX;
613
    SAA9730_RXCTL |= SAA9730_RXCTL_ENRX;
614
 
615
    __select_buffer(spd, spd->next_rx_bindex);
616
}
617
 
618
//
619
// This function is called to "start up" the interface.  It may be called
620
// multiple times, even when the hardware is already running.  It will be
621
// called whenever something "hardware oriented" changes and should leave
622
// the hardware ready to send/receive packets.
623
//
624
static void
625
saa9730_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
626
{
627
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
628
 
629
    if (spd->active)
630
        saa9730_stop(sc);
631
 
632
    __do_start(spd);
633
}
634
 
635
//
636
// This routine is called to perform special "control" opertions
637
//
638
static int
639
saa9730_control(struct eth_drv_sc *sc, unsigned long key,
640
               void *data, int data_length)
641
{
642
    switch (key) {
643
    case ETH_DRV_SET_MAC_ADDRESS:
644
        return 0;
645
        break;
646
    default:
647
        return 1;
648
        break;
649
    }
650
}
651
 
652
//
653
// This routine is called to see if it is possible to send another packet.
654
// It will return non-zero if a transmit is possible, zero otherwise.
655
//
656
static int
657
saa9730_can_send(struct eth_drv_sc *sc)
658
{
659
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
660
    unsigned long __base = spd->base;
661
 
662
    __tx_poll(sc);
663
 
664
    if (spd->next_tx_bindex == 0  && (SAA9730_OK2USE & SAA9730_OK2USE_TXA))
665
        return 0;
666
 
667
    if (spd->next_tx_bindex == 1  && (SAA9730_OK2USE & SAA9730_OK2USE_TXB))
668
        return 0;
669
 
670
    return 1;
671
}
672
 
673
 
674
static int tx_poll_count;
675
 
676
//
677
// This routine is called to send data to the hardware.
678
static void
679
saa9730_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
680
            int total_len, unsigned long key)
681
{
682
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
683
    unsigned long __base = spd->base;
684
    int bindex, pindex;
685
    cyg_uint32 pktlen = total_len;
686
    cyg_uint8  *pktdata, *to_p;
687
    volatile cyg_uint32 *pktstat ;
688
    struct eth_drv_sg *last_sg;
689
 
690
#ifdef DEBUG
691
    db_printf("saa9730_send: %d sg's, %d bytes, KEY %x\n",
692
              sg_len, total_len, key );
693
#endif
694
 
695
    if (!spd->active)
696
        return;
697
 
698
    bindex = spd->next_tx_bindex;
699
    pindex = spd->next_tx_pindex;
700
 
701
    spd->next_tx_pindex++;
702
    if (spd->next_tx_pindex >= SAA9730_TXPKTS_PER_BUFFER) {
703
        spd->next_tx_pindex = 0;
704
        spd->next_tx_bindex ^= 1;
705
    }
706
 
707
    pktstat = spd->tx_buffer[bindex][pindex];
708
 
709
    if (bindex == 0 && (SAA9730_OK2USE & SAA9730_OK2USE_TXA))
710
        return;
711
 
712
    if (bindex == 1 && (SAA9730_OK2USE & SAA9730_OK2USE_TXB))
713
        return;
714
 
715
    spd->tx_key[bindex][pindex] = key;
716
    spd->tx_used[bindex] += 1;
717
 
718
    pktdata = (cyg_uint8 *)((unsigned)pktstat + 4);
719
 
720
    // Copy from the sglist into the tx buffer
721
    to_p = pktdata;
722
 
723
    for (last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++) {
724
        cyg_uint8 *from_p;
725
        int l;
726
 
727
        from_p = (cyg_uint8 *)(sg_list->buf);
728
        l = sg_list->len;
729
 
730
        if (l > total_len)
731
            l = total_len;
732
 
733
        memcpy((unsigned char *)to_p, from_p, l);
734
        to_p += l;
735
        total_len -= l;
736
 
737
        if (total_len < 0)
738
            break; // Should exit via sg_last normally
739
    }
740
 
741
    // pad to minimum size
742
    if (pktlen < SAA9730_MIN_PACKET_SIZE) {
743
        memset(to_p, 0, SAA9730_MIN_PACKET_SIZE-pktlen);
744
        pktlen = SAA9730_MIN_PACKET_SIZE;
745
    }
746
 
747
    // Set transmit status WORD for hardware (LAN-DMA-ENGINE)
748
    *pktstat = CYG_CPU_TO_LE32(TX_READY | pktlen);
749
 
750
    // start hardware
751
    if (bindex == 0)
752
        SAA9730_OK2USE |= SAA9730_OK2USE_TXA;
753
    else
754
        SAA9730_OK2USE |= SAA9730_OK2USE_TXB;
755
 
756
    if (!spd->tx_busy) {
757
        tx_poll_count = 0;
758
        spd->tx_busy = bindex + 1;
759
    }
760
}
761
 
762
 
763
static void
764
__check_rxstate(struct saa9730_priv_data *spd)
765
{
766
    unsigned long __base = spd->base;
767
    cyg_uint32  status, flag, size;
768
    cyg_uint32  *pkt;
769
    int         i, j;
770
 
771
#ifdef DEBUG
772
    db_printf("__check_rxstate\n");
773
#endif
774
 
775
#ifdef CYGPKG_REDBOOT
776
    // Clear SAA9730 LAN interrupt and re-enable interrupts.
777
    SAA9730_EVM_ISR = SAA9730_EVM_LAN_INT;
778
    SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
779
#endif
780
 
781
    if ((SAA9730_DBGRXS & SAA9730_DBGRXS_RXDII_MASK) == SAA9730_DBGRXS_RXDII_ERROR) {
782
        // re-init driver and controller
783
#ifdef DEBUG
784
        db_printf("DBGRXS: reset\n");
785
#endif
786
        saa9730_reset(spd);
787
        __do_start(spd);
788
        return;
789
    }
790
 
791
    // Check RX packet status
792
    for (i = 0; i < SAA9730_BUFFERS; i++) {
793
        for (j = 1; j < SAA9730_RXPKTS_PER_BUFFER; j++) {
794
            pkt = spd->rx_buffer[i][j];
795
            status = CYG_LE32_TO_CPU(*pkt);
796
            size   = status & RXPACKET_STATUS_SIZE_MASK;
797
            flag   = status & RXPACKET_STATUS_FLAG_MASK;
798
            if (flag == RX_INVALID_STAT || size > 1514 || *(pkt - 1)) {
799
                // re-init driver and controller
800
#ifdef DEBUG
801
                db_printf("rxpkt: reset\n");
802
#endif
803
                saa9730_reset(spd);
804
                __do_start(spd);
805
                return;
806
            }
807
        }
808
    }
809
}
810
 
811
 
812
static void
813
__tx_poll(struct eth_drv_sc *sc)
814
{
815
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
816
    int                  bindex, pindex;
817
    volatile cyg_uint32 *pktstat;
818
    cyg_uint32 status;
819
 
820
    if (!spd->tx_busy)
821
        return;
822
 
823
    bindex = spd->tx_busy - 1;
824
    pindex = spd->tx_used[bindex] - 1;  // watch last pkt in buffer
825
 
826
    pktstat = spd->tx_buffer[bindex][pindex];
827
 
828
    status = CYG_LE32_TO_CPU(*pktstat);
829
    if ((status & TXPACKET_STATUS_FLAG_MASK) != TX_HWDONE) {
830
 
831
        hal_delay_us(1000);
832
 
833
        if (++tx_poll_count > 1000) {
834
            // reset
835
 
836
            for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++)
837
                (sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1);
838
 
839
            bindex ^= 1;
840
 
841
            for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++)
842
                (sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1);
843
 
844
            saa9730_reset(spd);
845
            __do_start(spd);
846
        }
847
        return;
848
    }
849
 
850
    for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++) {
851
        /* Check for error. */
852
        pktstat = spd->tx_buffer[bindex][pindex];
853
        status = CYG_LE32_TO_CPU(*pktstat);
854
 
855
        if (status & TXPACKET_STATUS_ERROR) {
856
            if (status & TXPACKET_STATUS_EXDEFER)
857
                db_printf("tx deferred\n");
858
 
859
            if (status & TXPACKET_STATUS_LATECOLLERR)
860
                db_printf("tx late collision\n");
861
 
862
            if (status & TXPACKET_STATUS_LOSTCARRIER)
863
                db_printf("tx no carrier\n");
864
 
865
            if (status & TXPACKET_STATUS_UNDERRUN)
866
                db_printf("tx underrun\n");
867
 
868
            if (status & TXPACKET_STATUS_SQERR)
869
                db_printf("tx sq\n");
870
        }
871
        /* free the space */
872
        *pktstat = CYG_CPU_TO_LE32(TX_EMPTY);
873
 
874
        (sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1 /* status */);
875
    }
876
 
877
    tx_poll_count = 0;
878
    spd->tx_used[bindex] = 0;
879
 
880
    bindex ^= 1;
881
    if (spd->tx_used[bindex])
882
        spd->tx_busy = bindex + 1;
883
    else
884
        spd->tx_busy = 0;
885
}
886
 
887
 
888
static void
889
__rx_poll(struct eth_drv_sc *sc)
890
{
891
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
892
    int                  bindex, pindex, done;
893
    volatile cyg_uint32 *pkt;
894
    cyg_uint32           status, pktlen;
895
 
896
#ifdef DEBUG
897
    db_printf("__rx_poll\n");
898
#endif
899
    if (!spd->active)
900
        return;
901
 
902
    done = 0;
903
    while (!done) {
904
        // index of next packet buffer
905
        bindex = spd->next_rx_bindex;
906
 
907
        // index of next packet within buffer
908
        pindex = spd->next_rx_pindex;
909
 
910
        pkt = spd->rx_buffer[bindex][pindex];
911
 
912
        // stop now if no more packets
913
        if (((status = CYG_LE32_TO_CPU(*pkt)) & RXPACKET_STATUS_FLAG_MASK) == RX_READY)
914
            break;
915
#ifdef DEBUG
916
        db_printf("__rx_poll pkt %08x status %08x\n",pkt,status);
917
#endif
918
        // if this is the first packet in a buffer, switch the SAA9730 to
919
        // use the next buffer for subsequent incoming packets.
920
        if (pindex == 0)
921
            __select_buffer(spd, bindex == 0);
922
 
923
        // check for good packet
924
        if (status & RXPACKET_STATUS_GOOD) {
925
 
926
            pktlen = status & RXPACKET_STATUS_SIZE_MASK ;
927
 
928
            if (pktlen > 0) {
929
                (sc->funs->eth_drv->recv)(sc, pktlen);
930
                // done = 1;
931
            }
932
        }
933
#ifdef DEBUG
934
        else
935
            db_printf("rx bad: %08x %08x\n",pkt,status);
936
#endif
937
 
938
        /* go to next packet in sequence */
939
        spd->next_rx_pindex++;
940
        if (spd->next_rx_pindex >= SAA9730_RXPKTS_PER_BUFFER) {
941
            spd->next_rx_pindex = 0;
942
            spd->next_rx_bindex++;
943
            if (spd->next_rx_bindex >= SAA9730_BUFFERS)
944
                spd->next_rx_bindex = 0;
945
        }
946
    }
947
 
948
    if (((poll_count++) % 100) == 0)
949
        __check_rxstate(spd);
950
}
951
 
952
 
953
static void
954
saa9730_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
955
{
956
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
957
    volatile cyg_uint32 *pkt;
958
    cyg_uint32          pktlen, status;
959
    struct eth_drv_sg   *last_sg;
960
 
961
    if (!spd->active)
962
        return;
963
 
964
    pkt = spd->rx_buffer[spd->next_rx_bindex][spd->next_rx_pindex];
965
 
966
    status = CYG_LE32_TO_CPU(*pkt);
967
    if (status & RXPACKET_STATUS_GOOD) {
968
        // packet is good
969
        pktlen = status & RXPACKET_STATUS_SIZE_MASK;
970
 
971
        if (pktlen > 0) {
972
            int total_len;
973
            cyg_uint8 *from_p;
974
 
975
            // check we have memory to copy into; we would be called even if
976
            // caller was out of memory in order to maintain our state.
977
            if (0 == sg_len || 0 == sg_list)
978
                return; // caller was out of mbufs
979
 
980
            total_len = pktlen;
981
            from_p = (cyg_uint8 *)((unsigned)pkt + 4);
982
 
983
            for (last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++) {
984
                cyg_uint8 *to_p;
985
                int l;
986
 
987
                to_p = (cyg_uint8 *)(sg_list->buf);
988
                l = sg_list->len;
989
 
990
                if (0 >= l || 0 == to_p)
991
                    return; // caller was out of mbufs
992
 
993
                if (l > total_len)
994
                    l = total_len;
995
 
996
                memcpy(to_p, (unsigned char *)from_p, l);
997
                from_p += l;
998
                total_len -= l;
999
            }
1000
        }
1001
    }
1002
}
1003
 
1004
static inline void
1005
__do_deliver(struct eth_drv_sc *sc)
1006
{
1007
    // First pass any rx data up the stack
1008
    __rx_poll(sc);
1009
 
1010
    // Then scan for completed Txen and inform the stack
1011
    __tx_poll(sc);
1012
}
1013
 
1014
static void
1015
saa9730_poll(struct eth_drv_sc *sc)
1016
{
1017
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
1018
 
1019
#ifndef CYGPKG_REDBOOT
1020
    cyg_drv_interrupt_mask(spd->vector);
1021
#endif
1022
 
1023
    (void)saa9730_isr(spd->vector, (cyg_addrword_t)spd);
1024
 
1025
    __do_deliver(sc);
1026
 
1027
    cyg_drv_interrupt_acknowledge(spd->vector);
1028
 
1029
#ifndef CYGPKG_REDBOOT
1030
    cyg_drv_interrupt_unmask(spd->vector);
1031
#endif    
1032
}
1033
 
1034
 
1035
// The deliver function (ex-DSR)  handles the ethernet [logical] processing
1036
static void
1037
saa9730_deliver(struct eth_drv_sc *sc)
1038
{
1039
    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
1040
    unsigned long __base = spd->base;
1041
 
1042
    if (spd->active)
1043
        __do_deliver(sc);
1044
 
1045
    cyg_drv_interrupt_acknowledge(spd->vector);
1046
 
1047
#ifndef CYGPKG_REDBOOT
1048
    // Clear SAA9730 LAN interrupt and re-enable interrupts.
1049
    SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
1050
    cyg_drv_interrupt_unmask(spd->vector);
1051
#endif    
1052
}
1053
 
1054
 

powered by: WebSVN 2.1.0

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