Example #1
0
void hfc_fifo_put(struct hfc_chan_simplex *chan,
			void *data, int size)
{
	struct hfc_card *card = chan->chan->card;
	int used_bytes = hfc_fifo_used_tx(chan);
	int free_bytes = hfc_fifo_free_tx(chan);

	if (!used_bytes && !chan->fifo_underrun++) {
		/*
		 * print warning only once, to make timing not worse
		 */
		printk(KERN_WARNING hfc_DRIVER_PREFIX
			"card %d: "
			"chan %s: "
			"TX FIFO has become empty\n",
			card->cardnum,
			chan->chan->name);
	}
	if (free_bytes < size) {
		printk(KERN_CRIT hfc_DRIVER_PREFIX
			"card %d: "
			"chan %s: "
			"TX FIFO full!\n",
			chan->chan->card->cardnum,
			chan->chan->name);
		chan->fifo_full++;
		hfc_clear_fifo_tx(chan);
	}

	hfc_fifo_mem_write(chan, data, size);
	chan->bytes += size;
	*Z1_F1(chan) = Z_inc(chan, *Z1_F1(chan), size);
}
Example #2
0
static ssize_t hfc_sys_chan_write(
	struct visdn_leg *visdn_leg,
	const void *buf, size_t count)
{
	struct hfc_sys_chan *chan = to_sys_chan(visdn_leg->chan);
	struct hfc_card *card = chan->port->card;
	int copied_octets;
	int available_octets;
	int used_octets;

	hfc_card_lock(card);

	hfc_fifo_select(&chan->tx_fifo);

	available_octets = hfc_fifo_free_tx(&chan->tx_fifo);

	copied_octets = available_octets > count ? count : available_octets;

	used_octets = hfc_fifo_used_tx(&chan->tx_fifo);

	chan->tx_fifo.stats_cycles++;
	if (chan->tx_fifo.stats_cycles >= 10) {
		if (chan->tx_fifo.stats_min < HFC_FIFO_JITTBUFF) {
			u8 foo = ((u8 *)buf)[0];
			hfc_fifo_mem_write(&chan->tx_fifo, &foo, 1);
//			printk(KERN_DEBUG "Added one sample\n");
		}

		chan->tx_fifo.stats_cycles = 0;
		chan->tx_fifo.stats_min = INT_MAX;
		chan->tx_fifo.stats_max = 0;
	}

	if (used_octets < chan->tx_fifo.stats_min)
		chan->tx_fifo.stats_min = used_octets;

	if (used_octets + copied_octets > chan->tx_fifo.stats_max)
		chan->tx_fifo.stats_max = used_octets + copied_octets;

	hfc_fifo_mem_write(&chan->tx_fifo, buf, copied_octets);

	hfc_card_unlock(card);

	return copied_octets;
}
Example #3
0
static int hfc_sys_chan_start(struct visdn_chan *visdn_chan)
{
	struct hfc_sys_chan *chan = to_sys_chan(visdn_chan);
	struct hfc_card *card = chan->port->card;
	int i;

	hfc_card_lock(card);

	chan->rx_fifo.enabled = TRUE;
	chan->tx_fifo.enabled = TRUE;

	hfc_sys_port_upload_fsm(chan->port);

	/* RX FIFO */
	hfc_fifo_select(&chan->rx_fifo);
	hfc_fifo_reset(&chan->rx_fifo);
	hfc_fifo_configure(&chan->rx_fifo);

	/* TX FIFO */
	hfc_fifo_select(&chan->tx_fifo);
	hfc_fifo_reset(&chan->tx_fifo);
	hfc_fifo_configure(&chan->tx_fifo);

	if (!chan->tx_fifo.framer_enabled) {
		for (i=0; i<HFC_FIFO_JITTBUFF; i++) {
			u8 foo = 0;
			hfc_fifo_mem_write(&chan->tx_fifo, &foo, 1);
		}
	}

	hfc_card_unlock(card);

	hfc_debug_sys_chan(chan, 1, "channel started\n");

	return 0;
}
Example #4
0
static int hfc_sys_chan_frame_xmit(
	struct visdn_leg *visdn_leg,
	struct sk_buff *skb)
{
	struct hfc_sys_chan *chan = to_sys_chan(visdn_leg->chan);
	struct hfc_card *card = chan->port->card;
	struct hfc_fifo *fifo = &chan->tx_fifo;

	hfc_card_lock(card);

	hfc_fifo_select(fifo);
	/*
	 * hfc_fifo_select() updates F/Z cache, so,
	 * size calculations are allowed
	 */

	if (hfc_fifo_free_frames(fifo) <= 1) {
		hfc_debug_sys_chan(chan, 3,
			"TX FIFO frames full, throttling\n");

		visdn_leg_stop_queue(&chan->visdn_chan.leg_b);
	}

	if (hfc_fifo_free_tx(fifo) < skb->len) {
		hfc_debug_sys_chan(chan, 3,
			"TX FIFO full (%d < %d), throttling\n",
			hfc_fifo_free_tx(fifo), skb->len);

		visdn_leg_stop_queue(&chan->visdn_chan.leg_b);

		visdn_leg_tx_error(&chan->visdn_chan.leg_b,
				VISDN_TX_ERROR_FIFO_FULL);

		goto err_no_free_tx;
	}

#ifdef DEBUG_CODE
	if (debug_level == 3) {
		hfc_fifo_refresh_fz_cache(fifo);
		hfc_debug_sys_chan(chan, 3, "TX len %2d: ", skb->len);

	} else if (debug_level >= 4) {
		hfc_fifo_refresh_fz_cache(fifo);
		hfc_debug_sys_chan(chan, 4,
			"TX (f1=%02x, f2=%02x, z1(f1)=%04x, z2(f2)=%04x)"
			" len %2d: ",
			fifo->f1, fifo->f2, fifo->z1, fifo->z2,
			skb->len);
	}

	if (debug_level >= 3) {
		int i;
		for (i=0; i<skb->len; i++)
			printk("%02x",((u8 *)skb->data)[i]);

		printk("\n");
	}
#endif

	hfc_fifo_mem_write(fifo, skb->data, skb->len);
	hfc_fifo_next_frame(fifo);

	hfc_card_unlock(card);

	visdn_kfree_skb(skb);

#if 0
	if (chan->connected_e1_chan) {
		struct hfc_led *led =
			&card->leds[chan->connected_e1_chan->port->id];

		led->alt_color = HFC_LED_OFF;
		led->flashing_freq = HZ / 10;
		led->flashes = 1;
		hfc_led_update(led);
	}
#endif

	return VISDN_TX_OK;

err_no_free_tx:
	hfc_card_unlock(card);

	return VISDN_TX_BUSY;
}