/* * Get a packet from input queue. */ static buf_t * eth_input(eth_t *u) { buf_t *p; mutex_lock(&u->netif.lock); p = buf_queue_get(&u->inq); mutex_unlock(&u->netif.lock); return p; }
/* * Get the received packet. Blocks the task until the data is available. */ buf_t * slip_recv (slip_t *u) { buf_t *p; mutex_lock (&u->netif.lock); for (;;) { p = buf_queue_get (&u->inq); if (p) { mutex_unlock (&u->netif.lock); return p; } mutex_wait (&u->netif.lock); } }
/* * Deallocate last transmitted packet and get next * packet from transmit queue. */ static void slip_out_next (slip_t *u) { buf_free (u->out_free); u->out_free = 0; if (! u->out) { /* Ставим на передачу пакет из очереди. */ u->out = buf_queue_get (&u->outq); if (u->out) { u->outseg = u->out; u->out_first = u->outseg->payload; u->out_limit = u->outseg->payload + u->outseg->len; u->out_flag = 1; slip_transmit_start (u); } } }
//return value: 0: no buf valid 1: at least one buf valid portBASE_TYPE transceiver::fetch(int8 *pbuf, uint16 *plen) { return (0 == buf_queue_get(&m_buf_queue, pbuf, plen))?(1):(0); }
/* * Process an interrupt. * Return nonzero when there was some activity. */ static unsigned handle_interrupt(eth_t *u) { unsigned active = 0; ARM_NVIC_ICPR(0) = 1 << ETH_IRQ; u->intr_flags = ARM_ETH->IFR; if (u->intr_flags & ARM_ETH_XF_UNDF) { ARM_ETH->R_CFG &= ~ARM_ETH_EN; ARM_ETH->X_CFG &= ~ARM_ETH_EN; ARM_ETH->G_CFG_HI |= ARM_ETH_XRST; ARM_ETH->X_TAIL = ARM_ETH->X_HEAD; ARM_ETH->G_CFG_HI &= ~ARM_ETH_XRST; ARM_ETH->X_CFG |= ARM_ETH_EN; ARM_ETH->R_CFG |= ARM_ETH_EN; } /* Обработка приёма пакета */ //if (ARM_ETH->X_TAIL != ARM_ETH->X_HEAD) { // /* Если есть данные, прочитать пакет */ // receive_packet(u); // active++; //} if (ARM_ETH->R_TAIL != ARM_ETH->R_HEAD) { /* Если есть данные, прочитать пакет */ while (ARM_ETH->STAT & 0xE0) { receive_packet(u); ARM_ETH->IFR |= ARM_ETH_RF_OK; } active++; } u->intr_flags = ARM_ETH->IFR; if (u->intr_flags & ARM_ETH_MISSED_F) { ARM_ETH->IFR |= ARM_ETH_MISSED_F; //ARM_ETH->R_HEAD = ARM_ETH->R_TAIL; //if (ARM_ETH->STAT & 0xE0){ // ARM_ETH->STAT -= 0x20; // ++u->in_missed_and_rx; //} //if(ARM_ETH->STAT & ~0xE0) // ARM_ETH->R_HEAD = ARM_ETH->R_TAIL; //chip_read_rxfifo(u, ARM_ETH_PKT_LENGTH(ARM_ETH_RX_FIFO)); ++u->netif.in_discards; ++u->in_missed; //ARM_NVIC_ICPR(0) = 1 << ETH_IRQ; //return 0; } /* успешная отправка */ if (u->intr_flags & ARM_ETH_XF_OK) { ARM_ETH->IFR |= ARM_ETH_XF_OK; /* debug_printf("Transmot ok. ARM_ETH->IFR = <0x%04x>\n", u->intr_flags); */ //#ifdef ETH_FIFO // unsigned tmp = ARM_ETH_TX_FIFO; //#endif /* Извлекаем следующий пакет из очереди. */ buf_t *p = buf_queue_get(&u->outq); if (p) { /* Передаём следующий пакет. */ transmit_packet(u, p); netif_free_buf (&u->netif, p); } active++; } if (u->intr_flags & ARM_ETH_XF_ERR) { ARM_ETH->IFR |= ARM_ETH_XF_ERR; ++u->netif.out_errors; //#ifdef ETH_FIFO // unsigned tmp = ARM_ETH_TX_FIFO; //#endif /* debug_printf("Error Tx on transmiteARM_ETH->IFR = <0x%04x>\n", u->intr_flags); */ } /* Подсчитываем коллизии. */ if (u->intr_flags & ARM_ETH_LC) { ARM_ETH->IFR |= ARM_ETH_LC; ++u->netif.out_collisions; /* debug_printf("Error collisions\n"); */ } //ARM_NVIC_ICPR(0) = 1 << ETH_IRQ; return active; }