/**
 * 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;
}
Example #2
0
void eth_rx_irq(int irqno,void *param)
{
	struct rt_eth_dev *dev = &eth_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(&eth_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);
}