📄 dp83815.c
字号:
/***********************************************************************//* *//* Module: dp83815.c *//* Release: 2001.3 *//* Version: 2001.0 *//* Purpose: Driver for the DP83815 10/100 Mbps Ethernet controller *//* *//*---------------------------------------------------------------------*//* *//* Copyright 2001, Blunk Microsystems *//* ALL RIGHTS RESERVED *//* *//* Licensees have the non-exclusive right to use, modify, or extract *//* this computer program for software development at a single site. *//* This program may be resold or disseminated in executable format *//* only. The source code may not be redistributed or resold. *//* *//***********************************************************************/#include <stdio.h>#include <tmlib/tmlibc.h>#include <tm1/tmInterrupts.h>#include "tw_defs.h"#include "tw_flash.h"#include "pci.h"#include "pnp.h"#include "dp83815.h"#include <unistd.h>#include <targetos.h> /* type definitions */#include <sockets.h> /* TargetTCP application include file */#include <tcp_ip.h> /* TargetTCP driver include file */#include <string.h>/***********************************************************************//* Symbol Definitions *//***********************************************************************/#define IEEE_OFFSET 8#define NUM_RX_BDS 10#define NUM_TX_BDS 10#define BEG_RX_BD 0#define END_RX_BD (BEG_RX_BD + NUM_RX_BDS - 1)#define BEG_TX_BD (END_RX_BD + 1)#define END_TX_BD (BEG_TX_BD + NUM_TX_BDS - 1)#define DP83815_VENDOR_ID 0x100B#define DP83815_DEVICE_ID 0x0020#define WIFI_VENDOR_ID 0x13BF#define WIFI_DEVICE_ID 0x00FA//#define USE_EEPROM_MAC_ADDRESS/***********************************************************************//* Macro Definitions *//***********************************************************************//*** Host to PCI byte order macros*/#ifdef BIG_ENDIAN#define htopl(l) (((l) << 24) | (((l) & 0xFF00) << 8) | \ (((l) & 0xFF0000) >> 8) | (ui8)((l) >> 24))#define htops(s) (ui16)(((s) << 8) | (ui8)((s) >> 8))#else /* little endian */#define htopl(l) (l)#define htops(s) (s)#endif#define ptohl(l) htopl(l)#define ptohs(s) htops(s)/*** Macros to read/write 32/16 bit data to/from DP83815 device registers.*/#define DP_REG32_WRITE(reg, val) \ pci_io_write32(IoAddress+(reg), htopl(((ui32)val)))#define DP_REG32_READ(reg) \ ptohl(io_read_32(IoAddress+(reg)))#define DP_REG16_WRITE(reg, val) \ pci_io_write16(IoAddress+(reg), htops(((ui16)val)))#define DP_REG16_READ(reg) \ ptohs(io_read_16(IoAddress+(reg)))#define DP_REG32_SET(reg, val) \ DP_REG32_WRITE(reg, DP_REG32_READ(reg) | (val))#define DP_REG32_CLR(reg, val) \ DP_REG32_WRITE(reg, DP_REG32_READ(reg) & ~(val))/***********************************************************************//* Type Definitions *//***********************************************************************//*** Ethernet address definition for easy word and byte access.*/typedef union{ ui8 byte[ETH_ALEN]; struct { ui16 word1; ui16 word2; ui16 word3; } a;} EthAddr;#define word1 a.word1#define word2 a.word2#define word3 a.word3/*** Receive frames must be aligned on long word boundaries.*/typedef struct{ EthAddr daddr; /* destination hardware address */ EthAddr saddr; /* source hardware address */ ui16 type; /* IP, ARP, or RARP */ ui8 buffer[ETH_MTU]; /* IP packet */ ui32 crc; /* HW generated */} FRAME;/*** Buffer Descriptor*/typedef struct{ vui32 link; /* points to next descriptor */ vui32 cmdsts; /* command/status field */ vui32 bufptr; /* points to transmit/receive buffer */ ui32 pad[13]; /* padding to bring size to 64 bytes */} BufDescType;/***********************************************************************//* Global Variable Declarations *//***********************************************************************/static NetBuf * volatile TxMsgQHead;static NetBuf * TxMsgQTail;static EthAddr OurAddress;static BufDescType * volatile RxNextBD; /* next BD for input */static BufDescType * volatile RxFillBD; /* next BD needing buf */static BufDescType * volatile TxNextBD; /* next BD to send */static BufDescType * volatile TxFreeBD; /* next BD to reclaim */static BufDescType *BufDesc;static NetBuf *TxNetBuf[NUM_TX_BDS];static NetBuf *RxNetBuf[NUM_RX_BDS];static Ni dp83815Ni;static volatile int NumBusyTxBds;static int FullDuplex;static int IsrCount;static int RxIsrCount;static int TxIsrCount;static PciAddr_t IoAddress;/***********************************************************************//* Function Prototypes *//***********************************************************************/static void fill_rx_ring(void);static void fill_tx_ring(void);static void receive_bufs(void);static void free_tx_bufs(void);/***********************************************************************//* Local Function Definitions *//***********************************************************************//***********************************************************************//* io_read_16: Read the 16 bit value at given I/O address *//* *//***********************************************************************/static ui16 io_read_16(ui32 io_port){ ui16 data16; pci_io_read16(io_port, &data16); return data16;}/***********************************************************************//* io_read_32: Read the 32 bit at given I/O address *//* *//***********************************************************************/static ui32 io_read_32(ui32 io_port){ ui32 data32; pci_io_read32(io_port, &data32); return data32;}/***********************************************************************//* ni_isr: DP83815 interrupt service routine *//* *//***********************************************************************/static void ni_isr(PnP pnp, void *unused){ /*-------------------------------------------------------------------*/ /* Temporarily mask all device interrupts. */ /*-------------------------------------------------------------------*/ DP_REG32_WRITE(DP_IER, DP_IER_ID); ++IsrCount; /*-------------------------------------------------------------------*/ /* Request service from TargetTCP daemon. */ /*-------------------------------------------------------------------*/ tcpPollReq(&dp83815Ni);}/***********************************************************************//* poll: Processing requested by interrupt service routine *//* *//***********************************************************************/static void poll(void){ ui32 ievent; /*-------------------------------------------------------------------*/ /* Read interrupt status register (clearing all bits). */ /*-------------------------------------------------------------------*/ ievent = DP_REG32_READ(DP_ISR); /*-------------------------------------------------------------------*/ /* If any frames have been received, process them. */ /*-------------------------------------------------------------------*/ if (ievent & (DP_INT_RXOK | DP_INT_RXERR)) { ++RxIsrCount; receive_bufs(); } /*-------------------------------------------------------------------*/ /* If transmission completed, reclaim transmitted buffers. */ /*-------------------------------------------------------------------*/ if (ievent & (DP_INT_TXOK | DP_INT_TXERR)) free_tx_bufs(); /*-------------------------------------------------------------------*/ /* Replenish the receive ring's supply of receive buffers. */ /*-------------------------------------------------------------------*/ fill_rx_ring(); /*-------------------------------------------------------------------*/ /* If transmission completed, keep transmit ring full. */ /*-------------------------------------------------------------------*/ if (ievent & (DP_INT_TXOK | DP_INT_TXERR)) { ++TxIsrCount; fill_tx_ring(); } /*-------------------------------------------------------------------*/ /* Re-enable device interrupts. */ /*-------------------------------------------------------------------*/ DP_REG32_WRITE(DP_IER, DP_IER_IE);}/***********************************************************************//* dev_reset: Perform soft reset on the DP83815 *//* *//***********************************************************************/static int dev_reset(void){ int timeout = 100; ui32 dp_isr; DP_REG32_WRITE(DP_CR, DP_CR_RST); while (timeout--) { dp_isr = DP_REG32_READ(DP_ISR); if (dp_isr == 0x03008000) return 0; microsleep(5); } printf("dp_isr %08x\n", dp_isr); return -1;}/***********************************************************************//* get_eth_addr: Get the Ethernet address *//* *//* Input: eth_addr = address to write Ethernet address to *//* *//* Returns: 0 if okay or -1 if error *//* *//***********************************************************************/static int get_eth_addr(ui8 *eth_addr){#if defined(USE_EEPROM_MAC_ADDRESS) int i; ui16 *eth_addr_ptr; for (i = 0, eth_addr_ptr = (ui16*)eth_addr; i < 3; ++i, ++eth_addr_ptr) { DP_REG32_WRITE(DP_RFCR, DP_RFCR_RFADDR_PMATCH1 + i*2); *eth_addr_ptr = ptohs(DP_REG32_READ(DP_RFDR)); }#else tmLibdevErr_t tmErr; MacAddr_t MacAddressStart; MacAddr_t MacAddressEnd; tmErr = TwFlash_GetMacAddresses(&MacAddressStart, &MacAddressEnd); if (tmErr != TMLIBDEV_OK) { printf("TwFlash_GetMacAddresses error %08x\n", tmErr); return -1; } memcpy(eth_addr, &MacAddressStart, sizeof(MacAddressStart));#endif return 0;}/***********************************************************************//* set_eth_addr: Set the Ethernet address *//* *//* Input: eth_addr = address to read Ethernet address from *//* *//***********************************************************************/static void set_eth_addr(ui8 *eth_addr){ int i; ui16 * eth_addr_ptr = (ui16 *)eth_addr; for (i = 0; i < 3; ++i, ++eth_addr_ptr) { DP_REG32_WRITE(DP_RFCR, DP_RFCR_RFADDR_PMATCH1 + i*2); DP_REG32_WRITE(DP_RFDR, htops(*eth_addr_ptr)); }}/***********************************************************************//* phy_setup: Reset and setup the PHY device *//* *//***********************************************************************/static int phy_setup(void){ ui32 dp_cfg_val; ui16 phy_status; ui16 timeout; /*-------------------------------------------------------------------*/ /* Recommended (data sheet) settings for optimum performance. */ /*-------------------------------------------------------------------*/ DP_REG32_WRITE(DP_PGSEL, 0x0001); DP_REG32_WRITE(DP_PHYCR, 0x189C); /* DC Speed = 01 */ DP_REG32_WRITE(DP_TSTDAT, 0x0000); /* Set value for C2 */ DP_REG32_WRITE(DP_DSPCFG, 0x5040); /* Load/Kill C2 */ DP_REG32_WRITE(DP_SDCFG, 0x008C); /* Raise SD off, from 4 to C */ /*-------------------------------------------------------------------*/ /* Additional PHY settings. */ /*-------------------------------------------------------------------*/ DP_REG16_WRITE(DP_BMCR, 0x1000); /* enable negotiation */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -