unsigned char fifo_init (fifo_t* f, unsigned char* buffer, const unsigned int size) { //if(f == NULL) return(0); f->buffer = buffer; f->size = size; fifo_purge(f); return(1); }
static void handle_raw_rx(struct modemctl *mc) { struct raw_hdr raw; struct sk_buff *skb = NULL; int recvdata = 0; /* process inbound packets */ while (fifo_read(&mc->raw_rx, &raw, sizeof(raw)) == sizeof(raw)) { struct net_device *dev = mc->ndev; unsigned sz = raw.len - (sizeof(raw) - 1); if (unlikely(raw.channel != RAW_CH_VNET0)) { MODEM_COUNT(mc, rx_unknown); pr_err("[VNET] unknown channel %d\n", raw.channel); if (fifo_skip(&mc->raw_rx, sz + 1) != (sz + 1)) goto purge_raw_fifo; continue; } skb = dev_alloc_skb(sz + NET_IP_ALIGN); if (skb == NULL) { MODEM_COUNT(mc, rx_dropped); /* TODO: consider timer + retry instead of drop? */ pr_err("[VNET] cannot alloc %d byte packet\n", sz); if (fifo_skip(&mc->raw_rx, sz + 1) != (sz + 1)) goto purge_raw_fifo; continue; } skb->dev = dev; skb_reserve(skb, NET_IP_ALIGN); if (fifo_read(&mc->raw_rx, skb_put(skb, sz), sz) != sz) goto purge_raw_fifo; if (fifo_skip(&mc->raw_rx, 1) != 1) goto purge_raw_fifo; skb->protocol = __constant_htons(ETH_P_IP); dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; netif_rx(skb); recvdata = 1; MODEM_COUNT(mc, rx_received); } if (recvdata) wake_lock_timeout(&mc->ip_rx_wakelock, HZ * 2); return; purge_raw_fifo: if (skb) dev_kfree_skb_irq(skb); pr_err("[VNET] purging raw rx fifo!\n"); fifo_purge(&mc->raw_tx); MODEM_COUNT(mc, rx_purged); }
/* must be called with pipe->rx_lock held */ static int modem_pipe_recv(struct m_pipe *pipe, struct modem_io *io) { int ret; ret = modem_acquire_mmio(pipe->mc); if (ret) return ret; ret = modem_pipe_read(pipe, io); modem_update_pipe(pipe); if ((ret != 0) && (ret != -EAGAIN)) { pr_err("[MODEM] purging %s fifo\n", pipe->dev.name); fifo_purge(pipe->rx); MODEM_COUNT(pipe->mc, pipe_rx_purged); } else if (ret == 0) { MODEM_COUNT(pipe->mc, pipe_rx); } modem_release_mmio(pipe->mc, 0); return ret; }