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

📄 if_i82559.c

📁 intel82559的以太网驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
//==========================================================================////      if_i82559.c////	Intel 82559 ethernet driver////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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####//####BSDCOPYRIGHTBEGIN####//// -------------------------------------------//// Portions of this software may have been derived from OpenBSD or// other sources, and are covered by the appropriate copyright// disclaimers included herein.//// -------------------------------------------////####BSDCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    hmt, gthomas// Contributors: Ron Spence, Pacific Softworks, jskov// Date:         2000-02-01// Purpose:      // Description:  hardware driver for 82559 Intel PRO/100+ ethernet// Notes:        CU commands such as dump and config should, according//               to the docs, set the CU active state while executing.//               That does not seem to be the case though, and the//               driver polls the completion bit in the packet status//               word instead.////               Platform code may provide this vector://               CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT if it//               requires the interrupts to be handled via demuxers//               attached to a distinct interrupt.////               Platform code may alternatively define://               CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL if it is necessary//               to demux all interrupt sources - for example if they are//               wire-or'd together on some hardware but distinct on//               others.  In this circumstance it is permitted for//               cyg_pci_translate_interrupt [HAL_PCI_TRANSLATE_INTERRUPT]//               to return invalid for 2nd and subsequent devices.////               Platform code can also define these three://               CYGPRI_DEVS_ETH_INTEL_I82559_MASK_INTERRUPTS(p_i82559,old)//               CYGPRI_DEVS_ETH_INTEL_I82559_UNMASK_INTERRUPTS(p_i82559,old)//               CYGPRI_DEVS_ETH_INTEL_I82559_ACK_INTERRUPTS(p_i82559)//               which are particularly useful when nested interrupt//               management is needed (which is always IMHO).////               Platform code can define this://               CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT(p_i82559)//               to detect a dropped interrupt and loop again or//               direct-call the DSR to reschedule the delivery routine.//               Only a problem on edge-triggered interrupt systems.////               Platform code can also provide this macro://               CYGPRI_DEVS_ETH_INTEL_I82559_INTERRUPT_ACK_LOOP(p_i82559)//               to handle delaying for acks to register on the interrupt//               controller as necessary on the EBSA.////               Platform can define CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA()//               as an external means to get ESAs, possibly from RedBoot//               configuration info that's stored in flash memory.////               Platform def CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM//               removes all code for dealing with the EEPROM for those//               targets where there is none fitted.  Either an external//               means to get ESAs should be used, or we must rely on//               hard-wiring the ESA's into each executable by means of the//               usual CDL configuration.////               Platform def CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM//               is for hardware with multiple devices, but only one with a//               serial EEPROM installed.  The 2nd device would get either//               the same ESA - because they are certain to be on different//               segment and internets - or the same ESA incremented by//               CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_MAC_ADJUST.//               CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM should be the//               number (0 or 1) of the device that does have the EEPROM.////               CYGHWR_DEVS_ETH_INTEL_I82559_PCIMEM_DISCONTIGUOUS enables//               checking code for breaks in the physical address of PCI//               window memory.  This can happen on some boards where a//               smaller SDRAM is fitted than the hardware allows, so some//               higher-order address bits are ignored.  We make SDRAM//               contiguous in mapped memory, but what the i82559 sees//               might be discontiguous.  The checking code skips any//               allocated chunk who appears to contain such a break, and//               tries again.////               CYGHWR_DEVS_ETH_INTEL_I82559_RESET_TIMEOUT( int32 )//               CYGHWR_DEVS_ETH_INTEL_I82559_TIMEOUT_FIRED( int32 ) if//               both defined give the driver a means to detect that we//               have been fixated on the same transmit operation for too//               long - we missed an interrupt or the device crashed.  The//               int32 argument is used to hold a eg. the value of a//               fast-running hardware timer.////               CYGHWR_DEVS_ETH_INTEL_I82559_ENDIAN_NEUTRAL_IO if PCI IO//               access is not affected by CPU endianess.////        FIXME: replace -1/-2 return values with proper E-defines//        FIXME: For 82557/8 compatibility i82559_configure() function//               probably needs some tweaking - config bits differ//               slightly but crucially.//        FIXME: EEPROM code not tested on a BE system.////####DESCRIPTIONEND####////==========================================================================#include <pkgconf/system.h>#ifdef CYGPKG_IO_ETH_DRIVERS#include <pkgconf/io_eth_drivers.h>#endif#include <pkgconf/devs_eth_intel_i82559.h>#include <cyg/infra/cyg_type.h>#include <cyg/infra/cyg_ass.h>#include <cyg/hal/hal_arch.h>#include <cyg/hal/hal_intr.h>#include <cyg/infra/diag.h>#include <cyg/hal/hal_if.h>#include <cyg/hal/drv_api.h>#include <cyg/io/eth/netdev.h>#include <cyg/io/eth/eth_drv.h>#include <string.h>#ifdef CYGPKG_NET#include <pkgconf/net.h>#include <net/if.h>  /* Needed for struct ifnet */#endif#ifdef CYGPKG_IO_PCI#include <cyg/io/pci.h>// So we can check the validity of the PCI window against the MLTs opinion,// and thereby what the malloc heap consumes willy-nilly:#include CYGHWR_MEMORY_LAYOUT_H#else#error "Need PCI package here"#endif// Exported statistics and the like#include <cyg/devs/eth/i82559_info.h>#include <cyg/io/eth/eth_drv_stats.h>#include CYGDAT_DEVS_ETH_INTEL_I82559_INL#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 */void CheckRxRing(struct i82559* p_i82559, char * func, int line);// ------------------------------------------------------------------------// Check on the environment.// // These are not CDL type config points; they are set up for your platform// in the platform driver's include file and that's that.  These messages// are for the eCos driver writer, not config tool users.#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL#ifdef CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT#error Both a separate demux interrupt *and* DEMUX_ALL are defined#endif#endif#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_WRITE_EEPROM#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM#error This platform has no EEPROM, yet WRITE_EEPROM is enabled#endif#endif#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM#error This platform has no EEPROM, yet it also HAS_ONE_EEPROM#endif#endif// ------------------------------------------------------------------------#ifdef CYGDBG_DEVS_ETH_INTEL_I82559_CHATTER#define DEBUG          // Startup printing mainly#define DEBUG_EE       // Some EEPROM specific retries &c#if (CYGDBG_DEVS_ETH_INTEL_I82559_CHATTER > 1)#define DEBUG_82559 // This one prints stuff as packets come and go#endif#endif#ifdef CYGDBG_USE_ASSERTSstatic struct {    int can_send;    int deliver;    int stats;    int waitcmd_timeouts;    int waitcmd_timeouts_cu;    int lockup_timeouts;    int bad_cu_idles;} missed_interrupt = { 0,0,0, 0,0, 0, 0 };#endifint console_printf(const char *fmt, ...){    va_list ap;    int ret;        START_CONSOLE();    va_start(ap, fmt);    ret = diag_vprintf(fmt, ap);    va_end(ap);        END_CONSOLE();    return (ret);}#define os_printf console_printf#define db_printf console_printf// ------------------------------------------------------------------------////                             MEMORY ADDRESSING// // There is scope for confusion here; we deal with LE/BE systems and// addressing issues in two separate ways depending on the type of access// in question.//// 1) IO-style access to the device regsiters over the PCI bus// 2) Memory access to build and read the structures in shared memory// // In detail:// // 1) IO-style access to the device regsiters over the PCI bus// // All such access is via macros which perform byte-swapping as necessary// for the endianness of the CPU.  These macros are called INL, INW, INB// and OUTL, OUTW, OUTB - for Long (32) Word (16) and Byte (8).  Intel// nomenclature seems to have crept in here for shorts.// // Consequently, all the constants only have to be expressed once, in their// true LE format - bit 15 is 0x8000, bit 0 is 1.// // All the offsets are also only expressed once.  This is OK so long as GIB// endian addressing (sic, see below) is not employed - or so long as is// does not affect the PCI bus accesses.//// // 2) Memory access to build and read the structures in shared memory// // These accesses are by means of peek and poke to an address created from// a base + offset.  No swapping occurs within the access so all constants// and flags need to be defined twice, once for BE and once for LE// accesses.  Worse, for BE, constants need to be defined in flavours for// 16-bit versus 32-bit accesses, ie. 0x8000 sets bit 7 only in BE; for a// 32-bit access you must instead write 0x80000000 to set bit 7.//// Thus all constants are defined twice depending on the CPU's endianness.//// For most BE/LE machines, this is sufficient; the layout of memory is the// same.  Specifically, within a 32-bit word, byte[0] will be data[0:7],// short[0] will be data [0:15] and so on.  &byte[0] == &short[0] == &word// regardless.  But data[0:7] *OF THE MEMORY SYSTEM* will hold either the// LSbyte (0xFF) on a LE machine, and the MSbyte (0xFF000000) on a BE// machine, for a 32-bit access.// // It is in terms of the memory system that the i82559 defines its view of// the world.// // Therefore the structure layouts remain the same for both BE and LE// machines.  This means that the offsets for, specifically, the status// word in command blocks is always zero, and the offset for the command// word is always two.//// But there is one furter variant: so-called GIB endian.  (BIG endian// backwards) Some architectures support BE only for software// compatibility; they allow code to run which relies on overlaid C// structures behaving in a certain way; specifically//     *(char *)&i == (i >> 24)// ARM's BE mode is an example of this.// // But while such an operation would use data[0:7] for the char access in a// true BE or any LE system, in a GE system, data[24:31] are used here.// The implementation is that for memory accesses, A0 and A1 are inverted// before going outside to the memory system.  So if &i == 0x1000,// accessing i uses address 0x1000, A0 and A1 being ignored for a 32-bit// access.  But the 8-bit access to *(char *)&i also uses 0x1000 for the// address as the code sees it, the memory system sees a byte request for// address 0x1003, thus picking up the MSbyte, from data[24:31].//// For such addressing, offsets need to be redefined to swap bytes and// shorts within words.  Therefore offsets are defined twice, once for// "normal" addressing, and once for "GIB endian" addressing.//// FIXME: this BE/GE configuration probably won't work with an ARM in its// BE mode - because that will define the global BE flags, yet it's not// true BE, it's GE.// Perhaps a solution whereby the GE flag CYG_ADDRESSING_IS_GIBENDIAN// overrides the BYTEORDER choices would be good; we want the constants to// be LE, but address offsets to be swapped per GE.

⌨️ 快捷键说明

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