📄 lan9118.c
字号:
if (intDisable(pDrvCtrl->ilevel) == ERROR) { return ERROR; } /* disable the interrupt input pin of cs. */ lan9118_pin_disable(); /* delete semaphore for interrupt. */ semDelete(semid_lan9118_tx_mux); semDelete(pDrvCtrl->semid_rx); return OK;}/* * lan9118Unload - 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. */STATUS lan9118Unload ( END_DEVICE* pDrvCtrl /* device to be unloaded */ ){ if(pDrvCtrl == NULL) return ERROR; END_OBJECT_UNLOAD(&pDrvCtrl->end); /* stop it. */ lan9118Stop(pDrvCtrl); /* reset it. */ lan9118Reset(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(lan9118ClDescTbl[0].memArea) { free(lan9118ClDescTbl[0].memArea); lan9118ClDescTbl[0].memArea = (char *)0; } if(lan9118MclBlkConfig.memArea) { free(lan9118MclBlkConfig.memArea); lan9118MclBlkConfig.memArea = (char *)0; } /* New: free the END_OBJ structure allocated during lan9118Load() */ cfree((char *)pDrvCtrl); pDrvCtrl = NULL; return OK;}/* * lan9118PollStart - start polled mode operations * * RETURNS: OK or ERROR. */STATUS lan9118PollStart ( END_DEVICE* pDrvCtrl /* device to be polled */ ){ int oldLevel; return OK;}/* * lan9118PollStop - 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. */STATUS lan9118PollStop ( END_DEVICE* pDrvCtrl /* device to be polled */ ){ int oldLevel;#if 0 oldLevel = intLock(); /* disable ints during register updates */ /* TODO - re-enable interrupts */ pDrvCtrl->flags &= ~lan9118_POLLING; intUnlock(oldLevel); lan9118Config(pDrvCtrl); DRV_LOG(DRV_DEBUG_POLL, "STOPPED\n", 1, 2, 3, 4, 5, 6);#endif return OK;}/*********************************************************************************************************//* * lan9118Reset - reset device * * RETURNS: N/A. */void lan9118Reset ( END_DEVICE* pDrvCtrl ){ int intState; if(pDrvCtrl->unit != 0) return; pDrvCtrl->resetting = TRUE; /* chip reset. */ intState = intLock(); lan9118_soft_reset(); intUnlock(intState); pDrvCtrl->resetting = FALSE; return;}/* * lan9118Config - reconfigure the interface under us. * * Reconfigure the interface setting promiscuous mode, and changing the * multicast interface list. * * RETURNS: N/A. */void lan9118Config ( END_DEVICE * pDrvCtrl /* device to be re-configured */ ){ /* Set promiscuous mode if it's asked for. */ /* start lan9118 */ lan9118_open(pDrvCtrl); return;}/* * lan9118MemInit - initialize memory for the chip * * This routine is highly specific to the device. * * Design choices available: * * Use default system buffers, or create device specific buffer pools. * * Use contiguous buffers for device frame descriptors and the data, or * use descriptor buffers separate from the data buffers. * * Use the same buffering scheme for Rx and Tx, or each side uses it's * own buffering scheme. * * RETURNS: OK or ERROR. */STATUS lan9118MemInit ( END_DEVICE * pDrvCtrl /* device to be initialized */ ){ /* Set up an END netPool using netBufLib(1). */ lan9118ClDescTbl[0].clNum = 1024*4; lan9118ClDescTbl[0].clSize = END_BUFSIZ; lan9118MclBlkConfig.clBlkNum = lan9118ClDescTbl[0].clNum; lan9118MclBlkConfig.mBlkNum = (lan9118MclBlkConfig.clBlkNum) * 2; /* Calculate the total memory for all the M-Blks and CL-Blks. */ lan9118MclBlkConfig.memSize = ((lan9118MclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) + (lan9118MclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long)))); /* allocate mbuf/Cluster blocks from normal memory */ lan9118MclBlkConfig.memArea = (char *)memalign(sizeof(long),lan9118MclBlkConfig.memSize); if(lan9118MclBlkConfig.memArea == NULL) { return ERROR; } /* Calculate the memory size of all the clusters. */ lan9118ClDescTbl[0].memSize = (lan9118ClDescTbl[0].clNum * (lan9118ClDescTbl[0].clSize + 8))+ sizeof (int); /* Allocate the memory for the clusters from cache safe memory. */ lan9118ClDescTbl[0].memArea = (char*)cacheDmaMalloc(lan9118ClDescTbl[0].memSize); if(lan9118ClDescTbl[0].memArea == NULL) { return ERROR; } /* TODO - allocate and initialize any shared memory areas */ if((pDrvCtrl->end.pNetPool = malloc(sizeof(NET_POOL))) == NULL) { return ERROR; } /* Initialize the memory pool. */ if(netPoolInit(pDrvCtrl->end.pNetPool, &lan9118MclBlkConfig, &lan9118ClDescTbl[0], lan9118ClDescTblNumEnt, NULL) == ERROR) { return ERROR; } return OK;}int get_rx_frame = 0;void lan9118RecvInt ( END_DEVICE * pDrvCtrl, int count ){ int i, j, len; char * pNewCluster; char * p_src; for (i = 0; i < count; i++) { pNewCluster = end_rx_frame_get(&len); if (len <= 0) { netClFree(pDrvCtrl->end.pNetPool, pNewCluster); } else { get_rx_frame += 1; for (j = (len-1); j >=0; j--) { pNewCluster[j+2] = pNewCluster[j]; } pNewCluster[0] = 0; pNewCluster[1] = 0; lan9118Recv(pDrvCtrl, pNewCluster, len); } } return;}/* * lan9118Recv - process the next incoming packet * * Handle one incoming packet. The packet is checked for errors. * * RETURNS: N/A. */int get_recv = 0;void lan9118Recv ( END_DEVICE * pDrvCtrl, /* device structure */ char* pNewCluster, int len ){ M_BLK_ID pMblk; CL_BLK_ID pClBlk; /* Packet must be checked for errors. */ END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_UCAST, +1); /* * We implicitly are loaning here, if copying is necessary this * step may be skipped, but the data must be copied before being * passed up to the protocols. */ /* Grab a cluster block to marry to the cluster we received. */ if((pClBlk = netClBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL) { netClFree(pDrvCtrl->end.pNetPool, (UCHAR *)pNewCluster); END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } if((pMblk = mBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) { netClBlkFree(pDrvCtrl->end.pNetPool, pClBlk); netClFree(pDrvCtrl->end.pNetPool, (UCHAR *)pNewCluster); END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } /* Join the cluster to the MBlock */ len += 2; netClBlkJoin(pClBlk, pNewCluster, len, NULL, 0, 0, 0); netMblkClJoin(pMblk, pClBlk); /* Invalidate any RFD dma buffers */ pMblk->mBlkHdr.mLen = len; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkPktHdr.len = len; pMblk->mBlkHdr.mData += 2; /* Done with processing, clean up and pass it up. */ /* Call the upper layer's receive routine. */ get_recv += 1; END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);cleanRXD: return;}/* * lan9118Int - handle controller interrupt * * This routine is called at interrupt level in response to an interrupt from * the controller. * * RETURNS: N/A. */void lan9118Int(END_DEVICE * pDrvCtrl){ int temp_int; temp_int = intLock(); lan9118_interrupt(pDrvCtrl); intUnlock(temp_int); return ;}/* lan9118_reg_read - read the data from the lan9118 register. * RETURNS: unsigned 32bits. */U32 lan9118_reg_read(U32 offset){ return (*((volatile U32 *)(LAN9118CS_BASE+offset)));}/* lan9118_reg_write - write the data to the lan9118 register. * RETURNS: void. */void lan9118_reg_write(U32 offset, U32 src){ (*((volatile U32 *)(LAN9118CS_BASE+offset))) = src; return;}/* * lan9118_pin_enable - Enable the pin for the interrupt of lan9118. * * RETURNS: status(int). */int lan9118_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)2 /* Value is 2, that falling edge triggered for EINT0. *//* (int)4 Value is 4, that rising 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;}/* * lan9118_pin_disable - Disable the pin for the interrupt of lan9118. * * RETURNS: status(int). */int lan9118_pin_disable(void){ mask32_change_bsp( (int*)0x56000050, /* GPFCON of s3c2410x */ (int)0, /* start bit0 */ (int)2, /* change length 2, bit0..1 */ (int)0 /* Value is 0 for input. */ ); mask32_change_bsp( (int*)0x56000088, /* EXTINT0 of s3c2410x */ (int)0, /* start bit0 */ (int)3, /* change length 3, bit0..2 */ (int)0 /* Value is 4, that low level triggered for EINT0. */ ); return 0;}/* add by phoenix */STATUS mask32_change_bsp(int* dist32, int num, int len, int src){ UINT32 tempUINT32; tempUINT32 = *dist32; if(len <= 0) return ERROR; if((num+len) > 32) return ERROR; tempUINT32 = ((tempUINT32&(~(((1<<len)-1)<<num)))|((src&((1<<len)-1))<<num)); *dist32 = tempUINT32; return OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -