void init_axiemac(xaxiemacif_s *xaxiemac, struct netif *netif) { int rdy; unsigned mac_address = (unsigned)(netif->state); unsigned link_speed = 1000; unsigned options; unsigned lock_message_printed = 0; XAxiEthernet *xaxiemacp; XAxiEthernet_Config *mac_config; /* obtain config of this emac */ mac_config = lookup_config(mac_address); xaxiemacp = &xaxiemac->axi_ethernet; XAxiEthernet_CfgInitialize(xaxiemacp, mac_config, mac_config->BaseAddress); options = XAxiEthernet_GetOptions(xaxiemacp); options |= XAE_FLOW_CONTROL_OPTION; #ifdef XLLTEMACIF_USE_JUMBO_FRAMES_EXPERIMENTAL options |= XAE_JUMBO_OPTION; #endif options |= XAE_TRANSMITTER_ENABLE_OPTION; options |= XAE_RECEIVER_ENABLE_OPTION; options |= XAE_FCS_STRIP_OPTION; options |= XAE_MULTICAST_OPTION; XAxiEthernet_SetOptions(xaxiemacp, options); XAxiEthernet_ClearOptions(xaxiemacp, ~options); /* set mac address */ XAxiEthernet_SetMacAddress(xaxiemacp, (Xuint8*)(netif->hwaddr)); /* set PHY <--> MAC data clock */ #ifdef CONFIG_LINKSPEED_AUTODETECT link_speed = get_IEEE_phy_speed(xaxiemacp); xil_printf("auto-negotiated link speed: %d\r\n", link_speed); #elif defined(CONFIG_LINKSPEED1000) link_speed = 1000; #elif defined(CONFIG_LINKSPEED100) link_speed = 100; #elif defined(CONFIG_LINKSPEED10) link_speed = 10; #endif XAxiEthernet_SetOperatingSpeed(xaxiemacp, link_speed); /* Setting the operating speed of the MAC needs a delay. */ { volatile int wait; for (wait=0; wait < 100000; wait++); for (wait=0; wait < 100000; wait++); } #ifdef NOTNOW /* in a soft temac implementation, we need to explicitly make sure that * the RX DCM has been locked. See xps_ll_temac manual for details. * This bit is guaranteed to be 1 for hard temac's */ lock_message_printed = 0; while (!(XAxiEthernet_ReadReg(xaxiemacp->Config.BaseAddress, XAE_IS_OFFSET) & XAE_INT_RXDCMLOCK_MASK)) { int first = 1; if (first) { print("Waiting for RX DCM to lock.."); first = 0; lock_message_printed = 1; } } if (lock_message_printed) print("RX DCM locked.\r\n"); #endif /* start the temac */ XAxiEthernet_Start(xaxiemacp); /* enable MAC interrupts */ XAxiEthernet_IntEnable(xaxiemacp, XAE_INT_RECV_ERROR_MASK); }
/** * * This function demonstrates the usage usage of the Axi Ethernet by sending * and receiving frames in interrupt driven SGDMA mode. * * * @param IntcInstancePtr is a pointer to the instance of the Intc * component. * @param AxiEthernetInstancePtr is a pointer to the instance of the * AxiEthernet component. * @param DmaInstancePtr is a pointer to the instance of the AXIDMA * component. * @param AxiEthernetDeviceId is Device ID of the Axi Ethernet Device , * typically XPAR_<AXIETHERNET_instance>_DEVICE_ID value from * xparameters.h. * @param AxiDmaDeviceId is Device ID of the Axi DMAA Device , * typically XPAR_<AXIDMA_instance>_DEVICE_ID value from * xparameters.h. * @param AxiEthernetIntrId is the Interrupt ID and is typically * XPAR_<INTC_instance>_<AXIETHERNET_instance>_VEC_ID * value from xparameters.h. * @param DmaRxIntrId is the interrupt id for DMA Rx and is typically * taken from XPAR_<AXIETHERNET_instance>_CONNECTED_DMARX_INTR * @param DmaTxIntrId is the interrupt id for DMA Tx and is typically * taken from XPAR_<AXIETHERNET_instance>_CONNECTED_DMATX_INTR * * @return -XST_SUCCESS to indicate success. * -XST_FAILURE to indicate failure. * * @note AxiDma hardware must be initialized before initializing * AxiEthernet. Since AxiDma reset line is connected to the * AxiEthernet reset line, a reset of AxiDma hardware during its * initialization would reset AxiEthernet. * ******************************************************************************/ int AxiEthernetExtVlanExample(INTC *IntcInstancePtr, XAxiEthernet *AxiEthernetInstancePtr, XAxiDma *DmaInstancePtr, u16 AxiEthernetDeviceId, u16 AxiDmaDeviceId, u16 AxiEthernetIntrId, u16 DmaRxIntrId, u16 DmaTxIntrId) { int Status; int LoopbackSpeed; XAxiEthernet_Config *MacCfgPtr; XAxiDma_BdRing *RxRingPtr = XAxiDma_GetRxRing(DmaInstancePtr); XAxiDma_BdRing *TxRingPtr = XAxiDma_GetTxRing(DmaInstancePtr); XAxiDma_Bd BdTemplate; XAxiDma_Config* DmaConfig; /*************************************/ /* Setup device for first-time usage */ /*************************************/ /* * Get the configuration of AxiEthernet hardware. */ MacCfgPtr = XAxiEthernet_LookupConfig(AxiEthernetDeviceId); /* * Check if DMA is present or not. */ if(MacCfgPtr->AxiDevType != XPAR_AXI_DMA) { AxiEthernetUtilErrorTrap ("Device HW not configured for SGDMA mode\r\n"); return XST_FAILURE; } DmaConfig = XAxiDma_LookupConfig(AxiDmaDeviceId); /* * Initialize AXIDMA engine. AXIDMA engine must be initialized before * AxiEthernet. During AXIDMA engine initialization, AXIDMA hardware is * reset, and since AXIDMA reset line is connected to AxiEthernet, this * would ensure a reset of AxiEthernet. */ Status = XAxiDma_CfgInitialize(DmaInstancePtr, DmaConfig); if(Status != XST_SUCCESS) { AxiEthernetUtilErrorTrap("Error initializing DMA\r\n"); return XST_FAILURE; } /* * Initialize AxiEthernet hardware. */ Status = XAxiEthernet_CfgInitialize(AxiEthernetInstancePtr, MacCfgPtr, MacCfgPtr->BaseAddress); if (Status != XST_SUCCESS) { AxiEthernetUtilErrorTrap("Error in initialize"); return XST_FAILURE; } /* * Set the MAC address */ Status = XAxiEthernet_SetMacAddress(AxiEthernetInstancePtr, AxiEthernetMAC); if (Status != XST_SUCCESS) { AxiEthernetUtilErrorTrap("Error setting MAC address"); return XST_FAILURE; } /* * Setup RxBD space. * * We have already defined a properly aligned area of memory to store * RxBDs at the beginning of this source code file so just pass its * address into the function. No MMU is being used so the physical and * virtual addresses are the same. * * Setup a BD template for the Rx channel. This template will be copied * to every RxBD. We will not have to explicitly set these again. */ /* * Create the RxBD ring */ Status = XAxiDma_BdRingCreate(RxRingPtr, (u32) &RxBdSpace, (u32) &RxBdSpace, BD_ALIGNMENT, RXBD_CNT); if (Status != XST_SUCCESS) { AxiEthernetUtilErrorTrap("Error setting up RxBD space"); return XST_FAILURE; } XAxiDma_BdClear(&BdTemplate); Status = XAxiDma_BdRingClone(RxRingPtr, &BdTemplate); if (Status != XST_SUCCESS) { AxiEthernetUtilErrorTrap("Error initializing RxBD space"); return XST_FAILURE; } /* * Setup TxBD space. * * Like RxBD space, we have already defined a properly aligned area of * memory to use. */ /* * Create the TxBD ring */ Status = XAxiDma_BdRingCreate(TxRingPtr, (u32) &TxBdSpace, (u32) &TxBdSpace, BD_ALIGNMENT, TXBD_CNT); if (Status != XST_SUCCESS) { AxiEthernetUtilErrorTrap("Error setting up TxBD space"); return XST_FAILURE; } /* * We reuse the bd template, as the same one will work for both rx and * tx. */ Status = XAxiDma_BdRingClone(TxRingPtr, &BdTemplate); if (Status != XST_SUCCESS) { AxiEthernetUtilErrorTrap("Error initializing TxBD space"); return XST_FAILURE; } /* * Set PHY to loopback, speed depends on phy type. * MII is 100 and all others are 1000. */ if (XAxiEthernet_GetPhysicalInterface(AxiEthernetInstancePtr) == XAE_PHY_TYPE_MII){ LoopbackSpeed = AXIETHERNET_LOOPBACK_SPEED; } else { LoopbackSpeed = AXIETHERNET_LOOPBACK_SPEED_1G; } AxiEthernetUtilEnterLoopback(AxiEthernetInstancePtr, LoopbackSpeed); /* * Set PHY<-->MAC data clock */ Status = XAxiEthernet_SetOperatingSpeed(AxiEthernetInstancePtr, (u16)LoopbackSpeed); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setting the operating speed of the MAC needs a delay. There * doesn't seem to be register to poll, so please consider this * during your application design. */ AxiEthernetUtilPhyDelay(2); /* * Connect to the interrupt controller and enable interrupts */ Status = AxiEthernetSetupIntrSystem(IntcInstancePtr, AxiEthernetInstancePtr, DmaInstancePtr, AxiEthernetIntrId, DmaRxIntrId, DmaTxIntrId); /****************************/ /* Run the example */ /****************************/ /* Run the new VLAN feature. Make sure HW has the capability */ if (XAxiEthernet_IsTxVlanTran(AxiEthernetInstancePtr) && XAxiEthernet_IsTxVlanStrp(AxiEthernetInstancePtr) && XAxiEthernet_IsTxVlanTag(AxiEthernetInstancePtr) && XAxiEthernet_IsRxVlanTran(AxiEthernetInstancePtr) && XAxiEthernet_IsRxVlanStrp(AxiEthernetInstancePtr) && XAxiEthernet_IsRxVlanTag(AxiEthernetInstancePtr)) { Status = AxiEthernetSgDmaIntrExtVlanExample (AxiEthernetInstancePtr,DmaInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } } /* * Disable the interrupts for the AxiEthernet device */ AxiEthernetDisableIntrSystem(IntcInstancePtr, AxiEthernetIntrId, DmaRxIntrId, DmaTxIntrId); /* * Stop the device */ XAxiEthernet_Stop(AxiEthernetInstancePtr); return XST_SUCCESS; }