📄 lan_am79c973.c
字号:
/************************************************************************ * * LAN_AM79C973.c * * The 'LAN_AM79C973' module implements the LAN_AM79C973 * device driver as an IO device with following services: * * 1) init serial device: configure and initialize LAN * AM79C973 driver * 2) open serial device: register receive handler * 3) close serial device: not used * 4) read serial device: poll for received frame * 5) write serial device: request frame to be transmitted * 6) ctrl serial device: display diagnostics * * * ###################################################################### * * mips_start_of_legal_notice * * Copyright (c) 2004 MIPS Technologies, Inc. All rights reserved. * * * Unpublished rights (if any) reserved under the copyright laws of the * United States of America and other countries. * * This code is proprietary to MIPS Technologies, Inc. ("MIPS * Technologies"). Any copying, reproducing, modifying or use of this code * (in whole or in part) that is not expressly permitted in writing by MIPS * Technologies or an authorized third party is strictly prohibited. At a * minimum, this code is protected under unfair competition and copyright * laws. Violations thereof may result in criminal penalties and fines. * * MIPS Technologies reserves the right to change this code to improve * function, design or otherwise. MIPS Technologies does not assume any * liability arising out of the application or use of this code, or of any * error or omission in such code. Any warranties, whether express, * statutory, implied or otherwise, including but not limited to the implied * warranties of merchantability or fitness for a particular purpose, are * excluded. Except as expressly provided in any written license agreement * from MIPS Technologies or an authorized third party, the furnishing of * this code does not give recipient any license to any intellectual * property rights, including any patent rights, that cover this code. * * This code shall not be exported, reexported, transferred, or released, * directly or indirectly, in violation of the law of any country or * international law, regulation, treaty, Executive Order, statute, * amendments or supplements thereto. Should a conflict arise regarding the * export, reexport, transfer, or release of this code, the laws of the * United States of America shall be the governing law. * * This code constitutes one or more of the following: commercial computer * software, commercial computer software documentation or other commercial * items. If the user of this code, or any related documentation of any * kind, including related technical data or manuals, is an agency, * department, or other entity of the United States government * ("Government"), the use, duplication, reproduction, release, * modification, disclosure, or transfer of this code, or any related * documentation of any kind, is restricted in accordance with Federal * Acquisition Regulation 12.212 for civilian agencies and Defense Federal * Acquisition Regulation Supplement 227.7202 for military agencies. The use * of this code by the Government is further restricted in accordance with * the terms of the license agreement(s) and/or applicable contract terms * and conditions covering this code from MIPS Technologies or an authorized * third party. * * * * * mips_end_of_legal_notice * * ************************************************************************//************************************************************************ * Include files ************************************************************************/#include <string.h>#include <stdio.h>#include <sysdefs.h>#include <syserror.h>#include <sysdev.h>#include <io_api.h>#include <syscon_api.h>#include <excep_api.h>#include <sys_api.h>#include <lan_api.h>#include <lan_am79c973_api.h>/************************************************************************ * Constant Definitions*************************************************************************/ #define WORD0_OFS 0x00000 /* Word0: */#define WORD1_OFS 0x00004 /* Word1: *//* Maximum cache line size */#define CACHE_LINE_SIZE 0x20typedef enum{ LAN_MINOR_AM79C973_DEVICE_1 = 0, /* The one and only AM79C973 LAN controller */ /******* ADD NEW MINOR DEVICES JUST BEFORE THIS LINE ONLY ********/ LAN_MINOR_AM79C973_DEVICES} t_LAN_MINOR_AM79C973_devices ;/* PHY definitions */#define PHY_CONTROL 0#define PHY_AUTOADV 4#define PHY_ADDRESS (30 << 5)#define PHY_SUMMARY 24#define PHY_SUMMARY_LINK_UP (1 << 3)#define PHY_SUMMARY_FULL_DUPLEX (1 << 2)#define PHY_SUMMARY_AUTONEG_CHANGED (1 << 1)#define PHY_SUMMARY_SPEED_100MB (1 << 0)/* Init Block: Size of Init Block */#define LAN_AM79C973_INITBLOCK_SIZE 28/* Init Block: 'TLEN' Number of Transmit Descriptor Ring Entries, (encoded) */#define LAN_AM79C973_INITBLOCK_TLEN 4/* Init Block: 'RLEN' Number of Receive Descriptor Ring Entries, (encoded) */#define LAN_AM79C973_INITBLOCK_RLEN 4/* Number of descriptors in transmit ring, derived from the TLEN field */#define LAN_AM79C973_TDRE_COUNT (1 << LAN_AM79C973_INITBLOCK_TLEN)#define LAN_AM79C973_TDRE_SIZE 16/* Number of descriptors in receive ring, derived from the RLEN field */#define LAN_AM79C973_RDRE_COUNT (1 << LAN_AM79C973_INITBLOCK_RLEN)#define LAN_AM79C973_RDRE_SIZE 16/* TX and RX data buffer size: fixed to 1536 bytes, */#define LAN_AM79C973_BUFFER_SIZE 0x600#define LAN_AM79C973_FCS_SIZE 0x4/* Number of TX data buffers, derived from the TLEN field */#define LAN_AM79C973_TX_BUFFERS (1 << LAN_AM79C973_INITBLOCK_TLEN)/* Number of RX data buffers, derived from the RLEN field */#define LAN_AM79C973_RX_BUFFERS (1 << LAN_AM79C973_INITBLOCK_RLEN)/* Minimum data buffer size */#define LAN_AM79C973_MIN_BUFFER_SIZE 60/************************************************************************ * LAN AM79C973: Relative Register Addresses, for PCI-BAR1, 32-bit mode*************************************************************************/#define LAN_AM79C973_RDP32_OFS 0x10 /* RDP register, CSR reg. acc. */#define LAN_AM79C973_RAP32_OFS 0x14 /* RAP register */#define LAN_AM79C973_RES32_OFS 0x18 /* RESET register */#define LAN_AM79C973_BDP32_OFS 0x1C /* BDP register, BCR reg. acc. *//************************************************************************ * Macro Definitions*************************************************************************//* The sequence is: a) Set 32-bit IO mode (writing '0' to offset 0x10) b) Read 'RESET' register c) Wait 10 ms. c) Set 32-bit IO mode*/#define LAN_AM79C973_RESET( membase, readvar ) \{ \ (*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_RDP32_OFS)) = 0 ; \ readvar = ((*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_RES32_OFS)) & 0xffff) ; \ sys_wait_ms( 10 ) ; \ (*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_RAP32_OFS)) = 0 ; \ (*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_RDP32_OFS)) = 0 ; \}#define CSR_READ( membase, csr, readvar ) \{ \ (*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_RAP32_OFS)) = (csr) ; \ readvar = ((*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_RDP32_OFS)) & 0xffff) ; \}#define CSR_WRITE( membase, csr, writevar ) \{ \ (*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_RAP32_OFS)) = (csr) ; \ (*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_RDP32_OFS)) = (writevar) & 0xffff ; \}#define BCR_READ( membase, bcr, readvar ) \{ \ (*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_RAP32_OFS)) = (bcr) ; \ readvar = ((*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_BDP32_OFS)) & 0xffff) ; \}#define BCR_WRITE( membase, bcr, writevar ) \{ \ (*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_RAP32_OFS)) = (bcr) ; \ (*(volatile UINT32 *)((UINT32)(membase)+LAN_AM79C973_BDP32_OFS)) = (writevar) & 0xffff ; \}#define IF_ERROR( completion, function ) \{ \ completion = function ; \ if ( completion != OK ) \{ \ return( completion ) ; \} \}/************************************************************************ * Type Definitions*************************************************************************//* protoype for int handler */typedef void (*t_inthandler)(void *data) ;/* * Network device statistics. */typedef struct net_device_stats{ UINT32 rx_packets; /* total packets received */ UINT32 tx_packets; /* total packets transmitted */ UINT32 rx_bytes; /* total bytes received */ UINT32 tx_bytes; /* total bytes transmitted */ UINT32 rx_errors; /* bad packets received */ UINT32 tx_errors; /* packet transmit problems */ UINT32 multicast; /* multicast packets received */ UINT32 collisions; UINT32 interrupts ; /* total number of interrupts */ /* detailed rx_errors: */ UINT32 rx_zero_length_errors; UINT32 rx_buffer_length_errors; UINT32 rx_over_errors; /* recved pkt with overflow */ UINT32 rx_crc_errors; /* recved pkt with crc error */ UINT32 rx_frame_errors; /* recv'd frame alignment error */ UINT32 rx_fifo_errors; /* recv'r fifo overrun */ UINT32 rx_no_resource_errors; /* recv'r no resource errors */ /* detailed tx_errors */ UINT32 tx_aborted_errors; UINT32 tx_carrier_errors; UINT32 tx_fifo_errors; UINT32 tx_heartbeat_errors; UINT32 tx_window_errors; UINT32 tx_timeout_errors; UINT32 tx_bus_parity_errors;} t_net_device_stats ;/* Device context for a AM79C973 LAN controller */typedef struct LAN_AM79C973_device{ /* pointer for the AM79C973 LAN controller, reg. base address */ void *p79C973Regs; /* Init Block, (pointer is in CPU address space) */ void *pInitBlock ; /* TX Descriptor Ring, (pointers are in CPU address space) */ UINT32 TXDRE[LAN_AM79C973_TDRE_COUNT] ; /* RX Descriptor Ring, (pointers are in CPU address space) */ UINT32 RXDRE[LAN_AM79C973_TDRE_COUNT] ; /* TX Buffers, (pointers are in CPU address space) */ UINT32 TxBuffer[LAN_AM79C973_TX_BUFFERS]; /* RX Buffers, (pointers are in CPU address space) */ UINT32 RxBuffer[LAN_AM79C973_RX_BUFFERS]; /* TDRE index */ UINT8 NextTDREIndex ; /* RDRE index */ UINT8 NextRDREIndex ; /* network statistics */ t_net_device_stats status ;} t_LAN_AM79C973_device ;/************************************************************************ * LAN AM79C973: Shared memory register field encodings*************************************************************************//************************************************************************ * LAN AM79C973: Initialization Block (SSIZE32=1)*************************************************************************/#define INIT_WORD0_OFS 0x00000 /* Word0: */#define INIT_WORD1_OFS 0x00004 /* Word1: */#define INIT_WORD2_OFS 0x00008 /* Word2: */#define INIT_WORD3_OFS 0x0000C /* Word3: */#define INIT_WORD4_OFS 0x00010 /* Word4: */#define INIT_WORD5_OFS 0x00014 /* Word5: */#define INIT_WORD6_OFS 0x00018 /* Word6: *//******** reg: Init Block, WORD0 ********//* field: TLEN */#define INIT_WORD0_TLEN_SHF 28#define INIT_WORD0_TLEN_MSK (MSK(4) << INIT_WORD0_TLEN_SHF)/* field: RLEN */#define INIT_WORD0_RLEN_SHF 20#define INIT_WORD0_RLEN_MSK (MSK(4) << INIT_WORD0_RLEN_SHF)/* field: MODE */#define INIT_WORD0_MODE_SHF 0#define INIT_WORD0_MODE_MSK (MSK(16) << INIT_WORD0_MODE_SHF)/* field: PROM */#define INIT_WORD0_PROM_SHF 15#define INIT_WORD0_PROM_MSK (MSK(1) << INIT_WORD0_PROM_SHF)#define INIT_WORD0_PROM_SET INIT_WORD0_PROM_MSK/* field: DRCVBC */#define INIT_WORD0_DRCVBC_SHF 14#define INIT_WORD0_DRCVBC_MSK (MSK(1) << INIT_WORD0_DRCVBC_SHF)#define INIT_WORD0_DRCVBC_SET INIT_WORD0_DRCVBC_MSK/* field: DRCVPA */#define INIT_WORD0_DRCVPA_SHF 13#define INIT_WORD0_DRCVPA_MSK (MSK(1) << INIT_WORD0_DRCVPA_SHF)#define INIT_WORD0_DRCVPA_SET INIT_WORD0_DRCVPA_MSK/* field: PORTSEL */#define INIT_WORD0_PORTSEL_SHF 7#define INIT_WORD0_PORTSEL_MSK (MSK(2) << INIT_WORD0_PORTSEL_SHF)/* field: INTL */#define INIT_WORD0_INTL_SHF 6#define INIT_WORD0_INTL_MSK (MSK(1) << INIT_WORD0_INTL_SHF)#define INIT_WORD0_INTL_SET INIT_WORD0_INTL_MSK/* field: DRTY */#define INIT_WORD0_DRTY_SHF 5#define INIT_WORD0_DRTY_MSK (MSK(1) << INIT_WORD0_DRTY_SHF)#define INIT_WORD0_DRTY_SET INIT_WORD0_DRTY_MSK/* field: FCOLL */#define INIT_WORD0_FCOLL_SHF 4#define INIT_WORD0_FCOLL_MSK (MSK(1) << INIT_WORD0_FCOLL_SHF)#define INIT_WORD0_FCOLL_SET INIT_WORD0_FCOLL_MSK/* field: DXMTFCS */#define INIT_WORD0_DXMTFCS_SHF 3#define INIT_WORD0_DXMTFCS_MSK (MSK(1) << INIT_WORD0_DXMTFCS_SHF)#define INIT_WORD0_DXMTFCS_SET INIT_WORD0_DXMTFCS_MSK/* field: LOOP */#define INIT_WORD0_LOOP_SHF 2#define INIT_WORD0_LOOP_MSK (MSK(1) << INIT_WORD0_LOOP_SHF)#define INIT_WORD0_LOOP_SET INIT_WORD0_LOOP_MSK/* field: DTX */#define INIT_WORD0_DTX_SHF 1#define INIT_WORD0_DTX_MSK (MSK(1) << INIT_WORD0_DTX_SHF)#define INIT_WORD0_DTX_SET INIT_WORD0_DTX_MSK/* field: DRX */#define INIT_WORD0_DRX_SHF 0#define INIT_WORD0_DRX_MSK (MSK(1) << INIT_WORD0_DRX_SHF)#define INIT_WORD0_DRX_SET INIT_WORD0_DRX_MSK/******** reg: Init Block, WORD1 ********//* field: MACADR3 */#define INIT_WORD1_MACADR3_SHF 24#define INIT_WORD1_MACADR3_MSK (MSK(8) << INIT_WORD1_MACADR3_SHF)/* field: MACADR2 */#define INIT_WORD1_MACADR2_SHF 16#define INIT_WORD1_MACADR2_MSK (MSK(8) << INIT_WORD1_MACADR2_SHF)/* field: MACADR1 */#define INIT_WORD1_MACADR1_SHF 8#define INIT_WORD1_MACADR1_MSK (MSK(8) << INIT_WORD1_MACADR1_SHF)/* field: MACADR0 */#define INIT_WORD1_MACADR0_SHF 0#define INIT_WORD1_MACADR0_MSK (MSK(8) << INIT_WORD1_MACADR0_SHF)/******** reg: Init Block, WORD2 ********//* field: MACADR5 */#define INIT_WORD2_MACADR5_SHF 8#define INIT_WORD2_MACADR5_MSK (MSK(8) << INIT_WORD2_MACADR5_SHF)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -