📄 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;}/*-----------------------------------------------------------------------------+| 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); br2=ppcMfbr2(); /* Disable ready pin and increase wait state since ethernet may not exist */ /* Also ethernet is not initialized yet */ ppcMtbr2((br2&0xFFFFBFFF)|0x3F00); /*--------------------------------------------------------------------------+ | 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); } /*--------------------------------------------------------------------------+ | 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)); ppcMtbr2(br2); (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); msdelay(3); (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 | pointer to page start. +--------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -