if_ed.c

来自「嵌入式系统开发中关于网络开发的的原代码及相关说明理。」· C语言 代码 · 共 892 行 · 第 1/2 页

C
892
字号
	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR), ED_CR_PAGE0 | ED_CR_STP);	/*	 *  DCR を肋年する。	 *    ˇFIFO のしきい猛を 8	 *    ˇル〖プバックモ〖ド	 */	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_DCR), ED_DCR_FT1 | ED_DCR_LS);	/* RBCR をクリア〖する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_RBCR0), 0);	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_RBCR1), 0);	/* 掐蜗フレ〖ムを瘦赂しない。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_RCR), ED_RCR_MON);	/* 柒婶ル〖プバックモ〖ドに肋年する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_TCR), ED_TCR_LB0);	/* 流减慨リングバッファの肋年 */	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_TPSR),   ED_INT_TXBUF_START);	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_PSTART), ED_INT_RXBUF_START);	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_PSTOP),  ED_INT_RXBUF_STOP);	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_BNRY),   ED_INT_RXBUF_START);	/* 链ての充り哈みフラグをリセットする。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_ISR), 0xff);	/*	 *  充り哈みを钓材する。	 *    ˇ流减慨窗位	 *    ˇ流减慨エラ〖	 *    ˇ减慨オ〖バ〖ライト	 */	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_IMR),	            ED_IMR_PRX | ED_IMR_PTX | ED_IMR_RXE | ED_IMR_TXE | ED_IMR_OVW);	/* レジスタペ〖ジ 1 を联买する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),	            ED_CR_RD2 | ED_CR_PAGE1 | ED_CR_STP);	/* MAC アドレスを肋年する。*/	for (ix = 0; ix < ETHER_ADDR_LEN; ix ++)		sil_wrb_mem((VP)(sc->nic_addr + ED_P1_PAR(ix)), ic->ifaddr.lladdr[ix]);	/* フレ〖ムを今き哈むペ〖ジを肋年する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P1_CURR), sc->rxb_read); 	/* 减慨菇喇レジスタ (RCR) を肋年する。*/ 	ed_setrcr(ic);	/* 柒婶ル〖プバックモ〖ドからぬける。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_TCR), 0);		/* 流慨材墙セマフォを介袋步する。*/	for (ix = NUM_IF_ED_TXBUF; ix --; )		sig_sem(ic->semid_txb_ready);	}#ifndef SUPPORT_INET6/* * ed_setrcr -- 减慨菇喇レジスタ (RCR) を肋年する。 */static voided_setrcr (T_IF_SOFTC *ic){	T_ED_SOFTC	*sc = ic->sc;	int		ix;	/* レジスタペ〖ジ 1 を联买する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),	            ED_CR_RD2 | ED_CR_PAGE1 | ED_CR_STP);#ifdef IF_ED_CFG_ACCEPT_ALL	/* マルチキャストの减慨肋年 */	for (ix = 0; ix < 8; ix ++)		/* マルチキャストを链て减慨する。*/		sil_wrb_mem((VP)(sc->nic_addr + ED_P1_MAR(ix)), 0xff);	/* レジスタペ〖ジ 0 を联买する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),	                 ED_CR_RD2 | ED_CR_PAGE0 | ED_CR_STP);	/* マルチキャストとエラ〖フレ〖ムも减慨するように肋年する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_RCR),	            ED_RCR_PRO | ED_RCR_AM | ED_RCR_AB |ED_RCR_SEP);#else	/* of #ifdef IF_ED_CFG_ACCEPT_ALL */	/* マルチキャストの减慨肋年 */	for (ix = 0; ix < 8; ix ++)		/* マルチキャストを链て减慨しない。*/		sil_wrb_mem((VP)(sc->nic_addr + ED_P1_MAR(ix)), 0x00);	/* レジスタペ〖ジ 0 を联买する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),	            ED_CR_RD2 | ED_CR_PAGE0 | ED_CR_STP);	/* 极尸とブロ〖ドキャストのみ减慨するように肋年する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_RCR), ED_RCR_AB);#endif	/* of #ifdef IF_ED_CFG_ACCEPT_ALL */	/* NIC を弹瓢する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),	            ED_CR_RD2 | ED_CR_PAGE0 | ED_CR_STA);	}#endif	/* of #ifndef SUPPORT_INET6 *//* * ed_reset -- ed ネットワ〖クインタフェ〖スをリセットする。 */voided_reset (T_IF_SOFTC *ic){	/* NIC からの充り哈みを敦贿する。*/	ed_dis_inter();	NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_RESETS], 1);	ed_stop(ic->sc);	ed_init_sub(ic);	/* NIC からの充り哈みを钓材する。*/	ed_ena_inter();	}/* *  get_ed_softc -- ネットワ〖クインタフェ〖スのソフトウェア攫鼠を手す。 */T_IF_SOFTC *ed_get_softc (void){	return &if_softc;	}/* * ed_watchdog -- ed ネットワ〖クインタフェ〖スのワッチドッグタイムアウト */voided_watchdog (T_IF_SOFTC *ic){	NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_OUT_ERR_PACKETS], 1);	NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_TIMEOUTS], 1);	ed_reset(ic);	}/* * ed_probe -- ed ネットワ〖クインタフェ〖スの浮叫 */voided_probe (T_IF_SOFTC *ic){#ifdef ED_CFG_HSB8S2638	static const UB mac_order[] = { 3, 1, 7, 5, 11, 9 };#else	/* #ifdef ED_CFG_HSB8S2638 */	static const UB mac_order[] = { 1, 3, 5, 7, 9, 11 };#endif	/* #ifdef ED_CFG_HSB8S2638 */	UB		romdata[ETHER_ADDR_LEN * 2], tmp;	T_ED_SOFTC	*sc = ic->sc;	int		ix;	/* リセットする。*/	tmp = sil_reb_mem((VP)(sc->asic_addr + ED_RESET_OFFSET));	sil_wrb_mem((VP)(sc->asic_addr + ED_RESET_OFFSET), tmp);	dly_tsk(5);	/* DMA を匿贿する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),	            ED_CR_RD2 | ED_CR_PAGE0 | ED_CR_STP);	dly_tsk(5);	/* 掐蜗フレ〖ムを瘦赂しない。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_RCR), ED_RCR_MON);	/*	 *  DCR を肋年する。	 *    ˇFIFO のしきい猛を 8	 *    ˇル〖プバックモ〖ド	 */	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_DCR), ED_DCR_FT1 | ED_DCR_LS);	/* MAC アドレスを粕み哈む。*/	ed_pio_readmem(sc, 0, romdata, ETHER_ADDR_LEN * 2);	for (ix = 0; ix < ETHER_ADDR_LEN; ix ++)		ic->ifaddr.lladdr[ix] = romdata[mac_order[ix]];	/* 链ての充り哈みフラグをリセットする。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_ISR), 0xff);	}/* * ed_init -- ed ネットワ〖クインタフェ〖スの介袋步 */voided_init (T_IF_SOFTC *ic){	/* NIC からの充り哈みを敦贿する。*/	ed_dis_inter();	/* ed_init 塑挛を钙び叫す。*/	ed_init_sub(ic);	/* NIC からの充り哈みを钓材する。*/	ed_ena_inter();	}/* * ed_read -- フレ〖ムの粕み哈み */T_NET_BUF *ed_read (T_IF_SOFTC *ic){	T_ED_FRAME_HDR	frame_hdr;	T_ED_SOFTC	*sc = ic->sc;	T_NET_BUF	*input = NULL;	UW		frame_ptr;	int		len;	UB		boundry;	UB		curr;	/* NIC からの充り哈みを敦贿する。*/	ed_dis_inter();	/* レジスタペ〖ジ 1 を联买する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),	            ED_CR_RD2 | ED_CR_PAGE1 | ED_CR_STA);	curr = sil_reb_mem((VP)(sc->nic_addr + ED_P1_CURR));	if (sc->rxb_read != curr) {		/* 减慨フレ〖ムの黎片を评る。*/		frame_ptr = sc->rxb_read * ED_PAGE_SIZE;		/* 减慨フレ〖ムヘッダ菇陇挛を艰り叫す。*/		ed_pio_readmem(sc, frame_ptr, (char *)&frame_hdr, sizeof(frame_hdr));#if SIL_ENDIAN == SIL_ENDIAN_BIG		frame_hdr.count = (frame_hdr.count << 8) | (frame_hdr.count >> 8);#endif	/* of #if SIL_ENDIAN == SIL_ENDIAN_BIG */		len = frame_hdr.count;		if (len >  sizeof(T_ED_FRAME_HDR) &&		    len <= IF_MTU + sizeof(T_ETHER_HDR) + sizeof(T_ED_FRAME_HDR) &&		    frame_hdr.next >= ED_INT_RXBUF_START &&		    frame_hdr.next <  ED_INT_RXBUF_STOP) {			input = ed_get_frame(sc, frame_ptr + sizeof(T_ED_FRAME_HDR),			                               len - sizeof(T_ED_FRAME_HDR));			}		else {			/* 减慨エラ〖とリセットを淡峡する。*/			NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_IN_ERR_PACKETS], 1);			NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_RESETS], 1);			ed_stop(sc);			ed_init_sub(ic);			/* NIC からの充り哈みを钓材する。*/			ed_ena_inter();			return NULL;			}		/* フレ〖ムポインタを构糠する。*/		sc->rxb_read = frame_hdr.next;		/* レジスタペ〖ジ 0 を联买する。*/		sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),		            ED_CR_RD2 | ED_CR_PAGE0 | ED_CR_STA);		/* NIC の董肠ポインタを构糠する。*/		boundry = sc->rxb_read - 1;		if (boundry < ED_INT_RXBUF_START)			boundry = ED_INT_RXBUF_STOP - 1;		sil_wrb_mem((VP)(sc->nic_addr + ED_P0_BNRY), boundry);		/* レジスタペ〖ジ 1 を联买する。*/		sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),		            ED_CR_RD2 | ED_CR_PAGE1 | ED_CR_STA);		}	/* 减慨リングバッファにデ〖タが荒っていれば、减慨借妄を费鲁する。*/	curr = sil_reb_mem((VP)(sc->nic_addr + ED_P1_CURR));	if (sc->rxb_read != curr)		sig_sem(ic->semid_rxb_ready);	/* NIC からの充り哈みを钓材する。*/	ed_ena_inter();	return input;	}/* * ed_start -- 流慨フレ〖ムをバッファリングする。 */voided_start (T_IF_SOFTC *ic, T_NET_BUF *output){	T_ED_SOFTC *sc = ic->sc;	NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_OUT_PACKETS], 1);	NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_OUT_OCTETS],  output->len);	/* NIC からの充り哈みを敦贿する。*/	ed_dis_inter();	/* 流慨バッファに今き哈む。*/	ed_pio_writemem(sc, output->buf, 	                ED_INT_RAM_BASE + sc->txb_write * NUM_IF_ED_TXBUF_PAGE * ED_PAGE_SIZE,	                output->len);	/* 流慨バッファに今き哈んだオクテット眶を淡峡する。*/	if (output->len > ETHER_MIN_LEN - ETHER_CRC_LEN)		sc->txb_len[sc->txb_write] = output->len;	else		sc->txb_len[sc->txb_write] = ETHER_MIN_LEN - ETHER_CRC_LEN;	/* 流慨バッファを磊り仑える。*/	sc->txb_write ++;	if (sc->txb_write == NUM_IF_ED_TXBUF)		sc->txb_write = 0;	sc->txb_inuse ++;	/* もし流慨面でなければ、流慨を倡幌する。*/	if (sc->txb_insend == 0)		ed_xmit(ic);	/* NIC からの充り哈みを钓材する。*/	ed_ena_inter();	}/* *  NIC 充り哈みハンドラ */voidif_ed_handler (void){	T_ED_SOFTC	*sc;	T_IF_SOFTC	*ic;	UB		isr, tsr;	UH		collisions;	ic = &if_softc;	sc = ic->sc;	/* レジスタペ〖ジ 0 を联买する。*/	sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),	            ED_CR_RD2 | ED_CR_PAGE0 | ED_CR_STA);	isr = sil_reb_mem((VP)(sc->nic_addr + ED_P0_ISR));	if (isr != 0) {		/* 链ての充り哈みフラグをリセットする。*/		sil_wrb_mem((VP)(sc->nic_addr + ED_P0_ISR), isr);		if (isr & (ED_ISR_PTX | ED_ISR_TXE)) {			collisions = sil_reb_mem((VP)(sc->nic_addr + ED_P0_NCR)) & 0x0f;			/* 流慨借妄 */			tsr = sil_reb_mem((VP)(sc->nic_addr + ED_P0_TSR));			if (isr & ED_ISR_TXE) {				/* 流慨エラ〖を淡峡する。*/				if ((tsr & ED_TSR_ABT) && (collisions == 0)) {					/*					 * コリジョンが 16 のとき、P_NCR は 0、					 * TSR_ABT は 1 になる。					 */					collisions = 16;					}				NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_OUT_ERR_PACKETS], 1);				}			if (sc->txb_insend)				sc->txb_insend --;			if (sc->txb_inuse)				sc->txb_inuse  --;			/* 流慨タイムアウトをリセットする。*/			ic->timer = 0;			/* まだ流慨バッファに荒っていれば流慨する。*/			if (sc->txb_inuse)				ed_xmit(ic);			if (isig_sem(ic->semid_txb_ready) != E_OK)				NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_TXB_QOVRS], 1);			/* コリジョンを淡峡する。*/			NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_COLS], collisions);			}		if (isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) {			if (isr & ED_ISR_OVW) {				/* 惧今きエラ〖とリセットを淡峡する。*/				NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_IN_ERR_PACKETS], 1);				NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_RESETS], 1);				/* DMA を匿贿する。*/				sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),				            ED_CR_RD2 | ED_CR_PAGE0 | ED_CR_STP);				ed_init_sub(ic);				}			else {				if (isr & ED_ISR_RXE) {					/* 减慨エラ〖を淡峡する。*/					NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_IN_ERR_PACKETS], 1);					}				/* 减慨充り哈み借妄 */				if (isig_sem(ic->semid_rxb_ready) != E_OK)					NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_RXB_QOVRS], 1);				}			}		/* レジスタペ〖ジ 0 を联买する。*/		sil_wrb_mem((VP)(sc->nic_addr + ED_P0_CR),		            ED_CR_RD2 | ED_CR_PAGE0 | ED_CR_STA);		/* ネットワ〖ク淡峡カウンタがオ〖バフロ〖したらリセットする。*/		if (isr & ED_ISR_CNT) {			(void)sil_reb_mem((VP)(sc->nic_addr + ED_P0_CNTR0));			(void)sil_reb_mem((VP)(sc->nic_addr + ED_P0_CNTR1));			(void)sil_reb_mem((VP)(sc->nic_addr + ED_P0_CNTR2));			}		}	}

⌨️ 快捷键说明

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