void hfc_fifo_put_frame(struct hfc_chan_simplex *chan, void *data, int size) { u16 newz1; int available_frames; #ifdef DEBUG if (debug_level == 3) { printk(KERN_DEBUG hfc_DRIVER_PREFIX "card %d: " "chan %s: " "TX len %2d: ", chan->chan->card->cardnum, chan->chan->name, size); } else if (debug_level >= 4) { printk(KERN_DEBUG hfc_DRIVER_PREFIX "card %d: " "chan %s: " "TX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ", chan->chan->card->cardnum, chan->chan->name, *chan->f1, *chan->f2, *Z1_F1(chan), *Z2_F1(chan), size); } if (debug_level >= 3) { int i; for (i = 0; i < size; i++) printk("%02x", ((u8 *)data)[i]); printk("\n"); } #endif available_frames = hfc_fifo_free_frames(chan); if (available_frames >= chan->f_num) { printk(KERN_CRIT hfc_DRIVER_PREFIX "card %d: " "chan %s: " "TX FIFO total number of frames exceeded!\n", chan->chan->card->cardnum, chan->chan->name); chan->fifo_full++; return; } hfc_fifo_put(chan, data, size); newz1 = *Z1_F1(chan); *chan->f1 = F_inc(chan, *chan->f1, 1); *Z1_F1(chan) = newz1; chan->frames++; }
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; }