?? cs8900aend.c
字號:
cs_chip_event_enable(pDrvCtrl); /* receive style. */ cs_pp_w(pDrvCtrl, CS_PKTPG_RX_CTL, CS_RX_CTL_RX_OK_A | CS_RX_CTL_ALL_FRAME_A | CS_RX_CTL_BCAST_A | CS_RX_CTL_IND_A); /* select 10baseT, and turn on rx/tx. */ cs_pp_w(pDrvCtrl, CS_PKTPG_LINE_CTL, CS_LINE_CTL_10BASET | CS_LINE_CTL_TX_ON | CS_LINE_CTL_RX_ON); /* full duplex mode. */ cs_pp_w(pDrvCtrl, CS_PKTPG_TEST_CTL, CS_TEST_CTL_FDX | CS_TEST_CTL_DIS_LT); /* led. */ cs_pp_w(pDrvCtrl, CS_PKTPG_SELF_CTL, 0); return;}/* * cs8900aAddrFilterSet - set the address filter for multicast addresses * * This routine goes through all of the multicast addresses on the list * of addresses (added with the endAddrAdd() routine) and sets the * device's filter correctly. * * RETURNS: N/A. */LOCAL void cs8900aAddrFilterSet ( END_DEVICE* pDrvCtrl /* device to be updated */ ){ ETHER_MULTI* pCurr; pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end); while(pCurr != NULL) { /* TODO - set up the multicast list */ pCurr = END_MULTI_LST_NEXT(pCurr); } /* TODO - update the device filter list */ /* Address Filter Register. */ cs_pp_w(pDrvCtrl, CS_PKTPG_IND_ADDR, pDrvCtrl->enetAddr[0]); cs_pp_w(pDrvCtrl, CS_PKTPG_IND_ADDR+2, pDrvCtrl->enetAddr[1]); cs_pp_w(pDrvCtrl, CS_PKTPG_IND_ADDR+4, pDrvCtrl->enetAddr[2]);}/* * cs8900aPollRcv - routine to receive a packet in polled mode. * * Polled mode operation takes place without any kernel or other OS * services available. Use extreme care to insure that this code does not * call any kernel services. Polled mode is only for WDB system mode use. * Kernel services, semaphores, tasks, etc, are not available during WDB * system mode. * * The WDB agent polls the device constantly looking for new data. Typically * the device has a ring of RFDs to receive incoming packets. This routine * examines the ring for any new data and copies it to the provided mblk. * The concern here is to keep the device supplied with empty buffers at all * time. * * RETURNS: OK upon success. EAGAIN is returned when no packet is available. * A return of ERROR indicates a hardware fault or no support for polled mode * at all. */LOCAL STATUS cs8900aPollRcv ( END_DEVICE* pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk /* ptr to buffer */ ){ USHORT stat = 0; int len = 0; int i = 0; /* Upper layer must provide a valid buffer. */ if((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT))) { return EAGAIN; } /* TODO - Invalidate any inbound RFD DMA buffers */ /* TODO - clear any status bits that may be set. */ stat = cs_pp_r(pDrvCtrl, CS_PKTPG_ISQ); if(!(stat & CS_RX_EVENT_RX_OK)) return EAGAIN; /* TODO - Check packet and device for errors */ /* Get packet and length from device buffer/descriptor */ stat = cs_pp_r(pDrvCtrl, CS_PKTPG_RX_STATUS); if(stat & CS_RX_EVENT_RX_OK) { len = cs_pp_r(pDrvCtrl, CS_PKTPG_RX_LENGTH); /* TODO - Process device packet into net buffer */ /* bcopy(pPacket, pMblk->m_data, len); */ for(i = 0; i < (len / 2); i++) { ((USHORT *)(pMblk->m_data + 2))[i] = cs_pp_r(pDrvCtrl, CS_PKTPG_RX_FRAME + (i * 2)); } pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */ pMblk->mBlkHdr.mLen = len + 2; /* set the data len */ pMblk->mBlkPktHdr.len = len + 2; /* set the total len */ } /* * TODO - Done with this packet, clean up device. If needed * setup a new RFD/buffer for incoming packets */ return OK;}/* * cs8900aPollSend - routine to send a packet in polled mode. * * Polled mode operation takes place without any kernel or other OS * services available. Use extreme care to insure that this code does not * call any kernel services. Polled mode is only for WDB system mode use. * Kernel services, semaphores, tasks, etc, are not available during WDB * system mode. * * A typical implementation is to set aside a fixed buffer for polled send * operation. Copy the mblk data to the buffer and pass the fixed buffer * to the device. Performance is not a consideration for polled operations. * * An alternate implementation is a synchronous one. The routine accepts * user data but does not return until the data has actually been sent. If an * error occurs, the routine returns EAGAIN and the user will retry the request. * * If the device returns OK, then the data has been sent and the user may free * the associated mblk. The driver never frees the mblk in polled mode. * The calling routine will free the mblk upon success. * * RETURNS: OK upon success. EAGAIN if device is busy or no resources. * A return of ERROR indicates a hardware fault or no support for polled mode * at all. */LOCAL STATUS cs8900aPollSend ( END_DEVICE* pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk /* packet to send */ ){ static UCHAR p_src_buf[CS_CHIP_FRAME_BUF_SIZE]; int length = 0; STATUS tx_status = ERROR; /* reset? */ if(pDrvCtrl->resetting) { return EAGAIN; } /* Get data from Mblk to tx buffer. */ length = netMblkToBufCopy(pMblk, p_src_buf, NULL); /* transmit it. */ tx_status = cs_chip_send_frame(pDrvCtrl, (USHORT *)p_src_buf, length); END_ERR_ADD(&pDrvCtrl->end, MIB2_OUT_UCAST, +1); if(tx_status == ERROR) { return EAGAIN; } netMblkClChainFree(pMblk); return OK;}/* * cs8900aMCastAdd - add a multicast address for the device * * This routine adds a multicast address to whatever the driver * is already listening for. It then resets the address filter. * * RETURNS: OK or ERROR. */LOCAL STATUS cs8900aMCastAdd ( END_DEVICE* pDrvCtrl, /* device pointer */ char* pAddress /* new address to add */ ){ int error; if((error = etherMultiAdd(&pDrvCtrl->end.multiList, pAddress)) == ENETRESET) { cs8900aConfig(pDrvCtrl); } return OK;}/* * cs8900aMCastDel - delete a multicast address for the device * * This routine removes a multicast address from whatever the driver * is listening for. It then resets the address filter. * * RETURNS: OK or ERROR. */LOCAL STATUS cs8900aMCastDel ( END_DEVICE* pDrvCtrl, /* device pointer */ char* pAddress /* address to be deleted */ ){ int error; if((error = etherMultiDel(&pDrvCtrl->end.multiList, (char*)pAddress)) == ENETRESET) { cs8900aConfig(pDrvCtrl); } return OK;}/* * cs8900aMCastGet - get the multicast address list for the device * * This routine gets the multicast list of whatever the driver * is already listening for. * * RETURNS: OK or ERROR. */LOCAL STATUS cs8900aMCastGet ( END_DEVICE* pDrvCtrl, /* device pointer */ MULTI_TABLE* pTable /* address table to be filled in */ ){ return(etherMultiGet(&pDrvCtrl->end.multiList, pTable));}/* * cs8900aStop - stop the device * * This function calls BSP functions to disconnect interrupts and stop * the device from operating in interrupt mode. * * RETURNS: OK or ERROR. */LOCAL STATUS cs8900aStop ( END_DEVICE* pDrvCtrl /* device to be stopped */ ){ END_FLAGS_CLR(&pDrvCtrl->end, IFF_UP | IFF_RUNNING); /* TODO - stop/disable the device. */ if(intDisable(pDrvCtrl->ilevel) == ERROR) { DRV_LOG(DRV_DEBUG_LOAD, "Could not disconnect interrupt!\n", 1, 2, 3, 4, 5, 6); return ERROR; } /* disable the interrupt input pin of cs. */ cs8900a_pin_disable(); cs_chip_int_disable(pDrvCtrl); return OK;}/* * cs8900aUnload - unload a driver from the system * * This function first brings down the device, and then frees any * stuff that was allocated by the driver in the load function. * * RETURNS: OK or ERROR. */LOCAL STATUS cs8900aUnload ( END_DEVICE* pDrvCtrl /* device to be unloaded */ ){ if(pDrvCtrl == NULL) return ERROR; END_OBJECT_UNLOAD(&pDrvCtrl->end); /* stop it. */ cs8900aStop(pDrvCtrl); /* reset it. */ cs8900aReset(pDrvCtrl); /* TODO - Free any special allocated memory */ if(pDrvCtrl->end.pNetPool) { netPoolDelete(pDrvCtrl->end.pNetPool); free(pDrvCtrl->end.pNetPool); pDrvCtrl->end.pNetPool = (NET_POOL_ID)0; } if(cs8900aClDescTbl[0].memArea) { free(cs8900aClDescTbl[0].memArea); cs8900aClDescTbl[0].memArea = (char *)0; } if(cs8900aMclBlkConfig.memArea) { free(cs8900aMclBlkConfig.memArea); cs8900aMclBlkConfig.memArea = (char *)0; } /* New: free the END_OBJ structure allocated during cs8900aLoad() */ cfree((char *)pDrvCtrl); pDrvCtrl = NULL; return OK;}/* * cs8900aPollStart - start polled mode operations * * RETURNS: OK or ERROR. */LOCAL STATUS cs8900aPollStart ( END_DEVICE* pDrvCtrl /* device to be polled */ ){ int oldLevel; oldLevel = intLock(); /* disable ints during update */ /* TODO - turn off interrupts */ pDrvCtrl->flags |= cs8900a_POLLING; intUnlock(oldLevel); /* now cs8900aInt won't get confused */ DRV_LOG(DRV_DEBUG_POLL, "STARTED\n", 1, 2, 3, 4, 5, 6); cs8900aConfig(pDrvCtrl); /* reconfigure device */ cs_chip_int_disable(pDrvCtrl); return OK;}/* * cs8900aPollStop - stop polled mode operations * * This function terminates polled mode operation. The device returns to * interrupt mode. * * The device interrupts are enabled, the current mode flag is switched * to indicate interrupt mode and the device is then reconfigured for * interrupt operation. * * RETURNS: OK or ERROR. */LOCAL STATUS cs8900aPollStop ( END_DEVICE* pDrvCtrl /* device to be polled */ ){ int oldLevel; oldLevel = intLock(); /* disable ints during register updates */ /* TODO - re-enable interrupts */ pDrvCtrl->flags &= ~cs8900a_POLLING; intUnlock(oldLevel); cs8900aConfig(pDrvCtrl); DRV_LOG(DRV_DEBUG_POLL, "STOPPED\n", 1, 2, 3, 4, 5, 6); return OK;}/* * cs8900aReset - reset device * * RETURNS: N/A. */LOCAL void cs8900aReset ( END_DEVICE* pDrvCtrl ){ int intState; if(pDrvCtrl->unit != 0) return; pDrvCtrl->resetting = TRUE; /* chip reset. */ intState = intLock(); cs_chip_self_reset(pDrvCtrl); intUnlock(intState); /* TODO - reset all device counters/pointers, etc. */ cs_soft_end_init(pDrvCtrl); pDrvCtrl->resetting = FALSE; return;}/* Addition. *//* * cs8900a_pin_enable - Enable the pin for the interrupt of cs8900a. * * RETURNS: status(int). */#if 0int cs8900a_pin_enable(void){ mask32_change_bsp( (int*)0x56000050, /* GPFCON of s3c2410x */ (int)0, /* start bit0 */ (int)2, /* change length 2, bit0..1 */ (int)0 /* Value is 2 for EINT0. */ ); mask32_change_bsp( (int*)0x56000088, /* EXTINT0 of s3c2410x */ (int)0, /* start bit0 */ (int)3, /* change length 3, bit0..2 */ (int)4 /* Value is 4, that rise edge triggered for EINT0. *//* (int)1 Value is 1, that high level triggered for EINT0. */ ); mask32_change_bsp( (int*)0x56000058, /* GPFUP of s3c2410x */ (int)0, /* start bit0 */ (int)1, /* change length 1, bit0 */ (int)1 /* Value is 1 for disable EINT0's pull-up. */ ); mask32_change_bsp( (int*)0x56000050, /* GPFCON of s3c2410x */ (int)0, /* start bit0 */ (int)2, /* change length 2, bit0..1 */ (int)2 /* Value is 2 for EINT0. */ ); return 0;}#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -