📄 eth.c
字号:
//-----------------------------------------------------------------------------
// Copyright (c) 2002 Jim Brady
// Do not use commercially without author's permission
// Last revised August 2002
// Net ETH.C
//
// This module is the Ethernet layer
//-----------------------------------------------------------------------------
#include <stdlib.h>
#include "net.h"
#include "serial.h"
#include "arp.h"
#include "ip.h"
#include "eth.h"
#include "utils.h"
#include "CP220x_ETH.h" // Include CP220x Ethernet Routines
//bit txd_buffer_select=0; //选择网卡的发送缓冲区
extern UCHAR debug;
extern UCHAR arpbuf[];
extern UCHAR my_hwaddr[];
void Delay1ms(unsigned char T);
extern UCHAR rcve_buf_allocated;
extern uint volatile event_word;
#define Rtl8019ResetLow P5 &= ~(0x4); // P52
#define Rtl8019ResetHigh P5 |= 0x4; // P52
//------------------------------------------------------------------------
// Initialize the Cirrus Logic 8019 chip
//------------------------------------------------------------------------
void ReadRtl8019NodeID(void)//读出网卡的物理地址存到my_ethernet_address.bytes[6]里
{
unsigned char i;
for (i=0;i<6;i++)
{
// my_hwaddr[i]=reg10;
// my_hwaddr[i]=reg10;
}
}
//------------------------------------------------------------------------
// This functions checks 8019 status then sends an ethernet
// frame to it by calling an assembler function.
//------------------------------------------------------------------------
void send_frame(UCHAR * outbuf, uint len)/*发送一个数据包的命令,长度最小为60字节,最大1514字节*/
{
CP220x_SendD(outbuf, len);
// s3c44b0_eth_send(outbuf, len);
// printf("send packet\n");
}
//------------------------------------------------------------------------
// This functions checks the 8019 receive event status
// word to see if an ethernet frame has arrived. If so,
// set EVENT_ETH_ARRIVED bit in global event_word
//------------------------------------------------------------------------
void query_8019(void)
{
}
//------------------------------------------------------------------------
// This function gets an incoming Ethernet frame from the 8019.
// There may be more than 1 waiting but just allocate memory for
// one and read one in. Use the 8019 to queue incoming packets.
//------------------------------------------------------------------------
UCHAR * rcve_frame()//如果收到一个有效的数据包,返回收到的数据,否则返回NULL
{
// UCHAR bnry,curr,next_page;
//
// uint len, ii;
// UCHAR temp;
// UCHAR * buf;
// if (buf_head!= buf_tail)
return NULL;
}
void eth_send(UCHAR * outbuf, UCHAR * hwaddr, uint ptype, uint len)
{
ETH_HEADER * eth;
eth = (ETH_HEADER *)outbuf;
// Add 14 byte Ethernet header]
//Ethernet V2标准:14 = 目的MAC地址6 byte + 源MAC地址6 byte + 类型(2) = 14, 不包括LLC层
//现不支持: 802.3标准. MAC数据报文最小长度46 - 1500字节。小于46, 填充0;
memcpy((char*)eth->dest_hwaddr, hwaddr, 6); //目的MAC地址6 byte
memcpy((char*)eth->source_hwaddr, my_hwaddr, 6); //源MAC地址6 byte
eth->frame_type = ptype; //类型2 byte. 比如0x0800, 表示上层使用IP数据包. =0x8137, 表示为Novell IPX发过来。
#ifdef __LITTLEENDIAN__
eth->frame_type = ntohs(eth->frame_type);
#endif
// We just added 14 bytes to length
send_frame(outbuf, len + 14);
}
//------------------------------------------------------------------------
// This is the handler for incoming Ethernet frames
// This is designed to handle standard Ethernet (RFC 893) frames
// See "TCP/IP Illustrated, Volume 1" Sect 2.2
//------------------------------------------------------------------------
void eth_rcve(uint Length, UCHAR* inbuf)
{
ETH_HEADER * eth;
eth = (ETH_HEADER *)inbuf;
#ifdef __LITTLEENDIAN__
eth->frame_type = ntohs(eth->frame_type);
#endif
// Reject frames in IEEE 802 format where Eth type field
// is used for length. Todo: Make it handle this format
if (eth->frame_type < 1520)
{
return;
}
//printf("frame_type %x", eth->frame_type);
// Figure out what type of frame it is from Eth header
// Call appropriate handler and supply address of buffer
switch (eth->frame_type)
{
case ARP_PACKET:
arp_rcve(inbuf);
break;
case IP_PACKET:
#ifdef __LITTLEENDIAN__
eth->frame_type = ntohs(eth->frame_type);
#endif
ip_rcve(inbuf);
break;
default:
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -