Example #1
0
void rt_hw_eth_init(void)
{
	u64 base_addr = Gmac_base; 
	struct synopGMACNetworkAdapter * synopGMACadapter;
	static u8 mac_addr0[6] = DEFAULT_MAC_ADDRESS;

	rt_sem_init(&sem_ack, "tx_ack", 1, RT_IPC_FLAG_FIFO);
	rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);


	memset(&eth_dev, 0, sizeof(eth_dev));
	synopGMACadapter = (struct synopGMACNetworkAdapter * )plat_alloc_memory(sizeof (struct synopGMACNetworkAdapter));
	if(!synopGMACadapter){
		rt_kprintf("Error in Memory Allocataion, Founction : %s \n", __FUNCTION__);
	}
	memset((char *)synopGMACadapter ,0, sizeof (struct synopGMACNetworkAdapter));

	synopGMACadapter->synopGMACdev    = NULL;

	synopGMACadapter->synopGMACdev = (synopGMACdevice *) plat_alloc_memory(sizeof (synopGMACdevice));
	if(!synopGMACadapter->synopGMACdev){
		rt_kprintf("Error in Memory Allocataion, Founction : %s \n", __FUNCTION__);
	}
	memset((char *)synopGMACadapter->synopGMACdev ,0, sizeof (synopGMACdevice));
	/*
	 * Attach the device to MAC struct This will configure all the required base addresses
	 * such as Mac base, configuration base, phy base address(out of 32 possible phys)
	 * */
	synopGMAC_attach(synopGMACadapter->synopGMACdev,(regbase + MACBASE), regbase + DMABASE, DEFAULT_PHY_BASE, mac_addr0);

	init_phy(synopGMACadapter->synopGMACdev);
	synopGMAC_reset(synopGMACadapter->synopGMACdev);

	/* MII setup */
	synopGMACadapter->mii.phy_id_mask = 0x1F;
	synopGMACadapter->mii.reg_num_mask = 0x1F;
	synopGMACadapter->mii.dev = synopGMACadapter;
	synopGMACadapter->mii.mdio_read = mdio_read;
	synopGMACadapter->mii.mdio_write = mdio_write;
	synopGMACadapter->mii.phy_id = synopGMACadapter->synopGMACdev->PhyBase;
	synopGMACadapter->mii.supports_gmii = mii_check_gmii_support(&synopGMACadapter->mii);

	eth_dev.iobase = base_addr;
	eth_dev.name = "e0";
	eth_dev.priv = synopGMACadapter;
	eth_dev.dev_addr[0] = mac_addr0[0];
	eth_dev.dev_addr[1] = mac_addr0[1];
	eth_dev.dev_addr[2] = mac_addr0[2];
	eth_dev.dev_addr[3] = mac_addr0[3];
	eth_dev.dev_addr[4] = mac_addr0[4];
	eth_dev.dev_addr[5] = mac_addr0[5];

	eth_dev.parent.parent.type          = RT_Device_Class_NetIf;
	eth_dev.parent.parent.init	        = eth_init;
	eth_dev.parent.parent.open	        = eth_open;
	eth_dev.parent.parent.close         = eth_close;
	eth_dev.parent.parent.read	        = eth_read;
	eth_dev.parent.parent.write	        = eth_write;
	eth_dev.parent.parent.control		= eth_control;
	eth_dev.parent.parent.user_data		= RT_NULL;

	eth_dev.parent.eth_tx            = rt_eth_tx;
	eth_dev.parent.eth_rx            = rt_eth_rx;

	eth_device_init(&(eth_dev.parent), "e0");
}
Example #2
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 = &eth_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;
}
Example #3
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;
}
Example #4
0
int rt_hw_eth_init(void)
{
    u64 base_addr = Gmac_base;
    struct synopGMACNetworkAdapter *synopGMACadapter;
    static u8 mac_addr0[6] = DEFAULT_MAC_ADDRESS;
    int index;

    rt_sem_init(&sem_ack, "tx_ack", 1, RT_IPC_FLAG_FIFO);
    rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);

    for (index = 21; index <= 30; index++)
    {
        pin_set_purpose(index, PIN_PURPOSE_OTHER);
        pin_set_remap(index, PIN_REMAP_DEFAULT);
    }
    pin_set_purpose(35, PIN_PURPOSE_OTHER);
    pin_set_remap(35, PIN_REMAP_DEFAULT);
    *((volatile unsigned int *)0xbfd00424) &= ~(7 << 28);
    *((volatile unsigned int *)0xbfd00424) |= (1 << 30); //wl rmii



    memset(&eth_dev, 0, sizeof(eth_dev));
    synopGMACadapter = (struct synopGMACNetworkAdapter *)plat_alloc_memory(sizeof(struct synopGMACNetworkAdapter));
    if (!synopGMACadapter)
    {
        rt_kprintf("Error in Memory Allocataion, Founction : %s \n", __FUNCTION__);
    }
    memset((char *)synopGMACadapter, 0, sizeof(struct synopGMACNetworkAdapter));

    synopGMACadapter->synopGMACdev    = NULL;

    synopGMACadapter->synopGMACdev = (synopGMACdevice *) plat_alloc_memory(sizeof(synopGMACdevice));
    if (!synopGMACadapter->synopGMACdev)
    {
        rt_kprintf("Error in Memory Allocataion, Founction : %s \n", __FUNCTION__);
    }
    memset((char *)synopGMACadapter->synopGMACdev, 0, sizeof(synopGMACdevice));
    /*
     * Attach the device to MAC struct This will configure all the required base addresses
     * such as Mac base, configuration base, phy base address(out of 32 possible phys)
     * */
    synopGMAC_attach(synopGMACadapter->synopGMACdev, (regbase + MACBASE), regbase + DMABASE, DEFAULT_PHY_BASE, mac_addr0);

    init_phy(synopGMACadapter->synopGMACdev);
    synopGMAC_reset(synopGMACadapter->synopGMACdev);

    /* MII setup */
    synopGMACadapter->mii.phy_id_mask = 0x1F;
    synopGMACadapter->mii.reg_num_mask = 0x1F;
    synopGMACadapter->mii.dev = synopGMACadapter;
    synopGMACadapter->mii.mdio_read = mdio_read;
    synopGMACadapter->mii.mdio_write = mdio_write;
    synopGMACadapter->mii.phy_id = synopGMACadapter->synopGMACdev->PhyBase;
    synopGMACadapter->mii.supports_gmii = mii_check_gmii_support(&synopGMACadapter->mii);

    eth_dev.iobase = base_addr;
    eth_dev.name = "e0";
    eth_dev.priv = synopGMACadapter;
    eth_dev.dev_addr[0] = mac_addr0[0];
    eth_dev.dev_addr[1] = mac_addr0[1];
    eth_dev.dev_addr[2] = mac_addr0[2];
    eth_dev.dev_addr[3] = mac_addr0[3];
    eth_dev.dev_addr[4] = mac_addr0[4];
    eth_dev.dev_addr[5] = mac_addr0[5];

    eth_dev.parent.parent.type          = RT_Device_Class_NetIf;
    eth_dev.parent.parent.init          = eth_init;
    eth_dev.parent.parent.open          = eth_open;
    eth_dev.parent.parent.close         = eth_close;
    eth_dev.parent.parent.read          = eth_read;
    eth_dev.parent.parent.write         = eth_write;
    eth_dev.parent.parent.control       = eth_control;
    eth_dev.parent.parent.user_data     = RT_NULL;

    eth_dev.parent.eth_tx            = rt_eth_tx;
    eth_dev.parent.eth_rx            = rt_eth_rx;

    eth_device_init(&(eth_dev.parent), "e0");

    eth_device_linkchange(&eth_dev.parent, RT_TRUE);   //linkup the e0 for lwip to check

    return 0;
}