// ------------------------------------------------------------------------- // ethernet.c // // 21.12.2003, J. Ahrensfeld // // ------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include "emac.h" #include "ethernet.h" // ------------------------------------------------------------------------- uint32_t eth_crc32(uint32_t crc, uint8_t *pData, uint32_t len) { uint32_t n; uint32_t crc_table[] = { 0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0, 0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320, 0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190, 0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 }; for (n=0; n < len; n++) { crc = (crc >> 4) ^ crc_table[(crc ^ (pData[n] >> 0)) & 0x0F]; /* lower nibble */ crc = (crc >> 4) ^ crc_table[(crc ^ (pData[n] >> 4)) & 0x0F]; /* upper nibble */ } return crc; } // ------------------------------------------------------------------------- void EthInit(void) { } uint8_t *Eth_pkt_create(packet_t *pPacket, uint16_t proto, uint8_t *pHwAddr_src, uint8_t *pHwAddr_dst) { eth_hdr_t *pEth_hdr; pPacket->pData = pPacket->pkt_buf; pEth_hdr = (eth_hdr_t*)pPacket->pData; memcpy(pEth_hdr->eth_addr_src, pHwAddr_src, 6); memcpy(pEth_hdr->eth_addr_dst, pHwAddr_dst, 6); pEth_hdr->proto = proto; pPacket->size = sizeof(eth_hdr_t); pPacket->pData += pPacket->size; return pPacket->pData; } uint8_t *Eth_pkt_append(packet_t *pPacket, uint32_t size) { pPacket->size += size; pPacket->pData += size; return pPacket->pData; } uint8_t *Eth_pkt_buffer_get(packet_t *pPacket) { return pPacket->pData; } uint32_t Eth_pkt_send(packet_t *pPacket) { volatile uint32_t *pEmac_ctrl = (uint32_t*)SYS_EMAC_TX_CTRL; volatile uint32_t *pEmac_size = (uint32_t*)SYS_EMAC_TX_SIZE; volatile uint32_t *pEmac_data = (uint32_t*)SYS_EMAC_DATA; uint32_t *pData = (uint32_t*)pPacket->pkt_buf; uint32_t i, num_words, num_bytes; num_bytes = pPacket->size; do { EMAC_TX_alloc(num_bytes); } while(!EMAC_TX_is_avail()); num_words = num_bytes >> 2; if (num_bytes & 3) num_words++; while(num_words >= 8) { *pEmac_data = pData[i+0]; *pEmac_data = pData[i+1]; *pEmac_data = pData[i+2]; *pEmac_data = pData[i+3]; *pEmac_data = pData[i+4]; *pEmac_data = pData[i+5]; *pEmac_data = pData[i+6]; *pEmac_data = pData[i+7]; i += 8; num_words -= 8; } for (i=0; i < num_words; i++) { *pEmac_data = pData[i]; } EMAC_TX_commit(); return num_bytes; } uint32_t Eth_pkt_recv(uint8_t *pData) { volatile uint32_t *pEmac_ctrl = (uint32_t*)SYS_EMAC_RX_CTRL; volatile uint32_t *pEmac_size = (uint32_t*)SYS_EMAC_RX_SIZE; volatile uint32_t *pEmac_data = (uint32_t*)SYS_EMAC_DATA; uint32_t i, num_words, num_bytes; if(EMAC_RX_is_avail()) { if (EMAC_RX_is_valid()) { // if ((*pEmac_ctrl & EMAC_RX_STAT_PKT_BCAST)) // { // printf("Packet broad cast!\n"); // } num_bytes = EMAC_RX_get_size(); num_words = num_bytes >> 2; if (num_bytes & 3) num_words++; EMAC_RX_request(); for (i=0; i < num_words; i++) { ((uint32_t*)pData)[i] = *pEmac_data; } EMAC_RX_free(); } } return num_bytes; } uint16_t htons(uint16_t a) { return HTONS(a); }