📄 netjet.c
字号:
bcs->tx_cnt -= bcs->tx_skb->len; bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf; return(0);}static void got_frame(struct BCState *bcs, int count) { struct sk_buff *skb; if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "TIGER: receive out of memory\n"); else { SET_SKB_FREE(skb); memcpy(skb_put(skb, count), bcs->hw.tiger.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } bcs->event |= 1 << B_RCVBUFREADY; queue_task(&bcs->tqueue, &tq_immediate); mark_bh(IMMEDIATE_BH); if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME) printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec");}static void read_raw(struct BCState *bcs, u_int *buf, int cnt){ int i; register u_char j; register u_char val; u_int *pend = bcs->hw.tiger.rec +NETJET_DMA_SIZE -1; register u_char state = bcs->hw.tiger.r_state; register u_char r_one = bcs->hw.tiger.r_one; register u_char r_val = bcs->hw.tiger.r_val; register u_int bitcnt = bcs->hw.tiger.r_bitcnt; u_int *p = buf; for (i=0;i<cnt;i++) { val = bcs->channel ? ((*p>>8) & 0xff) : (*p & 0xff); p++; if (p > pend) p = bcs->hw.tiger.rec; if (val == 0xff) { state = HDLC_ZERO_SEARCH; bcs->hw.tiger.r_tot++; bitcnt = 0; r_one = 0; continue; } for (j=0;j<8;j++) { if (state == HDLC_ZERO_SEARCH) { if (val & 1) { r_one++; } else { r_one=0; state= HDLC_FLAG_SEARCH; if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger read_raw: zBit(%d,%d,%d) %x", bcs->hw.tiger.r_tot,i,j,val); } } else if (state == HDLC_FLAG_SEARCH) { if (val & 1) { r_one++; if (r_one>6) { state=HDLC_ZERO_SEARCH; } } else { if (r_one==6) { bitcnt=0; r_val=0; state=HDLC_FLAG_FOUND; if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger read_raw: flag(%d,%d,%d) %x", bcs->hw.tiger.r_tot,i,j,val); } r_one=0; } } else if (state == HDLC_FLAG_FOUND) { if (val & 1) { r_one++; if (r_one>6) { state=HDLC_ZERO_SEARCH; } else { r_val >>= 1; r_val |= 0x80; bitcnt++; } } else { if (r_one==6) { bitcnt=0; r_val=0; r_one=0; val >>= 1; continue; } else if (r_one!=5) { r_val >>= 1; r_val &= 0x7f; bitcnt++; } r_one=0; } if ((state != HDLC_ZERO_SEARCH) && !(bitcnt & 7)) { state=HDLC_FRAME_FOUND; bcs->hw.tiger.r_fcs = PPP_INITFCS; bcs->hw.tiger.rcvbuf[0] = r_val; bcs->hw.tiger.r_fcs = PPP_FCS (bcs->hw.tiger.r_fcs, r_val); if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x", bcs->hw.tiger.r_tot,i,j,r_val,val, bcs->cs->hw.njet.irqstat0); } } else if (state == HDLC_FRAME_FOUND) { if (val & 1) { r_one++; if (r_one>6) { state=HDLC_ZERO_SEARCH; bitcnt=0; } else { r_val >>= 1; r_val |= 0x80; bitcnt++; } } else { if (r_one==6) { r_val=0; r_one=0; bitcnt++; if (bitcnt & 7) { debugl1(bcs->cs, "tiger: frame not byte aligned"); state=HDLC_FLAG_SEARCH; bcs->hw.tiger.r_err++; } else { if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger frame end(%d,%d): fcs(%x) i %x", i,j,bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0); if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) { got_frame(bcs, (bitcnt>>3)-3); } else if (bcs->cs->debug) { debugl1(bcs->cs, "tiger FCS error"); printframe(bcs->cs, bcs->hw.tiger.rcvbuf, (bitcnt>>3)-1, "rec"); bcs->hw.tiger.r_err++; } state=HDLC_FLAG_FOUND; } bitcnt=0; } else if (r_one==5) { val >>= 1; r_one=0; continue; } else { r_val >>= 1; r_val &= 0x7f; bitcnt++; } r_one=0; } if ((state == HDLC_FRAME_FOUND) && !(bitcnt & 7)) { if ((bitcnt>>3)>=HSCX_BUFMAX) { debugl1(bcs->cs, "tiger: frame to big"); r_val=0; state=HDLC_FLAG_SEARCH; bcs->hw.tiger.r_err++; } else { bcs->hw.tiger.rcvbuf[(bitcnt>>3)-1] = r_val; bcs->hw.tiger.r_fcs = PPP_FCS (bcs->hw.tiger.r_fcs, r_val); } } } val >>= 1; } bcs->hw.tiger.r_tot++; } bcs->hw.tiger.r_state = state; bcs->hw.tiger.r_one = r_one; bcs->hw.tiger.r_val = r_val; bcs->hw.tiger.r_bitcnt = bitcnt;}static void read_tiger(struct IsdnCardState *cs) { u_int *p; int cnt = NETJET_DMA_SIZE/2; if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) { debugl1(cs,"tiger warn read double dma %x/%x", cs->hw.njet.irqstat0, cs->hw.njet.last_is0); return; } else { cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ; cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ); } if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1) p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE - 1; else p = cs->bcs[0].hw.tiger.rec + cnt - 1; if (cs->bcs[0].mode == L1_MODE_HDLC) read_raw(cs->bcs, p, cnt); if (cs->bcs[1].mode == L1_MODE_HDLC) read_raw(cs->bcs + 1, p, cnt); cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_READ;}static void write_raw(struct BCState *bcs, u_int *buf, int cnt);static void fill_dma(struct BCState *bcs){ register u_int *p, *sp; register int cnt; if (!bcs->tx_skb) return; if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel, bcs->Flag); if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag)) return; if (make_raw_data(bcs)) return; if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel, bcs->Flag); if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free); } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) { p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR)); sp = bcs->hw.tiger.sendp; if (p == bcs->hw.tiger.s_end) p = bcs->hw.tiger.send -1; if (sp == bcs->hw.tiger.s_end) sp = bcs->hw.tiger.send -1; cnt = p - sp; if (cnt <0) { write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free); } else { p++; cnt++; if (p > bcs->hw.tiger.s_end) p = bcs->hw.tiger.send; p++; cnt++; if (p > bcs->hw.tiger.s_end) p = bcs->hw.tiger.send; write_raw(bcs, p, bcs->hw.tiger.free - cnt); } } else if (test_and_clear_bit(BC_FLG_EMPTY, &bcs->Flag)) { p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR)); cnt = bcs->hw.tiger.s_end - p; if (cnt < 2) { p = bcs->hw.tiger.send + 1; cnt = NETJET_DMA_SIZE/2 - 2; } else { p++; p++; if (cnt <= (NETJET_DMA_SIZE/2)) cnt += NETJET_DMA_SIZE/2; cnt--; cnt--; } write_raw(bcs, p, cnt); } if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel, bcs->Flag);}static void write_raw(struct BCState *bcs, u_int *buf, int cnt) { u_int mask, val, *p=buf; u_int i, s_cnt; if (cnt <= 0) return; if (test_bit(BC_FLG_BUSY, &bcs->Flag)) { if (bcs->hw.tiger.sendcnt> cnt) { s_cnt = cnt; bcs->hw.tiger.sendcnt -= cnt; } else { s_cnt = bcs->hw.tiger.sendcnt; bcs->hw.tiger.sendcnt = 0; } if (bcs->channel) mask = 0xffff00ff; else mask = 0xffffff00; for (i=0; i<s_cnt; i++) { val = bcs->channel ? ((bcs->hw.tiger.sp[i] <<8) & 0xff00) : (bcs->hw.tiger.sp[i]); *p &= mask; *p++ |= val; if (p>bcs->hw.tiger.s_end) p = bcs->hw.tiger.send; } bcs->hw.tiger.s_tot += s_cnt; if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger write_raw: c%d %x-%x %d/%d %d %x", bcs->channel, (u_int)buf, (u_int)p, s_cnt, cnt, bcs->hw.tiger.sendcnt, bcs->cs->hw.njet.irqstat0); if (bcs->cs->debug & L1_DEB_HSCX_FIFO) printframe(bcs->cs, bcs->hw.tiger.sp, s_cnt, "snd"); bcs->hw.tiger.sp += s_cnt; bcs->hw.tiger.sendp = p; if (!bcs->hw.tiger.sendcnt) { if (!bcs->tx_skb) { debugl1(bcs->cs,"tiger write_raw: NULL skb s_cnt %d", s_cnt); } else { if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len); dev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; } test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); bcs->hw.tiger.free = cnt - s_cnt; if (bcs->hw.tiger.free > (NETJET_DMA_SIZE/2)) test_and_set_bit(BC_FLG_HALF, &bcs->Flag); else { test_and_clear_bit(BC_FLG_HALF, &bcs->Flag); test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag); } if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { fill_dma(bcs); } else { mask ^= 0xffffffff; if (s_cnt < cnt) { for (i=s_cnt; i<cnt;i++) { *p++ |= mask; if (p>bcs->hw.tiger.s_end) p = bcs->hw.tiger.send; } if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs, "tiger write_raw: fill rest %d", cnt - s_cnt); } bcs->event |= 1 << B_XMTBUFREADY; queue_task(&bcs->tqueue, &tq_immediate); mark_bh(IMMEDIATE_BH); } } } else if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { test_and_set_bit(BC_FLG_HALF, &bcs->Flag); fill_mem(bcs, buf, cnt, bcs->channel, 0xff); bcs->hw.tiger.free += cnt; if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger write_raw: fill half"); } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) { test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag); fill_mem(bcs, buf, cnt, bcs->channel, 0xff); if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger write_raw: fill full"); }}static void write_tiger(struct IsdnCardState *cs) { u_int *p, cnt = NETJET_DMA_SIZE/2; if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) { debugl1(cs,"tiger warn write double dma %x/%x", cs->hw.njet.irqstat0, cs->hw.njet.last_is0); return; } else { cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE; cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE); } if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE_1) p = cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE - 1; else p = cs->bcs[0].hw.tiger.send + cnt - 1; if (cs->bcs[0].mode == L1_MODE_HDLC) write_raw(cs->bcs, p, cnt); if (cs->bcs[1].mode == L1_MODE_HDLC) write_raw(cs->bcs + 1, p, cnt); cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_WRITE;}static voidtiger_l2l1(struct PStack *st, int pr, void *arg){ struct sk_buff *skb = arg; long flags; switch (pr) { case (PH_DATA | REQUEST): save_flags(flags); cli();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -