/****************************************************************************** * * ae_SetMACFromPhy - read Phy settings and update Mac * with current duplex and speed. * * RETURNS: */ static void ae531x_SetMACFromPhy(ae531x_MAC_t *MACInfo) { UINT32 macCtl; BOOL fullDuplex; ARRIVE(); /* Get duplex mode from Phy */ fullDuplex = phyIsFullDuplex(MACInfo->unit); /* Flag is set for full duplex mode, else cleared */ macCtl = ae531x_ReadMacReg(MACInfo, MacControl); if (fullDuplex) { /* set values of control registers */ macCtl &= ~MacDisableRxOwn; macCtl |= MacFullDuplex; ae531x_WriteMacReg(MACInfo, MacControl, macCtl); ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitFdx); } else { /* set values of control registers */ ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitHdx); macCtl |= MacDisableRxOwn; macCtl &= ~MacFullDuplex; ae531x_WriteMacReg(MACInfo, MacControl, macCtl); } LEAVE(); }
/****************************************************************************** * ae531x_QueueDestroy -- Free all buffers and descriptors associated * with a queue. */ static void ae531x_QueueDestroy(AE531X_QUEUE *q) { int i; int count; VIRT_ADDR descAddr; ARRIVE(); count = q->count; for (i=0, descAddr=q->firstDescAddr; i<count; i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE)) { AE531X_DESC_STATUS_SET(descAddr, 0); AE531X_DESC_CTRLEN_SET(descAddr, 0); AE531X_DESC_BUFPTR_SET(descAddr, (UINT32)0); AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0); #if 0 /* TBDXXX */ ae531x_rxbuf_free(descAddr); /* Free OS-specific software pointer */ #endif AE531X_DESC_SWPTR_SET(descAddr, NULL); } LEAVE(); }
/****************************************************************************** * * ae531x_MACAddressSet - Set the ethernet address * * Sets the ethernet address from the given address field * * RETURNS: void */ static void ae531x_MACAddressSet(ae531x_MAC_t *MACInfo) { unsigned int data; UINT8 *macAddr; ARRIVE(); macAddr = macAddrGet(MACInfo); /* set our MAC address */ data = (macAddr[5]<<8) | macAddr[4]; ae531x_WriteMacReg(MACInfo, MacAddrHigh, data ); data = (macAddr[3]<<24) | (macAddr[2]<<16) | (macAddr[1]<<8) | macAddr[0]; ae531x_WriteMacReg(MACInfo, MacAddrLow, data ); AE531X_PRINT(AE531X_DEBUG_RESET, ("eth%d Verify MAC address %8.8X %8.8X \n", MACInfo->unit, ae531x_ReadMacReg(MACInfo, MacAddrLow), ae531x_ReadMacReg(MACInfo, MacAddrHigh))); AE531X_PRINT(AE531X_DEBUG_RESET, (" sb = %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 0xff&macAddr[0], 0xff&macAddr[1], 0xff&macAddr[2], 0xff&macAddr[3], 0xff&macAddr[4], 0xff&macAddr[5])); LEAVE(); }
static void ag7100_stop(struct eth_device *dev) { ag7100_priv_data_t *ag7100_priv = (ag7100_priv_data_t *)dev->priv; ag7100_mac_t *MACInfo = (ag7100_mac_t *)&ag7100_priv->MACInfo; ARRIVE(); //ag7100_hw_stop(MACInfo); LEAVE(); }
/****************************************************************************** * Initialize generic queue data */ void ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count) { ARRIVE(); q->firstDescAddr = pMem; q->lastDescAddr = (VIRT_ADDR)((UINT32)q->firstDescAddr + (count - 1) * AE531X_QUEUE_ELE_SIZE); q->curDescAddr = q->firstDescAddr; q->count = count; LEAVE(); }
static int ag7100_control(struct eth_drv_sc *sc, unsigned long key, void *data, int data_length) { ARRIVE(); /* TBDXXX */ LEAVE(); return 0; }
/****************************************************************************** * ae531x_RxQueueCreate - create a circular queue of Rx descriptors */ int ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo, AE531X_QUEUE *q, char *pMem, int count) { int i; VIRT_ADDR descAddr; ARRIVE(); ae531x_QueueInit(q, pMem, count); q->reapDescAddr = NULL; /* Initialize Rx buffer descriptors */ for (i=0, descAddr=q->firstDescAddr; i<count; i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE)) { void *swptr; char *rxBuffer; int rxBufferSize; swptr = ae531x_rxbuf_alloc(MACInfo, &rxBuffer, &rxBufferSize); if (swptr == NULL) { AE531X_PRINT(AE531X_DEBUG_RESET, ("eth%d RX queue: ae531x_rxbuf_alloc failed\n", MACInfo->unit)); ae531x_QueueDestroy(q); return -1; } AE531X_DESC_SWPTR_SET(descAddr, swptr); AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma); AE531X_DESC_CTRLEN_SET(descAddr, rxBufferSize); AE531X_DESC_BUFPTR_SET(descAddr, virt_to_bus(rxBuffer)); AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0); } /* for each desc */ /* Make the queue circular */ AE531X_DESC_CTRLEN_SET(q->lastDescAddr, DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr)); AE531X_PRINT(AE531X_DEBUG_RESET, ("eth%d Rxbuf begin = %x, end = %x\n", MACInfo->unit, (UINT32)q->firstDescAddr, (UINT32)q->lastDescAddr)); LEAVE(); return 0; }
/* * Standard eCos initialization routine. Call the upper-level ethernet * driver and let it know our MAC address. */ static int ag7100_init(struct eth_device *dev, bd_t *bis) //struct cyg_netdevtab_entry *tab) { unsigned char enaddr[ETHER_ADDR_LEN]; ag7100_priv_data_t *ag7100_priv; ag7100_mac_t *mac; int unit; ARRIVE(); ag7100_priv = (ag7100_priv_data_t *)dev->priv; unit = ag7100_priv->enetUnit; mac = &ag7100_priv->MACInfo; ag7100_macs[unit]=mac; /* Get ethernet's MAC address from board configuration data */ ag7100_get_macaddr(mac, enaddr); ag7100_priv->dev = dev; ag7100_priv->rxRecvdListHead = NULL; ag7100_priv->rxRecvdListTail = NULL; /* Initialize MACInfo */ mac->mac_unit = unit; mac->mac_osdep = (void *)ag7100_priv; mac->mac_base = ag7100_mac_base(unit); #if 0 AG7100_PRINT(AG7100_DEBUG_RESET, ("ag7100_init eth%d macBase=0x%x\n", mac->mac_unit, mac->mac_base)); #endif /* Initialize the device */ ag7100_reset(mac); ag7100_hw_setup(mac); ag7100_phy_setup(mac->mac_unit); //(sc->funs->eth_drv->init)(sc, enaddr); LEAVE(); udelay(2000000); return 0; }
static int ag7100_recv(struct eth_device *dev) //struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len) { ag7100_priv_data_t *ag7100_priv = (ag7100_priv_data_t *)dev->priv; ag7100RxBuf_t *rxBuf; unsigned long oldIntrState; unsigned char *RxBufData; struct eth_drv_sg *sg_item; int i; ARRIVE(); intDisable(oldIntrState); rxBuf = ag7100_priv->rxRecvdListHead; ag7100_priv->rxRecvdListHead = ag7100_priv->rxRecvdListHead->next; intEnable(oldIntrState); #if 0 //by Zhangyu if ((char *)sg_list->buf != NULL) { /* Copy out from driver Rx buffer to sg_list */ RxBufData = rxBuf->data; sg_item = sg_list; for (i=0; i<sg_len; sg_item++, i++) { char *segment_addr; int segment_len; segment_addr = (char *)sg_item->buf; segment_len = sg_item->len; #if defined(CONFIG_ATHRS26_PHY) && defined(HEADER_EN) /* remove header */ if ((ag7100_priv->enetUnit == 0) && (i == 0)) { RxBufData += 2; segment_len -= 2; } #endif memcpy(segment_addr, RxBufData, segment_len); RxBufData += segment_len; } } else { /* Handle according to convention: bit bucket the packet */ } #endif RxBufData = rxBuf->data; NetReceive(RxBufData, AG7100_RX_BUF_SIZE); /* Free driver Rx buffer */ ag7100_rxbuf_free(ag7100_priv, rxBuf); LEAVE(); }
static int ag7100_start(struct eth_device *dev, bd_t *bis) { ag7100_priv_data_t *ag7100_priv; unsigned char enet_addr[ETHER_ADDR_LEN]; ag7100_mac_t *mac; uint32_t mac_l, mac_h; ARRIVE(); ag7100_priv = (ag7100_priv_data_t *)dev->priv; mac = (ag7100_mac_t *)&ag7100_priv->MACInfo; memcpy(enet_addr, bis->bi_enetaddr, ETHER_ADDR_LEN); memcpy(ag7100_priv->enet_addr, enet_addr, ETHER_ADDR_LEN); /* Attach interrupt handler */ /* TBDXXX */ if(ag7100_setup_fifos(mac)) { debug("Fifo setup failed\n"); goto skip_start; } /* * XXX get the mac addr from flash? */ mac_l = (enet_addr[4] << 8) | (enet_addr[5]); mac_h = (enet_addr[0] << 24) | (enet_addr[1] << 16) | (enet_addr[2] << 8) | (enet_addr[3] << 0); ag7100_reg_wr(mac, AG7100_GE_MAC_ADDR1, mac_l); ag7100_reg_wr(mac, AG7100_GE_MAC_ADDR2, mac_h); ag7100_priv->linkChkCntr = 1; /* Force link check on first poll */ ag7100_check_link(mac); ag7100_reg_wr(mac, AG7100_DMA_RX_DESC, virt_to_bus((uint32_t)(mac->fifo_rx[0]))); ag7100_rx_start(mac); return 1; skip_start: LEAVE(); return 0; }
/****************************************************************************** * ae531x_TxQueueCreate - create a circular queue of descriptors for Transmit */ static int ae531x_TxQueueCreate(ae531x_MAC_t *MACInfo, AE531X_QUEUE *q, char *pMem, int count) { int i; VIRT_ADDR descAddr; ARRIVE(); ae531x_QueueInit(q, pMem, count); q->reapDescAddr = q->lastDescAddr; /* Initialize Tx buffer descriptors. */ for (i=0, descAddr=q->firstDescAddr; i<count; i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE)) { /* Update the size, BUFPTR, and SWPTR fields */ AE531X_DESC_STATUS_SET(descAddr, 0); AE531X_DESC_CTRLEN_SET(descAddr, 0); AE531X_DESC_BUFPTR_SET(descAddr, (UINT32)0); AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0); AE531X_DESC_SWPTR_SET(descAddr, (void *)0); } /* for each desc */ /* Make the queue circular */ AE531X_DESC_CTRLEN_SET(q->lastDescAddr, DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr)); AE531X_PRINT(AE531X_DEBUG_RESET, ("eth%d Txbuf begin = %x, end = %x\n", MACInfo->unit, (UINT32)q->firstDescAddr, (UINT32)q->lastDescAddr)); LEAVE(); return 0; }
/****************************************************************************** * * ae531x_DmaReset - Reset DMA and TLI controllers * * RETURNS: N/A */ void ae531x_DmaReset(ae531x_MAC_t *MACInfo) { int i; UINT32 descAddr; unsigned long oldIntrState; ARRIVE(); /* Disable device interrupts prior to any errors during stop */ intDisable(oldIntrState); /* Disable MAC rx and tx */ ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable)); /* Reset dma controller */ ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaResetOn); /* Delay 2 usec */ sysUDelay(2); /* Flush the rx queue */ descAddr = (UINT32)MACInfo->rxQueue.firstDescAddr; MACInfo->rxQueue.curDescAddr = MACInfo->rxQueue.firstDescAddr; for (i=0; i<(MACInfo->rxDescCount); i++, descAddr += AE531X_QUEUE_ELE_SIZE) { AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma); } /* Flush the tx queue */ descAddr = (UINT32)MACInfo->txQueue.firstDescAddr; MACInfo->txQueue.curDescAddr = MACInfo->txQueue.firstDescAddr; MACInfo->txQueue.reapDescAddr = MACInfo->txQueue.lastDescAddr; for (i=0; i<(MACInfo->txDescCount); i++, descAddr += AE531X_QUEUE_ELE_SIZE) { AE531X_DESC_STATUS_SET (descAddr, 0); } /* Set init register values */ ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaBusModeInit); /* Install the first Tx and Rx queues on the device */ ae531x_WriteDmaReg(MACInfo, DmaRxBaseAddr, (UINT32)MACInfo->rxQueue.firstDescAddr); ae531x_WriteDmaReg(MACInfo, DmaTxBaseAddr, (UINT32)MACInfo->txQueue.firstDescAddr); ae531x_WriteDmaReg(MACInfo, DmaControl, DmaStoreAndForward); ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable); AE531X_PRINT(AE531X_DEBUG_RESET, ("eth%d: DMA RESET!\n", MACInfo->unit)); /* Turn on device interrupts -- enable most errors */ ae531x_DmaIntClear(MACInfo); /* clear interrupt requests */ ae531x_DmaIntEnable(MACInfo); /* enable interrupts */ ae531x_EndResetMode(MACInfo); intEnable(oldIntrState); LEAVE(); }
/****************************************************************************** * ae531x_AllocateQueues - Allocate receive and transmit queues */ int ae531x_AllocateQueues(ae531x_MAC_t *MACInfo) { size_t QMemSize; char *pTxBuf = NULL; char *pRxBuf = NULL; ARRIVE(); QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->txDescCount; pTxBuf = MACInfo->pTxDescs; if (pTxBuf == NULL) { AE531X_PRINT(AE531X_DEBUG_RESET, ("eth%d Failed to allocate TX queue\n", MACInfo->unit)); goto AllocQFail; } if (ae531x_TxQueueCreate(MACInfo, &MACInfo->txQueue, pTxBuf, MACInfo->txDescCount) < 0) { AE531X_PRINT(AE531X_DEBUG_RESET, ("eth%d Failed to create TX queue\n", MACInfo->unit)); goto AllocQFail; } QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->rxDescCount; pRxBuf = MACInfo->pRxDescs; if (pRxBuf == NULL) { AE531X_PRINT(AE531X_DEBUG_RESET, ("eth%d Failed to allocate RX queue\n", MACInfo->unit)); goto AllocQFail; } if (ae531x_RxQueueCreate(MACInfo, &MACInfo->rxQueue, pRxBuf, MACInfo->rxDescCount) < 0) { AE531X_PRINT(AE531X_DEBUG_RESET, ("eth%d Failed to create RX queue\n", MACInfo->unit)); goto AllocQFail; } AE531X_PRINT(AE531X_DEBUG_RESET, ("eth%d Memory setup complete.\n", MACInfo->unit)); LEAVE(); return 0; AllocQFail: MACInfo->txDescCount = 0; /* sanity */ MACInfo->rxDescCount = 0; /* sanity */ if (pTxBuf) { FREE(pTxBuf); } if (pRxBuf) { FREE(pRxBuf); } LEAVE(); return -1; }
/* MAIN PROGRAM */ int main(int argc, char** argv) { int next_event; char keytoclose = 'p'; if(!startup_check(0)) return -1; /* Initialize csiglib and simulation */ while (initialize(argc, (const char * *)argv)) {; /* Schedule beginning of simulation */ event_time = current_time; event_type = RUN_event; schedule_event(); /* Schedule end of simulation */ event_time = stop_time; event_type = run_end_event; event_priority = 9999; schedule_event(); /* EVENT EXECUTION CONTROL LOOP */ while (!run_error && !done) { /* Pull next event from event list */ next_event = c_timing(); /* increment the event count for this event */ event_count[next_event]++; /* Call appropriate event routine */ switch ( next_event ) { case run_end_event: run_end(); break; case RUN_event: RUN(); event_trace("RUN",event_count[next_event]); break; case ARRIVE_event: ARRIVE(); event_trace("ARRIVE",event_count[next_event]); break; case STFCFC_event: STFCFC(); event_trace("STFCFC",event_count[next_event]); break; case FINFCFC_event: FINFCFC(); event_trace("FINFCFC",event_count[next_event]); break; case STFCE_event: STFCE(); event_trace("STFCE",event_count[next_event]); break; case FINFCE_event: FINFCE(); event_trace("FINFCE",event_count[next_event]); break; case STEE_event: STEE(); event_trace("STEE",event_count[next_event]); break; case FINEE_event: FINEE(); event_trace("FINEE",event_count[next_event]); break; case SETSRVR_event: SETSRVR(); event_trace("SETSRVR",event_count[next_event]); break; case ADDECON_event: ADDECON(); event_trace("ADDECON",event_count[next_event]); break; case ADDFC_event: ADDFC(); event_trace("ADDFC",event_count[next_event]); break; case ASSIGN_event: ASSIGN(); event_trace("ASSIGN",event_count[next_event]); break; } } } // experiments terminated printf("Experiments ended! If runs end early: \n\r1. check fields in *.exp file. \n\r2. check if output file was already open. \n\r"); return 0; }