static void synopGMAC_linux_powerdown_mac(synopGMACdevice *gmacdev) { rt_kprintf("Put the GMAC to power down mode..\n"); GMAC_Power_down = 1; synopGMAC_disable_dma_tx(gmacdev); plat_delay(10000); synopGMAC_tx_disable(gmacdev); synopGMAC_rx_disable(gmacdev); plat_delay(10000); synopGMAC_disable_dma_rx(gmacdev); synopGMAC_magic_packet_enable(gmacdev); synopGMAC_write_wakeup_frame_register(gmacdev, synopGMAC_wakeup_filter_config3); synopGMAC_wakeup_frame_enable(gmacdev); synopGMAC_rx_enable(gmacdev); synopGMAC_pmt_int_enable(gmacdev); synopGMAC_power_down_enable(gmacdev); return; }
/** * Function to reset the GMAC core. * This reests the DMA and GMAC core. After reset all the registers holds their respective reset value * @param[in] pointer to synopGMACdevice. * \return 0 on success else return the error status. */ s32 synopGMAC_reset(synopGMACdevice *gmacdev) { u32 data = 0; int cnt = 0; synopGMACWriteReg(gmacdev->DmaBase, DmaBusMode ,DmaResetOn); plat_delay(DEFAULT_LOOP_VARIABLE); while (1) { data = synopGMACReadReg(gmacdev->DmaBase, DmaBusMode); TR("DATA after Reset = %08x\n",data); if (data & DmaResetOn) { if(cnt > 10) printf("Bus Mode Reg after reset: 0x%08x\n", data); // udelay(1); cnt ++; } else break; } return 0; }
static rt_err_t eth_init(rt_device_t device ) { struct eth_device *eth_device = (struct eth_device *)device; RT_ASSERT(eth_device != RT_NULL); s32 ijk; s32 status = 0; u64 dma_addr; u32 Mac_changed = 0; struct pbuf *pbuf; u8 macaddr[6] = DEFAULT_MAC_ADDRESS; struct rt_eth_dev *dev = ð_dev; struct synopGMACNetworkAdapter *adapter = dev->priv; synopGMACdevice * gmacdev = (synopGMACdevice *)adapter->synopGMACdev; synopGMAC_reset(gmacdev); synopGMAC_attach(gmacdev,(regbase + MACBASE),(regbase + DMABASE), DEFAULT_PHY_BASE, macaddr); synopGMAC_read_version(gmacdev); synopGMAC_set_mdc_clk_div(gmacdev,GmiiCsrClk3); gmacdev->ClockDivMdc = synopGMAC_get_mdc_clk_div(gmacdev); init_phy(adapter->synopGMACdev); rt_kprintf("tx desc_queue\n"); synopGMAC_setup_tx_desc_queue(gmacdev,TRANSMIT_DESC_SIZE, RINGMODE); synopGMAC_init_tx_desc_base(gmacdev); rt_kprintf("rx desc_queue\n"); synopGMAC_setup_rx_desc_queue(gmacdev,RECEIVE_DESC_SIZE, RINGMODE); synopGMAC_init_rx_desc_base(gmacdev); DEBUG_MES("DmaRxBaseAddr = %08x\n",synopGMACReadReg(gmacdev->DmaBase,DmaRxBaseAddr)); // u32 dmaRx_Base_addr = synopGMACReadReg(gmacdev->DmaBase,DmaRxBaseAddr); // rt_kprintf("first_desc_addr = 0x%x\n", dmaRx_Base_addr); #ifdef ENH_DESC_8W synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength32 | DmaDescriptorSkip2 | DmaDescriptor8Words ); #else //synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength4 | DmaDescriptorSkip1); synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength4 | DmaDescriptorSkip2); #endif synopGMAC_dma_control_init(gmacdev,DmaStoreAndForward |DmaTxSecondFrame|DmaRxThreshCtrl128); status = synopGMAC_check_phy_init(adapter); synopGMAC_mac_init(gmacdev); synopGMAC_pause_control(gmacdev); #ifdef IPC_OFFLOAD synopGMAC_enable_rx_chksum_offload(gmacdev); synopGMAC_rx_tcpip_chksum_drop_enable(gmacdev); #endif u32 skb; do{ skb = (u32)plat_alloc_memory(RX_BUF_SIZE); //should skb aligned here? if(skb == RT_NULL){ rt_kprintf("ERROR in skb buffer allocation\n"); break; } dma_addr = plat_dma_map_single(gmacdev,(void *)skb,RX_BUF_SIZE); //获取 skb 的 dma 地址 status = synopGMAC_set_rx_qptr(gmacdev,dma_addr,RX_BUF_SIZE,(u32)skb,0,0,0); if(status < 0) { rt_kprintf("status < 0!!\n"); plat_free_memory((void *)skb); } }while(status >= 0 && (status < (RECEIVE_DESC_SIZE - 1))); synopGMAC_clear_interrupt(gmacdev); synopGMAC_disable_mmc_tx_interrupt(gmacdev, 0xFFFFFFFF); synopGMAC_disable_mmc_rx_interrupt(gmacdev, 0xFFFFFFFF); synopGMAC_disable_mmc_ipc_rx_interrupt(gmacdev, 0xFFFFFFFF); // synopGMAC_disable_interrupt_all(gmacdev); synopGMAC_enable_interrupt(gmacdev, DmaIntEnable); synopGMAC_enable_dma_rx(gmacdev); synopGMAC_enable_dma_tx(gmacdev); plat_delay(DEFAULT_LOOP_VARIABLE); synopGMAC_check_phy_init(adapter); synopGMAC_mac_init(gmacdev); rt_timer_init(&dev->link_timer, "link_timer", synopGMAC_linux_cable_unplug_function, (void *)adapter, RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC); rt_timer_start(&dev->link_timer); #ifdef RT_USING_GMAC_INT_MODE /* installl isr */ DEBUG_MES("%s\n", __FUNCTION__); rt_hw_interrupt_install(LS1C_MAC_IRQ, eth_rx_irq, RT_NULL, "e0_isr"); rt_hw_interrupt_umask(LS1C_MAC_IRQ); #else rt_timer_init(&dev->rx_poll_timer, "rx_poll_timer", eth_rx_irq, (void *)adapter, 1, RT_TIMER_FLAG_PERIODIC); rt_timer_start(&dev->rx_poll_timer); #endif /*RT_USING_GMAC_INT_MODE*/ rt_kprintf("eth_inited!\n"); return RT_EOK; }