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

📄 lan91c111.c

📁 Intel PXA270的bootloader程序,在linux环境下运行的.
💻 C
📖 第 1 页 / 共 2 页
字号:
//The driver for Lan91c111 only ////Made by Ray.xian in 51Board co,,td////6/18/05//#include <types.h>#include <setup.h>#include <stdio.h>#include <string.h>#include <io.h>#include <network.h>#include <hardware.h>#include <netdev.h>#include <time.h>//#include <cs8900.h>#include <lan91c111.h>#define u16(x)  (*(volatile unsigned short *)(x))#define u32(x)  (*(volatile unsigned int  * )(x))#define LAN91C111_BASE_ADDR		(0x0c000300)#define LAN91C111_CHIP_ID                0x3390#define report(fmt, args...)	printf(fmt, ##args)#define assert(fmt, args...)	printf(fmt, ##args)#define failed(fmt, args...)	printf(fmt, ##args)static bool lan91c111_init(void);static void lan91c111_exit(void);static int  lan91c111_recv_packet(void);static bool lan91c111_send_packet(void *packet, int len);static void lan91c111_enable(void);static void lan91c111_disable(void);extern  clock_t timeout;static const unsigned long base = LAN91C111_BASE_ADDR;void test_get_reg();void sec_sleep(int second){  unsigned long nx_timer;  nx_timer = clock() + CLOCKS_PER_SEC * second/2 ;  while( clock()<nx_timer ) {};}void delay(time){   int i, j;   for(i=0; i<time; i++)     for(j=0; j<1000; j++);}static unsigned charreadforbyte(int offset){  unsigned char * iobase; unsigned char val; int act_offset, temp=0; iobase = (unsigned char *) base ; temp = offset>>8;    //Determine the high byte(1) or low byte(0) act_offset = offset & 0xf; if (temp)  //Only LAN91C111_INTERRUPT_M or LAN91C111_ARR   val = (unsigned char)(*(iobase + act_offset +1)); else       //Only LAN91C111_INTERRUPT or LAN91C111_PNR   val = (unsigned char)(*(iobase + act_offset));     return val;}static unsigned shortreadforword(int offset){/*unsigned short *  iobase ;  int temp=0;    iobase = (unsigned short *)base;   temp = offset;   offset >>= 1;   if(offset == 0x6)      return u16(base + offset);    if(temp & 0x2)       return (*(iobase + offset)>>16);   else       return  ((*(iobase + offset)<<16) >>16 );  */  unsigned short * iobase;  int act_offset = offset & 0xf;   iobase = (unsigned short *)base;    return *(iobase + (act_offset>>1) );}static void writeforword(int offset, unsigned short val){ // int temp;  unsigned short * iobase= (unsigned short *)base;    offset &= 0xf;  offset >>= 1;  *(iobase + offset)=val;  }static voidwriteforbyte(int offset, unsigned short val){ unsigned char * iobase; int temp=0;  iobase = (unsigned char *)base; temp = offset>>8;                 //determine low byte(0) or high byte(1) if (offset == LAN91C111_ARR)   { printf("LAN91C111_ARR(BANK 2 ,OFFSET 3) is not allowed writed, only READ ONLY\n");     return ;   } if (temp)  // only the LAN91C111_INTERRUPT_M    {     *(iobase + (offset & 0xf) +1 ) = (unsigned char )val;    } else        // only the LAN91C111_INTERRUPT or LAN91C111_PNR    {    *(iobase + (offset & 0xf) ) = (unsigned char)val;    }}//To detemine the reg belong to which bank;static void selectbank(int reg){  char i,whichbank=0;    char temp =0;    unsigned short * iobase = (unsigned short *)base;  temp  = (reg & 0x0f0)>>4 ;    for(i=1 ; i <temp; i<<=1 )     whichbank ++;#if DEBUG & 1  printf("whichbank is 0x%08x\n", whichbank);#endif       *(iobase + ((LAN91C111_BANK & 0xf)>>1) ) = (whichbank); // u32(base + (LAN91C111_BANK & 0xf)  -2 ) = (whichbank<<16);#if DEBUG & 1  printf("bank is 0x%08x\n", u16(base + (LAN91C111_BANK&0xf)));#endif }//The rutine is devoted to get the register value; static unsigned shortget_reg(int reg){  unsigned short val=0;     selectbank(reg);  if ((reg == LAN91C111_PNR) || (reg == LAN91C111_ARR))          val = readforbyte(reg);  else if ((reg == LAN91C111_INTERRUPT) || (reg == LAN91C111_INTERRUPT_M))          val = readforbyte(reg);  else            val = readforword(reg);#if DEBUG & 2  printf("reg 0x%08x\n value is 0x%08x\n", reg, val );#endif   return val  ;}//The rutine is devoted to set the register value;static void put_reg(int reg, unsigned short val ){  unsigned int * iobase;  iobase = (unsigned int *)base;  selectbank(reg);    if( (reg==LAN91C111_PNR) || (reg==LAN91C111_ARR) )      writeforbyte(reg, val);         else if( (reg==LAN91C111_INTERRUPT) || (reg==LAN91C111_INTERRUPT_M) )        writeforbyte(reg, val );  else      writeforword(reg, val);}static unsigned shortlan91c111_read_phy( char phyaddr, char phyreg ){  unsigned short  phy_info[32], i=0, mgmt_cur, value=0, in_dex, info=0;  int mask;    //Get the current value of MGMT  mgmt_cur = get_reg(LAN91C111_MGMT);    //Get the reserved bit of the MGMT  mgmt_cur &= ~(MGMT_MSK_CRS100| MGMT_MDOE | MGMT_MCLK | MGMT_MDI | MGMT_MDO);    //start code 01]  phy_info[ info++ ] = MGMT_MDOE ;  phy_info[ info++ ] = MGMT_MDOE | MGMT_MDO;//Read Command[10]  phy_info[ info++ ] = MGMT_MDOE | MGMT_MDO;  phy_info[ info++ ] = MGMT_MDOE;//PHY Addr[phyaddr]  for(mask = 0x10; mask>0; mask >>=1)     {       if (phyaddr & mask)           phy_info[ info++ ] = MGMT_MDOE | MGMT_MDO;       else           phy_info[ info++ ] = MGMT_MDOE;     }       //PHY REGISTER[phyreg]   for(mask = 0x10; mask>0; mask>>=1)     {       if (phyreg & mask)           phy_info[ info++ ] = MGMT_MDOE | MGMT_MDO;       else            phy_info[ info++ ] = MGMT_MDOE;     }   //Turnaround Time[00]   phy_info[ info++ ] = 0;  in_dex = info ;//REGISTER VALUE   for(i=0; i<16; i++)      phy_info[ info++ ] =0;//put PHY into IDLE modle   for(i=0; i<32; i++)    {      put_reg(LAN91C111_MGMT, mgmt_cur | MGMT_MDOE | MGMT_MDO );      delay(50);      put_reg(LAN91C111_MGMT, mgmt_cur | MGMT_MDOE | MGMT_MDO | MGMT_MCLK  );      delay(50);    }//input the management infomation first 16 bits   for(i=0; i<32; i++)    {       put_reg( LAN91C111_MGMT, mgmt_cur | phy_info[i]  );       delay(50);         put_reg( LAN91C111_MGMT, mgmt_cur | phy_info[i] | MGMT_MCLK );       delay(50);       phy_info[i] |= get_reg( LAN91C111_MGMT ) & MGMT_MDI ;     }//put the PHY into IDLE state   put_reg(LAN91C111_MGMT, mgmt_cur );   delay(50);//read the input value    for(value=0, i=0; i<16; ++i)    {      value <<=1;      if(phy_info[in_dex++] & MGMT_MDI)          value |= 1;    }   return value;}static voidlan91c111_write_phy(char phyaddr, char phyreg, unsigned short value ){  unsigned short phy_info[32], mgmt_cur=0;  int i=0, info=0, mask;  mgmt_cur = get_reg(LAN91C111_MGMT);  mgmt_cur &= ~(MGMT_MSK_CRS100 | MGMT_MDOE | MGMT_MCLK | MGMT_MDI | MGMT_MDO); //start bit[01]  phy_info[ info++ ] = MGMT_MDOE;  phy_info[ info++ ] = MGMT_MDOE | MGMT_MDO; //READ AND WRITE BIT[01]  phy_info[ info++ ] = MGMT_MDOE;  phy_info[ info++ ] = MGMT_MDOE | MGMT_MDO; //Add phy addr bits[phyaddr]  for(mask=0x10; mask>0; mask>>=1)     {       if (phyaddr & mask)           phy_info[ info++ ] = MGMT_MDOE | MGMT_MDO;       else           phy_info[ info++ ] = MGMT_MDOE;     } //Add phy register bits[phyreg]  for(mask=0x10; mask>0; mask>>=1)     {       if (phyreg & mask)           phy_info[ info++ ] = MGMT_MDOE | MGMT_MDO;       else           phy_info[ info++ ] = MGMT_MDOE;     } //Tristate and turnaround[00]   phy_info[ info++ ] = 0;   phy_info[ info++ ] = 0; //Add value into the 16bits[value]   for( mask=0x8000; mask>0; mask>>=1 )    {      if (value & mask)           phy_info[ info++ ] = MGMT_MDOE | MGMT_MDO;      else            phy_info[ info++ ] = MGMT_MDOE ;    } //put the phy into the idle state   for(i=0; i<32; i++)     { put_reg(LAN91C111_MGMT, mgmt_cur | MGMT_MDOE | MGMT_MDO );       delay( 50 );             put_reg(LAN91C111_MGMT, mgmt_cur | MGMT_MDOE | MGMT_MDO | MGMT_MCLK);       delay( 50 );      } //trans the management into      for(i=0; i<32; i++)     {        put_reg(LAN91C111_MGMT, phy_info[i] | mgmt_cur );        delay( 50 );           put_reg(LAN91C111_MGMT, phy_info[i] | mgmt_cur | MGMT_MCLK);        delay( 50 );     }     put_reg(LAN91C111_MGMT, mgmt_cur );     delay(50);}extern bool eth_init(void){	return lan91c111_init();}extern void eth_exit(void){	lan91c111_exit();	return;}extern bool eth_recv_poll(void){	return lan91c111_recv_packet();}extern bool eth_send(void *packet, int length){	return lan91c111_send_packet(packet, length);}extern void eth_enable(void){	lan91c111_enable();	return;}extern void eth_disable(void){	lan91c111_disable();	return;}extern void eth_set_haddr(const void *haddr){	const uint16 *mac = haddr;          put_reg(LAN91C111_IA01, *mac++ );        put_reg(LAN91C111_IA23, *mac++ );        put_reg(LAN91C111_IA45, *mac++ ); //       test_get_reg();    	return;}static void put_data(int value){   unsigned short * iobase = (unsigned short *)base;   selectbank(LAN91C111_DATA_HIGH);   *(iobase + ((LAN91C111_DATA_HIGH & 0xf)>>1)) = value;   }static unsigned int get_data_32(){  int val=0, offset;     unsigned short * iobase=(unsigned short *)base;  offset = ((LAN91C111_DATA_HIGH & 0xf)>>1);  val = *((unsigned int *)(iobase + offset ));  return val;}/*staticvoid test_ram_buffer() {    unsigned short val=0;    int j=0;//    unsigned short * iobase = (unsigned short *) base;//    unsigned int * iobase_32 = (unsigned int *)base;    put_reg(LAN91C111_MMU_COMMAND, 0x20);    while(!(get_reg(LAN91C111_INTERRUPT) & 0x08)){};       val = get_reg(LAN91C111_ARR);    put_reg(LAN91C111_PNR, (val & 0x3f));                 put_reg(LAN91C111_POINTER, 0x4000);     for(j=0; j<1024; j++)       {        //  put_reg(LAN91C111_POINTER, (0x0+j*2));       //   *(iobase + ((LAN91C111_DATA_HIGH & 0xf)>>1)) =  j*2;           put_data(j*2);       }    put_reg(LAN91C111_POINTER, 0x6000);    for(j=0; j<1024; j++)       {            //    put_reg(LAN91C111_POINTER, (0x2000+j*2));            val = get_data();         //   val = *(unsigned short *)(iobase + ((LAN91C111_DATA_HIGH & 0xf)>>1));          printf(" test ram buffer  0x%08x is 0x%08x\n" , j,  val);          if (val!= j*2) printf("i 0x%08x occour erro\n", j);        }}*//*void test_transmit(){   unsigned short val, i;      put_reg(LAN91C111_MMU_COMMAND, 0x0020 );      while(!(get_reg(LAN91C111_INTERRUPT) & 0x08 )){};   val = get_reg(LAN91C111_ARR);   put_reg(LAN91C111_PNR, (val & 0x3f));    put_reg(LAN91C111_POINTER, 0x4000);   //write_data    put_data(0x0000);    put_data(0x46);        put_data(0xffff);    put_data(0xffff);    put_data(0xffff);    put_data(0x0);    put_data(0x0);    put_data(0x0);    put_data(0x0040);    for(i=0; i<46; i++);      put_data(i);      put_data(0x0);

⌨️ 快捷键说明

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