static void hisax_d_l2l1(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs = st->l1.hardware; struct hisax_d_if *hisax_d_if = cs->hw.hisax_d_if; struct sk_buff *skb = arg; switch (pr) { case PH_DATA | REQUEST: case PH_PULL | INDICATION: if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); Logl2Frame(cs, skb, "PH_DATA_REQ", 0); // FIXME lock? if (!test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags)) D_L2L1(hisax_d_if, PH_DATA | REQUEST, skb); else skb_queue_tail(&cs->sq, skb); break; case PH_PULL | REQUEST: if (!test_bit(FLG_L1_DBUSY, &cs->HW_Flags)) st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); else set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; default: D_L2L1(hisax_d_if, pr, arg); break; } }
static void HFCD_l1hw(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; u_long flags; switch (pr) { case (PH_DATA | REQUEST): if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); spin_lock_irqsave(&cs->lock, flags); if (cs->tx_skb) { skb_queue_tail(&cs->sq, skb); #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0); #endif } else { cs->tx_skb = skb; cs->tx_cnt = 0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0); #endif if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { hfc_fill_dfifo(cs); test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); } else debugl1(cs, "hfc_fill_dfifo blocked"); } spin_unlock_irqrestore(&cs->lock, flags); break; case (PH_PULL | INDICATION): spin_lock_irqsave(&cs->lock, flags); if (cs->tx_skb) { if (cs->debug & L1_DEB_WARN) debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); skb_queue_tail(&cs->sq, skb); spin_unlock_irqrestore(&cs->lock, flags); break; } if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); cs->tx_skb = skb; cs->tx_cnt = 0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); #endif if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { hfc_fill_dfifo(cs); test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); } else debugl1(cs, "hfc_fill_dfifo blocked"); spin_unlock_irqrestore(&cs->lock, flags); break; case (PH_PULL | REQUEST): #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL"); #endif if (!cs->tx_skb) { test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); } else test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; case (HW_RESET | REQUEST): spin_lock_irqsave(&cs->lock, flags); cs->writeisac(cs, HFCD_STATES, HFCD_LOAD_STATE | 3); /* HFC ST 3 */ udelay(6); cs->writeisac(cs, HFCD_STATES, 3); /* HFC ST 2 */ cs->hw.hfcD.mst_m |= HFCD_MASTER; cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m); cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION); spin_unlock_irqrestore(&cs->lock, flags); l1_msg(cs, HW_POWERUP | CONFIRM, NULL); break; case (HW_ENABLE | REQUEST): spin_lock_irqsave(&cs->lock, flags); cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION); spin_unlock_irqrestore(&cs->lock, flags); break; case (HW_DEACTIVATE | REQUEST): spin_lock_irqsave(&cs->lock, flags); cs->hw.hfcD.mst_m &= ~HFCD_MASTER; cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m); spin_unlock_irqrestore(&cs->lock, flags); break; case (HW_INFO3 | REQUEST): spin_lock_irqsave(&cs->lock, flags); cs->hw.hfcD.mst_m |= HFCD_MASTER; cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m); spin_unlock_irqrestore(&cs->lock, flags); break; default: if (cs->debug & L1_DEB_WARN) debugl1(cs, "hfcd_l1hw unknown pr %4x", pr); break; } }
static void W6692_l1hw(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; int val; switch (pr) { case (PH_DATA | REQUEST): if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); if (cs->tx_skb) { skb_queue_tail(&cs->sq, skb); #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0); #endif } else { cs->tx_skb = skb; cs->tx_cnt = 0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0); #endif W6692_fill_fifo(cs); } break; case (PH_PULL | INDICATION): if (cs->tx_skb) { if (cs->debug & L1_DEB_WARN) debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); skb_queue_tail(&cs->sq, skb); break; } if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); cs->tx_skb = skb; cs->tx_cnt = 0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); #endif W6692_fill_fifo(cs); break; case (PH_PULL | REQUEST): #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL"); #endif if (!cs->tx_skb) { test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); } else test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; case (HW_RESET | REQUEST): if ((cs->dc.w6692.ph_state == W_L1IND_DRD)) ph_command(cs, W_L1CMD_ECK); else { ph_command(cs, W_L1CMD_RST); cs->dc.w6692.ph_state = W_L1CMD_RST; W6692_new_ph(cs); } break; case (HW_ENABLE | REQUEST): ph_command(cs, W_L1CMD_ECK); break; case (HW_INFO3 | REQUEST): ph_command(cs, W_L1CMD_AR8); break; case (HW_TESTLOOP | REQUEST): val = 0; if (1 & (long) arg) val |= 0x0c; if (2 & (long) arg) val |= 0x3; /* !!! not implemented yet */ break; case (HW_DEACTIVATE | RESPONSE): skb_queue_purge(&cs->rq); skb_queue_purge(&cs->sq); if (cs->tx_skb) { dev_kfree_skb_any(cs->tx_skb); cs->tx_skb = NULL; } if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) del_timer(&cs->dbusytimer); if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) W6692_sched_event(cs, D_CLEARBUSY); break; default: if (cs->debug & L1_DEB_WARN) debugl1(cs, "W6692_l1hw unknown %04x", pr); break; } }
static void Amd7930_l1hw(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; u_long flags; if (cs->debug & L1_DEB_ISAC) debugl1(cs, "Amd7930: l1hw called, pr: 0x%04X", pr); switch (pr) { case (PH_DATA | REQUEST): if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); spin_lock_irqsave(&cs->lock, flags); if (cs->tx_skb) { skb_queue_tail(&cs->sq, skb); #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA Queued", 0); #endif } else { cs->tx_skb = skb; cs->tx_cnt = 0; cs->dc.amd7930.tx_xmtlen=0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA", 0); #endif Amd7930_fill_Dfifo(cs); } spin_unlock_irqrestore(&cs->lock, flags); break; case (PH_PULL | INDICATION): spin_lock_irqsave(&cs->lock, flags); if (cs->tx_skb) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen"); skb_queue_tail(&cs->sq, skb); spin_unlock_irqrestore(&cs->lock, flags); break; } if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); cs->tx_skb = skb; cs->tx_cnt = 0; cs->dc.amd7930.tx_xmtlen=0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA_PULLED", 0); #endif Amd7930_fill_Dfifo(cs); spin_unlock_irqrestore(&cs->lock, flags); break; case (PH_PULL | REQUEST): #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) debugl1(cs, "Amd7930: l1hw: -> PH_REQUEST_PULL, skb: %s", (cs->tx_skb)? "yes":"no"); #endif if (!cs->tx_skb) { test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); } else test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; case (HW_RESET | REQUEST): spin_lock_irqsave(&cs->lock, flags); if ((cs->dc.amd7930.ph_state == 8)) { /* b-channels off, PH-AR cleared * change to F3 */ Amd7930_ph_command(cs, 0x20, "HW_RESET REQEST"); //LMR1 bit 5 spin_unlock_irqrestore(&cs->lock, flags); } else { Amd7930_ph_command(cs, 0x40, "HW_RESET REQUEST"); cs->dc.amd7930.ph_state = 2; spin_unlock_irqrestore(&cs->lock, flags); Amd7930_new_ph(cs); } break; case (HW_ENABLE | REQUEST): cs->dc.amd7930.ph_state = 9; Amd7930_new_ph(cs); break; case (HW_INFO3 | REQUEST): // automatic break; case (HW_TESTLOOP | REQUEST): /* not implemented yet */ break; case (HW_DEACTIVATE | RESPONSE): skb_queue_purge(&cs->rq); skb_queue_purge(&cs->sq); if (cs->tx_skb) { dev_kfree_skb(cs->tx_skb); cs->tx_skb = NULL; } if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) del_timer(&cs->dbusytimer); if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) schedule_event(cs, D_CLEARBUSY); break; default: if (cs->debug & L1_DEB_WARN) debugl1(cs, "Amd7930: l1hw: unknown %04x", pr); break; } }
void DChannel_proc_rcv(struct IsdnCardState *cs) { struct sk_buff *skb, *nskb; struct PStack *stptr = cs->stlist; int found, tei, sapi; if (stptr) if (test_bit(FLG_L1_ACTTIMER, &stptr->l1.Flags)) FsmEvent(&stptr->l1.l1m, EV_TIMER_ACT, NULL); while ((skb = skb_dequeue(&cs->rq))) { #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 1); #endif stptr = cs->stlist; if (skb->len<3) { debugl1(cs, "D-channel frame too short(%d)",skb->len); dev_kfree_skb(skb); return; } if ((skb->data[0] & 1) || !(skb->data[1] &1)) { debugl1(cs, "D-channel frame wrong EA0/EA1"); dev_kfree_skb(skb); return; } sapi = skb->data[0] >> 2; tei = skb->data[1] >> 1; if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 1); if (tei == GROUP_TEI) { if (sapi == CTRL_SAPI) { /* sapi 0 */ while (stptr != NULL) { if ((nskb = skb_clone(skb, GFP_ATOMIC))) stptr->l1.l1l2(stptr, PH_DATA | INDICATION, nskb); else printk(KERN_WARNING "HiSax: isdn broadcast buffer shortage\n"); stptr = stptr->next; } } else if (sapi == TEI_SAPI) { while (stptr != NULL) { if ((nskb = skb_clone(skb, GFP_ATOMIC))) stptr->l1.l1tei(stptr, PH_DATA | INDICATION, nskb); else printk(KERN_WARNING "HiSax: tei broadcast buffer shortage\n"); stptr = stptr->next; } } dev_kfree_skb(skb); } else if (sapi == CTRL_SAPI) { /* sapi 0 */ found = 0; while (stptr != NULL) if (tei == stptr->l2.tei) { stptr->l1.l1l2(stptr, PH_DATA | INDICATION, skb); found = !0; break; } else stptr = stptr->next; if (!found) dev_kfree_skb(skb); } else dev_kfree_skb(skb); } }
static void amd7930_Dchan_l2l1(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; char str[64]; switch (pr) { case (PH_DATA_REQ): if (cs->tx_skb) { skb_queue_tail(&cs->sq, skb); #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0); #endif } else { if ((cs->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */ LogFrame(cs, skb->data, skb->len); sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei); dlogframe(cs, skb->data+4, skb->len-4, str); } cs->tx_skb = skb; cs->tx_cnt = 0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0); #endif amd7930_dxmit(0, skb->data, skb->len, &amd7930_dxmit_callback, cs); } break; case (PH_PULL_IND): if (cs->tx_skb) { if (cs->debug & L1_DEB_WARN) debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); skb_queue_tail(&cs->sq, skb); break; } if ((cs->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */ LogFrame(cs, skb->data, skb->len); sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei); dlogframe(cs, skb->data + 4, skb->len - 4, str); } cs->tx_skb = skb; cs->tx_cnt = 0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); #endif amd7930_dxmit(0, cs->tx_skb->data, cs->tx_skb->len, &amd7930_dxmit_callback, cs); break; case (PH_PULL_REQ): #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL"); #endif if (!cs->tx_skb) { test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); st->l1.l1l2(st, PH_PULL_CNF, NULL); } else test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; } }