📄 sl_lepus_gmac.c
字号:
//{ // tmp = 0x796c200; // gmac_write_reg(tp->base_addr, GMAC_CONFIG0, tmp,0xffffffff); //}}/*----------------------------------------------------------------------* toe_gmac_clear_counter*----------------------------------------------------------------------*/static int toe_gmac_clear_counter (GMAC_INFO_T *tp){ /* clear counter */ gmac_read_reg(tp->base_addr, GMAC_IN_DISCARDS); gmac_read_reg(tp->base_addr, GMAC_IN_ERRORS); gmac_read_reg(tp->base_addr, GMAC_IN_MCAST); gmac_read_reg(tp->base_addr, GMAC_IN_BCAST); gmac_read_reg(tp->base_addr, GMAC_IN_MAC1); gmac_read_reg(tp->base_addr, GMAC_IN_MAC2); // 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); }/*----------------------------------------------------------------------* toe_gmac_hw_start*----------------------------------------------------------------------*/static void toe_gmac_hw_start(GMAC_INFO_T *tp){ GMAC_DMA_CTRL_T dma_ctrl, dma_ctrl_mask; /* program dma control register */ dma_ctrl.bits32 = 0; dma_ctrl.bits.rd_enable = 1; dma_ctrl.bits.td_enable = 1; dma_ctrl.bits.loopback = 0; dma_ctrl.bits.drop_small_ack = 0; dma_ctrl.bits.rd_prot = 0; dma_ctrl.bits.rd_burst_size = 3; dma_ctrl.bits.rd_insert_bytes = RX_INSERT_BYTES; dma_ctrl.bits.rd_bus = 3; dma_ctrl.bits.td_prot = 0; dma_ctrl.bits.td_burst_size = 3; dma_ctrl.bits.td_bus = 3; dma_ctrl_mask.bits32 = 0; dma_ctrl_mask.bits.rd_enable = 1; dma_ctrl_mask.bits.td_enable = 1; dma_ctrl_mask.bits.loopback = 1; dma_ctrl_mask.bits.drop_small_ack = 1; dma_ctrl_mask.bits.rd_prot = 3; dma_ctrl_mask.bits.rd_burst_size = 3; dma_ctrl_mask.bits.rd_insert_bytes = 3; dma_ctrl_mask.bits.rd_bus = 3; dma_ctrl_mask.bits.td_prot = 0x0f; dma_ctrl_mask.bits.td_burst_size = 3; dma_ctrl_mask.bits.td_bus = 3; gmac_write_reg(tp->dma_base_addr, GMAC_DMA_CTRL_REG, dma_ctrl.bits32, dma_ctrl_mask.bits32); return; } /*----------------------------------------------------------------------* toe_init_free_queue* (1) Initialize the Free Queue Descriptor Base Address & size* Register: TOE_GLOBAL_BASE + 0x0004* (2) Initialize DMA Read/Write pointer for * SW Free Queue and HW Free Queue* (3) Initialize DMA Descriptors for* SW Free Queue and HW Free Queue, *----------------------------------------------------------------------*/void toe_init_free_queue(void){ int i, mac; TOE_INFO_T *toe; DMA_RWPTR_T rwptr_reg; unsigned int rwptr_addr; unsigned int desc_buf,skb_buf; GMAC_RXDESC_T *desc_ptr; //struct sk_buff *skb; unsigned int buf_ptr, skb_ptr; toe = (TOE_INFO_T *)&toe_private_data; desc_buf = DMA_MALLOC((TOE_SW_FREEQ_DESC_NUM * sizeof(GMAC_RXDESC_T)), (dma_addr_t *)&toe->sw_freeq_desc_base_dma) ; desc_ptr = (GMAC_RXDESC_T *)desc_buf; if (!desc_buf) { printk("%s::DMA_MALLOC fail !\n",__func__); return; } memset((void *)desc_buf, 0, TOE_SW_FREEQ_DESC_NUM * sizeof(GMAC_RXDESC_T)); // DMA Queue Base & Size writel((desc_buf & DMA_Q_BASE_MASK) | TOE_SW_FREEQ_DESC_POWER, TOE_GLOBAL_BASE + GLOBAL_SW_FREEQ_BASE_SIZE_REG); // init descriptor base toe->swfq_desc_base = desc_buf; skb_buf = DMA_MALLOC((TOE_SW_FREEQ_DESC_NUM * RX_BUF_SIZE), (dma_addr_t *)&toe->sw_freeq_desc_base_dma) ; skb_ptr = skb_buf; if (!skb_buf) { printk("%s::DMA_MALLOC fail !\n",__func__); return; } memset((void *)skb_buf, 0, TOE_SW_FREEQ_DESC_NUM * RX_BUF_SIZE); // SW Free Queue Read/Write Pointer rwptr_reg.bits.wptr = TOE_SW_FREEQ_DESC_NUM - 1; rwptr_reg.bits.rptr = 0; toe->fq_rx_rwptr.bits32 = rwptr_reg.bits32; writel(rwptr_reg.bits32, TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG); // SW Free Queue Descriptors for (i=0; i<TOE_SW_FREEQ_DESC_NUM; i++) { desc_ptr->word0.bits.buffer_size = RX_BUF_SIZE; desc_ptr->word1.bits.sw_id = i; // used to locate skb desc_ptr->word2.buf_adr = (unsigned int)(skb_ptr+i*RX_BUF_SIZE); //hal_cache_consistent_sync((unsigned int)desc_ptr, sizeof(GMAC_RXDESC_T), PCI_DMA_TODEVICE); // hal_cache_consistent_sync((unsigned int)skb->data, RX_BUF_SIZE, PCI_DMA_TODEVICE); desc_ptr++; } // init hardware free queues desc_buf = DMA_MALLOC((TOE_HW_FREEQ_DESC_NUM * sizeof(GMAC_RXDESC_T)), (dma_addr_t *)&toe->hw_freeq_desc_base_dma) ; desc_ptr = (GMAC_RXDESC_T *)desc_buf; if (!desc_buf) { printk("%s::DMA_MALLOC fail !\n",__func__); return; } memset((void *)desc_buf, 0, TOE_HW_FREEQ_DESC_NUM * sizeof(GMAC_RXDESC_T)); // DMA Queue Base & Size writel((desc_buf & DMA_Q_BASE_MASK) | TOE_HW_FREEQ_DESC_POWER, TOE_GLOBAL_BASE + GLOBAL_HW_FREEQ_BASE_SIZE_REG); // init descriptor base toe->hwfq_desc_base = desc_buf; // HW Free Queue Read/Write Pointer rwptr_reg.bits.wptr = TOE_HW_FREEQ_DESC_NUM - 1; rwptr_reg.bits.rptr = 0; writel(rwptr_reg.bits32, TOE_GLOBAL_BASE + GLOBAL_HWFQ_RWPTR_REG); buf_ptr = DMA_MALLOC(((TOE_HW_FREEQ_DESC_NUM) * RX_BUF_SIZE), (dma_addr_t *)&toe->hwfq_buf_base_dma); toe->hwfq_buf_base = buf_ptr; for (i=0; i<TOE_HW_FREEQ_DESC_NUM; i++) { desc_ptr->word0.bits.buffer_size = RX_BUF_SIZE; desc_ptr->word1.bits.sw_id = i; desc_ptr->word2.buf_adr = (unsigned int)(buf_ptr+i*RX_BUF_SIZE); //hal_cache_consistent_sync((unsigned int)desc_ptr, sizeof(GMAC_RXDESC_T), PCI_DMA_TODEVICE); // hal_cache_consistent_sync((unsigned int)buf_ptr, RX_BUF_SIZE, PCI_DMA_TODEVICE); desc_ptr++; //buf_ptr += RX_BUF_SIZE; }}/*----------------------------------------------------------------------* toe_init_swtx_queue* (2) Initialize the GMAC 0/1 SW TXQ Queue Descriptor Base Address & size* GMAC_SW_TX_QUEUE_BASE_REG(0x0050)* (2) Initialize DMA Read/Write pointer for * GMAC 0/1 SW TX Q0-5*----------------------------------------------------------------------*/void toe_init_swtx_queue(void){ int i, j, mac; TOE_INFO_T *toe; DMA_RWPTR_T rwptr_reg; unsigned int rwptr_addr; unsigned int desc_buf, txbuf; //struct sk_buff *skb; unsigned int buf_ptr; toe = (TOE_INFO_T *)&toe_private_data; // GMAC-0, SW-TXQ // The GMAC-0 and GMAC-0 maybe have different descriptor number // so, not use for instruction if(!gmac_num) { desc_buf = DMA_MALLOC((TOE_GMAC0_SWTXQ_DESC_NUM * TOE_SW_TXQ_NUM * sizeof(GMAC_TXDESC_T)), (dma_addr_t *)&toe->gmac.swtxq_desc_base_dma) ; toe->gmac.swtxq_desc_base = desc_buf; if (!desc_buf) { printk("%s::DMA_MALLOC fail !\n",__func__); return; } memset((void *)desc_buf, 0, TOE_GMAC0_SWTXQ_DESC_NUM * TOE_SW_TXQ_NUM * sizeof(GMAC_TXDESC_T)); writel((desc_buf & DMA_Q_BASE_MASK) | TOE_GMAC0_SWTXQ_DESC_POWER, TOE_GMAC0_DMA_BASE+ GMAC_SW_TX_QUEUE_BASE_REG); // GMAC0 SW TX Q0-Q5 rwptr_reg.bits.wptr = 0; rwptr_reg.bits.rptr = 0; rwptr_addr = TOE_GMAC0_DMA_BASE + GMAC_SW_TX_QUEUE0_PTR_REG; for (i=0; i<TOE_SW_TXQ_NUM; i++) { toe->gmac.swtxq[i].rwptr_reg = rwptr_addr; toe->gmac.swtxq[i].desc_base = desc_buf; toe->gmac.swtxq[i].total_desc_num = TOE_GMAC0_SWTXQ_DESC_NUM; desc_buf += TOE_GMAC0_SWTXQ_DESC_NUM * sizeof(GMAC_TXDESC_T); writel(rwptr_reg.bits32, rwptr_addr); rwptr_addr+=4; } // txbuf = DMA_MALLOC((TOE_GMAC0_SWTXQ_DESC_NUM * TOE_SW_TXQ_NUM * (MAX_ETH_FRAME_SIZE)), (dma_addr_t *)&toe->gmac.swtxq_desc_base_dma) ; if (!txbuf) { printk("%s::DMA_MALLOC fail !\n",__func__); return; } memset((void *)txbuf, 0, TOE_GMAC0_SWTXQ_DESC_NUM * TOE_SW_TXQ_NUM * MAX_ETH_FRAME_SIZE); for(j=0;j<TOE_GMAC0_SWTXQ_DESC_NUM;j++) txbuf_ptr[j] = txbuf +j*MAX_ETH_FRAME_SIZE; } else { desc_buf = DMA_MALLOC((TOE_GMAC1_SWTXQ_DESC_NUM * TOE_SW_TXQ_NUM * sizeof(GMAC_TXDESC_T)), (dma_addr_t *)&toe->gmac.swtxq_desc_base_dma) ; toe->gmac.swtxq_desc_base = desc_buf; if (!desc_buf) { printk("%s::DMA_MALLOC fail !\n",__func__); return; } memset((void *)desc_buf, 0, TOE_GMAC1_SWTXQ_DESC_NUM * TOE_SW_TXQ_NUM * sizeof(GMAC_TXDESC_T)); writel((desc_buf & DMA_Q_BASE_MASK) | TOE_GMAC1_SWTXQ_DESC_POWER, TOE_GMAC1_DMA_BASE+ GMAC_SW_TX_QUEUE_BASE_REG); // GMAC0 SW TX Q0-Q5 rwptr_reg.bits.wptr = 0; rwptr_reg.bits.rptr = 0; rwptr_addr = TOE_GMAC1_DMA_BASE + GMAC_SW_TX_QUEUE0_PTR_REG; for (i=0; i<TOE_SW_TXQ_NUM; i++) { toe->gmac.swtxq[i].rwptr_reg = rwptr_addr; toe->gmac.swtxq[i].desc_base = desc_buf; toe->gmac.swtxq[i].total_desc_num = TOE_GMAC1_SWTXQ_DESC_NUM; desc_buf += TOE_GMAC1_SWTXQ_DESC_NUM * sizeof(GMAC_TXDESC_T); writel(rwptr_reg.bits32, rwptr_addr); rwptr_addr+=4; } // txbuf = DMA_MALLOC((TOE_GMAC1_SWTXQ_DESC_NUM * TOE_SW_TXQ_NUM * (MAX_ETH_FRAME_SIZE)), (dma_addr_t *)&toe->gmac.swtxq_desc_base_dma) ; if (!txbuf) { printk("%s::DMA_MALLOC fail !\n",__func__); return; } memset((void *)txbuf, 0, TOE_GMAC1_SWTXQ_DESC_NUM * TOE_SW_TXQ_NUM * MAX_ETH_FRAME_SIZE); for(j=0;j<TOE_GMAC1_SWTXQ_DESC_NUM;j++) txbuf_ptr[j] = txbuf +j*MAX_ETH_FRAME_SIZE; } }/*----------------------------------------------------------------------* toe_init_default_queue* (1) Initialize the default 0/1 Queue Header* Register: TOE_DEFAULT_Q0_HDR_BASE (0x60002000)* TOE_DEFAULT_Q1_HDR_BASE (0x60002008)* (2) Initialize Descriptors of Default Queue 0/1*----------------------------------------------------------------------*/void toe_init_default_queue(void){ TOE_INFO_T *toe; volatile NONTOE_QHDR_T *qhdr; GMAC_RXDESC_T *desc_ptr; DMA_SKB_SIZE_T skb_size; toe = (TOE_INFO_T *)&toe_private_data; if(gmac_num) { desc_ptr = (GMAC_RXDESC_T *)DMA_MALLOC((TOE_DEFAULT_Q1_DESC_NUM * sizeof(GMAC_RXDESC_T)), (dma_addr_t *)&toe->gmac.default_desc_base_dma); if (!desc_ptr) { printk("%s::DMA_MALLOC fail !\n",__func__); return; } memset((void *)desc_ptr, 0, TOE_DEFAULT_Q1_DESC_NUM * sizeof(GMAC_RXDESC_T)); toe->gmac.default_desc_base = (unsigned int)desc_ptr; toe->gmac.default_desc_num = TOE_DEFAULT_Q1_DESC_NUM; qhdr = (volatile NONTOE_QHDR_T *)TOE_DEFAULT_Q1_HDR_BASE; qhdr->word0.base_size = ((unsigned int)desc_ptr & NONTOE_QHDR0_BASE_MASK) | TOE_DEFAULT_Q1_DESC_POWER; qhdr->word1.bits32 = 0; toe->gmac.rx_rwptr.bits32 = 0; toe->gmac.default_qhdr = (NONTOE_QHDR_T *)qhdr; } else { desc_ptr = (GMAC_RXDESC_T *)DMA_MALLOC((TOE_DEFAULT_Q0_DESC_NUM * sizeof(GMAC_RXDESC_T)), (dma_addr_t *)&toe->gmac.default_desc_base_dma); if (!desc_ptr) { printk("%s::DMA_MALLOC fail !\n",__func__); return; } memset((void *)desc_ptr, 0, TOE_DEFAULT_Q0_DESC_NUM * sizeof(GMAC_RXDESC_T)); toe->gmac.default_desc_base = (unsigned int)desc_ptr; toe->gmac.default_desc_num = TOE_DEFAULT_Q0_DESC_NUM; qhdr = (volatile NONTOE_QHDR_T *)TOE_DEFAULT_Q0_HDR_BASE; qhdr->word0.base_size = ((unsigned int)desc_ptr & NONTOE_QHDR0_BASE_MASK) | TOE_DEFAULT_Q0_DESC_POWER; qhdr->word1.bits32 = 0; toe->gmac.rx_rwptr.bits32 = 0; toe->gmac.default_qhdr = (NONTOE_QHDR_T *)qhdr; } skb_size.bits.hw_skb_size = RX_BUF_SIZE; skb_size.bits.sw_skb_size = RX_BUF_SIZE; writel(skb_size.bits32, TOE_GLOBAL_BASE + GLOBAL_DMA_SKB_SIZE_REG);}/*----------------------------------------------------------------------* toe_init_interrupt_config* Interrupt Select Registers are used to map interrupt to int0 or int1* Int0 and int1 are wired to CPU 0/1 GMAC 0/1* Interrupt Device Inteface data are used to pass device info to* upper device deiver or store status/statistics* ISR handler* (1) If status bit ON but masked, the prinf error message (bug issue)* (2) If select bits are for me, handle it, else skip to let * the other ISR handles it.* Notes:* GMACx init routine (for eCOS) or open routine (for Linux)* enable the interrupt bits only which are selected for him.** Default Setting:* GMAC0 intr bits ------> int0 ----> eth0* GMAC1 intr bits ------> int1 ----> eth1* TOE intr -------------> int0 ----> eth0* Classification Intr --> int0 ----> eth1 // eth1: fpga testing, eth0: normal* Default Q0 -----------> int0 ----> eth0* Default Q1 -----------> int1 ----> eth1*----------------------------------------------------------------------*/static void toe_init_interrupt_config(void){ TOE_INFO_T *toe; volatile NONTOE_QHDR_T *qhdr; GMAC_RXDESC_T *desc_ptr; unsigned int desc_buf_addr; int i, j; toe = (TOE_INFO_T *)&toe_private_data; toe->intr0_select.bits32 = GMAC1_TXDERR_INT_BIT |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -