void __init initW6692(struct IsdnCardState *cs, int part)
{
	if (part & 1) {
		cs->tqueue.routine = (void *) (void *) W6692_bh;
		cs->setstack_d = setstack_W6692;
		cs->DC_Close = DC_Close_W6692;
		cs->dbusytimer.function = (void *) dbusy_timer_handler;
		cs->dbusytimer.data = (long) cs;
		init_timer(&cs->dbusytimer);
		resetW6692(cs);
		ph_command(cs, W_L1CMD_RST);
		cs->dc.w6692.ph_state = W_L1CMD_RST;
		W6692_new_ph(cs);
		ph_command(cs, W_L1CMD_ECK);

		cs->bcs[0].BC_SetStack = setstack_w6692;
		cs->bcs[1].BC_SetStack = setstack_w6692;
		cs->bcs[0].BC_Close = close_w6692state;
		cs->bcs[1].BC_Close = close_w6692state;
		W6692Bmode(cs->bcs, 0, 0);
		W6692Bmode(cs->bcs + 1, 0, 0);
	}
	if (part & 2) {
		/* Reenable all IRQ */
		cs->writeW6692(cs, W_IMASK, 0x18);
		cs->writeW6692(cs, W_D_EXIM, 0x00);
		cs->BC_Write_Reg(cs, 0, W_B_EXIM, 0x00);
		cs->BC_Write_Reg(cs, 1, W_B_EXIM, 0x00);
		/* Reset D-chan receiver and transmitter */
		cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST);
	}
}
Пример #2
0
void initW6692(struct w6692_hw *card)
{
	u8	val;

	card->dch.timer.function = (void *)dbusy_timer_handler;
	card->dch.timer.data = (u_long)&card->dch;
	init_timer(&card->dch.timer);
	w6692_mode(&card->bc[0], ISDN_P_NONE);
	w6692_mode(&card->bc[1], ISDN_P_NONE);
	WriteW6692(card, W_D_CTL, 0x00);
	disable_hwirq(card);
	WriteW6692(card, W_D_SAM, 0xff);
	WriteW6692(card, W_D_TAM, 0xff);
	WriteW6692(card, W_D_MODE, W_D_MODE_RACT);
	card->state = W_L1CMD_RST;
	ph_command(card, W_L1CMD_RST);
	ph_command(card, W_L1CMD_ECK);
	/* enable all IRQ but extern */
	card->imask = 0x18;
	WriteW6692(card, W_D_EXIM, 0x00);
	WriteW6692B(&card->bc[0], W_B_EXIM, 0);
	WriteW6692B(&card->bc[1], W_B_EXIM, 0);
	/* Reset D-chan receiver and transmitter */
	WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST);
	/* Reset B-chan receiver and transmitter */
	WriteW6692B(&card->bc[0], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
	WriteW6692B(&card->bc[1], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
	/* enable peripheral */
	if (card->subtype == W6692_USR) {
		/* seems that USR implemented some power control features
		 * Pin 79 is connected to the oscilator circuit so we
		 * have to handle it here
		 */
		card->pctl = 0x80;
		card->xdata = 0;
		WriteW6692(card, W_PCTL, card->pctl);
		WriteW6692(card, W_XDATA, card->xdata);
	} else {
		card->pctl = W_PCTL_OE5 | W_PCTL_OE4 | W_PCTL_OE2 |
			W_PCTL_OE1 | W_PCTL_OE0;
		card->xaddr = 0x00;/* all sw off */
		if (card->fmask & pots)
			card->xdata |= 0x06;	/*  POWER UP/ LED OFF / ALAW */
		if (card->fmask & led)
			card->xdata |= 0x04;	/* LED OFF */
		if ((card->fmask & pots) || (card->fmask & led)) {
			WriteW6692(card, W_PCTL, card->pctl);
			WriteW6692(card, W_XADDR, card->xaddr);
			WriteW6692(card, W_XDATA, card->xdata);
			val = ReadW6692(card, W_XADDR);
			if (debug & DEBUG_HW)
				pr_notice("%s: W_XADDR=%02x\n",
					card->name, val);
		}
	}
}
Пример #3
0
void initW6692(struct w6692_hw *card)
{
	u8	val;

	card->dch.timer.function = (void *)dbusy_timer_handler;
	card->dch.timer.data = (u_long)&card->dch;
	init_timer(&card->dch.timer);
	w6692_mode(&card->bc[0], ISDN_P_NONE);
	w6692_mode(&card->bc[1], ISDN_P_NONE);
	WriteW6692(card, W_D_CTL, 0x00);
	disable_hwirq(card);
	WriteW6692(card, W_D_SAM, 0xff);
	WriteW6692(card, W_D_TAM, 0xff);
	WriteW6692(card, W_D_MODE, W_D_MODE_RACT);
	card->state = W_L1CMD_RST;
	ph_command(card, W_L1CMD_RST);
	ph_command(card, W_L1CMD_ECK);
	
	card->imask = 0x18;
	WriteW6692(card, W_D_EXIM, 0x00);
	WriteW6692B(&card->bc[0], W_B_EXIM, 0);
	WriteW6692B(&card->bc[1], W_B_EXIM, 0);
	
	WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST);
	
	WriteW6692B(&card->bc[0], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
	WriteW6692B(&card->bc[1], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
	
	if (card->subtype == W6692_USR) {
		
		card->pctl = 0x80;
		card->xdata = 0;
		WriteW6692(card, W_PCTL, card->pctl);
		WriteW6692(card, W_XDATA, card->xdata);
	} else {
		card->pctl = W_PCTL_OE5 | W_PCTL_OE4 | W_PCTL_OE2 |
			W_PCTL_OE1 | W_PCTL_OE0;
		card->xaddr = 0x00;
		if (card->fmask & pots)
			card->xdata |= 0x06;	
		if (card->fmask & led)
			card->xdata |= 0x04;	
		if ((card->fmask & pots) || (card->fmask & led)) {
			WriteW6692(card, W_PCTL, card->pctl);
			WriteW6692(card, W_XADDR, card->xaddr);
			WriteW6692(card, W_XDATA, card->xdata);
			val = ReadW6692(card, W_XADDR);
			if (debug & DEBUG_HW)
				pr_notice("%s: W_XADDR=%02x\n",
					card->name, val);
		}
	}
}
Пример #4
0
static void
icc_new_ph(struct IsdnCardState *cs)
{
	switch (cs->dc.icc.ph_state) {
		case (ICC_IND_EI1):
			ph_command(cs, ICC_CMD_DI);
			l1_msg(cs, HW_RESET | INDICATION, NULL);
			break;
		case (ICC_IND_DC):
			l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
			break;
		case (ICC_IND_DR):
			l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
			break;
		case (ICC_IND_PU):
			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
			break;
		case (ICC_IND_FJ):
			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
			break;
		case (ICC_IND_AR):
			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
			break;
		case (ICC_IND_AI):
			l1_msg(cs, HW_INFO4 | INDICATION, NULL);
			break;
		default:
			break;
	}
}
static void
W6692_new_ph(struct IsdnCardState *cs)
{
	switch (cs->dc.w6692.ph_state) {
		case (W_L1CMD_RST):
			ph_command(cs, W_L1CMD_DRC);
			l1_msg(cs, HW_RESET | INDICATION, NULL);
			/* fallthru */
		case (W_L1IND_CD):
			l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
			break;
		case (W_L1IND_DRD):
			l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
			break;
		case (W_L1IND_CE):
			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
			break;
		case (W_L1IND_LD):
			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
			break;
		case (W_L1IND_ARD):
			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
			break;
		case (W_L1IND_AI8):
			l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
			break;
		case (W_L1IND_AI10):
			l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
			break;
		default:
			break;
	}
}
static void l1_timer3(struct FsmInst *fi, int event, void *arg)
{
	struct isac *isac = fi->userdata;

	ph_command(isac, ISAC_CMD_DI);
	D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL);
}
static void l1_ar8(struct FsmInst *fi, int event, void *arg)
{
	struct isac *isac = fi->userdata;

	FsmRestartTimer(&isac->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2);
	ph_command(isac, ISAC_CMD_AR8);
}
static void l1_go_f3pend(struct FsmInst *fi, int event, void *arg)
{
	struct isac *isac = fi->userdata;

	FsmChangeState(fi, ST_L1_F3_PEND_DEACT);
	ph_command(isac, ISAC_CMD_DI);
}
static void l1_di(struct FsmInst *fi, int event, void *arg)
{
	struct isac *isac = fi->userdata;

	FsmChangeState(fi, ST_L1_RESET);
	ph_command(isac, ISAC_CMD_DI);
}
Пример #10
0
static void
W6692_new_ph(struct w6692_hw *card)
{
	if (card->state == W_L1CMD_RST)
		ph_command(card, W_L1CMD_DRC);
	schedule_event(&card->dch, FLG_PHCHANGE);
}
Пример #11
0
static void
isac_new_ph(struct IsdnCardState *cs)
{
	switch (cs->dc.isac.ph_state) {
		case (ISAC_IND_RS):
		case (ISAC_IND_EI):
			ph_command(cs, ISAC_CMD_DUI);
			l1_msg(cs, HW_RESET | INDICATION, NULL);
			break;
		case (ISAC_IND_DID):
			l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
			break;
		case (ISAC_IND_DR):
			l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
			break;
		case (ISAC_IND_PU):
			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
			break;
		case (ISAC_IND_RSY):
			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
			break;
		case (ISAC_IND_ARD):
			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
			break;
		case (ISAC_IND_AI8):
			l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
			break;
		case (ISAC_IND_AI10):
			l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
			break;
		default:
			break;
	}
}
static void l1_go_f3pend_deact_ind(struct FsmInst *fi, int event, void *arg)
{
	struct isac *isac = fi->userdata;

	FsmChangeState(fi, ST_L1_F3_PEND_DEACT);
	D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL);
	ph_command(isac, ISAC_CMD_DI);
}
static void l1_go_f7_act_ind(struct FsmInst *fi, int event, void *arg)
{
	struct isac *isac = fi->userdata;

	FsmDelTimer(&isac->timer, 0);
	FsmChangeState(fi, ST_L1_F7);
	ph_command(isac, ISAC_CMD_AR8);
	D_L1L2(isac, PH_ACTIVATE | INDICATION, NULL);
}
Пример #14
0
static void
isac_ph_state_change(struct isac_hw *isac)
{
	switch (isac->state) {
	case (ISAC_IND_RS):
	case (ISAC_IND_EI):
		ph_command(isac, ISAC_CMD_DUI);
	}
	schedule_event(&isac->dch, FLG_PHCHANGE);
}
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;
	}
}
Пример #16
0
static int
w6692_l1callback(struct dchannel *dch, u32 cmd)
{
	struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
	u_long flags;

	pr_debug("%s: cmd(%x) state(%02x)\n", card->name, cmd, card->state);
	switch (cmd) {
	case INFO3_P8:
		spin_lock_irqsave(&card->lock, flags);
		ph_command(card, W_L1CMD_AR8);
		spin_unlock_irqrestore(&card->lock, flags);
		break;
	case INFO3_P10:
		spin_lock_irqsave(&card->lock, flags);
		ph_command(card, W_L1CMD_AR10);
		spin_unlock_irqrestore(&card->lock, flags);
		break;
	case HW_RESET_REQ:
		spin_lock_irqsave(&card->lock, flags);
		if (card->state != W_L1IND_DRD)
			ph_command(card, W_L1CMD_RST);
		ph_command(card, W_L1CMD_ECK);
		spin_unlock_irqrestore(&card->lock, flags);
		break;
	case HW_DEACT_REQ:
		skb_queue_purge(&dch->squeue);
		if (dch->tx_skb) {
			dev_kfree_skb(dch->tx_skb);
			dch->tx_skb = NULL;
		}
		dch->tx_idx = 0;
		if (dch->rx_skb) {
			dev_kfree_skb(dch->rx_skb);
			dch->rx_skb = NULL;
		}
		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
			del_timer(&dch->timer);
		break;
	case HW_POWERUP_REQ:
		spin_lock_irqsave(&card->lock, flags);
		ph_command(card, W_L1CMD_ECK);
		spin_unlock_irqrestore(&card->lock, flags);
		break;
	case PH_ACTIVATE_IND:
		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
			GFP_ATOMIC);
		break;
	case PH_DEACTIVATE_IND:
		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
			GFP_ATOMIC);
		break;
	default:
		pr_debug("%s: %s unknown command %x\n", card->name,
			__func__, cmd);
		return -1;
	}
	return 0;
}