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

📄 net.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 C
字号:
/***************************************** Copyright (c) 2002-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the boot loader *//* * net.c * * network layer  * * First revision by Ho Lee 11/06/2002 * New buffer management and interrupt driven networking by Ho Lee 03/18/2004 */#include "config.h"#include "util.h"#include "uart.h"#include "timer.h"#include "net.h"#include "net_ipv4.h"#include "bootconfig.h"#if 0#define DPRINTF(x...)       uart_printf(x)#else#define DPRINTF(x...)#endif// from ne2kpci.cextern int ne2kpci_probe(struct net_device *dev);// from rtl18xx.cextern int rtl81xx_probe(struct net_device *dev);// from em86xx_eth.cextern int em86xx_eth_probe(struct net_device *dev);//// ethernet buffer manipulation//#define ETHER_BUF_NUM           512static unsigned char *g_ether_buf;static volatile int *g_ether_bufstat;static volatile int g_ether_first_free;void ether_buf_init(void);unsigned char *ether_buf_alloc(int len);void ether_buf_free(unsigned char *buf, int len);void ether_buf_init(void){    g_ether_buf = (unsigned char *) malloc(ETHER_BUF_NUM * ETH_BUF_LEN);    g_ether_bufstat = (int *) malloc(ETHER_BUF_NUM * sizeof(int));    memset((void *)g_ether_bufstat, 0, ETHER_BUF_NUM * sizeof(int));    g_ether_first_free = 0;}unsigned char *ether_buf_alloc(int len){    int i;    i = g_ether_first_free;    do {        if (g_ether_bufstat[i] == 0) {            g_ether_bufstat[i] = 1;            g_ether_first_free = (i + 1) % ETHER_BUF_NUM;            return g_ether_buf + i * ETH_BUF_LEN;        }        if (++i == ETHER_BUF_NUM)            i = 0;    } while (i != g_ether_first_free);    return NULL;}void ether_buf_free(unsigned char *buf, int len){    int idx;    unsigned int offset = buf - g_ether_buf;    if ((offset % ETH_BUF_LEN) != 0) {        DPRINTF("Try to free invalid ethernet buffer pointer %p\n", buf);        return;    }        idx = offset / ETH_BUF_LEN;        if (g_ether_bufstat[idx] == 0) {        DPRINTF("Try to free unallocated ethernet buffer index %d\n", idx);        return;    }    g_ether_bufstat[idx] = 0;}//// socket buffer manipulation//#define SOCKET_BUF_MAX      512struct sk_buff *g_skb;static volatile int *g_skbstat;                             // socket buffer is allocatedstatic volatile int g_skb_first_free;                       // first unused socket bufferstatic volatile struct sk_buff *g_skb_head, *g_skb_tail;    // list of socket buffer with datastatic volatile int g_skb_time_begin, g_skb_time_end;       // timestampvoid skb_init(void);struct sk_buff *skb_alloc(int len);void skb_free(struct sk_buff *skb);struct sk_buff *skb_dup(struct sk_buff *skb);void skb_put(struct sk_buff *skb);struct sk_buff *skb_get(void);void skb_init(void){    g_skb = (struct sk_buff *) malloc(sizeof(struct sk_buff) * SOCKET_BUF_MAX);    memset(g_skb, 0, sizeof(struct sk_buff) * SOCKET_BUF_MAX);    g_skbstat = (int *) malloc(sizeof(int) * SOCKET_BUF_MAX);    memset((void *)g_skbstat, 0, sizeof(int) * SOCKET_BUF_MAX);    g_skb_first_free = 0;    g_skb_head = g_skb_tail = NULL;    g_skb_time_begin = g_skb_time_end = 0;}// allocate socket buffer from socket buffer pool, net\core\skbuff.cstruct sk_buff *skb_alloc(int len){    int i;    struct sk_buff *skb;try_alloc:    i = g_skb_first_free;    do {        if (g_skbstat[i] == 0) {            skb = g_skb + i;            if ((skb->data = ether_buf_alloc(len)) == NULL)                goto retry_alloc;            skb->data += 2;            g_skbstat[i] = 1;            g_skb_first_free = (i + 1) % SOCKET_BUF_MAX;            skb->len = len;            skb->buflen = len;            skb->valid = 0;            skb->owned = 0;            skb->next = NULL;            DPRINTF("skb alloc %d\n", i);            return skb;        }        if (++i == SOCKET_BUF_MAX)            i = 0;    } while (i != g_skb_first_free);retry_alloc:    // if the buffer is full, remove lastest sk_buff from buffer, and retry    if ((skb = skb_get()) == NULL) {        uart_puts("skb_alloc: No buffer available\n");#if 0        {            int i;            struct sk_buff *skb;                uart_printf("### Socket buffer status ###\n");                for (i = 0; i < SOCKET_BUF_MAX; ++i) {                skb = g_skb + i;                uart_printf("  %3d : %d %d %d",                    i, skb->valid, skb->owned, g_skbstat[i]);                if (skb->valid)                    uart_printf(" %p, %4d %4d %05d %3d", skb->data, skb->len, skb->buflen, skb->timestamp, skb->next == NULL ? -1 : skb->next - g_skb);                uart_puts("\n");            }        }#endif        return NULL;    } else        skb_free(skb);    goto try_alloc;}// free socket buffer void skb_free(struct sk_buff *skb){    int idx = skb - g_skb;    if (skb == NULL)        return;    if (g_skbstat[idx] == 0) {        DPRINTF("Try to free unallocated socket buffer index %d\n", idx);        return;    }    skb->data -= 2;    ether_buf_free(skb->data, skb->buflen);    skb->valid = 0;    skb->owned = 0;    g_skbstat[idx] = 0;    DPRINTF("skb free %d\n", idx);}struct sk_buff *skb_dup(struct sk_buff *skb){    struct sk_buff *new_skb = skb_alloc(skb->len);    if (new_skb)        memcpy(new_skb->data, skb->data, skb->len);    return new_skb;}// packet is ready. mark the packet is validvoid skb_put(struct sk_buff *skb){    if (skb == NULL)        return;    if (ipv4_check_for_me(skb)) {        if (net_defaultaction(skb) == 0) {            DPRINTF("skb put %d\n", skb - g_skb);            skb->valid = 1;            skb->next = NULL;            skb->timestamp = g_skb_time_end++;            if (g_skb_head == NULL) {                g_skb_head = g_skb_tail = skb;            } else {                g_skb_tail->next = skb;                g_skb_tail = skb;            }            return;        }    }    skb_free(skb);}// get next available packetstruct sk_buff *skb_get(void){    struct sk_buff *skb;    if (g_skb_head == NULL)        return NULL;    skb = (struct sk_buff *)g_skb_head;    skb->owned = 1;    g_skb_head = g_skb_head->next;    DPRINTF("skb get %d\n", skb - g_skb);    if (skb->timestamp != g_skb_time_begin)        DPRINTF("skb_get: unexpected timestamp %d (should be %d)\n", skb->timestamp, g_skb_time_begin);    ++g_skb_time_begin;        return skb;}struct sk_buff *skb_alloc_tx(int len){    return skb_alloc(len);}//// network device manipulation// static volatile int g_net_waitpacket = 0;static int net_inited = 0;struct net_device g_netdev;int net_init(void){    if (net_inited != 0)	goto network_inited;    ether_buf_init();    skb_init();    // initialize protocol stack    ipv4_init();    #ifdef CONFIG_ENABLE_NETWORK_NE2KPCI    if (ne2kpci_probe(&g_netdev)) 	goto network_inited;#endif#ifdef CONFIG_ENABLE_NETWORK_RTL81XX    if (rtl81xx_probe(&g_netdev)) 	goto network_inited;#endif#ifdef CONFIG_ENABLE_NETWORK_TANGO15    if (em86xx_eth_probe(&g_netdev)) 	goto network_inited;#endif    return 1;network_inited:    net_inited = 1;    return 0;}int net_found(void){    return (g_netdev.state);}int net_arp_setup(void){    ipv4_setup_arptable(g_bootconfig.ipaddr, g_bootconfig.netmask, g_netdev.dev_addr,        g_bootconfig.gateway, g_bootconfig.dns);    return 0;}int net_dev_up(void){    if ((g_netdev.state) && (g_netdev.state == NETDEV_UP)) 	uart_puts("Network is up already.\n");    else if ((g_netdev.state) && (g_netdev.state != NETDEV_UP)) {        // setup network before enable device        memcpy(g_netdev.dev_addr, g_bootconfig.macaddr, MACADDR_LEN);        // initialize device        g_netdev.open(&g_netdev);        // bring up the protocol stack        switch (g_bootconfig.protocol) {        case BOOTNET_STATIC :            if (!ipv4_ipaddr_valid(g_bootconfig.ipaddr)) {                uart_puts("Invalid static IP address.\n");            } else {                uart_puts("Bring up network with static IP address.\n");                net_arp_setup();            }            break;        case BOOTNET_BOOTP :        case BOOTNET_DHCP :            uart_printf("Bring up network with %s.\n", g_bootconfig.protocol == BOOTNET_BOOTP ? "BOOTP" : "DHCP");            arp_setaddr_index(ARP_CLIENT, INADDR_ANY, INADDR_ANY, g_netdev.dev_addr);            em86xx_msleep(500); // wait until network device gets stable            return ipv4_bootp(g_bootconfig.protocol == BOOTNET_BOOTP ? 1 : 0);        }        // setup after enable device        return 0;    }     return 1;}int net_dev_down(void){    if ((g_netdev.state) && (g_netdev.state == NETDEV_DOWN)) 	uart_puts("Network is down already.\n");    else if ((g_netdev.state) && (g_netdev.state == NETDEV_UP)) {        g_netdev.close(&g_netdev);        return 0;    }     return 1;}//// Network packet manipulation//// timeout : //   0 : no wait//   > 0 : wait until timeout//   < 0 : wait until get any packetstruct sk_buff *net_getpacket(int timeout){    struct sk_buff *skbuff = NULL;    unsigned int startticks = timer_getticks();    if (!g_netdev.state)        return NULL;    // if there is no packet in the buffer, check the device if any packet is ready    g_net_waitpacket = 1;    do {        if (!em86xx_irqenabled())            g_netdev.receive_packet(&g_netdev);        if ((skbuff = skb_get()) != NULL)            break;    } while (!timer_timeout(startticks, timeout));    g_net_waitpacket = 0;    return skbuff;}int net_sendpacket(struct sk_buff *skb, int async){    if (!g_netdev.state || !skb->valid)        return 1;    g_netdev.send_packet(skb, &g_netdev, async);    return 0;}// return //   -1 : ignore packet//   0 : packet is not processed (keep)//   1 : packet is processed (remove)int net_defaultaction(struct sk_buff *skb){    if (ipv4_parsepacket(skb) != 0)        return -1;    if (ipv4_processpacket(skb))        return 1;    return 0;}void net_device_status(void){    if (g_netdev.print_status)        g_netdev.print_status(&g_netdev);}

⌨️ 快捷键说明

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