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 + -
显示快捷键?