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

📄 enetlib.c

📁 Ibmstb02500 miniboot 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* openbios/enetLib/enetLib.c *//*-----------------------------------------------------------------------------+||       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|              SMSC LAN91C111 Ethernet driver.||  Author:     Alan Booker, Maciej P. Tyrlik, Jim Haller||  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|  13-Aug-01   ********* SMSC LAN91C111 ******************************     jfh|  13-Aug-01   Complete rewrite for SMSC 91111 for Redwood V/Pallas        jfh|  06-Dec-01   Fixing many bugs to let it work finally.                 YYD/GY|  06-Mar-02   Fixed Autospeed negotiation problems.                    YYD/GY|  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"#define SMC_TLVL     0x00        // 0x08 is default// 0000             1.16//   ...// 1000             1.00//   ...// 1111             0.86/*-----------------------------------------------------------------------------+| Private defines.+-----------------------------------------------------------------------------*/#undef  DEBUG_MSG_ISTHERE#undef  DEBUG_MSG_TEST#undef  DEBUG_MSG_INIT#undef  DEBUG_MSG_PHYWRITE#undef  DEBUG_MSG_PHYREAD#undef  DEBUG_MSG_PHYINT#undef  DEBUG_MSG_SETSPEED#undef  DEBUG_MSG_SETDUPLEX#undef  DEBUG_MSG_PHYRESET#undef  DEBUG_MSG_ENETRESET#undef DEBUG_MSG_MACFRAME#undef DEBUG_MSG_ENETSEND#undef DEBUG_MSG_RCVPACKET#define NUMRECV_BUFF                    2#define LAN91C111_MEMORY_MULTIPLIER     (1024*2)#define ALLOC_TIMEOUT   10      // 10 ms/*-----------------------------------------------------------------------------+| 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 char             outframe[ENET_MAX_MTU];static volatile unsigned long    outframe_len=0;static volatile int              flih_bufnum=0;static volatile 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 long Ticks_per_sec;extern int _callxlc(int,...);extern struct board_cfg_data board_cfg;static int      enet_rcv_packet(char *inframe, int max);static struct enet_device dev;static const char version[] = "v1.02 12/20/01\n";static const char name[]    = "smc91111";static void enet_reset ();static void phy_clkMDIO (unsigned int MII_MGMTData );static unsigned int phy_readreg (char PHYAddr, char RegAdd );static void phy_writereg (char PHYAddr, char RegAdd, unsigned int wData );static void phy_interrupt();static void smc_tx();/******************************************************************************** nsdelay - task delay to insure minimum clock values for the MAC-PHY***/static void nsdelay(unsigned long ns){  unsigned long t1;  unsigned long delay;  while(ns)  {    t1 = powerpcMftbl();    if(ns > 1000000000)      delay = 1000000000;    else      delay = ns;    ns -= delay;    delay = 1 + (delay * (BOARD_CLOCK/1000000)+999)/1000;   //YYD, fixed potential mul overflow issue    while(delay > powerpcMftbl() - t1);  }  return;}/*-----------------------------------------------------------------------------+| EnetRecv.+-----------------------------------------------------------------------------*/int enetRecv(char *p, int len, int *parmp){   int                  rc;   tb_t                 tb_start;   tb_t                 tb_end;   unsigned long        msr;   (void)ppcMftb(&tb_start);   while (1) {      msr=ppcAndMsr(~ppcMsrEE);      /*-----------------------------------------------------------------------+      | Frame length is reduced by 14 (6 for dest addr, 6 for source addr, and      | 2 for frame type fields) since we only want to copy the data portion      | of the packet.      +-----------------------------------------------------------------------*/      if (inframe[read_bufnum].inframe_len<len) {         rc=inframe[read_bufnum].inframe_len - 14;      } else {         rc=len - 14;      }      /*-----------------------------------------------------------------------+      | Frame data starts at byte 16 (2 for aligment 12 for addresses 2 for      | frame type).      +-----------------------------------------------------------------------*/      if (rc>0) {         (void)memcpy(p, &inframe[read_bufnum].data[14], rc);         inframe[read_bufnum].inframe_len=0;         read_bufnum=(read_bufnum+ 1)% NUMRECV_BUFF;         (void)ppcMtmsr(msr);#ifdef DEBUG_MSG_RCVPACKET           s1printf("Received Packet\n");           dump( p, rc );#endif         return(rc);      }      (void)ppcMtmsr(msr);      (void)ppcMftb(&tb_end);      if (tbmilisec_dif(&tb_end, &tb_start)>3000/*9000*/) {  // timeout if it is larget than 9 seconds         return(-1);      }   }}/*-----------------------------------------------------------------------------+| Enet_rcv_packet.*------------------------------------------------------------------------------- . . receive a packet from the card . . There is ( at least ) a packet waiting to be read from . chip-memory. . . o Read the status . o If an error, record it . o otherwise, read in the packet --------------------------------------------------------------*/static int enet_rcv_packet(char *inframe,           int max){   int           packet_number;   unsigned int  status;   unsigned int  packet_length;//   s1printf("%s:enet_rcv_packet\n", dev.name);   /* assume bank 2 */   packet_number = in16( ENET_IO_ADDR + RXFIFO_REG );   if ( packet_number & RXFIFO_REMPTY ) {           /* we got called, but nothing was on the FIFO */           s1printf("%s: WARNING: enet_rcv_packet with nothing on FIFO. \n",                   dev.name);           /* don't need to restore anything */           return(0);   }   /*  start reading from the start of the packet */   out16( ENET_IO_ADDR + PTR_REG, PTR_READ | PTR_RCV | PTR_AUTOINC );   /* First two words are status and packet_length */   status          = in16( ENET_IO_ADDR + DATA_REG );   packet_length   = in16( ENET_IO_ADDR + DATA_REG );   packet_length &= 0x07ff;  /* mask off top bits *///   s1printf("RCV: STATUS %4x LENGTH %4x\n", status, packet_length );   if ( !(status & RS_ERRORS ) ){           /* do stuff to make a new packet */           /* set multicast stats */           if ( status & RS_MULTICAST )                   dev.stats.multicast++;           // Allocate enough memory for entire receive frame, to be safe           /* Adjust for having already read the first two words */           packet_length -= 4;//           s1printf(" Reading %d words and %d byte(s) \n",//                   (packet_length >> 1 ), packet_length & 1 );           insw(ENET_IO_ADDR + DATA_REG, inframe, packet_length >> 1);#ifdef DEBUG_MSG_RCVPACKET           s1printf("Receiving Packet\n");           dump( inframe, packet_length );#endif           dev.stats.rx_packets++;   } else {           /* error ... */           dev.stats.rx_errors++;           if ( status & RS_ALGNERR )  dev.stats.rx_frame_errors++;           if ( status & (RS_TOOSHORT | RS_TOOLONG ) )                   dev.stats.rx_length_errors++;           if ( status & RS_BADCRC)        dev.stats.rx_crc_errors++;   }   while ( in16( ENET_IO_ADDR + MMU_CMD_REG ) & MC_BUSY )           nsdelay(1000);   /*  error or good, tell the card to get rid of this packet */   out16( ENET_IO_ADDR + MMU_CMD_REG, MC_RELEASE );   /*--------------------------------------------------------------------------+   | Return number of bytes read.   +--------------------------------------------------------------------------*/   return(packet_length);}/*-----------------------------------------------------------------------------+| Enet_register.+-----------------------------------------------------------------------------*/int enet_register(void (*recv_function)(char *frame, unsigned long frame_len),    unsigned long ip_addr){   osopen_enet.recv_function=recv_function;   osopen_enet.ip_addr=ip_addr;   return(0);}/*-----------------------------------------------------------------------------+| EnetisThere.+-----------------------------------------------------------------------------*/int enetisThere(unsigned long *ip_src,    unsigned long *ip_dst, int *parmp){   unsigned int    bank, i ;   unsigned short  revision_register;   unsigned int    base_address_register;   extern struct board_cfg_data board_cfg;#ifdef DEBUG_MSG_ISTHERE   s1printf("enetisthere Entered...\n");#endif   nsdelay(1000000);   (void)memcpy(hwd_addr, board_cfg.mac_address, sizeof(hwd_addr));   (void)memcpy(parmp, hwd_addr, sizeof(hwd_addr));   /* First, see if the high byte is 0x33 */   bank = in16( ENET_IO_ADDR + BANK_SELECT );   if ( (bank & 0xFF00) != 0x3300 ) {           s1printf("Read Bank 0x%x =  0x%x\n", ENET_IO_ADDR+BANK_SELECT, bank);           s1printf("Return(0) # 1\n");           return(0);   }#ifdef DEBUG_MSG_ISTHERE   s1printf("enetisThere: Read Bank 0x%x =  0x%x\n", ENET_IO_ADDR+BANK_SELECT, bank);#endif   nsdelay(1000000);   /* The above MIGHT indicate a device, but I need to write to further */   out16( ENET_IO_ADDR + BANK_SELECT, 0x00 );   bank = in16( ENET_IO_ADDR + BANK_SELECT );   if ( (bank & 0xFF00) != 0x3300 ) {      s1printf("Write Bank Select 0x%x, 0x00\n", ENET_IO_ADDR+BANK_SELECT);      s1printf("Read Bank 0x%x =  0x%x\n", ENET_IO_ADDR+BANK_SELECT, bank);      s1printf("Return(0) # 2\n");      return(0);   }#ifdef DEBUG_MSG_ISTHERE   s1printf("enetisThere: Write Bank Select 0x%x, 0x00\n", ENET_IO_ADDR+BANK_SELECT);   s1printf("enetisThere: Read Bank 0x%x =  0x%x\n", ENET_IO_ADDR+BANK_SELECT, bank);#endif   nsdelay(1000000);

⌨️ 快捷键说明

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