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

📄 mac.c

📁 此文档为采用FPGA实现的以太网MAC层
💻 C
字号:
#include "mac.h"#include "mac_low.h"#include "serial.h"#include "sys.h"#include "ip.h"IP_SETTINGS ipsettings;Uint16 data_buffer[100];extern ARP_TABLE arptable;void arp_process(ARPFRAME * frame);Uint32 rxcounter;Uint32 txcounter;Uint8 flags[RXBDCOUNT];Uint8 rxbdindex;Uint8 rxbdindex_rd;Uint8 txbdindex;//----------------------------------------////// RX Processing////----------------------------------------//void mac_process(Uint8 bdindex){     ETHHEADER *eth_header;     ARPFRAME *arp_frame;     IPHEADER *ip_header;    Uint8 x;    Uint16 *tmpptr,tmpint;    Uint32 tmpword;    //Set eth_header pointer to RAM address    tmpword = mac_getbdaddr(bdindex);    eth_header = (ETHHEADER *) (tmpword);    tmpword += ETH_SIZE;    arp_frame = (ARPFRAME *) tmpword;    ip_header = (IPHEADER *) tmpword;    //eth_header = (ETHHEADER *) EMAC_RX_PTR;    //dbg(0xffff);    //Check if ARP    if (eth_header->type == ARP_TYPE)    {        //Set ARP Frame pointer        //arp_frame = (ARPFRAME *)(EMAC_RX_PTR + ARP_OFFSET);        //Send for processing        arp_process(arp_frame);    }    else if (eth_header->type == IP_TYPE)    {        //Grab IPV4 frame        //mac_read(IP_SIZE/2,(Uint16 *)&ip_header);        //ip_header = (IPHEADER *)(EMAC_RX_PTR + ETH_SIZE);        //ip_header = (IPHEADER *) ((&(*eth_header)) + ETH_SIZE);        ip_process(ip_header, eth_header);    }}//ARP Processing called from ISRvoid arp_process(ARPFRAME * packet){    //Check if requested IP is the same as our own    if ((packet->targetip_h == ipsettings.ip_address_h) && (packet->targetip_l == ipsettings.ip_address_l))    {        //dbg(arp_frame->senderip_h);        //Add MAC to arptable if not already there        if (arptable_match(packet->senderip_h, packet->senderip_l) == 0xff)        {            arptable_add(packet->senderip_h, packet->senderip_l, packet->senderhardware);        }        arp_handler(packet);        //Set Flags        //flags |= ARP_RDY;    }}//*******************************************************************//// TX Processing////*******************************************************************void mac_send(Uint16 mac_index, Uint16 msgtype, Uint16 len){    ETHHEADER * eth_header;    BD_TYPE   * bdptr;    Uint8       x;    Uint32      word;    txcounter++;    //Set eth_header pointer to point to start of TX Buffer    eth_header = (ETHHEADER *) EMAC_TX_PTR;    //Set source mac address and dest mac address    if (mac_index == 0xfe)    {    for (x = 0; x < 6; x++)    {        eth_header->destmac[x] = 0xff;        eth_header->sourcemac[x] = ipsettings.mac_address[x];    }    }    else    {    for (x = 0; x < 6; x++)    {        eth_header->destmac[x] = arptable.entry[mac_index].mac_address[x];        eth_header->sourcemac[x] = ipsettings.mac_address[x];    }    }    eth_header->type = msgtype;    //Length should be modified to account for ETh_HEADER    mac_set_len(0,len + (ETH_SIZE / 2));    //Set register bits in BD    //Set TX ready bit to on and WR, no interrupt generation    bdptr = EMAC_TXBD_PTR;    //Check if buffer is ready    while (bdptr->reg & 0x8000);    bdptr->buffer_address = EMAC_TX_OFFSET;    bdptr->reg |= 0xA000;    mac_txen();    //Buffer has been marked as ready, should be sent out now}//ARP handler to see if response is requested - expects that valid data exists in framevoid arp_handler(ARPFRAME *packet){    Uint8      x;    ARPFRAME * srcarp_frame;    //packet = (ARPFRAME *)(EMAC_RX_PTR + ARP_OFFSET);    //packet = (ARPFRAME *) (mac_getbdaddr(rxbdindex_rd));    //packet += ARP_OFFSET;    //Setup ARP frame to point to RAM    srcarp_frame = (ARPFRAME *)(EMAC_TX_PTR + ARP_OFFSET);    srcarp_frame->operation = 0x2;    for (x = 0; x < 6; x++)    {        srcarp_frame->targethardware[x] = packet->senderhardware[x];    }    srcarp_frame->targetip_h = packet->senderip_h;    srcarp_frame->targetip_l = packet->senderip_l;    //Fill in src arp frame    srcarp_frame->hardware = 1;    srcarp_frame->hardwarelength = 6;    srcarp_frame->protocol = 0x800;    srcarp_frame->protocollength = 4;    for (x = 0; x < 6; x++)    {        srcarp_frame->senderhardware[x] = ipsettings.mac_address[x];    }    srcarp_frame->senderip_h = ipsettings.ip_address_h;    srcarp_frame->senderip_l = ipsettings.ip_address_l;    //Set length    //mac_set_len((ETH_SIZE+ARP_SIZE)/2);    //Send packet    mac_send(arptable_match(srcarp_frame->targetip_h, srcarp_frame->targetip_l), ARP_TYPE, ARP_SIZE / 2);}//*******************************************************************//// Utility functions////*******************************************************************void mac_init(void){    Uint8 x;    rxbdindex = rxbdindex_rd = txbdindex = 0;    //Set flags to zero    for (x=0;x<RXBDCOUNT;x++)        flags[x]=0;    //Fill in ip-settings    //ipsettings.ip_address = 0xc0a8016e;    //IP Address 192.168.1.110    //ipsettings.ip_address_h = 0xc0a8;    //ipsettings.ip_address_l = 0x016e;    ipsettings.mac_address[0] = 0x00;    ipsettings.mac_address[1] = 0x20;    ipsettings.mac_address[2] = 0x30;    ipsettings.mac_address[3] = 0x40;    ipsettings.mac_address[4] = 0x50;    ipsettings.mac_address[5] = 0x60;    mac_low_init();    mac_set_address(ipsettings.mac_address);    //Enble interrupts    //mac_reg_write(EMAC_IE,0x2);    //EMAC_IE = 0x2;    ip_init();    //Unmask interrupt    mac_rxint_en();    //Enable receiver    mac_rxen();    //Enable transmitter    //mac_txen();    txcounter = rxcounter = 0;}//////////////////////////////////////////////////

⌨️ 快捷键说明

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