static void tx_d_frame(struct hfc4s8s_l1 *l1p) { struct sk_buff *skb; u_char f1, f2; u_char *cp; long cnt; if (l1p->l1_state != 7) return; /* TX fifo */ Write_hfc8(l1p->hw, R_FIFO, (l1p->st_num * 8 + 4)); wait_busy(l1p->hw); f1 = Read_hfc8(l1p->hw, A_F1); f2 = Read_hfc8_stable(l1p->hw, A_F2); if ((f1 ^ f2) & MAX_F_CNT) return; /* fifo is still filled */ if (l1p->tx_cnt > 0) { cnt = l1p->tx_cnt; l1p->tx_cnt = 0; l1p->d_if.ifc.l1l2(&l1p->d_if.ifc, PH_DATA | CONFIRM, (void *) cnt); } if ((skb = skb_dequeue(&l1p->d_tx_queue))) { cp = skb->data; cnt = skb->len; SetRegAddr(l1p->hw, A_FIFO_DATA0); while (cnt >= 4) { SetRegAddr(l1p->hw, A_FIFO_DATA0); fWrite_hfc32(l1p->hw, *(unsigned long *) cp); cp += 4; cnt -= 4; } while (cnt--) fWrite_hfc8(l1p->hw, *cp++); l1p->tx_cnt = skb->truesize; Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); /* increment f counter */ wait_busy(l1p->hw); dev_kfree_skb(skb); } } /* tx_d_frame */
static void tx_b_frame(struct hfc4s8s_btype *bch) { struct sk_buff *skb; struct hfc4s8s_l1 *l1 = bch->l1p; u_char *cp; int cnt, max, hdlc_num; long ack_len = 0; if (!l1->enabled || (bch->mode == L1_MODE_NULL)) return; /* TX fifo */ Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); wait_busy(l1->hw); do { if (bch->mode == L1_MODE_HDLC) { hdlc_num = Read_hfc8(l1->hw, A_F1) & MAX_F_CNT; hdlc_num -= (Read_hfc8_stable(l1->hw, A_F2) & MAX_F_CNT); if (hdlc_num < 0) hdlc_num += 16; if (hdlc_num >= 15) break; /* fifo still filled up with hdlc frames */ } else hdlc_num = 0; if (!(skb = bch->tx_skb)) { if (!(skb = skb_dequeue(&bch->tx_queue))) { l1->hw->mr.fifo_slow_timer_service[l1-> st_num] &= ~((bch->bchan == 1) ? 1 : 4); break; /* list empty */ } bch->tx_skb = skb; bch->tx_cnt = 0; } if (!hdlc_num) l1->hw->mr.fifo_slow_timer_service[l1->st_num] |= ((bch->bchan == 1) ? 1 : 4); else l1->hw->mr.fifo_slow_timer_service[l1->st_num] &= ~((bch->bchan == 1) ? 1 : 4); max = Read_hfc16_stable(l1->hw, A_Z2); max -= Read_hfc16(l1->hw, A_Z1); if (max <= 0) max += 384; max--; if (max < 16) break; /* don't write to small amounts of bytes */ cnt = skb->len - bch->tx_cnt; if (cnt > max) cnt = max; cp = skb->data + bch->tx_cnt; bch->tx_cnt += cnt; #ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1->hw, A_FIFO_DATA0); #endif while (cnt >= 4) { #ifdef HISAX_HFC4S8S_PCIMEM fWrite_hfc32(l1->hw, A_FIFO_DATA0, *(unsigned long *) cp); #else fWrite_hfc32(l1->hw, *(unsigned long *) cp); #endif cp += 4; cnt -= 4; } while (cnt--) #ifdef HISAX_HFC4S8S_PCIMEM fWrite_hfc8(l1->hw, A_FIFO_DATA0, *cp++); #else fWrite_hfc8(l1->hw, *cp++); #endif if (bch->tx_cnt >= skb->len) { if (bch->mode == L1_MODE_HDLC) { /* increment f counter */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 1); } ack_len += skb->truesize; bch->tx_skb = NULL; bch->tx_cnt = 0; dev_kfree_skb(skb); } else /* Re-Select */ Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); wait_busy(l1->hw); } while (1); if (ack_len) bch->b_if.ifc.l1l2((struct hisax_if *) &bch->b_if, PH_DATA | CONFIRM, (void *) ack_len); } /* tx_b_frame */
static void tx_d_frame(struct hfc4s8s_l1 *l1p) { struct sk_buff *skb; u_char f1, f2; u_char *cp; long cnt; if (l1p->l1_state != 7) return; /* */ Write_hfc8(l1p->hw, R_FIFO, (l1p->st_num * 8 + 4)); wait_busy(l1p->hw); f1 = Read_hfc8(l1p->hw, A_F1); f2 = Read_hfc8_stable(l1p->hw, A_F2); if ((f1 ^ f2) & MAX_F_CNT) return; /* */ if (l1p->tx_cnt > 0) { cnt = l1p->tx_cnt; l1p->tx_cnt = 0; l1p->d_if.ifc.l1l2(&l1p->d_if.ifc, PH_DATA | CONFIRM, (void *) cnt); } if ((skb = skb_dequeue(&l1p->d_tx_queue))) { cp = skb->data; cnt = skb->len; #ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1p->hw, A_FIFO_DATA0); #endif while (cnt >= 4) { #ifdef HISAX_HFC4S8S_PCIMEM fWrite_hfc32(l1p->hw, A_FIFO_DATA0, *(unsigned long *) cp); #else SetRegAddr(l1p->hw, A_FIFO_DATA0); fWrite_hfc32(l1p->hw, *(unsigned long *) cp); #endif cp += 4; cnt -= 4; } #ifdef HISAX_HFC4S8S_PCIMEM while (cnt--) fWrite_hfc8(l1p->hw, A_FIFO_DATA0, *cp++); #else while (cnt--) fWrite_hfc8(l1p->hw, *cp++); #endif l1p->tx_cnt = skb->truesize; Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); /* */ wait_busy(l1p->hw); dev_kfree_skb(skb); } } /* */