/** * 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; }
void eth_rx_irq(int irqno,void *param) { struct rt_eth_dev *dev = ð_dev; struct synopGMACNetworkAdapter *adapter = dev->priv; //DEBUG_MES("in irq!!\n"); #ifdef RT_USING_GMAC_INT_MODE int i ; for(i = 0; i < 7200; i++) ; #endif /*RT_USING_GMAC_INT_MODE*/ synopGMACdevice * gmacdev = (synopGMACdevice *)adapter->synopGMACdev; u32 interrupt,dma_status_reg; s32 status; u32 dma_addr; //rt_kprintf("irq i = %d\n", i++); dma_status_reg = synopGMACReadReg(gmacdev->DmaBase, DmaStatus); if(dma_status_reg == 0) { rt_kprintf("dma_status ==0 \n"); return; } //rt_kprintf("dma_status_reg is 0x%x\n", dma_status_reg); u32 gmacstatus; synopGMAC_disable_interrupt_all(gmacdev); gmacstatus = synopGMACReadReg(gmacdev->MacBase,GmacStatus); if(dma_status_reg & GmacPmtIntr){ rt_kprintf("%s:: Interrupt due to PMT module\n",__FUNCTION__); //synopGMAC_linux_powerup_mac(gmacdev); } if(dma_status_reg & GmacMmcIntr){ rt_kprintf("%s:: Interrupt due to MMC module\n",__FUNCTION__); DEBUG_MES("%s:: synopGMAC_rx_int_status = %08x\n",__FUNCTION__,synopGMAC_read_mmc_rx_int_status(gmacdev)); DEBUG_MES("%s:: synopGMAC_tx_int_status = %08x\n",__FUNCTION__,synopGMAC_read_mmc_tx_int_status(gmacdev)); } if(dma_status_reg & GmacLineIntfIntr){ rt_kprintf("%s:: Interrupt due to GMAC LINE module\n",__FUNCTION__); } interrupt = synopGMAC_get_interrupt_type(gmacdev); //rt_kprintf("%s:Interrupts to be handled: 0x%08x\n",__FUNCTION__,interrupt); if(interrupt & synopGMACDmaError){ u8 mac_addr0[6]; rt_kprintf("%s::Fatal Bus Error Inetrrupt Seen\n",__FUNCTION__); memcpy(mac_addr0,dev->dev_addr,6); synopGMAC_disable_dma_tx(gmacdev); synopGMAC_disable_dma_rx(gmacdev); synopGMAC_take_desc_ownership_tx(gmacdev); synopGMAC_take_desc_ownership_rx(gmacdev); synopGMAC_init_tx_rx_desc_queue(gmacdev); synopGMAC_reset(gmacdev); synopGMAC_set_mac_addr(gmacdev,GmacAddr0High,GmacAddr0Low, mac_addr0); synopGMAC_dma_bus_mode_init(gmacdev,DmaFixedBurstEnable| DmaBurstLength8 | DmaDescriptorSkip2 ); synopGMAC_dma_control_init(gmacdev,DmaStoreAndForward); synopGMAC_init_rx_desc_base(gmacdev); synopGMAC_init_tx_desc_base(gmacdev); synopGMAC_mac_init(gmacdev); synopGMAC_enable_dma_rx(gmacdev); synopGMAC_enable_dma_tx(gmacdev); } if(interrupt & synopGMACDmaRxNormal){ //DEBUG_MES("%s:: Rx Normal \n", __FUNCTION__); //synop_handle_received_data(netdev); eth_device_ready(ð_dev.parent); } if(interrupt & synopGMACDmaRxAbnormal){ //rt_kprintf("%s::Abnormal Rx Interrupt Seen\n",__FUNCTION__); if(GMAC_Power_down == 0){ adapter->synopGMACNetStats.rx_over_errors++; synopGMACWriteReg(gmacdev->DmaBase, DmaStatus ,0x80); synopGMAC_resume_dma_rx(gmacdev); } } if(interrupt & synopGMACDmaRxStopped){ rt_kprintf("%s::Receiver stopped seeing Rx interrupts\n",__FUNCTION__); //Receiver gone in to stopped state } if(interrupt & synopGMACDmaTxNormal){ DEBUG_MES("%s::Finished Normal Transmission \n",__FUNCTION__); // synop_handle_transmit_over(netdev); } if(interrupt & synopGMACDmaTxAbnormal){ rt_kprintf("%s::Abnormal Tx Interrupt Seen\n",__FUNCTION__); } if(interrupt & synopGMACDmaTxStopped){ TR("%s::Transmitter stopped sending the packets\n",__FUNCTION__); if(GMAC_Power_down == 0){ // If Mac is not in powerdown synopGMAC_disable_dma_tx(gmacdev); synopGMAC_take_desc_ownership_tx(gmacdev); synopGMAC_enable_dma_tx(gmacdev); // netif_wake_queue(netdev); TR("%s::Transmission Resumed\n",__FUNCTION__); } } /* Enable the interrrupt before returning from ISR*/ synopGMAC_enable_interrupt(gmacdev,DmaIntEnable); return; }
/** * Disable all the interrupts. * Disables all DMA interrupts. * @param[in] pointer to synopGMACdevice. * \return returns void. * \note This function disabled all the interrupts, if you want to disable a particular interrupt then * use synopGMAC_disable_interrupt(). */ void synopGMAC_disable_interrupt_all(synopGMACdevice *gmacdev) { synopGMACWriteReg(gmacdev->DmaBase, DmaInterrupt, 0); return; }
/** * Programs the DmaTxBaseAddress with the Tx descriptor base address. * Tx Descriptor's base address is available in the gmacdev structure. This function progrms the * Dma Tx Base address with the starting address of the descriptor ring or chain. * @param[in] pointer to synopGMACdevice. * \return returns void. */ void synopGMAC_init_tx_desc_base(synopGMACdevice *gmacdev) { synopGMACWriteReg(gmacdev->DmaBase, DmaTxBaseAddr, (u32)gmacdev->TxDescDma); return; }
/** * Resumes the DMA Transmission. * the DmaTxPollDemand is written. (the data writeen could be anything). * This forces the DMA to resume transmission. * @param[in] pointer to synopGMACdevice. * \return returns void. */ void synopGMAC_resume_dma_tx(synopGMACdevice * gmacdev) { synopGMACWriteReg(gmacdev->DmaBase, DmaTxPollDemand, 1); }