static void hfc_fill_fifo(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; long flags; int idx, fcnt; int count; u_char cip; char tmp[64]; if (!bcs->hw.hfc.tx_skb) return; if (bcs->hw.hfc.tx_skb->len <= 0) return; save_flags(flags); cli(); SelFiFo(cs, HFCB_SEND | HFCB_CHANNEL(bcs->channel)); cip = HFCB_FIFO | HFCB_F1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel); WaitNoBusy(cs); bcs->hw.hfc.f1 = ReadReg(cs, HFCD_DATA, cip); WaitNoBusy(cs); cip = HFCB_FIFO | HFCB_F2 | HFCB_SEND | HFCB_CHANNEL(bcs->channel); WaitNoBusy(cs); bcs->hw.hfc.f2 = ReadReg(cs, HFCD_DATA, cip); bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel)); sti(); if (cs->debug & L1_DEB_HSCX) { sprintf(tmp, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)", bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2, bcs->hw.hfc.send[bcs->hw.hfc.f1]); debugl1(cs, tmp); } fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2; if (fcnt < 0) fcnt += 32; if (fcnt > 30) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfc_fill_fifo more as 30 frames"); restore_flags(flags); return; } count = GetFreeFifoBytes_B(bcs); if (cs->debug & L1_DEB_HSCX) { sprintf(tmp, "hfc_fill_fifo %d count(%d/%d),%lx", bcs->channel, bcs->hw.hfc.tx_skb->len, count, current->state); debugl1(cs, tmp); } if (count < bcs->hw.hfc.tx_skb->len) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfc_fill_fifo no fifo mem"); restore_flags(flags); return; } cip = HFCB_FIFO | HFCB_FIFO_IN | HFCB_SEND | HFCB_CHANNEL(bcs->channel); idx = 0; cli(); WaitForBusy(cs); WaitNoBusy(cs); WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->hw.hfc.tx_skb->data[idx++]); while (idx < bcs->hw.hfc.tx_skb->len) { cli(); if (!WaitNoBusy(cs)) break; WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->hw.hfc.tx_skb->data[idx]); sti(); idx++; } if (idx != bcs->hw.hfc.tx_skb->len) { sti(); debugl1(cs, "FIFO Send BUSY error"); printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel); } else { bcs->tx_cnt -= bcs->hw.hfc.tx_skb->len; if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->hw.hfc.tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hfc.tx_skb->len); dev_kfree_skb(bcs->hw.hfc.tx_skb); bcs->hw.hfc.tx_skb = NULL; } WaitForBusy(cs); cli(); WaitNoBusy(cs); ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F1_INC | HFCB_SEND | HFCB_CHANNEL(bcs->channel)); sti(); WaitForBusy(cs); test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); restore_flags(flags); return; }
static void hfc_fill_fifo(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; int idx, fcnt; int count; u_char cip; if (!bcs->tx_skb) return; if (bcs->tx_skb->len <= 0) return; SelFiFo(cs, HFCB_SEND | HFCB_CHANNEL(bcs->channel)); cip = HFCB_FIFO | HFCB_F1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel); WaitNoBusy(cs); bcs->hw.hfc.f1 = ReadReg(cs, HFCD_DATA, cip); WaitNoBusy(cs); cip = HFCB_FIFO | HFCB_F2 | HFCB_SEND | HFCB_CHANNEL(bcs->channel); WaitNoBusy(cs); bcs->hw.hfc.f2 = ReadReg(cs, HFCD_DATA, cip); bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel)); if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)", bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2, bcs->hw.hfc.send[bcs->hw.hfc.f1]); fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2; if (fcnt < 0) fcnt += 32; if (fcnt > 30) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfc_fill_fifo more as 30 frames"); return; } count = GetFreeFifoBytes_B(bcs); if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfc_fill_fifo %d count(%u/%d),%lx", bcs->channel, bcs->tx_skb->len, count, current->state); if (count < bcs->tx_skb->len) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfc_fill_fifo no fifo mem"); return; } cip = HFCB_FIFO | HFCB_FIFO_IN | HFCB_SEND | HFCB_CHANNEL(bcs->channel); idx = 0; WaitForBusy(cs); WaitNoBusy(cs); WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx++]); while (idx < bcs->tx_skb->len) { if (!WaitNoBusy(cs)) break; WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx]); idx++; } if (idx != bcs->tx_skb->len) { debugl1(cs, "FIFO Send BUSY error"); printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel); } else { bcs->tx_cnt -= bcs->tx_skb->len; if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && (PACKET_NOACK != bcs->tx_skb->pkt_type)) { u_long flags; spin_lock_irqsave(&bcs->aclock, flags); bcs->ackcnt += bcs->tx_skb->len; spin_unlock_irqrestore(&bcs->aclock, flags); schedule_event(bcs, B_ACKPENDING); } dev_kfree_skb_any(bcs->tx_skb); bcs->tx_skb = NULL; } WaitForBusy(cs); WaitNoBusy(cs); ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F1_INC | HFCB_SEND | HFCB_CHANNEL(bcs->channel)); WaitForBusy(cs); test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); return; }
static void hfc_fill_fifo(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; u_int idx; int fcnt; u_int count; u8 cip; if (!bcs->tx_skb) return; if (bcs->tx_skb->len <= 0) return; SelFiFo(cs, HFCB_SEND | HFCB_CHANNEL(bcs->channel)); cip = HFCB_FIFO | HFCB_F1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel); WaitNoBusy(cs); bcs->hw.hfc.f1 = ReadReg(cs, HFCD_DATA, cip); WaitNoBusy(cs); cip = HFCB_FIFO | HFCB_F2 | HFCB_SEND | HFCB_CHANNEL(bcs->channel); WaitNoBusy(cs); bcs->hw.hfc.f2 = ReadReg(cs, HFCD_DATA, cip); bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel)); if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)", bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2, bcs->hw.hfc.send[bcs->hw.hfc.f1]); fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2; if (fcnt < 0) fcnt += 32; if (fcnt > 30) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfc_fill_fifo more as 30 frames"); return; } count = GetFreeFifoBytes_B(bcs); if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfc_fill_fifo %d count(%ld/%d),%lx", bcs->channel, bcs->tx_skb->len, count, current->state); if (count < bcs->tx_skb->len) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfc_fill_fifo no fifo mem"); return; } cip = HFCB_FIFO | HFCB_FIFO_IN | HFCB_SEND | HFCB_CHANNEL(bcs->channel); idx = 0; WaitForBusy(cs); WaitNoBusy(cs); WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx++]); while (idx < bcs->tx_skb->len) { if (!WaitNoBusy(cs)) break; WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx]); idx++; } if (idx != bcs->tx_skb->len) { debugl1(cs, "FIFO Send BUSY error"); printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel); } else { bcs->tx_cnt -= bcs->tx_skb->len; xmit_complete_b(bcs); } WaitForBusy(cs); WaitNoBusy(cs); ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F1_INC | HFCB_SEND | HFCB_CHANNEL(bcs->channel)); WaitForBusy(cs); test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); return; }