int NetLoop(proto_t protocol)

來源:互聯網
上載者:User

/**********************************************************************/
/*
 *    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);
        }
    }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.