📄 gmac_sl2312.c
字号:
tp->tx_desc->frame_ctrl.bits_tx_out.buffer_size = TX_BUF_SIZE; /* set tx buffer size for descriptor */ tp->tx_desc->buf_adr = tp->tx_bufs_dma; /* set data buffer address */ tp->tx_bufs_dma = tp->tx_bufs_dma + TX_BUF_SIZE; /* point to next buffer address */ tp->tx_desc_dma = tp->tx_desc_dma + sizeof(GMAC_DESCRIPTOR_T); /* next tx descriptor DMA address */ tp->tx_desc->next_desc.next_descriptor = tp->tx_desc_dma | 0x0000000b; tp->tx_desc = &tp->tx_desc[1] ; /* next tx descriptor virtual address */ } /* the last descriptor will point back to first descriptor */ tp->tx_desc->frame_ctrl.bits_tx_out.own = CPU; tp->tx_desc->frame_ctrl.bits_tx_out.buffer_size = TX_BUF_SIZE; tp->tx_desc->buf_adr = (unsigned int)tp->tx_bufs_dma; tp->tx_desc->next_desc.next_descriptor = tx_first_desc_dma | 0x0000000b; tp->tx_desc = tp->tx_cur_desc; tp->tx_desc_dma = tx_first_desc_dma; tp->tx_bufs_dma = tx_first_buf_dma; /* RX descriptors initial */ tp->rx_cur_desc = tp->rx_desc; /* virtual address */ tp->rx_desc_dma = (unsigned int)tp->rx_desc; rx_first_desc_dma = tp->rx_desc_dma; /* physical address */ rx_first_buf_dma = tp->rx_bufs_dma; for (i = 1; i < RX_DESC_NUM; i++) { tp->rx_desc->frame_ctrl.bits_rx.own = DMA; /* set owner bit to DMA */ tp->rx_desc->frame_ctrl.bits_rx.buffer_size = RX_BUF_SIZE; /* set rx buffer size for descriptor */ tp->rx_desc->buf_adr = tp->rx_bufs_dma; /* set data buffer address */ tp->rx_bufs_dma = tp->rx_bufs_dma + RX_BUF_SIZE; /* point to next buffer address */ tp->rx_desc_dma = tp->rx_desc_dma + sizeof(GMAC_DESCRIPTOR_T); /* next rx descriptor DMA address */ tp->rx_desc->next_desc.next_descriptor = tp->rx_desc_dma | 0x0000000b; tp->rx_desc = &tp->rx_desc[1]; /* next rx descriptor virtual address */ } /* the last descriptor will point back to first descriptor */ tp->rx_desc->frame_ctrl.bits_rx.own = DMA; tp->rx_desc->frame_ctrl.bits_rx.buffer_size = RX_BUF_SIZE; tp->rx_desc->buf_adr = tp->rx_bufs_dma; tp->rx_desc->next_desc.next_descriptor = rx_first_desc_dma | 0x0000000b; tp->rx_desc = tp->rx_cur_desc; tp->rx_desc_dma = rx_first_desc_dma; tp->rx_bufs_dma = rx_first_buf_dma; return (0); } /*----------------------------------------------------------------------* gmac_clear_counter*----------------------------------------------------------------------*/static int gmac_clear_counter (void){// GMAC_INFO_T *tp = (GMAC_INFO_T *)&gmac_private_data; /* clear counter */ gmac_read_reg(GMAC_IN_DISCARDS); gmac_read_reg(GMAC_IN_ERRORS); // tp->stats.tx_bytes = 0;// tp->stats.tx_packets = 0;// tp->stats.tx_errors = 0;// tp->stats.rx_bytes = 0;// tp->stats.rx_packets = 0;// tp->stats.rx_errors = 0;// tp->stats.rx_dropped = 0; return (0); } /*----------------------------------------------------------------------* gmac_sl2312_start*----------------------------------------------------------------------*/static void gmac_sl2312_start(void){ /* allocates tx/rx descriptor and buffer memory */ gmac_init_desc_buf(); /* set PHY register to start autonegition process */ gmac_set_phy_status(); /* GMAC initialization */ if ( gmac_init_chip() ) { diag_printf ("GMAC init fail\n"); } /* enable tx/rx register */ gmac_enable_tx_rx(); /* start DMA process */ gmac_hw_start(); /* clear statistic counter */ gmac_clear_counter(); return ; }/*----------------------------------------------------------------------* gmac_sl2312_stop*----------------------------------------------------------------------*/static void gmac_sl2312_stop(void){ /* stop tx/rx packet */ gmac_disable_tx_rx(); /* stop the chip's Tx and Rx DMA processes */ gmac_hw_stop(); }/*----------------------------------------------------------------------* gmac_weird_interrupt*----------------------------------------------------------------------*/static void gmac_weird_interrupt(void){}/*----------------------------------------------------------------------* gmac_sl2312_isr*----------------------------------------------------------------------*/void gmac_sl2312_isr(void){ GMAC_RXDMA_FIRST_DESC_T rxdma_busy; GMAC_TXDMA_FIRST_DESC_T txdma_busy; GMAC_TXDMA_CTRL_T txdma_ctrl,txdma_ctrl_mask; GMAC_RXDMA_CTRL_T rxdma_ctrl,rxdma_ctrl_mask; GMAC_DMA_STATUS_T status; sl2312_eth_disable_interrupt(); // for (;;) { /* read DMA status */ status.bits32 = gmac_read_reg(GMAC_DMA_STATUS); /* clear DMA status */ gmac_write_reg(GMAC_DMA_STATUS,status.bits32,status.bits32); /* receive rx interrupt */ //if ( ((status.bits.rs_eofi==1)||(status.bits.rs_finish==1))|| // ((status.bits.ts_eofi==1)||(status.bits.ts_finish==1)) ) if ((status.bits.rs_eofi==1) || (status.bits.rs_finish==1)) if (status.bits32 & 0x220) { sl2312_gmac_deliver(); } if ((status.bits32 & 0xffffc000)==0) { // break; sl2312_eth_enable_interrupt(); return; } if (status.bits.rx_overrun == 1) { /* if RX DMA process is stoped , restart it */ rxdma_busy.bits32 = gmac_read_reg(GMAC_RXDMA_FIRST_DESC) ; if (rxdma_busy.bits.rd_busy == 0) { /* restart Rx DMA process */ rxdma_ctrl.bits32 = 0; rxdma_ctrl.bits.rd_start = 1; /* start RX DMA transfer */ rxdma_ctrl.bits.rd_continue = 1; /* continue RX DMA operation */ rxdma_ctrl_mask.bits32 = 0; rxdma_ctrl_mask.bits.rd_start = 1; rxdma_ctrl_mask.bits.rd_continue = 1; gmac_write_reg(GMAC_RXDMA_CTRL,rxdma_ctrl.bits32,rxdma_ctrl_mask.bits32); } } /* receive tx interrupt */// if ( ((status.bits.ts_eofi==1)||(status.bits.ts_finish==1)) )// {// gmac_tx_interrupt(dev);// } /* check uncommon events */ #if 0 if ((status.bits32 & 0x633fc000)!=0) { gmac_weird_interrupt(); }#endif } sl2312_eth_enable_interrupt(); return;}/*----------------------------------------------------------------------* sl2312_gmac_deliver*----------------------------------------------------------------------*/void sl2312_gmac_deliver(void){ GMAC_INFO_T *tp = (GMAC_INFO_T *)&gmac_private_data; GMAC_DESCRIPTOR_T *rx_desc; unsigned int pkt_len; unsigned int own; unsigned int desc_count; GMAC_RXDMA_FIRST_DESC_T rxdma_busy; static UINT32 gmac_poll_phy_ticks=0; int i; while (1) { own = tp->rx_cur_desc->frame_ctrl.bits32 >> 31; if (own == CPU) /* check owner bit */ { rx_desc = tp->rx_cur_desc; /* check error interrupt */#if 0 if ( (rx_desc->frame_ctrl.bits_rx.derr==1)||(rx_desc->frame_ctrl.bits_rx.perr==1) ) { diag_printf("gmac_rx_interrupt::Rx Descriptor Processing Error !!!\n"); }#endif /* get frame information from the first descriptor of the frame */ pkt_len = rx_desc->flag_status.bits_rx_status.frame_count-4; /*total byte count in a frame*/ desc_count = rx_desc->frame_ctrl.bits_rx.desc_count; /* get descriptor count per frame */ if ((pkt_len > 0) && (rx_desc->frame_ctrl.bits_rx.frame_state == 0x000)) /* good frame */ { // (sc->funs->eth_drv->recv)(sc, pkt_len); // queue it enet_input(rx_desc->buf_adr, pkt_len); } rx_desc->frame_ctrl.bits_rx.own = DMA; /* release rx descriptor to DMA */ /* point to next rx descriptor */ tp->rx_cur_desc = (GMAC_DESCRIPTOR_T *)(tp->rx_cur_desc->next_desc.next_descriptor & 0xfffffff0); /* release buffer to Remaining Buffer Number Register */ if (flow_control_enable ==1) { gmac_write_reg(GMAC_BNCR, desc_count, 0x0000ffff); } } else { if ((sys_get_ticks() - gmac_poll_phy_ticks) >= (BOARD_TPS * 3)) { gmac_get_phy_status(); gmac_poll_phy_ticks = sys_get_ticks(); } break; } } /* if RX DMA process is stoped , restart it */ rxdma_busy.bits.rd_first_des_ptr = gmac_read_reg(GMAC_RXDMA_FIRST_DESC); if (rxdma_busy.bits.rd_busy == 0) { GMAC_RXDMA_CTRL_T rxdma_ctrl,rxdma_ctrl_mask; rxdma_ctrl.bits32 = 0; rxdma_ctrl.bits.rd_start = 1; /* start RX DMA transfer */ rxdma_ctrl.bits.rd_continue = 1; /* continue RX DMA operation */ rxdma_ctrl_mask.bits32 = 0; rxdma_ctrl_mask.bits.rd_start = 1; rxdma_ctrl_mask.bits.rd_continue = 1; gmac_write_reg(GMAC_RXDMA_CTRL,rxdma_ctrl.bits32,rxdma_ctrl_mask.bits32); }}/*----------------------------------------------------------------------* gmac_sl2312_send*----------------------------------------------------------------------*/void gmac_sl2312_send(char *bufp, int total_len){ GMAC_INFO_T *tp = (GMAC_INFO_T *)&gmac_private_data; GMAC_TXDMA_CTRL_T tx_ctrl,tx_ctrl_mask; GMAC_TXDMA_FIRST_DESC_T txdma_busy; // Share Pin issue#ifndef MIDWAY REG32(SL2312_GLOBAL_BASE+GLOBAL_MISC_CTRL) |= GLOBAL_FLASH_EN_BIT; //0x00000001 ;#endif if ((tp->tx_cur_desc->frame_ctrl.bits_tx_out.own == CPU) && (total_len < TX_BUF_SIZE)) { if (FLAG_SWITCH==1 && (chip_id<0xA3) && vlan_enabled) { tp->tx_cur_desc->frame_ctrl.bits_tx_out.vlan_enable = 1; /* enable vlan TIC insertion */ tp->tx_cur_desc->flag_status.bits_tx_flag.vlan_id = 1; /* 1:To LAN . 2:To WAN */ } else { tp->tx_cur_desc->frame_ctrl.bits_tx_out.vlan_enable = 0; /* disable vlan TIC insertion */ } { int bd_id; bd_id = ((unsigned long)tp->tx_cur_desc - (unsigned long)tx_desc_array) / sizeof(GMAC_DESCRIPTOR_T); tp->tx_cur_desc->buf_adr = (unsigned int)tx_buf_array + (TX_BUF_SIZE * bd_id); memcpy((unsigned char *)(tp->tx_cur_desc->buf_adr), bufp, total_len); } tp->tx_cur_desc->frame_ctrl.bits_tx_out.buffer_size = total_len; /* descriptor byte count */ tp->tx_cur_desc->flag_status.bits_tx_flag.frame_count = total_len; /* total frame byte count */ tp->tx_cur_desc->next_desc.bits.sof_eof = 0x03; /*only one descriptor*/ tp->tx_cur_desc->frame_ctrl.bits_tx_out.own = DMA; /* set owner bit */ tp->tx_cur_desc = (GMAC_DESCRIPTOR_T *)(tp->tx_cur_desc->next_desc.next_descriptor & 0xfffffff0); } /* if TX DMA process is stoped , restart it */ txdma_busy.bits32 = gmac_read_reg(GMAC_TXDMA_FIRST_DESC); if (txdma_busy.bits.td_busy == 0) { /* restart DMA process */ tx_ctrl.bits32 = 0; tx_ctrl.bits.td_start = 1; tx_ctrl.bits.td_continue = 1; tx_ctrl_mask.bits32 = 0; tx_ctrl_mask.bits.td_start = 1; tx_ctrl_mask.bits.td_continue = 1; gmac_write_reg(GMAC_TXDMA_CTRL,tx_ctrl.bits32,tx_ctrl_mask.bits32); } }/*----------------------------------------------------------------------* gmac_sl2312_can_send*----------------------------------------------------------------------*/int gmac_sl2312_can_send(void){ GMAC_INFO_T *tp = (GMAC_INFO_T *)&gmac_private_data; if (tp->tx_cur_desc->frame_ctrl.bits_tx_out.own == CPU) { return (1); } else { return (0); } }/*----------------------------------------------------------------------* emac_reset_statistics*----------------------------------------------------------------------*/void gmac_reset_statistics(void){#ifdef GMAC_STATISTICS GMAC_INFO_T *tp = (GMAC_INFO_T *)&gmac_private_data; tp->interrupt_cnt = 0; tp->rx_intr_cnt = 0; tp->tx_intr_cnt = 0; tp->rx_pkts = 0; tp->tx_pkts = 0; tp->rx_overrun = 0; tp->tx_underrun = 0; tp->tx_no_resource = 0;#endif}/*----------------------------------------------------------------------* emac_show_statistics*----------------------------------------------------------------------*/void gmac_show_statistics(char argc, char *argv[]){#ifdef GMAC_STATISTICS GMAC_INFO_T *tp = (GMAC_INFO_T *)&gmac_private_data; EMAC_DESCRIPTOR_T *bd; int i, type, total; printf("EMAC Statistics:\n"); printf("Interrupts : %u\n", tp->interrupt_cnt); printf("Rx Intr : %u\n", tp->rx_intr_cnt); printf("Tx Intr : %u\n", tp->tx_intr_cnt); printf("Rx packets : %u\n", tp->rx_pkts); printf("Tx packets : %u\n", tp->tx_pkts); printf("Rx Overrun : %u\n", tp->rx_overrun); printf("Tx Underrun : %u\n", tp->tx_underrun); printf("Tx no resource: %u\n", tp->tx_no_resource); printf("rx_head : %d\n", tp->rx_head); printf("rx_tail : %d\n", tp->rx_tail); printf("tx_head : %d\n", tp->tx_head); printf("tx_tail : %d\n", tp->tx_tail); type = 0; total = RX_DESC_NUM; if (argc == 2) { if (strncasecmp(argv[1], "rx", 2)==0) { type = 0; total = RX_DESC_NUM; } else if (strncasecmp(argv[1], "tx", 2)==0) { type = 1; total = TX_DESC_NUM; } } switch (type) { case 0: bd = (EMAC_DESCRIPTOR_T *)&tp->rx_desc[0]; printf("Receive Buffer Descriptors:\n"); break; case 1: bd = (EMAC_DESCRIPTOR_T *)&tp->tx_desc[0]; printf("Transmit Buffer Descriptors:\n"); break; } printf("id Frame Control Status/Flag Buffer Addr Next Descriptor\n"); for (i=0; i<total; i++) { printf("%-2d 0x%08X 0x%08X 0x%08X 0x%08X\n", i, bd->frame_ctrl.bits32, bd->flag_status.bits32, bd->buf_adr, bd->next_desc.next_descriptor); bd++; } #endif}#endif // MIDWAY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -