📄 enetlib.c
字号:
/* openbios/enetLib/enetLib.c, redbios, redbios_iii_1.0 6/4/99 14:56:32 *//*-----------------------------------------------------------------------------+|| This source code has been made available to you by IBM on an AS-IS| basis. Anyone receiving this source is licensed under IBM| copyrights to use it in any way he or she deems fit, including| copying it, modifying it, compiling it, and redistributing it either| with or without modifications. No license under IBM patents or| patent applications is to be implied by the copyright license.|| Any user of this software should understand that IBM cannot provide| technical support for this software and will not be responsible for| any consequences resulting from the use of this software.|| Any person who transfers this source code or any derivative work| must include the IBM copyright notice, this paragraph, and the| preceding two paragraphs in the transferred software.|| COPYRIGHT I B M CORPORATION 1995| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M+-----------------------------------------------------------------------------*//*-----------------------------------------------------------------------------+|| File Name: enetLib.c|| Function: This module contains the base module for the OpenBios 83902| Ethernet driver.|| Author: Alan Booker, Maciej P. Tyrlik.|| Change Activity-|| Date Description of Change BY| --------- --------------------- ---| 13-Aug-93 Created AJB| 27-May-94 Port to Oak MPT| 07-Nov-94 Added error conditions, remove PASS.... defines MPT| 11-Jan-95 Added timeout to enet_send_macframe KDW| 23-Jan-97 Ported to DDI board KDW| 20-Jan-99 Updated for Redwood III changes KDW| 25-May-99 Added delays prior to each chip access pag| 04-Jun-99 Updated enetRecv() to return correct byte count (issue 72) pag| 04-Jun-99 Fix for issue #73 - enetInt() - check own IP when pinged pag| 02-Feb-00 Inverted Extern Interrupt Polarity for Redwood IV/Vesta jfh| 24-Jun-02 Fixed ip address dynamic updating issues YYD|+-----------------------------------------------------------------------------*/#include <types.h>#include <sys/types.h>#include <stdlib.h>#include <limits.h>#include <ppcLib.h>#include <machine/endian.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <enetLib.h>#include <openbios.h>#include <string.h>#include <eval.h>#include "enetloc.h"/*-----------------------------------------------------------------------------+| Private defines.+-----------------------------------------------------------------------------*/#define NUMRECV_BUFF 2/*-----------------------------------------------------------------------------+| Global variables. Flih_bufnum and read_bufnum are used to point to correct| receive buffer.+-----------------------------------------------------------------------------*/static char hwd_addr[ENET_ADDR_LENGTH]= {0xBA, 0xD0, 0xAD, 0xD0, 0x00, 0x00};static char brd_addr[ENET_ADDR_LENGTH]= {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};unsigned char next_packet_ptr;static unsigned long *ip_addr;static unsigned char outframe[ENET_MAX_MTU];static unsigned long outframe_len=0;static int flih_bufnum=0;static int read_bufnum=0;static struct { int inframe_len; char data[ENET_MAX_MTU+ 2];} inframe[NUMRECV_BUFF];static struct { void (*recv_function)(char *frame, unsigned long frame_len); unsigned long ip_addr;} osopen_enet;extern struct board_cfg_data board_cfg;extern int _callxlc(int,...);static int enet_rcv_packet(char *inframe, int max);/*-----------------------------------------------------------------------------+| Write_cr.+-----------------------------------------------------------------------------*/static void write_cr(unsigned char value){ in8(NIC_DMA); /* add delay prior to each chip access */ (void)out8(CR, value); return;}/*-----------------------------------------------------------------------------+| Read_nic.+-----------------------------------------------------------------------------*/static unsigned char read_nic(unsigned long reg_addr, unsigned char page){ unsigned char cr; in8(NIC_DMA); /* add delay prior to each chip access */ cr=in8(CR); if ((cr&PBMASK)!=page) { cr&=0x3F; in8(NIC_DMA); /* add delay prior to each chip access */ (void)out8(CR, cr|page); } in8(NIC_DMA); /* add delay prior to each chip access */ cr=in8(reg_addr); return(cr);}/*-----------------------------------------------------------------------------+| Write_nic.+-----------------------------------------------------------------------------*/static void write_nic(unsigned long reg_addr, unsigned char value, unsigned char page){ unsigned char cr; in8(NIC_DMA); /* add delay prior to each chip access */ cr=in8(CR); if ((cr&PBMASK)!=page) { cr&=0x3F; in8(NIC_DMA); /* add delay prior to each chip access */ (void)out8(CR, cr|page); } in8(NIC_DMA); /* add delay prior to each chip access */ (void)out8(reg_addr, value); return;}#if 0static void rtl8019_dump(){ int i, j; int cmd; s1printf("Dumping RTL8109 registers\n"); cmd = in8(CR);; // keep the original for(i=0; i<3; i++) { s1printf("Page %d\n", i); out8(CR, STP+RD2+ (i<<6)); // select page for(j=0; j<16; j++) { int k, v; v = in8(CR+j); s1printf("Addr %02x = %02x \n", j, v); } } out8(CR, cmd);}#endif/*-----------------------------------------------------------------------------+| EnetisThere.+-----------------------------------------------------------------------------*/int enetisThere(unsigned long *ip_src, unsigned long *ip_dst, int *parmp){ unsigned char mult0; unsigned char mult1; unsigned long msr,br2; msr=ppcAndMsr(~ppcMsrEE); /*--------------------------------------------------------------------------+ | Poke values in the enet registers to test if the chip is there. Use | multicast address registers for read/write values. Multicast addresses | are not used in this driver. +--------------------------------------------------------------------------*/ mult0=read_nic(MAR0, PAGE1); mult1=read_nic(MAR1, PAGE1); (void)write_nic(MAR0, 0xAA, PAGE1); (void)write_nic(MAR1, 0x55, PAGE1); if (read_nic(MAR0, PAGE1)!=0xAA) { (void)ppcMtmsr(msr); return(0); } // check for RTL8019AS write_cr(STP+RD2+PAGE0); if(read_nic(NIC_BASE+0x0A, PAGE0) == 'P' && read_nic(NIC_BASE+0x0B, PAGE0) == 'p') { // s1printf("Detected RTL8019AS ethernet card.\n"); } else return 0; /*--------------------------------------------------------------------------+ | Copy network address into return parameter and restore multicase address | values. We get network address from vital product data region. +--------------------------------------------------------------------------*/ (void)write_nic(MAR0, mult0, PAGE1); (void)write_nic(MAR1, mult1, PAGE1); (void)memcpy(hwd_addr, board_cfg.mac_address, sizeof(hwd_addr)); (void)memcpy(parmp, hwd_addr, sizeof(hwd_addr)); (void)ppcMtmsr(msr); return(1);}/*-----------------------------------------------------------------------------+| EnetTest.+-----------------------------------------------------------------------------*/int enetTest(){ char hw_addr[6]; if (enetisThere(NULL, NULL, (int *)hw_addr)==1) { return(0); } else { return(-1); }}/*-----------------------------------------------------------------------------+| enetInit.+-----------------------------------------------------------------------------*/int enetInit(unsigned long *srcaddr, unsigned long *dstaddr, int *parmp){ unsigned long temp; unsigned long msr; /*--------------------------------------------------------------------------+ | Initialization procedure from page 1-118 of the controller data sheet. +--------------------------------------------------------------------------*/ msr=ppcAndMsr(~ppcMsrEE); (void)write_cr(RD2|STP); write_nic(RTL_RESET, read_nic(RTL_RESET, PAGE0) , PAGE0); // RTL8019 specific msdelay(3); // delay 3 milisec (void)write_cr(RD2|STP); msdelay(3); // delay 3 milisec (void)write_nic(DCR, LS|FT8B, PAGE0); (void)write_nic(RBCR0, 0x0, PAGE0); (void)write_nic(RBCR1, 0x0, PAGE0); (void)write_nic(RCR, AB, PAGE0); (void)write_nic(TCR, LBM1, PAGE0); /*--------------------------------------------------------------------------+ | Initialize receive buffer ring. Set aside first 8 pages as transmit pages, | rest as receive ring. In a 8 K buffer, pages are numbered 0 to 31. First | receive page is page 8. PSTOP is set to one past last valid buffer. +--------------------------------------------------------------------------*/ (void)write_nic(PSTART, PSTART_VALUE, PAGE0); (void)write_nic(PSTOP, PSTOP_VALUE, PAGE0); (void)write_nic(BNRY, PSTART_VALUE, PAGE0); next_packet_ptr=PSTART_VALUE+ 1; /*--------------------------------------------------------------------------+ | Clear all bits in ISR register. Interrupt on receive packets and buffer | overflow only. +--------------------------------------------------------------------------*/ (void)write_nic(ISR, 0xFF, PAGE0); (void)write_nic(IMR, PRXE|OVWE, PAGE0); /*--------------------------------------------------------------------------+ | Initialize physical address and multicast address. Set current page
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -