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

📄 ethernet_cs8900a.c

📁 Intrisyc 公司的PXA255-bootloader,源码易懂
💻 C
📖 第 1 页 / 共 2 页
字号:
      return 0;   }   //if there are no errors, assume everything is ok   return 1;}////////////////////////////////////////////////////////////////////////////////// rx_packet_ethernet// PURPOSE: Receives a packet.// PARAMS:  (IN)  u8 * data  - buffer for received packet.//          (IN)  u16 * size - size of buffer.//          (OUT) u16 * size - actual size of received packet. If unchanged//                             packet may be truncated.// RETURNS: 1 for success, 0 for failure.////////////////////////////////////////////////////////////////////////////////intrx_packet_ethernet(u8 *data,                   u16 *size,                   char bcast_enable){   u16 rx_size = 1;   int i;   u16 oddword;   u16 temp;   //see if the chip has a packet waiting to be copied out   temp = readcs(RX_EVENT);   if((temp & RX_PACKET_RECEIVED_OK) == 0)   {      return 0;   }   rx_size = readcs(RX_LENGTH);   //tell the chip to automatically increment it's internal address register   //each time we read from it.   (*(volatile u16 *)(BASE_ADDR + ADDRESS_PORT)) = (RX_FRAME | AUTOINCREMENT);   //copy the packet out of the chips buffer   //if our destination address is u16 aligned, we can do 16 bit transfers   if((u32)data % sizeof(u16))   {      for(i = 0;i < (rx_size / sizeof(u16));i++)      {         oddword = *(volatile u16 *)(BASE_ADDR + DATA_PORT);         *(u8 *)data++ = (u8)oddword & 0xFF;         *(u8 *)data++ = (u8)(oddword >> 8) & 0xFF;      }   }   else   {      for(i = 0;i < (rx_size / 2);i++)      {         *(u16 *)data = *(volatile u16 *)(BASE_ADDR + DATA_PORT);         data += 2;      }   }   //If the rxed packet is of uneven size, we will need to get the last byte   if(rx_size % sizeof(u16))   {      *data = (u8)(*(volatile u16 *)(BASE_ADDR + DATA_PORT) & 0xFF);   }   //For some reason, the CS8900 reports the size as one dword larger than it   //actually is. Perhaps it is including the values of RX_EVENT and RX_LENGTH   //in the size.   *size = (int)rx_size - sizeof(u32);   return 1;}#if DEBUG_LEVEL >= 4////////////////////////////////////////////////////////////////////////////////// dump_eeprom// PURPOSE: Dumps the raw contents of the interesting portion of the EEPROM// PARAMS:  Nothing.// RETURNS: Nothing.////////////////////////////////////////////////////////////////////////////////static inline voiddump_eeprom(void){    int addr;    for (addr=0; addr < (EEPROM_ADDR_IA_W2+1); ++addr)    {        u16 data;        read_eeprom_ethernet(addr, &data);        itc_printf("%x: %x\r\n", addr, data);    }}#endif////////////////////////////////////////////////////////////////////////////////// read_mac_ethernet// PURPOSE: Reads the MAC address.// PARAMS:  (OUT) u16 * macaddr - An array to return the MAC address.// RETURNS: 1 for success, 0 for failure.////////////////////////////////////////////////////////////////////////////////intread_mac_ethernet(u16 *macaddr, unsigned short num){#if defined (TAGGED_EEPROM) && defined(CONFIG_EEPROM_24LC64)    u16 mac_size=sizeof(short) * 3;    char tag[7];    // Try to read the tagged format MAC address.     if (check_eeprom_header())    {	itc_strcpy(tag, "MACADx");	tag[5] = num + '0';	if (eeprom_get_item(tag, sizeof(tag)-1, (u8 *)macaddr, &mac_size) <= 0)	{	    DEBUG_3("Could not find EEPROM tag %s\r\n", tag);	    return 0;	}	return 1;    }    //no fallback!    return 0;#endif   if (num != 0)   {       // This driver supports only a single Ethernet chip       return 0;   }   if (!probe_cs8900a((char *)BASE_ADDR))   {       // We don't seem to have a CS8900 to read       return 0;   }#if DEBUG_LEVEL >= 4    dump_eeprom();#endif   // If the reset configuration block of the EEPROM was read correctly   // at reset time, then SSR_EEPROM_OK will be set.  Get the MAC address   // from the CS8900 Individual Address Register in that case.   if (readcs(SSR) & SSR_EEPROM_OK)   {       macaddr[0] = readcs(IAR+0);       macaddr[1] = readcs(IAR+2);       macaddr[2] = readcs(IAR+4);       DEBUG_4("Got MAC from chip\r\n");       return 1;   }   // The chip indicates that no reset configuration block was found.  This   // means either that the MAC address is not set on this device, or was set   // on an older version of I-Boot using our own nonstandard format.   DEBUG_4("Got MAC from EEPROM\r\n");   return (read_eeprom_ethernet(EEPROM_ADDR_IA_W0, &macaddr[0]) &&           read_eeprom_ethernet(EEPROM_ADDR_IA_W1, &macaddr[1]) &&           read_eeprom_ethernet(EEPROM_ADDR_IA_W2, &macaddr[2]));}////////////////////////////////////////////////////////////////////////////////// write_mac_ethernet// PURPOSE: Writes a new MAC address.// PARAMS:  (IN) u16 * macaddr - An array containing the new MAC address.// RETURNS: 1 for success, 0 for failure.////////////////////////////////////////////////////////////////////////////////intwrite_mac_ethernet(u16 *macaddr, unsigned short num){   // See section 3.4.4 in the data sheet for the meaning of this structure   static u16 data[]=   {      // Magic header      0xa10a,      // Block 1 (reg 0x158 (IAR), len 2+1)      (2 << 12) | IAR,      0x0000, /* MAC ADDR */      0x0000,      0x0000,   };   int result = 1;   u16 sum = 0;   int i;#if defined (TAGGED_EEPROM) && defined(CONFIG_EEPROM_24LC64)   u16 mac_size=sizeof(short) * 3;   char tag[7];   itc_strcpy(tag, "MACADx");   tag[5] = num + '0';   if (eeprom_write_item(tag, sizeof(tag)-1, (u8 *)macaddr, mac_size) < 0)   {       itc_printf("ERROR: Could not write to EEPROM\r\n");       return 0;   }   return 1;#endif   /* insert MAC ADDR into block 1 */   data[2] = macaddr[0];   data[3] = macaddr[1];   data[4] = macaddr[2];   /* write configuration block */   for(i=0; i < countof(data); i++)   {      sum += (data[i]&0xff) + (data[i]>>8);      result &= write_eeprom_ethernet(i, data[i]);   }   /* write the checksum */   result &= write_eeprom_ethernet(i, ((0x100 - (sum & 0xff)) & 0xff) << 8);   /*    * Write a copy of the MAC address here for backwards compatibility with    * old bootloaders.    * Note that this could overwrite data stored in tagged EEPROM format,    * but that will be caught by the CRC check.    */   result &= write_eeprom_ethernet(EEPROM_ADDR_IA_W0, macaddr[0]);   result &= write_eeprom_ethernet(EEPROM_ADDR_IA_W1, macaddr[1]);   result &= write_eeprom_ethernet(EEPROM_ADDR_IA_W2, macaddr[2]);   return result;}////////////////////////////////////////////////////////////////////////////////// read_eeprom_ethernet// PURPOSE: Reads from the attached EEPROM.// PARAMS:  (IN)  u16 offset  - Offset from which to read.// PARAMS:  (OUT) u16 * value - Value read.// RETURNS: 1 for success, 0 for failure.////////////////////////////////////////////////////////////////////////////////intread_eeprom_ethernet(u16 offset,                     u16 *value){   //wait for EEPROM to be free   notbusy();   writecs(ECR, (offset | EEPROM_READ_CMD));   //wait for it to finish   notbusy();   *value = readcs(EEPROM_DATA);   return 1;}////////////////////////////////////////////////////////////////////////////////// write_eeprom_ethernet// PURPOSE: Writes to the attached EEPROM.// PARAMS:  (IN) u16 offset - Offset from which to write.//          (IN) u16 value - Value to write.// RETURNS: 1 for success, 0 for failure.////////////////////////////////////////////////////////////////////////////////intwrite_eeprom_ethernet(u16 offset,                      u16 value){   //wait for EEPROM to be free   notbusy();   writecs(ECR, EEPROM_ERASE_ENABLE);   notbusy();   writecs(EEPROM_DATA, value);   notbusy();   writecs(ECR, (offset | EEPROM_WRITE_CMD));   notbusy();   writecs(ECR, EEPROM_ERASE_DISABLE);   notbusy();   return 1;}// Not strictly necessary on the Crystalint rx_ethernet_off (void){   return 1;}// Not strictly necessary on the Crystalint rx_ethernet_on (void){   return 1;}// Not strictly necessary on the Crystalint flush_ethernet (void){   return 1;}

⌨️ 快捷键说明

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