⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eth_drv.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//==========================================================================////      src/net/eth_drv.c////      Hardware independent ethernet driver////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2002, 2003 Gary Thomas//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    gthomas// Contributors: gthomas// Date:         2000-01-10// Purpose:      Hardware independent ethernet driver// Description:  //              ////####DESCRIPTIONEND####////==========================================================================// High-level ethernet driver#include <sys/param.h>#include <sys/errno.h>#include <sys/ioctl.h>#include <sys/mbuf.h>#include <sys/socket.h>#include <net/if.h>#include <net/if_dl.h>#include <net/if_types.h>#include <net/netisr.h>#ifdef INET#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/in_var.h>#include <netinet/ip.h>#include <netinet/if_ether.h>#endif#ifndef NBPFILTER#define NBPFILTER 0#endif#if NBPFILTER > 0#include <net/bpf.h>#include <net/bpfdesc.h>#endif#include <cyg/infra/cyg_ass.h>#include <cyg/hal/drv_api.h>#include <pkgconf/hal.h>#include <cyg/hal/hal_if.h>#include <pkgconf/io_eth_drivers.h> // module configury; SIMULATED_FAILURES#include <pkgconf/net.h>            // CYGPKG_NET_FAST_THREAD_TICKLE_DEVS?#include <cyg/io/eth/eth_drv.h>#include <cyg/io/eth/netdev.h>#ifndef min#define min( _x_, _y_ ) ((_x_) < (_y_) ? (_x_) : (_y_))#endif// ------------------------------------------------------------------------#ifdef CYGPKG_IO_ETH_DRIVERS_SIMULATED_FAILURES#define noLOG_RANDOM 32 // so you can tell this is really being random#ifdef LOG_RANDOMstatic struct {    unsigned int *which;    unsigned int random;    unsigned int r100;} random_log[LOG_RANDOM];static int random_index = 0;#endifstatic unsigned intrandomize( unsigned int *p ){    unsigned int r100;    HAL_CLOCK_READ( &r100 );    r100 ^= *p;    *p = (r100 * 1103515245) + 12345;    r100 &= 127;    if ( r100 >= 100 ) // spread the overflow around evenly        r100 = 4 * (r100 - 100);    if ( r100 >= 100 ) // and again - (125,126,127=>100,104,108)        r100 = 12 * (r100 - 100); // =>(0,48,96)#ifdef LOG_RANDOM    random_log[random_index].which  = p;    random_log[random_index].random = *p;    random_log[random_index].r100   = r100;    random_index++;    random_index &= (LOG_RANDOM-1);#endif    return r100;}#define SIMULATE_FAIL_SEND     1#define SIMULATE_FAIL_RECV     2#define SIMULATE_FAIL_CORRUPT  3static struct simulated_failure_state {    struct eth_drv_sc *sc;    unsigned int r_tx_fail;    unsigned int r_rx_fail;    unsigned int r_rx_corrupt;    cyg_tick_count_t droptime;    cyg_tick_count_t passtime;} simulated_failure_states[2] = {{0},{0}};static intsimulate_fail( struct eth_drv_sc *sc, int which ){    struct simulated_failure_state *s;          for ( s = &simulated_failure_states[0]; s < &simulated_failure_states[2];          s++ ) {        if ( 0 == s->sc ) {            s->sc = sc;            s->r_tx_fail    = (unsigned int)sc;            s->r_rx_fail    = (unsigned int)sc ^ 0x01234567;            s->r_rx_corrupt = (unsigned int)sc ^ 0xdeadbeef;            s->droptime = 0;            s->passtime = 0;        }        if ( sc == s->sc )            break;    }    if ( &simulated_failure_states[2] == s ) {        CYG_FAIL( "No free slot in simulated_failure_states[]" );        return 1; // always fail    }#ifdef CYGPKG_IO_ETH_DRIVERS_SIMULATE_LINE_CUT    // Regardless of the question, we say "yes" during the period of    // unpluggedness...    {        cyg_tick_count_t now = cyg_current_time();        if ( now > s->droptime && 0 == s->passtime ) { // [initial condition]            s->droptime = 0; // go into a passing phase            (void)randomize( &s->r_tx_fail );            (void)randomize( &s->r_rx_fail );            (void)randomize( &s->r_rx_corrupt );            s->passtime = s->r_tx_fail + s->r_rx_fail + s->r_rx_corrupt;            s->passtime &= 0x3fff; // 16k cS is up to 160S, about 2.5 minutes            s->passtime += now;        }        else if ( now > s->passtime && 0 == s->droptime ) {            s->passtime = 0; // go into a dropping phase            (void)randomize( &s->r_tx_fail );            (void)randomize( &s->r_rx_fail );            (void)randomize( &s->r_rx_corrupt );            s->droptime = s->r_tx_fail + s->r_rx_fail + s->r_rx_corrupt;            s->droptime &= 0x0fff; // 4k cS is up to 40S, about 1/2 a minute            s->droptime += now;        }        if ( now < s->droptime )            return 1; // Say "no"    }#endif    switch ( which ) {#ifdef CYGPKG_IO_ETH_DRIVERS_SIMULATE_DROP_TX    case SIMULATE_FAIL_SEND: {        unsigned int z = randomize( &s->r_tx_fail );        return z < CYGPKG_IO_ETH_DRIVERS_SIMULATE_DROP_TX;    }#endif#ifdef CYGPKG_IO_ETH_DRIVERS_SIMULATE_DROP_RX    case SIMULATE_FAIL_RECV: {        unsigned int z = randomize( &s->r_rx_fail );        return z < CYGPKG_IO_ETH_DRIVERS_SIMULATE_DROP_RX;    }#endif#ifdef CYGPKG_IO_ETH_DRIVERS_SIMULATE_CORRUPT_RX    case SIMULATE_FAIL_CORRUPT: {        unsigned int z = randomize( &s->r_rx_corrupt );        return z < CYGPKG_IO_ETH_DRIVERS_SIMULATE_CORRUPT_RX;    }#endif    default:        // do nothing - for when options above are not enabled.    }    return 0;}#define noLOG_CORRUPTION 32 // so you can tell this is really being random#ifdef LOG_CORRUPTIONstatic struct {    int len;    int thislen;    int off;    unsigned char xor;    unsigned char idx;} corruption_log[LOG_CORRUPTION];static int corruption_index = 0;#endifstatic voidsimulate_fail_corrupt_sglist( struct eth_drv_sg *sg_list, int sg_len ){    unsigned int z, len, i, off;    HAL_CLOCK_READ( &z );    z += simulated_failure_states[0].r_rx_corrupt;    z += simulated_failure_states[1].r_rx_corrupt;    CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow in corrupt" );    for ( i = 0, len = 0; i < sg_len && sg_list[i].buf && sg_list[i].len; i++ )        len =+ sg_list[i].len;    CYG_ASSERT( 1500 >= len, "sg...len > ether MTU" );    if ( 14 >= len ) // normal ether header        return;    off = z & 2047; // next (2^N-1) > MTU    while ( off > len )        off -= len;    for ( i = 0; i < sg_len && sg_list[i].buf && sg_list[i].len; i++ ) {        if ( off < sg_list[i].len ) { // corrupt this one            unsigned char *p = (unsigned char *)sg_list[i].buf;            p[off] ^= (0xff & (z >> 11));#ifdef LOG_CORRUPTION            corruption_log[corruption_index].len = len;            corruption_log[corruption_index].thislen = sg_list[i].len;            corruption_log[corruption_index].off = off;            corruption_log[corruption_index].xor = (0xff & (z >> 11));            corruption_log[corruption_index].idx = i;            corruption_index++;            corruption_index &= (LOG_CORRUPTION-1);#endif            return;        }        off -= sg_list[i].len;    }        CYG_FAIL( "Didn't corrupt anything" );}#endif // CYGPKG_IO_ETH_DRIVERS_SIMULATED_FAILURES// ------------------------------------------------------------------------#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT#include <cyg/hal/hal_if.h>// Use with care!  Local variable defined!#define START_CONSOLE()                                                                 \{   /* NEW BLOCK */                                                                     \    int _cur_console =                                                                  \        CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);      \    {                                                                                   \        int i;                                                                          \        if ( CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,                 \                                          "info_console_force", &i,                     \                                          CYGNUM_FLASH_CFG_TYPE_CONFIG_BOOL ) ) {       \            if ( i ) {                                                                  \                if ( CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,         \                                                  "info_console_number", &i,            \                                                  CYGNUM_FLASH_CFG_TYPE_CONFIG_INT ) ){ \                    /* Then i is the console to force it to: */                         \                    CYGACC_CALL_IF_SET_CONSOLE_COMM( i );                               \                }                                                                       \            }                                                                           \        }                                                                               \    }#define END_CONSOLE()                                   \    CYGACC_CALL_IF_SET_CONSOLE_COMM(_cur_console);      \}   /* END BLOCK */#else#define START_CONSOLE()#define END_CONSOLE()#endif// ------------------------------------------------------------------------#ifdef CYGPKG_NET_FREEBSD_STACKextern char *_ioctl_name(u_long cmd);typedef void void_fun(void *);#endifstatic int  eth_drv_ioctl(struct ifnet *, u_long, caddr_t);static void eth_drv_send(struct ifnet *);static void eth_drv_start(struct eth_drv_sc *sc);#ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG int cyg_io_eth_net_debug = CYGDBG_IO_ETH_DRIVERS_DEBUG_VERBOSITY;#endif// Interfaces exported to driversstatic void eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr);static void eth_drv_recv(struct eth_drv_sc *sc, int total_len);static void eth_drv_tx_done(struct eth_drv_sc *sc, CYG_ADDRESS key, int status);struct eth_drv_funs eth_drv_funs = {eth_drv_init, eth_drv_recv, eth_drv_tx_done};//// This function is called during system initialization to register a// network interface with the system.//static voideth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr){    struct ifnet *ifp = &sc->sc_arpcom.ac_if;#ifdef CYGPKG_NET_FREEBSD_STACK    int unit;    char *np, *xp;#endif    // Set up hardware address    if (NULL != enaddr)        bcopy(enaddr, &sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);    // Initialize ifnet structure

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -