int NetLoop(proto_t protocol)

/**********************************************************************/
/*
 *    Main network processing loop.
 */

int
NetLoop(proto_t protocol)
{
    bd_t *bd = gd->bd;

#ifdef CONFIG_NET_MULTI
    NetRestarted = 0;
    NetDevExists = 0;
#endif

    /* XXX problem with bss workaround */
    NetArpWaitPacketMAC = NULL;
    NetArpWaitTxPacket = NULL;
    NetArpWaitPacketIP = 0;
    NetArpWaitReplyIP = 0;
    NetArpWaitTxPacket = NULL;
    NetTxPacket = NULL;

    if (!NetTxPacket) {
        int    i;
        /*
         *    Setup packet buffers, aligned correctly.
         */
        NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
        NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;                                   //分配NetTxPacket
        for (i = 0; i < PKTBUFSRX; i++) {
            NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;                     //分配NetRxPackets[4]
        }
    }

    if (!NetArpWaitTxPacket) {
        NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
        NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;         //分配NetArpWaitTxPacket
        NetArpWaitTxPacketSize = 0;                                                                   //NetArpWaitTxPacketSize=0
    }

    eth_halt();                                           //网卡停止
#ifdef CONFIG_NET_MULTI
    eth_set_current();
#endif
    if (eth_init(bd) < 0) {                           //网卡硬件初始化
        eth_halt();
        return(-1);
    }

restart:
#ifdef CONFIG_NET_MULTI
    memcpy (NetOurEther, eth_get_dev()->enetaddr, 6);            //读取本机MAC地址
#else
    memcpy (NetOurEther, bd->bi_enetaddr, 6);
#endif

    NetState = NETLOOP_CONTINUE;                                          //设置网络状态为OK

    /*
     *    Start the ball rolling with the given start function.  From
     *    here on, this code is a state machine driven by received
     *    packets and timer events.
     */

    switch (protocol) {                                                                 //选择命令
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
    case NFS:
#endif
#if (CONFIG_COMMANDS & CFG_CMD_PING)                          //定义了的命令
    case PING:
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
    case SNTP:
#endif
    case NETCONS:
    case TFTP:
        NetCopyIP(&NetOurIP, &bd->bi_ip_addr);                          //读取本机ip地址
        NetOurGatewayIP = getenv_IPaddr ("gatewayip");          //读取本机网关地址
        NetOurSubnetMask= getenv_IPaddr ("netmask");             //读取本机掩码地址
        NetOurVLAN = getenv_VLAN("vlan");                              //读取虚拟网
        NetOurNativeVLAN = getenv_VLAN("nvlan");                  //读取虚拟网

        switch (protocol) {
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
        case NFS:
#endif
        case NETCONS:
        case TFTP:
            NetServerIP = getenv_IPaddr ("serverip");
            break;
#if (CONFIG_COMMANDS & CFG_CMD_PING)
        case PING:
            /* nothing */
            break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
        case SNTP:
            /* nothing */
            break;
#endif
        default:
            break;
        }

        break;
    case BOOTP:
    case RARP:
        /*
         * initialize our IP addr to 0 in order to accept ANY
         * IP addr assigned to us by the BOOTP / RARP server
         */
        NetOurIP = 0;
        NetServerIP = getenv_IPaddr ("serverip");
        NetOurVLAN = getenv_VLAN("vlan");    /* VLANs must be read */
        NetOurNativeVLAN = getenv_VLAN("nvlan");
    case CDP:
        NetOurVLAN = getenv_VLAN("vlan");    /* VLANs must be read */
        NetOurNativeVLAN = getenv_VLAN("nvlan");
        break;
    default:
        break;
    }

    switch (net_check_prereq (protocol)) {                  //检测命令格式,正确返回0
    case 1:
        /* network not configured */
        eth_halt();
        return (-1);

#ifdef CONFIG_NET_MULTI
    case 2:
        /* network device not configured */
        break;
#endif /* CONFIG_NET_MULTI */

    case 0:
#ifdef CONFIG_NET_MULTI
        NetDevExists = 1;
#endif
        switch (protocol) {
        case TFTP:
            /* always use ARP to get server ethernet address */
            TftpStart();
            break;

#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
        case DHCP:
            /* Start with a clean slate... */
            BootpTry = 0;
            NetOurIP = 0;
            NetServerIP = getenv_IPaddr ("serverip");
            DhcpRequest();        /* Basically same as BOOTP */
            break;
#endif /* CFG_CMD_DHCP */

        case BOOTP:
            BootpTry = 0;
            BootpRequest ();
            break;

        case RARP:
            RarpTry = 0;
            RarpRequest ();
            break;
#if (CONFIG_COMMANDS & CFG_CMD_PING)
        case PING:
             PingStart();
            break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
        case NFS:
            NfsStart();
            break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_CDP)
        case CDP:
            CDPStart();
            break;
#endif
#ifdef CONFIG_NETCONSOLE
        case NETCONS:
            NcStart();
            break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
        case SNTP:
            SntpStart();
            break;
#endif
        default:
            break;
        }

        NetBootFileXferSize = 0;              // 实际传输的启动文件的大小(以字节为单位)
        break;
    }

#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
#if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED)
    /*
     * Echo the inverted link state to the fault LED.
     */
    if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) {
        status_led_set (STATUS_LED_RED, STATUS_LED_OFF);
    } else {
        status_led_set (STATUS_LED_RED, STATUS_LED_ON);
    }
#endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */

    /*
     *    Main packet reception loop.  Loop receiving packets until
     *    someone sets `NetState' to a state that terminates.
     */
    for (;;) {
        WATCHDOG_RESET();
#ifdef CONFIG_SHOW_ACTIVITY
        {
            extern void show_activity(int arg);
            show_activity(1);
        }
#endif
        /*
         *    Check the ethernet for a new packet.  The ethernet
         *    receive routine will process it.
         */
            eth_rx();

        /*
         *    Abort if ctrl-c was pressed.
         */
        if (ctrlc()) {
            eth_halt();
            puts ("\nAbort\n");
            return (-1);
        }

        ArpTimeoutCheck();

        /*
         *    Check for a timeout, and run the timeout handler
         *    if we have one.
         */
        if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) {
            thand_f *x;

#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
#  if defined(CFG_FAULT_ECHO_LINK_DOWN) && \
      defined(CONFIG_STATUS_LED) &&       \
      defined(STATUS_LED_RED)
            /*
             * Echo the inverted link state to the fault LED.
             */
            if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) {
                status_led_set (STATUS_LED_RED, STATUS_LED_OFF);
            } else {
                status_led_set (STATUS_LED_RED, STATUS_LED_ON);
            }
#  endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */
            x = timeHandler;
            timeHandler = (thand_f *)0;
            (*x)();
        }


        switch (NetState) {

        case NETLOOP_RESTART:
#ifdef CONFIG_NET_MULTI
            NetRestarted = 1;
#endif
            goto restart;

        case NETLOOP_SUCCESS:
            if (NetBootFileXferSize > 0) {
                char buf[10];
                printf("Bytes transferred = %ld (%lx hex)\n",
                    NetBootFileXferSize,
                    NetBootFileXferSize);
                sprintf(buf, "%lx", NetBootFileXferSize);
                setenv("filesize", buf);

                sprintf(buf, "%lX", (unsigned long)load_addr);
                setenv("fileaddr", buf);
            }
            eth_halt();
            return NetBootFileXferSize;

        case NETLOOP_FAIL:
            return (-1);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值