⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pc300_drv.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 */void falc_remote_loop(pc300_t * card, int ch, int loop_on){	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;	falc_t *pfalc = (falc_t *) & chan->falc;	uclong falcbase = card->hw.falcbase;	if (loop_on) {		// EVENT_FALC_ABNORMAL		if (conf->media == IF_IFACE_T1) {			/* Disable this interrupt as it may otherwise interfere with 			 * other working boards. */			cpc_writeb(falcbase + F_REG(IMR0, ch),				   cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN);		}		falc_disable_comm(card, ch);		// EVENT_FALC_ABNORMAL		cpc_writeb(falcbase + F_REG(LIM1, ch),			   cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RL);		pfalc->loop_active = 1;	} else {		cpc_writeb(falcbase + F_REG(LIM1, ch),			   cpc_readb(falcbase + F_REG(LIM1, ch)) & ~LIM1_RL);		pfalc->sync = 0;		cpc_writeb(falcbase + card->hw.cpld_reg2,			   cpc_readb(falcbase + card->hw.cpld_reg2) &			   ~(CPLD_REG2_FALC_LED2 << (2 * ch)));		pfalc->active = 0;		falc_issue_cmd(card, ch, CMDR_XRES);		pfalc->loop_active = 0;	}}/*---------------------------------------------------------------------------- * falc_local_loop *---------------------------------------------------------------------------- * Description: The local loopback mode disconnects the receive lines  *		RL1/RL2 resp. RDIP/RDIN from the receiver. Instead of the *		signals coming from the line the data provided by system *		interface are routed through the analog receiver back to *		the system interface. The unipolar bit stream will be *		undisturbed transmitted on the line. Receiver and transmitter *		coding must be identical. *---------------------------------------------------------------------------- */void falc_local_loop(pc300_t * card, int ch, int loop_on){	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];	falc_t *pfalc = (falc_t *) & chan->falc;	uclong falcbase = card->hw.falcbase;	if (loop_on) {		cpc_writeb(falcbase + F_REG(LIM0, ch),			   cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_LL);		pfalc->loop_active = 1;	} else {		cpc_writeb(falcbase + F_REG(LIM0, ch),			   cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_LL);		pfalc->loop_active = 0;	}}/*---------------------------------------------------------------------------- * falc_payload_loop *---------------------------------------------------------------------------- * Description: This routine allows to enable/disable payload loopback. *		When the payload loop is activated, the received 192 bits *		of payload data will be looped back to the transmit *		direction. The framing bits, CRC6 and DL bits are not  *		looped. They are originated by the FALC-LH transmitter. *---------------------------------------------------------------------------- */void falc_payload_loop(pc300_t * card, int ch, int loop_on){	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;	falc_t *pfalc = (falc_t *) & chan->falc;	uclong falcbase = card->hw.falcbase;	if (loop_on) {		// EVENT_FALC_ABNORMAL		if (conf->media == IF_IFACE_T1) {			/* Disable this interrupt as it may otherwise interfere with 			 * other working boards. */			cpc_writeb(falcbase + F_REG(IMR0, ch),				   cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN);		}		falc_disable_comm(card, ch);		// EVENT_FALC_ABNORMAL		cpc_writeb(falcbase + F_REG(FMR2, ch),			   cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_PLB);		if (conf->media == IF_IFACE_T1) {			cpc_writeb(falcbase + F_REG(FMR4, ch),				   cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_TM);		} else {			cpc_writeb(falcbase + F_REG(FMR5, ch),				   cpc_readb(falcbase + F_REG(FMR5, ch)) | XSP_TT0);		}		falc_open_all_timeslots(card, ch);		pfalc->loop_active = 2;	} else {		cpc_writeb(falcbase + F_REG(FMR2, ch),			   cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_PLB);		if (conf->media == IF_IFACE_T1) {			cpc_writeb(falcbase + F_REG(FMR4, ch),				   cpc_readb(falcbase + F_REG(FMR4, ch)) & ~FMR4_TM);		} else {			cpc_writeb(falcbase + F_REG(FMR5, ch),				   cpc_readb(falcbase + F_REG(FMR5, ch)) & ~XSP_TT0);		}		pfalc->sync = 0;		cpc_writeb(falcbase + card->hw.cpld_reg2,			   cpc_readb(falcbase + card->hw.cpld_reg2) &			   ~(CPLD_REG2_FALC_LED2 << (2 * ch)));		pfalc->active = 0;		falc_issue_cmd(card, ch, CMDR_XRES);		pfalc->loop_active = 0;	}}/*---------------------------------------------------------------------------- * turn_off_xlu *---------------------------------------------------------------------------- * Description:	Turns XLU bit off in the proper register *---------------------------------------------------------------------------- */void turn_off_xlu(pc300_t * card, int ch){	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;	uclong falcbase = card->hw.falcbase;	if (conf->media == IF_IFACE_T1) {		cpc_writeb(falcbase + F_REG(FMR5, ch),			   cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLU);	} else {		cpc_writeb(falcbase + F_REG(FMR3, ch),			   cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLU);	}}/*---------------------------------------------------------------------------- * turn_off_xld *---------------------------------------------------------------------------- * Description: Turns XLD bit off in the proper register *---------------------------------------------------------------------------- */void turn_off_xld(pc300_t * card, int ch){	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;	uclong falcbase = card->hw.falcbase;	if (conf->media == IF_IFACE_T1) {		cpc_writeb(falcbase + F_REG(FMR5, ch),			   cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLD);	} else {		cpc_writeb(falcbase + F_REG(FMR3, ch),			   cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLD);	}}/*---------------------------------------------------------------------------- * falc_generate_loop_up_code *---------------------------------------------------------------------------- * Description:	This routine writes the proper FALC chip register in order *		to generate a LOOP activation code over a T1/E1 line. *---------------------------------------------------------------------------- */void falc_generate_loop_up_code(pc300_t * card, int ch){	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;	falc_t *pfalc = (falc_t *) & chan->falc;	uclong falcbase = card->hw.falcbase;	if (conf->media == IF_IFACE_T1) {		cpc_writeb(falcbase + F_REG(FMR5, ch),			   cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLU);	} else {		cpc_writeb(falcbase + F_REG(FMR3, ch),			   cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLU);	}	// EVENT_FALC_ABNORMAL	if (conf->media == IF_IFACE_T1) {		/* Disable this interrupt as it may otherwise interfere with 		 * other working boards. */		cpc_writeb(falcbase + F_REG(IMR0, ch),			   cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN);	}	falc_disable_comm(card, ch);	// EVENT_FALC_ABNORMAL	pfalc->loop_gen = 1;}/*---------------------------------------------------------------------------- * falc_generate_loop_down_code *---------------------------------------------------------------------------- * Description:	This routine writes the proper FALC chip register in order *		to generate a LOOP deactivation code over a T1/E1 line. *---------------------------------------------------------------------------- */void falc_generate_loop_down_code(pc300_t * card, int ch){	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;	falc_t *pfalc = (falc_t *) & chan->falc;	uclong falcbase = card->hw.falcbase;	if (conf->media == IF_IFACE_T1) {		cpc_writeb(falcbase + F_REG(FMR5, ch),			   cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLD);	} else {		cpc_writeb(falcbase + F_REG(FMR3, ch),			   cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLD);	}	pfalc->sync = 0;	cpc_writeb(falcbase + card->hw.cpld_reg2,		   cpc_readb(falcbase + card->hw.cpld_reg2) &		   ~(CPLD_REG2_FALC_LED2 << (2 * ch)));	pfalc->active = 0;//	falc_issue_cmd(card, ch, CMDR_XRES);	pfalc->loop_gen = 0;}/*---------------------------------------------------------------------------- * falc_pattern_test *---------------------------------------------------------------------------- * Description:	This routine generates a pattern code and checks *		it on the reception side. *---------------------------------------------------------------------------- */void falc_pattern_test(pc300_t * card, int ch, unsigned int activate){	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;	falc_t *pfalc = (falc_t *) & chan->falc;	uclong falcbase = card->hw.falcbase;	if (activate) {		pfalc->prbs = 1;		pfalc->bec = 0;		if (conf->media == IF_IFACE_T1) {			/* Disable local loop activation/deactivation detect */			cpc_writeb(falcbase + F_REG(IMR3, ch),				   cpc_readb(falcbase + F_REG(IMR3, ch)) | IMR3_LLBSC);		} else {			/* Disable local loop activation/deactivation detect */			cpc_writeb(falcbase + F_REG(IMR1, ch),				   cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_LLBSC);		}		/* Activates generation and monitoring of PRBS 		 * (Pseudo Random Bit Sequence) */		cpc_writeb(falcbase + F_REG(LCR1, ch),			   cpc_readb(falcbase + F_REG(LCR1, ch)) | LCR1_EPRM | LCR1_XPRBS);	} else {		pfalc->prbs = 0;		/* Deactivates generation and monitoring of PRBS 		 * (Pseudo Random Bit Sequence) */		cpc_writeb(falcbase + F_REG(LCR1, ch),			   cpc_readb(falcbase+F_REG(LCR1,ch)) & ~(LCR1_EPRM | LCR1_XPRBS));		if (conf->media == IF_IFACE_T1) {			/* Enable local loop activation/deactivation detect */			cpc_writeb(falcbase + F_REG(IMR3, ch),				   cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC);		} else {			/* Enable local loop activation/deactivation detect */			cpc_writeb(falcbase + F_REG(IMR1, ch),				   cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_LLBSC);		}	}}/*---------------------------------------------------------------------------- * falc_pattern_test_error *---------------------------------------------------------------------------- * Description:	This routine returns the bit error counter value *---------------------------------------------------------------------------- */ucshort falc_pattern_test_error(pc300_t * card, int ch){	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];	falc_t *pfalc = (falc_t *) & chan->falc;	return (pfalc->bec);}/**********************************//***   Net Interface Routines   ***//**********************************/static voidcpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx){	struct sk_buff *skb;	if ((skb = dev_alloc_skb(10 + skb_main->len)) == NULL) {		printk("%s: out of memory\n", dev->name);		return;	}	skb_put(skb, 10 + skb_main->len);	skb->dev = dev;	skb->protocol = htons(ETH_P_CUST);	skb->mac.raw = skb->data;	skb->pkt_type = PACKET_HOST;	skb->len = 10 + skb_main->len;	memcpy(skb->data, dev->name, 5);	skb->data[5] = '[';	skb->data[6] = rx_tx;	skb->data[7] = ']';	skb->data[8] = ':';	skb->data[9] = ' ';	memcpy(&skb->data[10], skb_main->data, skb_main->len);	netif_rx(skb);}void cpc_tx_timeout(struct net_device *dev){	pc300dev_t *d = (pc300dev_t *) dev->priv;	pc300ch_t *chan = (pc300ch_t *) d->chan;	pc300_t *card = (pc300_t *) chan->card;	struct net_device_stats *stats = &d->hdlc->stats;	int ch = chan->channel;	uclong flags;	ucchar ilar;	stats->tx_errors++;	stats->tx_aborted_errors++;	CPC_LOCK(card, flags);	if ((ilar = cpc_readb(card->hw.scabase + ILAR)) != 0) {		printk("%s: ILAR=0x%x\n", dev->name, ilar);		cpc_writeb(card->hw.scabase + ILAR, ilar);		cpc_writeb(card->hw.scabase + DMER, 0x80);	}	if (card->hw.type == PC300_TE) {		cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,			   cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) &			   ~(CPLD_REG2_FALC_LED1 << (2 * ch)));	}	dev->trans_start = jiffies;	CPC_UNLOCK(card, flags);	netif_wake_queue(dev);}int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev){	pc300dev_t *d = (pc300dev_t *) dev->priv;	pc300ch_t *chan = (pc300ch_t *) d->chan;	pc300_t *card = (pc300_t *) chan->card;	struct net_device_stats *stats = &d->hdlc->stats;	int ch = chan->channel;	uclong flags;#ifdef PC300_DEBUG_TX	int i;#endif	if (chan->conf.monitor) {		/* In monitor mode no Tx is done: ignore packet */		dev_kfree_skb(skb);		return 0;	} else if (!netif_carrier_ok(dev)) {		/* DCD must be OFF: drop packet */		dev_kfree_skb(skb);		stats->tx_errors++;		stats->tx_carrier_errors++;		return 0;	} else if (cpc_readb(card->hw.scabase + M_REG(ST3, ch)) & ST3_DCD) {		printk("%s: DCD is OFF. Going administrative down.\n", dev->name);		stats->tx_errors++;		stats->tx_carrier_errors++;		dev_kfree_skb(skb);		netif_carrier_off(dev);		CPC_LOCK(card, flags);		cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR);		if (card->hw.type == PC300_TE) {			cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,				   cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & 				   			~(CPLD_REG2_FALC_LED1 << (2 * ch)));		}		CPC_UNLOCK(card, flags);		netif_wake_queue(dev);		return 0;	}	/* Write buffer to DMA buffers */	if (dma_buf_write(card, ch, (ucchar *) skb->data, skb->len) != 0) {//		printk("%s: write error. Dropping TX packet.\n", dev->name);		netif_stop_queue(dev);		dev_kfree_skb(skb);		stats->tx_errors++;		stats->tx_dropped++;		return 0;	}#ifdef PC300_DEBUG_TX	printk("%s T:", dev->name);	for (i = 0; i < skb->len; i++)		printk(" %02x", *(skb->data + i));	printk("\n");#endif	if (d->trace_on) {		cpc_trace(dev, skb, 'T');	}	dev->trans_start = jiffies;	/* Start transmission */	CPC_LOCK(card, flags);	/* verify if it has more than one free descriptor */	if (card->chan[ch].nfree_tx_bd <= 1) {		/* don't have so stop the queue */		netif_stop_queue(dev);	}	cpc_writel(card->hw.scabase + DTX_REG(EDAL, ch),		   TX_BD_ADDR(ch, chan->tx_next_bd));	cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -