void net_set_arp_handler(rxhand_f *f) { debug_cond(DEBUG_INT_STATE, "--- NetLoop ARP handler set (%p)\n", f); if (f == NULL) arp_packet_handler = dummy_handler; else arp_packet_handler = f; }
void net_set_udp_handler(rxhand_f *f) { debug_cond(DEBUG_INT_STATE, "--- net_loop UDP handler set (%p)\n", f); if (f == NULL) udp_packet_handler = dummy_handler; else udp_packet_handler = f; }
static void at91emac_halt(struct eth_device *netdev) { at91_emac_t *emac; emac = (at91_emac_t *) netdev->iobase; writel(readl(&emac->ctl) & ~(AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE), &emac->ctl); debug_cond(DEBUG_AT91EMAC, "halt MAC\n"); }
static int setdma_tx(struct dwc2_ep *ep, struct dwc2_request *req) { u32 *buf, ctrl = 0; u32 length, pktcnt; u32 ep_num = ep_index(ep); buf = req->req.buf + req->req.actual; length = req->req.length - req->req.actual; if (ep_num == EP0_CON) length = min(length, (u32)ep_maxpacket(ep)); ep->len = length; ep->dma_buf = buf; flush_dcache_range((unsigned long) ep->dma_buf, (unsigned long) ep->dma_buf + ROUND(ep->len, CONFIG_SYS_CACHELINE_SIZE)); if (length == 0) pktcnt = 1; else pktcnt = (length - 1)/(ep->ep.maxpacket) + 1; /* Flush the endpoint's Tx FIFO */ writel(TX_FIFO_NUMBER(ep->fifo_num), ®->grstctl); writel(TX_FIFO_NUMBER(ep->fifo_num) | TX_FIFO_FLUSH, ®->grstctl); while (readl(®->grstctl) & TX_FIFO_FLUSH) ; writel((unsigned long) ep->dma_buf, ®->in_endp[ep_num].diepdma); writel(DIEPT_SIZ_PKT_CNT(pktcnt) | DIEPT_SIZ_XFER_SIZE(length), ®->in_endp[ep_num].dieptsiz); ctrl = readl(®->in_endp[ep_num].diepctl); /* Write the FIFO number to be used for this endpoint */ ctrl &= DIEPCTL_TX_FIFO_NUM_MASK; ctrl |= DIEPCTL_TX_FIFO_NUM(ep->fifo_num); /* Clear reserved (Next EP) bits */ ctrl = (ctrl&~(EP_MASK<<DEPCTL_NEXT_EP_BIT)); writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, ®->in_endp[ep_num].diepctl); debug_cond(DEBUG_IN_EP, "%s:EP%d TX DMA start : DIEPDMA0 = 0x%x," "DIEPTSIZ0 = 0x%x, DIEPCTL0 = 0x%x\n" "\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n", __func__, ep_num, readl(®->in_endp[ep_num].diepdma), readl(®->in_endp[ep_num].dieptsiz), readl(®->in_endp[ep_num].diepctl), buf, pktcnt, length); return length; }
static int at91emac_write_hwaddr(struct eth_device *netdev) { at91_emac_t *emac; at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; emac = (at91_emac_t *) netdev->iobase; writel(1 << ATMEL_ID_EMAC, &pmc->pcer); debug_cond(DEBUG_AT91EMAC, "init MAC-ADDR %02x:%02x:%02x:%02x:%02x:%02x\n", netdev->enetaddr[5], netdev->enetaddr[4], netdev->enetaddr[3], netdev->enetaddr[2], netdev->enetaddr[1], netdev->enetaddr[0]); writel( (netdev->enetaddr[0] | netdev->enetaddr[1] << 8 | netdev->enetaddr[2] << 16 | netdev->enetaddr[3] << 24), &emac->sa2l); writel((netdev->enetaddr[4] | netdev->enetaddr[5] << 8), &emac->sa2h); debug_cond(DEBUG_AT91EMAC, "init MAC-ADDR %x%x\n", readl(&emac->sa2h), readl(&emac->sa2l)); return 0; }
int f_cloner_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct cloner *cloner = func_to_cloner(f); debug_cond(BURNNER_DEBUG,"f_cloner_bind\n"); intf_desc.bInterfaceNumber = usb_interface_id(c, f); if(intf_desc.bInterfaceNumber < 0 ) return intf_desc.bInterfaceNumber; cloner->ep0 = cdev->gadget->ep0; cloner->ep0req = cdev->req; cloner->gadget = cdev->gadget; cloner->ack = 0; cloner->cdev = cdev; cloner->cmd = (union cmd *)cloner->ep0req->buf; if (gadget_is_dualspeed(cdev->gadget)) { hs_bulk_in_desc.bEndpointAddress = fs_bulk_in_desc.bEndpointAddress; hs_bulk_out_desc.bEndpointAddress = fs_bulk_out_desc.bEndpointAddress; } cdev->req->context = cloner; cloner->ep_in = usb_ep_autoconfig(cdev->gadget, &fs_bulk_in_desc); cloner->ep_out = usb_ep_autoconfig(cdev->gadget, &fs_bulk_out_desc); cloner->write_req = usb_ep_alloc_request(cloner->ep_out,0); cloner->args_req = usb_ep_alloc_request(cloner->ep_out,0); cloner->read_req = usb_ep_alloc_request(cloner->ep_in,0); cloner->buf_size = 1024*1024; cloner->buf = malloc(1024*1024); cloner->write_req->complete = handle_write; cloner->write_req->buf = cloner->buf; cloner->write_req->length = 1024*1024; cloner->write_req->context = cloner; cloner->args_req->complete = handle_write; cloner->args_req->buf = cloner->args; cloner->args_req->length = ARGS_LEN; cloner->args_req->context = cloner; cloner->read_req->complete = handle_read_complete; cloner->read_req->buf = cloner->buf; cloner->read_req->length = 1024*1024; cloner->read_req->context = cloner; return 0; }
static void nc_send_packet(const char *buf, int len) { #ifdef CONFIG_DM_ETH struct udevice *eth; #else struct eth_device *eth; #endif int inited = 0; uchar *pkt; uchar *ether; struct in_addr ip; debug_cond(DEBUG_DEV_PKT, "output: \"%*.*s\"\n", len, len, buf); eth = eth_get_dev(); if (eth == NULL) return; if (!memcmp(nc_ether, net_null_ethaddr, 6)) { if (eth_is_active(eth)) return; /* inside net loop */ output_packet = buf; output_packet_len = len; input_recursion = 1; net_loop(NETCONS); /* wait for arp reply and send packet */ input_recursion = 0; output_packet_len = 0; return; } if (!eth_is_active(eth)) { if (eth_is_on_demand_init()) { if (eth_init() < 0) return; eth_set_last_protocol(NETCONS); } else { eth_init_state_only(); } inited = 1; } pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE; memcpy(pkt, buf, len); ether = nc_ether; ip = nc_ip; net_send_udp_packet(ether, ip, nc_out_port, nc_in_port, len); if (inited) { if (eth_is_on_demand_init()) eth_halt(); else eth_halt_state_only(); } }
static void dwc2_udc_pre_setup(void) { u32 ep_ctrl; debug_cond(DEBUG_IN_EP, "%s : Prepare Setup packets.\n", __func__); writel(DOEPT_SIZ_PKT_CNT(1) | sizeof(struct usb_ctrlrequest), ®->out_endp[EP0_CON].doeptsiz); writel(usb_ctrl_dma_addr, ®->out_endp[EP0_CON].doepdma); ep_ctrl = readl(®->out_endp[EP0_CON].doepctl); writel(ep_ctrl|DEPCTL_EPENA, ®->out_endp[EP0_CON].doepctl); debug_cond(DEBUG_EP0 != 0, "%s:EP0 ZLP DIEPCTL0 = 0x%x\n", __func__, readl(®->in_endp[EP0_CON].diepctl)); debug_cond(DEBUG_EP0 != 0, "%s:EP0 ZLP DOEPCTL0 = 0x%x\n", __func__, readl(®->out_endp[EP0_CON].doepctl)); }
int altera_load(Altera_desc *desc, const void *buf, size_t bsize) { const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); if (!fpga) return FPGA_FAIL; debug_cond(FPGA_DEBUG, "%s: Launching the %s Loader...\n", __func__, fpga->name); if (fpga->load) return fpga->load(desc, buf, bsize); return 0; }
int at91emac_write(at91_emac_t *at91mac, unsigned char addr, unsigned char reg, unsigned short value) { unsigned long netstat; debug_cond(DEBUG_AT91PHY, "AT91PHY write %p REG(%d)=%p\n", at91mac, reg, &value); at91emac_EnableMDIO(at91mac); writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_W | AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 | AT91_EMAC_MAN_PHYA(addr) | (value & AT91_EMAC_MAN_DATA_MASK), &at91mac->man); do { netstat = readl(&at91mac->sr); debug_cond(DEBUG_AT91PHY, "poll SR %08lx\n", netstat); } while (!(netstat & AT91_EMAC_SR_IDLE)); at91emac_DisableMDIO(at91mac); return 0; }
void s3c_udc_pre_setup(void) { u32 ep_ctrl; debug_cond(DEBUG_IN_EP, "%s : Prepare Setup packets.\n", __func__); invalidate_dcache_range((unsigned long) usb_ctrl_dma_addr, (unsigned long) usb_ctrl_dma_addr + DMA_BUFFER_SIZE); writel(DOEPT_SIZ_PKT_CNT(1) | sizeof(struct usb_ctrlrequest), ®->out_endp[EP0_CON].doeptsiz); writel(usb_ctrl_dma_addr, ®->out_endp[EP0_CON].doepdma); ep_ctrl = readl(®->out_endp[EP0_CON].doepctl); writel(ep_ctrl|DEPCTL_EPENA, ®->out_endp[EP0_CON].doepctl); debug_cond(DEBUG_EP0 != 0, "%s:EP0 ZLP DIEPCTL0 = 0x%x\n", __func__, readl(®->in_endp[EP0_CON].diepctl)); debug_cond(DEBUG_EP0 != 0, "%s:EP0 ZLP DOEPCTL0 = 0x%x\n", __func__, readl(®->out_endp[EP0_CON].doepctl)); }
static inline void dwc2_udc_ep0_zlp(struct dwc2_udc *dev) { u32 ep_ctrl; writel(usb_ctrl_dma_addr, ®->in_endp[EP0_CON].diepdma); writel(DIEPT_SIZ_PKT_CNT(1), ®->in_endp[EP0_CON].dieptsiz); ep_ctrl = readl(®->in_endp[EP0_CON].diepctl); writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK, ®->in_endp[EP0_CON].diepctl); debug_cond(DEBUG_EP0 != 0, "%s:EP0 ZLP DIEPCTL0 = 0x%x\n", __func__, readl(®->in_endp[EP0_CON].diepctl)); dev->ep0state = WAIT_FOR_IN_COMPLETE; }
int jz_cloner_add(struct usb_configuration *c) { int id; id = usb_string_id(c->cdev); if (id < 0) return id; burner_intf_string_defs[0].id = id; intf_desc.iInterface = id; debug_cond(BURNNER_DEBUG,"%s: cdev: 0x%p gadget:0x%p gadget->ep0: 0x%p\n", __func__, c->cdev, c->cdev->gadget, c->cdev->gadget->ep0); return cloner_function_bind_config(c); }
static int at91emac_send(struct eth_device *netdev, void *packet, int length) { at91_emac_t *emac; emac = (at91_emac_t *) netdev->iobase; while (!(readl(&emac->tsr) & AT91_EMAC_TSR_BNQ)) ; writel((u32) packet, &emac->tar); writel(AT91_EMAC_TCR_LEN(length), &emac->tcr); while (AT91_EMAC_TCR_LEN(readl(&emac->tcr))) ; debug_cond(DEBUG_AT91EMAC, "Send %d\n", length); writel(readl(&emac->tsr) | AT91_EMAC_TSR_COMP, &emac->tsr); return 0; }
static void configure_wait(void) { if (timeout_ms == -1) return; /* poll, being ready to adjust current timeout */ if (!timeout_ms) timeout_ms = random_delay_ms(PROBE_WAIT); /* set deadline_ms to the point in time when we timeout */ deadline_ms = MONOTONIC_MS() + timeout_ms; debug_cond(DEBUG_DEV_PKT, "...wait %d %s nprobes=%u, nclaims=%u\n", timeout_ms, eth_get_name(), nprobes, nclaims); NetSetTimeout(timeout_ms, link_local_timeout); }
static inline void s3c_udc_ep0_zlp(struct s3c_udc *dev) { u32 ep_ctrl; flush_dcache_range((unsigned long) usb_ctrl_dma_addr, (unsigned long) usb_ctrl_dma_addr + DMA_BUFFER_SIZE); writel(usb_ctrl_dma_addr, ®->in_endp[EP0_CON].diepdma); writel(DIEPT_SIZ_PKT_CNT(1), ®->in_endp[EP0_CON].dieptsiz); ep_ctrl = readl(®->in_endp[EP0_CON].diepctl); writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK, ®->in_endp[EP0_CON].diepctl); debug_cond(DEBUG_EP0 != 0, "%s:EP0 ZLP DIEPCTL0 = 0x%x\n", __func__, readl(®->in_endp[EP0_CON].diepctl)); dev->ep0state = WAIT_FOR_IN_COMPLETE; }
static int setdma_rx(struct s3c_ep *ep, struct s3c_request *req) { u32 *buf, ctrl; u32 length, pktcnt; u32 ep_num = ep_index(ep); buf = req->req.buf + req->req.actual; length = min(req->req.length - req->req.actual, (int)ep->ep.maxpacket); ep->len = length; ep->dma_buf = buf; invalidate_dcache_range((unsigned long) ep->dev->dma_buf[ep_num], (unsigned long) ep->dev->dma_buf[ep_num] + DMA_BUFFER_SIZE); if (length == 0) pktcnt = 1; else pktcnt = (length - 1)/(ep->ep.maxpacket) + 1; pktcnt = 1; ctrl = readl(®->out_endp[ep_num].doepctl); writel(the_controller->dma_addr[ep_index(ep)+1], ®->out_endp[ep_num].doepdma); writel(DOEPT_SIZ_PKT_CNT(pktcnt) | DOEPT_SIZ_XFER_SIZE(length), ®->out_endp[ep_num].doeptsiz); writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, ®->out_endp[ep_num].doepctl); debug_cond(DEBUG_OUT_EP != 0, "%s: EP%d RX DMA start : DOEPDMA = 0x%x," "DOEPTSIZ = 0x%x, DOEPCTL = 0x%x\n" "\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n", __func__, ep_num, readl(®->out_endp[ep_num].doepdma), readl(®->out_endp[ep_num].doeptsiz), readl(®->out_endp[ep_num].doepctl), buf, pktcnt, length); return 0; }
static int setdma_rx(struct dwc2_ep *ep, struct dwc2_request *req) { u32 *buf, ctrl; u32 length, pktcnt; u32 ep_num = ep_index(ep); buf = req->req.buf + req->req.actual; length = min_t(u32, req->req.length - req->req.actual, ep_num ? DMA_BUFFER_SIZE : ep->ep.maxpacket); ep->len = length; ep->dma_buf = buf; if (ep_num == EP0_CON || length == 0) pktcnt = 1; else pktcnt = (length - 1)/(ep->ep.maxpacket) + 1; ctrl = readl(®->out_endp[ep_num].doepctl); invalidate_dcache_range((unsigned long) ep->dma_buf, (unsigned long) ep->dma_buf + ROUND(ep->len, CONFIG_SYS_CACHELINE_SIZE)); writel((unsigned long) ep->dma_buf, ®->out_endp[ep_num].doepdma); writel(DOEPT_SIZ_PKT_CNT(pktcnt) | DOEPT_SIZ_XFER_SIZE(length), ®->out_endp[ep_num].doeptsiz); writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, ®->out_endp[ep_num].doepctl); debug_cond(DEBUG_OUT_EP != 0, "%s: EP%d RX DMA start : DOEPDMA = 0x%x," "DOEPTSIZ = 0x%x, DOEPCTL = 0x%x\n" "\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n", __func__, ep_num, readl(®->out_endp[ep_num].doepdma), readl(®->out_endp[ep_num].doeptsiz), readl(®->out_endp[ep_num].doepctl), buf, pktcnt, length); return 0; }
static int at91emac_recv(struct eth_device *netdev) { emac_device *dev; at91_emac_t *emac; rbf_t *rbfp; int size; emac = (at91_emac_t *) netdev->iobase; dev = (emac_device *) netdev->priv; rbfp = &dev->rbfdt[dev->rbindex]; while (rbfp->addr & RBF_OWNER) { size = rbfp->size & RBF_SIZE; NetReceive(NetRxPackets[dev->rbindex], size); debug_cond(DEBUG_AT91EMAC, "Recv[%ld]: %d bytes @ %lx\n", dev->rbindex, size, rbfp->addr); rbfp->addr &= ~RBF_OWNER; rbfp->size = 0; if (dev->rbindex < (RBF_FRAMEMAX-1)) dev->rbindex++; else dev->rbindex = 0; rbfp = &(dev->rbfdt[dev->rbindex]); if (!(rbfp->addr & RBF_OWNER)) writel(readl(&emac->rsr) | AT91_EMAC_RSR_REC, &emac->rsr); } if (readl(&emac->isr) & AT91_EMAC_IxR_RBNA) { /* EMAC silicon bug 41.3.1 workaround 1 */ writel(readl(&emac->ctl) & ~AT91_EMAC_CTL_RE, &emac->ctl); writel(readl(&emac->ctl) | AT91_EMAC_CTL_RE, &emac->ctl); dev->rbindex = 0; printf("%s: reset receiver (EMAC dead lock bug)\n", netdev->name); } return 0; }
int f_cloner_set_alt(struct usb_function *f, unsigned interface, unsigned alt) { struct cloner *cloner = func_to_cloner(f); const struct usb_endpoint_descriptor *epin_desc,*epout_desc; int status = 0; debug_cond(BURNNER_DEBUG,"set interface %d alt %d\n",interface,alt); epin_desc = ep_choose(cloner->gadget,&hs_bulk_in_desc,&fs_bulk_in_desc); epout_desc = ep_choose(cloner->gadget,&hs_bulk_out_desc,&fs_bulk_out_desc); status += usb_ep_enable(cloner->ep_in,epin_desc); status += usb_ep_enable(cloner->ep_out,epout_desc); if (status < 0) { printf("usb enable ep failed\n"); goto failed; } cloner->ep_in->driver_data = cloner; cloner->ep_out->driver_data = cloner; failed: return status; }
void link_local_receive_arp(struct arp_hdr *arp, int len) { int source_ip_conflict; int target_ip_conflict; if (state == DISABLED) return; /* We need to adjust the timeout in case we didn't receive a conflicting packet. */ if (timeout_ms > 0) { unsigned diff = deadline_ms - MONOTONIC_MS(); if ((int)(diff) < 0) { /* Current time is greater than the expected timeout time. This should never happen */ debug_cond(DEBUG_LL_STATE, "missed an expected timeout\n"); timeout_ms = 0; } else { debug_cond(DEBUG_INT_STATE, "adjusting timeout\n"); timeout_ms = diff | 1; /* never 0 */ } } /* * XXX Don't bother with ethernet link just yet if ((fds[0].revents & POLLIN) == 0) { if (fds[0].revents & POLLERR) { // FIXME: links routinely go down; // this shouldn't necessarily exit. bb_error_msg("iface %s is down", eth_get_name()); if (ready) { run(argv, "deconfig", &ip); } return EXIT_FAILURE; } continue; } */ debug_cond(DEBUG_INT_STATE, "%s recv arp type=%d, op=%d,\n", eth_get_name(), ntohs(arp->ar_pro), ntohs(arp->ar_op)); debug_cond(DEBUG_INT_STATE, "\tsource=%pM %pI4\n", &arp->ar_sha, &arp->ar_spa); debug_cond(DEBUG_INT_STATE, "\ttarget=%pM %pI4\n", &arp->ar_tha, &arp->ar_tpa); if (arp->ar_op != htons(ARPOP_REQUEST) && arp->ar_op != htons(ARPOP_REPLY) ) { configure_wait(); return; } source_ip_conflict = 0; target_ip_conflict = 0; if (memcmp(&arp->ar_spa, &ip, ARP_PLEN) == 0 && memcmp(&arp->ar_sha, NetOurEther, ARP_HLEN) != 0 ) { source_ip_conflict = 1; } if (arp->ar_op == htons(ARPOP_REQUEST) && memcmp(&arp->ar_tpa, &ip, ARP_PLEN) == 0 && memcmp(&arp->ar_tha, NetOurEther, ARP_HLEN) != 0 ) { target_ip_conflict = 1; } debug_cond(DEBUG_NET_PKT, "state = %d, source ip conflict = %d, target ip conflict = " "%d\n", state, source_ip_conflict, target_ip_conflict); switch (state) { case PROBE: case ANNOUNCE: /* When probing or announcing, check for source IP conflicts and other hosts doing ARP probes (target IP conflicts). */ if (source_ip_conflict || target_ip_conflict) { conflicts++; state = PROBE; if (conflicts >= MAX_CONFLICTS) { debug("%s ratelimit\n", eth_get_name()); timeout_ms = RATE_LIMIT_INTERVAL * 1000; state = RATE_LIMIT_PROBE; } /* restart the whole protocol */ ip = pick(); timeout_ms = 0; nprobes = 0; nclaims = 0; } break; case MONITOR: /* If a conflict, we try to defend with a single ARP probe */ if (source_ip_conflict) { debug("monitor conflict -- defending\n"); state = DEFEND; timeout_ms = DEFEND_INTERVAL * 1000; arp_raw_request(ip, NetOurEther, ip); } break; case DEFEND: /* Well, we tried. Start over (on conflict) */ if (source_ip_conflict) { state = PROBE; debug("defend conflict -- starting over\n"); ready = 0; NetOurIP = 0; /* restart the whole protocol */ ip = pick(); timeout_ms = 0; nprobes = 0; nclaims = 0; } break; default: /* Invalid, should never happen. Restart the whole protocol */ debug("invalid state -- starting over\n"); state = PROBE; ip = pick(); timeout_ms = 0; nprobes = 0; nclaims = 0; break; } configure_wait(); }
static void link_local_timeout(void) { switch (state) { case PROBE: /* timeouts in the PROBE state mean no conflicting ARP packets have been received, so we can progress through the states */ if (nprobes < PROBE_NUM) { nprobes++; debug_cond(DEBUG_LL_STATE, "probe/%u %s@%pI4\n", nprobes, eth_get_name(), &ip); arp_raw_request(0, NetEtherNullAddr, ip); timeout_ms = PROBE_MIN * 1000; timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); } else { /* Switch to announce state */ state = ANNOUNCE; nclaims = 0; debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n", nclaims, eth_get_name(), &ip); arp_raw_request(ip, NetOurEther, ip); timeout_ms = ANNOUNCE_INTERVAL * 1000; } break; case RATE_LIMIT_PROBE: /* timeouts in the RATE_LIMIT_PROBE state mean no conflicting ARP packets have been received, so we can move immediately to the announce state */ state = ANNOUNCE; nclaims = 0; debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n", nclaims, eth_get_name(), &ip); arp_raw_request(ip, NetOurEther, ip); timeout_ms = ANNOUNCE_INTERVAL * 1000; break; case ANNOUNCE: /* timeouts in the ANNOUNCE state mean no conflicting ARP packets have been received, so we can progress through the states */ if (nclaims < ANNOUNCE_NUM) { nclaims++; debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n", nclaims, eth_get_name(), &ip); arp_raw_request(ip, NetOurEther, ip); timeout_ms = ANNOUNCE_INTERVAL * 1000; } else { /* Switch to monitor state */ state = MONITOR; printf("Successfully assigned %pI4\n", &ip); NetCopyIP(&NetOurIP, &ip); ready = 1; conflicts = 0; timeout_ms = -1; /* Never timeout in the monitor state */ NetSetTimeout(0, NULL); /* NOTE: all other exit paths should deconfig ... */ net_set_state(NETLOOP_SUCCESS); return; } break; case DEFEND: /* We won! No ARP replies, so just go back to monitor */ state = MONITOR; timeout_ms = -1; conflicts = 0; break; default: /* Invalid, should never happen. Restart the whole protocol */ state = PROBE; ip = pick(); timeout_ms = 0; nprobes = 0; nclaims = 0; break; } configure_wait(); }
int NetLoop(enum proto_t protocol) { bd_t *bd = gd->bd; int ret = -1; NetRestarted = 0; NetDevExists = 0; NetTryCount = 1; debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n"); bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); if (eth_is_on_demand_init() || protocol != NETCONS) { eth_halt(); eth_set_current(); if (eth_init(bd) < 0) { eth_halt(); return -1; } } else eth_init_state_only(bd); restart: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif net_set_state(NETLOOP_CONTINUE); /* * 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. */ debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n"); NetInitLoop(); switch (net_check_prereq(protocol)) { case 1: /* network not configured */ eth_halt(); return -1; case 2: /* network device not configured */ break; case 0: NetDevExists = 1; NetBootFileXferSize = 0; switch (protocol) { case TFTPGET: #ifdef CONFIG_CMD_TFTPPUT case TFTPPUT: #endif /* always use ARP to get server ethernet address */ TftpStart(protocol); break; #ifdef CONFIG_CMD_TFTPSRV case TFTPSRV: TftpStartServer(); break; #endif #if defined(CONFIG_CMD_DHCP) case DHCP: BootpReset(); NetOurIP = 0; DhcpRequest(); /* Basically same as BOOTP */ break; #endif case BOOTP: BootpReset(); NetOurIP = 0; BootpRequest(); break; #if defined(CONFIG_CMD_RARP) case RARP: RarpTry = 0; NetOurIP = 0; RarpRequest(); break; #endif #if defined(CONFIG_CMD_PING) case PING: ping_start(); break; #endif #if defined(CONFIG_CMD_NFS) case NFS: NfsStart(); break; #endif #if defined(CONFIG_CMD_CDP) case CDP: CDPStart(); break; #endif #if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) case NETCONS: NcStart(); break; #endif #if defined(CONFIG_CMD_SNTP) case SNTP: SntpStart(); break; #endif #if defined(CONFIG_CMD_DNS) case DNS: DnsStart(); break; #endif #if defined(CONFIG_CMD_LINK_LOCAL) case LINKLOCAL: link_local_start(); break; #endif default: break; } break; } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_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, CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); else status_led_set(STATUS_LED_RED, STATUS_LED_ON); #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 1; #endif /* * Main packet reception loop. Loop receiving packets until * someone sets `net_state' to a state that terminates. */ for (;;) { WATCHDOG_RESET(); #ifdef CONFIG_SHOW_ACTIVITY 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()) { /* cancel any ARP that may not have completed */ NetArpWaitPacketIP = 0; net_cleanup_loop(); eth_halt(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!\n"); goto done; } 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) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_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, CONFIG_SYS_FAULT_MII_ADDR)) { status_led_set(STATUS_LED_RED, STATUS_LED_OFF); } else { status_led_set(STATUS_LED_RED, STATUS_LED_ON); } #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n"); x = timeHandler; timeHandler = (thand_f *)0; (*x)(); } switch (net_state) { case NETLOOP_RESTART: NetRestarted = 1; goto restart; case NETLOOP_SUCCESS: net_cleanup_loop(); if (NetBootFileXferSize > 0) { printf("Bytes transferred = %ld (%lx hex)\n", NetBootFileXferSize, NetBootFileXferSize); setenv_hex("filesize", NetBootFileXferSize); setenv_hex("fileaddr", load_addr); } if (protocol != NETCONS) eth_halt(); else eth_halt_state_only(); eth_set_last_protocol(protocol); ret = NetBootFileXferSize; debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n"); goto done; case NETLOOP_FAIL: net_cleanup_loop(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n"); goto done; case NETLOOP_CONTINUE: continue; } } done: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif #ifdef CONFIG_CMD_TFTPPUT /* Clear out the handlers */ net_set_udp_handler(NULL); net_set_icmp_handler(NULL); #endif return ret; }
static void complete_rx(struct dwc2_udc *dev, u8 ep_num) { struct dwc2_ep *ep = &dev->ep[ep_num]; struct dwc2_request *req = NULL; u32 ep_tsr = 0, xfer_size = 0, is_short = 0; if (list_empty(&ep->queue)) { debug_cond(DEBUG_OUT_EP != 0, "%s: RX DMA done : NULL REQ on OUT EP-%d\n", __func__, ep_num); return; } req = list_entry(ep->queue.next, struct dwc2_request, queue); ep_tsr = readl(®->out_endp[ep_num].doeptsiz); if (ep_num == EP0_CON) xfer_size = (ep_tsr & DOEPT_SIZ_XFER_SIZE_MAX_EP0); else xfer_size = (ep_tsr & DOEPT_SIZ_XFER_SIZE_MAX_EP); xfer_size = ep->len - xfer_size; /* * NOTE: * * Please be careful with proper buffer allocation for USB request, * which needs to be aligned to CONFIG_SYS_CACHELINE_SIZE, not only * with starting address, but also its size shall be a cache line * multiplication. * * This will prevent from corruption of data allocated immediatelly * before or after the buffer. * * For armv7, the cache_v7.c provides proper code to emit "ERROR" * message to warn users. */ invalidate_dcache_range((unsigned long) ep->dma_buf, (unsigned long) ep->dma_buf + ROUND(xfer_size, CONFIG_SYS_CACHELINE_SIZE)); req->req.actual += min(xfer_size, req->req.length - req->req.actual); is_short = !!(xfer_size % ep->ep.maxpacket); debug_cond(DEBUG_OUT_EP != 0, "%s: RX DMA done : ep = %d, rx bytes = %d/%d, " "is_short = %d, DOEPTSIZ = 0x%x, remained bytes = %d\n", __func__, ep_num, req->req.actual, req->req.length, is_short, ep_tsr, req->req.length - req->req.actual); if (is_short || req->req.actual == req->req.length) { if (ep_num == EP0_CON && dev->ep0state == DATA_STATE_RECV) { debug_cond(DEBUG_OUT_EP != 0, " => Send ZLP\n"); dwc2_udc_ep0_zlp(dev); /* packet will be completed in complete_tx() */ dev->ep0state = WAIT_FOR_IN_COMPLETE; } else { done(ep, req, 0); if (!list_empty(&ep->queue)) { req = list_entry(ep->queue.next, struct dwc2_request, queue); debug_cond(DEBUG_OUT_EP != 0, "%s: Next Rx request start...\n", __func__); setdma_rx(ep, req); } } } else
void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) { struct arp_hdr *arp; struct in_addr reply_ip_addr; uchar *pkt; int eth_hdr_size; /* * We have to deal with two types of ARP packets: * - REQUEST packets will be answered by sending our * IP address - if we know it. * - REPLY packates are expected only after we asked * for the TFTP server's or the gateway's ethernet * address; so if we receive such a packet, we set * the server ethernet address */ debug_cond(DEBUG_NET_PKT, "Got ARP\n"); arp = (struct arp_hdr *)ip; if (len < ARP_HDR_SIZE) { printf("bad length %d < %d\n", len, ARP_HDR_SIZE); return; } if (ntohs(arp->ar_hrd) != ARP_ETHER) return; if (ntohs(arp->ar_pro) != PROT_IP) return; if (arp->ar_hln != ARP_HLEN) return; if (arp->ar_pln != ARP_PLEN) return; if (net_ip.s_addr == 0) return; if (net_read_ip(&arp->ar_tpa).s_addr != net_ip.s_addr) return; switch (ntohs(arp->ar_op)) { case ARPOP_REQUEST: /* reply with our IP address */ debug_cond(DEBUG_DEV_PKT, "Got ARP REQUEST, return our IP\n"); pkt = (uchar *)et; eth_hdr_size = net_update_ether(et, et->et_src, PROT_ARP); pkt += eth_hdr_size; arp->ar_op = htons(ARPOP_REPLY); memcpy(&arp->ar_tha, &arp->ar_sha, ARP_HLEN); net_copy_ip(&arp->ar_tpa, &arp->ar_spa); memcpy(&arp->ar_sha, net_ethaddr, ARP_HLEN); net_copy_ip(&arp->ar_spa, &net_ip); #ifdef CONFIG_CMD_LINK_LOCAL /* * Work-around for brain-damaged Cisco equipment with * arp-proxy enabled. * * If the requesting IP is not on our subnet, wait 5ms to * reply to ARP request so that our reply will overwrite * the arp-proxy's instead of the other way around. */ if ((net_read_ip(&arp->ar_tpa).s_addr & net_netmask.s_addr) != (net_read_ip(&arp->ar_spa).s_addr & net_netmask.s_addr)) udelay(5000); #endif net_send_packet((uchar *)et, eth_hdr_size + ARP_HDR_SIZE); return; case ARPOP_REPLY: /* arp reply */ /* are we waiting for a reply */ if (!net_arp_wait_packet_ip.s_addr) break; #ifdef CONFIG_KEEP_SERVERADDR if (net_server_ip.s_addr == net_arp_wait_packet_ip.s_addr) { char buf[20]; sprintf(buf, "%pM", &arp->ar_sha); setenv("serveraddr", buf); } #endif reply_ip_addr = net_read_ip(&arp->ar_spa); /* matched waiting packet's address */ if (reply_ip_addr.s_addr == net_arp_wait_reply_ip.s_addr) { debug_cond(DEBUG_DEV_PKT, "Got ARP REPLY, set eth addr (%pM)\n", arp->ar_data); /* save address for later use */ if (arp_wait_packet_ethaddr != NULL) memcpy(arp_wait_packet_ethaddr, &arp->ar_sha, ARP_HLEN); net_get_arp_handler()((uchar *)arp, 0, reply_ip_addr, 0, len); /* set the mac address in the waiting packet's header and transmit it */ memcpy(((struct ethernet_hdr *)net_tx_packet)->et_dest, &arp->ar_sha, ARP_HLEN); net_send_packet(net_tx_packet, arp_wait_tx_packet_size); /* no arp request pending now */ net_arp_wait_packet_ip.s_addr = 0; arp_wait_tx_packet_size = 0; arp_wait_packet_ethaddr = NULL; } return; default: debug("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op)); return; } }
int net_loop(enum proto_t protocol) { int ret = -EINVAL; net_restarted = 0; net_dev_exists = 0; net_try_count = 1; debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n"); bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); if (eth_is_on_demand_init() || protocol != NETCONS) { eth_halt(); eth_set_current(); ret = eth_init(); if (ret < 0) { eth_halt(); return ret; } } else { eth_init_state_only(); } restart: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif net_set_state(NETLOOP_CONTINUE); /* * 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. */ debug_cond(DEBUG_INT_STATE, "--- net_loop Init\n"); net_init_loop(); switch (net_check_prereq(protocol)) { case 1: /* network not configured */ eth_halt(); return -ENODEV; case 2: /* network device not configured */ break; case 0: net_dev_exists = 1; net_boot_file_size = 0; switch (protocol) { case TFTPGET: #ifdef CONFIG_CMD_TFTPPUT case TFTPPUT: #endif /* always use ARP to get server ethernet address */ tftp_start(protocol); break; #ifdef CONFIG_CMD_TFTPSRV case TFTPSRV: tftp_start_server(); break; #endif #if defined(CONFIG_CMD_DHCP) case DHCP: bootp_reset(); net_ip.s_addr = 0; dhcp_request(); /* Basically same as BOOTP */ break; #endif case BOOTP: bootp_reset(); net_ip.s_addr = 0; bootp_request(); break; #if defined(CONFIG_CMD_RARP) case RARP: rarp_try = 0; net_ip.s_addr = 0; rarp_request(); break; #endif #if defined(CONFIG_CMD_PING) case PING: ping_start(); break; #endif #if defined(CONFIG_CMD_NFS) case NFS: nfs_start(); break; #endif #if defined(CONFIG_CMD_CDP) case CDP: cdp_start(); break; #endif #if defined(CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) case NETCONS: nc_start(); break; #endif #if defined(CONFIG_CMD_SNTP) case SNTP: sntp_start(); break; #endif #if defined(CONFIG_CMD_DNS) case DNS: dns_start(); break; #endif #if defined(CONFIG_CMD_LINK_LOCAL) case LINKLOCAL: link_local_start(); break; #endif default: break; } break; } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_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, CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); else status_led_set(STATUS_LED_RED, STATUS_LED_ON); #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 1; #endif /* * Main packet reception loop. Loop receiving packets until * someone sets `net_state' to a state that terminates. */ for (;;) { WATCHDOG_RESET(); #ifdef CONFIG_SHOW_ACTIVITY show_activity(1); #endif if (arp_timeout_check() > 0) time_start = get_timer(0); /* * Check the ethernet for a new packet. The ethernet * receive routine will process it. * Most drivers return the most recent packet size, but not * errors that may have happened. */ eth_rx(); /* * Abort if ctrl-c was pressed. */ if (ctrlc()) { /* cancel any ARP that may not have completed */ net_arp_wait_packet_ip.s_addr = 0; net_cleanup_loop(); eth_halt(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!\n"); ret = -EINTR; goto done; } /* * Check for a timeout, and run the timeout handler * if we have one. */ if (time_handler && ((get_timer(0) - time_start) > time_delta)) { thand_f *x; #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_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, CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); else status_led_set(STATUS_LED_RED, STATUS_LED_ON); #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ debug_cond(DEBUG_INT_STATE, "--- net_loop timeout\n"); x = time_handler; time_handler = (thand_f *)0; (*x)(); } if (net_state == NETLOOP_FAIL) ret = net_start_again(); switch (net_state) { case NETLOOP_RESTART: net_restarted = 1; goto restart; case NETLOOP_SUCCESS: net_cleanup_loop(); if (net_boot_file_size > 0) { printf("Bytes transferred = %d (%x hex)\n", net_boot_file_size, net_boot_file_size); setenv_hex("filesize", net_boot_file_size); setenv_hex("fileaddr", load_addr); } if (protocol != NETCONS) eth_halt(); else eth_halt_state_only(); eth_set_last_protocol(protocol); ret = net_boot_file_size; debug_cond(DEBUG_INT_STATE, "--- net_loop Success!\n"); goto done; case NETLOOP_FAIL: net_cleanup_loop(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n"); goto done; case NETLOOP_CONTINUE: continue; } } done: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif #ifdef CONFIG_CMD_TFTPPUT /* Clear out the handlers */ net_set_udp_handler(NULL); net_set_icmp_handler(NULL); #endif return ret; }
int f_cloner_setup_handle(struct usb_function *f, const struct usb_ctrlrequest *ctlreq) { struct cloner *cloner = f->config->cdev->req->context; struct usb_request *req = cloner->ep0req; debug_cond(BURNNER_DEBUG,"vendor bRequestType %x,bRequest %x wLength %d\n", ctlreq->bRequestType, ctlreq->bRequest, ctlreq->wLength); if ((ctlreq->bRequestType & USB_TYPE_MASK) != USB_TYPE_VENDOR) { printf("Unkown RequestType 0x%x \n",ctlreq->bRequestType); cloner->ack = -ENOSYS; return -ENOSYS; } usb_ep_dequeue(cloner->ep0, cloner->ep0req); usb_ep_dequeue(cloner->ep_in, cloner->read_req); usb_ep_dequeue(cloner->ep_out, cloner->write_req); cloner->cmd_type = ctlreq->bRequest; req->length = ctlreq->wLength; req->complete = handle_cmd; switch (ctlreq->bRequest) { case VR_GET_CPU_INFO: strcpy(cloner->ep0req->buf,"BOOT47XX"); break; case VR_GET_ACK: if (cloner->ack) printf("cloner->ack = %d\n",cloner->ack); memcpy(cloner->ep0req->buf,&cloner->ack,sizeof(int)); break; case VR_GET_CRC: if (cloner->ack) printf("cloner->ack = %d, cloner->crc = %x\n",cloner->ack, cloner->crc); memcpy(cloner->ep0req->buf,&cloner->ack,sizeof(int)); memcpy(cloner->ep0req->buf + sizeof(int),&cloner->crc,sizeof(int)); break; case VR_INIT: break; case VR_UPDATE_CFG: case VR_WRITE: cloner->ack = -EBUSY; break; #ifdef CONFIG_CMD_EFUSE case VR_GET_CHIP_ID: case VR_GET_USER_ID: cloner->ep0req->length = ctlreq->wLength; cloner->ack = efuse_program(cloner); break; #endif case VR_SET_DATA_ADDR: case VR_SET_DATA_LEN: cloner->full_size = ctlreq->wIndex | ctlreq->wValue << 16; cloner->full_size_remainder = cloner->full_size; printf("cloner->full_size = %x\n", cloner->full_size); break; } return usb_ep_queue(cloner->ep0, cloner->ep0req, 0); }
void handle_cmd(struct usb_ep *ep,struct usb_request *req) { struct cloner *cloner = req->context; if(req->status == -ECONNRESET) { cloner->ack = -ECONNRESET; return; } if (req->actual != req->length) { printf("cmd transfer length is err req->actual = %d, req->length = %d\n", req->actual,req->length); cloner->ack = -EIO; return; } union cmd *cmd = req->buf; debug_cond(BURNNER_DEBUG,"handle_cmd type=%x\n",cloner->cmd_type); switch(cloner->cmd_type) { case VR_UPDATE_CFG: cloner->args_req->length = cmd->update.length; usb_ep_queue(cloner->ep_out, cloner->args_req, 0); break; case VR_WRITE: realloc_buf(cloner, cmd->write.length); cloner->write_req->length = cmd->write.length; usb_ep_queue(cloner->ep_out, cloner->write_req, 0); break; case VR_INIT: if(!cloner->inited) { cloner->ack = -EBUSY; cloner_init(cloner); cloner->inited = 1; cloner->ack = 0; } break; case VR_READ: handle_read(cloner); break; case VR_GET_CRC: if (!cloner->ack) usb_ep_queue(cloner->ep_in, cloner->read_req, 0); break; case VR_SYNC_TIME: cloner->ack = rtc_set(&cloner->cmd->rtc); break; case VR_CHECK: cloner->ack = handle_check(cloner); break; case VR_GET_CHIP_ID: case VR_GET_USER_ID: case VR_GET_ACK: case VR_GET_CPU_INFO: case VR_SET_DATA_ADDR: case VR_SET_DATA_LEN: break; case VR_REBOOT: #ifdef CONFIG_FPGA mdelay(1000); do_udc_reset(); mdelay(10000); #endif do_reset(NULL,0,0,NULL); break; case VR_POWEROFF: burner_set_reset_tag(); do_reset(NULL,0,0,NULL); break; } }
int NetLoop(enum proto_t protocol) { int ret = -1; NetRestarted = 0; NetDevExists = 0; NetTryCount = 1; debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n"); net_init(); restart: net_set_state(NETLOOP_CONTINUE); /* * 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. */ debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n"); NetInitLoop(); switch (net_check_prereq(protocol)) { case 1: case 2: return -1; case 0: NetDevExists = 1; NetBootFileXferSize = 0; switch (protocol) { case TFTPGET: #ifdef CONFIG_CMD_TFTPPUT case TFTPPUT: #endif /* always use ARP to get server ethernet address */ TftpStart(protocol); break; case PING: ping_start(); break; default: break; } break; } /* * Main packet reception loop. Loop receiving packets until * someone sets `net_state' to a state that terminates. */ for (;;) { /* * Check the ethernet for a new packet. The ethernet * receive routine will process it. */ eth_rx(); /* * Abort if q was pressed. */ if ('q' == ftuart_kbhit()) { /* cancel any ARP that may not have completed */ NetArpWaitPacketIP = 0; net_cleanup_loop(); puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!\n"); goto done; } ArpTimeoutCheck(); /* * Check for a timeout, and run the timeout handler * if we have one. */ if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) { thand_f *x; debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n"); x = timeHandler; timeHandler = (thand_f *)0; (*x)(); } switch (net_state) { case NETLOOP_RESTART: NetRestarted = 1; goto restart; case NETLOOP_SUCCESS: net_cleanup_loop(); if (NetBootFileXferSize > 0) { prints("Bytes transferred = %ld (%lx hex)\n", NetBootFileXferSize, NetBootFileXferSize); } ret = NetBootFileXferSize; debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n"); goto done; case NETLOOP_FAIL: net_cleanup_loop(); debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n"); goto done; case NETLOOP_CONTINUE: continue; } } done: #ifdef CONFIG_CMD_TFTPPUT /* Clear out the handlers */ net_set_udp_handler(NULL); net_set_icmp_handler(NULL); #endif return ret; }