?? enetlib.c-fjj-bak
字號:
/* 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 u8 unsigned char#define u16 unsigned short#define u32 unsigned int #define GPO_TEST 0x40060000#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 mstypedef struct _RX_DESC{ unsigned char rxbyte; unsigned char status; unsigned short length;}RX_DESC;typedef union{ u8 buf[4]; RX_DESC desc;} rx_t;/*-----------------------------------------------------------------------------+| Global variables. Flih_bufnum and read_bufnum are used to point to correct| receive buffer.+-----------------------------------------------------------------------------*/static char hwd_addr[ENET_ADDR_LENGTH]= {0x00, 0x60, 0x6E, 0x42, 0xB9, 0xff};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 tx_num=0;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[] = "dm9000a";unsigned char ip_packet=0;/******************************************************************************** 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;// s1printf("\n Enter Received Packet\n"); (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; /* read_bufnum=read_bufnum+1; if(read_bufnum==100) read_bufnum=0;*/ (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)>9000) { // timeout if it is larget than 9seconds return(-1); } }}u8 check_rx_ready(u8 rxbyte){ if (!(rxbyte & 0x01)) return 0; return ((rxbyte >> 4) | 0x01);}/*-----------------------------------------------------------------------------+| 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 */ unsigned char rxbyte, val; unsigned short i, GoodPacket, tmplen = 0; u32 tmpdata; unsigned char MDRAH, MDRAL; rx_t rx; u16 * ptr = (u16*)℞ u8* rdptr; do { /*store the value of Memory Data Read address register*/ MDRAH=ior(DM9KS_MDRAH); MDRAL=ior(DM9KS_MDRAL); ior(DM9KS_MRCMDX); /* Dummy read */ rxbyte = in16(ENET_IO_ADDR+4)&0xff; /* Got most updated data */ /* packet ready to receive check */ if(!(val = check_rx_ready(rxbyte))) break; /* A packet ready now & Get status/length */ GoodPacket = TRUE; iow(DM9KS_MRCMD); /* Read packet status & length */ *ptr = in16(ENET_IO_ADDR+4); packet_length= in16(ENET_IO_ADDR+4); // s1printf("packet_length is %x\n",packet_length); /* rx.desc.length=(((rx.desc.length>>8) & 0xff) | ((rx.desc.length<<8) & 0xff00)); */ /* Read received packet from RX SARM */ tmplen = (packet_length + 1) / 2; for (i = 0; i < tmplen; i++) ((u16 *)inframe)[i] = in16(ENET_IO_ADDR+4); /*if((packet_length==0x40)&&inframe[0]==0xffff) dump(inframe,packet_length); /* Pass to upper layer */ /* skb->protocol = eth_type_trans(skb,dev);*/ }while((rxbyte & 0x01) == DM9KS_PKT_RDY); return(packet_length-4);}/*-----------------------------------------------------------------------------+| 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,id_val ; 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)); out16( ENET_IO_ADDR,DM9KS_VID_L); nsdelay(50); id_val = in16(ENET_IO_ADDR + 4)&0x00ff; nsdelay(50); out16(ENET_IO_ADDR,DM9KS_VID_H);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -