⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dm9000end.c

📁 操作系统中的一找你个的相关的淡淡的码源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    pDrvCtrl->unit = atoi (tok);
#ifdef DM_DEBUG_PRINT
    logMsg("dm9000Parse: unit = %x\n ",pDrvCtrl->unit, 0, 0, 0, 0, 0);
#endif
	
    /* IO Base */
    tok = strtok_r (NULL, ":", &pHolder);
    if (tok == NULL) return ERROR;
    
    address = strtoul (tok, NULL, 16);
    pDrvCtrl->IOBase = (UINT)address;
#ifdef DM_DEBUG_PRINT
    logMsg("dm9000Parse: IOBase = %x\n ",pDrvCtrl->IOBase, 0, 0, 0, 0, 0);
#endif

    /* Interrupt level. */
    tok = strtok_r (NULL, ":", &pHolder);
    if (tok == NULL) return ERROR;
    
    pDrvCtrl->ilevel = (UINT)strtoul (tok,NULL,16);
#ifdef DM_DEBUG_PRINT
    logMsg("dm9000Parse: ilevel = %d\n ",pDrvCtrl->ilevel, 0, 0, 0, 0, 0);
#endif
 
   /*Interrupt vector*/
   pDrvCtrl->ivec = INT_VEC_EINT_0;
#ifdef DM_DEBUG_PRINT
    logMsg("dm9000Parse: ivec = %d\n ",pDrvCtrl->ivec, 0, 0, 0, 0, 0);
#endif   
    return OK;

}

/*******************************************************************************
*
* dm9000MemInit - initialize memory for the chip
*
* This routine is highly specific to the device.
*
* RETURNS: OK or ERROR.
*/

static STATUS dm9000MemInit( END_DEVICE *pDrvCtrl )    /* device to be initialized */
{
    
    if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)
        return (ERROR);

    /* Calculate the total memory for all the M-Blks and CL-Blks. */
    dm9000MclBlkConfig.memSize = (dm9000MclBlkConfig.mBlkNum *
                                 (M_BLK_SZ + sizeof (long))) +
                                 (dm9000MclBlkConfig.clBlkNum *
                                 (CL_BLK_SZ + sizeof(long)));

    if ((dm9000MclBlkConfig.memArea = (char *) memalign (sizeof(long),
                                 dm9000MclBlkConfig.memSize)) == NULL)
        return (ERROR);

    /* Calculate the memory size of all the clusters. */

    dm9000ClDescTbl[0].memSize = (dm9000ClDescTbl[0].clNum * (2048 + 8)) + sizeof(int);

    /* Allocate the memory for the clusters from cache safe memory. */

    dm9000ClDescTbl[0].memArea = (char *) cacheDmaMalloc (dm9000ClDescTbl[0].memSize) ;
    if (dm9000ClDescTbl[0].memArea == NULL)
    {
#ifdef DM_DEBUG_PRINT
        logMsg("dm9000MemInit: system memory unavailable!\n",
                0, 0, 0, 0, 0, 0);
#endif
        return (ERROR);
    }

    /* Initialize the memory pool. */
    if (netPoolInit(pDrvCtrl->end.pNetPool, &dm9000MclBlkConfig,
                    &dm9000ClDescTbl[0], dm9000ClDescTblNumEnt,NULL) == ERROR)
        {
#ifdef DM_DEBUG_PRINT
        logMsg("dm9000MemInit: Could not init buffering!\n",
                0, 0, 0, 0, 0, 0);
#endif
        return (ERROR);
        }

    /*
     * If you need clusters to store received packets into then get them
     * here ahead of time.
     */

    if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool,2048, (BOOL)FALSE))== NULL)
      {
#ifdef DM_DEBUG_PRINT
      	logMsg("dm9000MemInit: Could not memory cluster ID!\n",
      	        0,0,0,0,0,0);
#endif
        return (ERROR);
      }
#ifdef DM_DEBUG_PRINT
   logMsg("dm9000MemInit: Memory setup complete!\n",
       0, 0, 0, 0, 0, 0);
#endif

    return OK;
}

/*******************************************************************************
*
* dm9000Start - start the device
*
* This function calls BSP functions to connect interrupts and start the
* device running in interrupt mode.
*
* RETURNS: OK or ERROR
*
*/

static STATUS dm9000Start( END_DEVICE *pV )  /* device ID */
{ 
     END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV;
   
     s3cExtIntPinEnable ();  

    /*Setup the interrupt handler and IDT table entry*/
    if(intConnect(INUM_TO_IVEC(pDrvCtrl->ivec), dm9000Int, (int)pDrvCtrl) == ERROR)
	  { 
#ifdef DM_DEBUG_PRINT
		logMsg("dm9000Start:Can not connect interrupt!\n",
		    0, 0, 0, 0, 0, 0);
#endif
		return ERROR;
	  }
	
  /*Enable DM9000 interrupt at the systerm lecel*/
  if(intEnable(pDrvCtrl->ilevel)==ERROR)
		{
#ifdef DM_DEBUG_PRINT
			logMsg("dm9000Start: Can not enable interrupt!\n ",
			        0, 0, 0, 0, 0, 0);
#endif
		  return ERROR;
		}
		 

    /*Mark the interface as up and running*/
	  END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));
	
    /* Activate DM9000 */
    DM9000_OUT_REG( 0x05, DM9000_REG05 );          /* RX enable */
    DM9000_OUT_REG( 0xff, DM9000_REGFF );          /* Enable TX/RX interrupt mask */

    return (OK);
}

/*******************************************************************************
*
* dm9000Int - handle controller interrupt
*
* This routine is called at interrupt level in response to an interrupt from
* the controller.
*
* RETURNS: N/A.
*/

static void dm9000Int( END_DEVICE  *pDrvCtrl  )  /* interrupting device */
{ 
    UCHAR stat, reg_save,isr_status,TX_comple_status,tx_status; 

    /*clear s3c2410 external intpand reg */ 
    intDisable (pDrvCtrl->ilevel); 
    rpINTMSK |= 1;
    rpINTPND |= 1;
    rpSRCPND |= 1;
    /*save previous register address */
    DM9000_IN_ADDR( reg_save );
    DM9000_OUT_REG( 0xff, DM9000_REGFF_OFF );

    /* Read and Clear ISR status */
    DM9000_IN_REG( 0xfe, isr_status );
    DM9000_OUT_REG( 0xfe, isr_status );
	
#ifdef DM_DEBUG_PRINT
     logMsg("dm9000Int: got interrupt!\n", 0, 0, 0, 0, 0, 0);
#endif

    /*
     * enable interrupts, clear receive and/or transmit interrupts, and clear
     * any errors that may be set.
     */
    if( isr_status & 0x02 )
    {

         /*Clear Tx Packet Complete Status*/
         DM9000_IN_REG(0x01, TX_comple_status);
       
         if (TX_comple_status & 0xc)
         { 
             if (TX_comple_status & 0x4) pDrvCtrl->tx_pkt_cnt--;
        	   if (TX_comple_status & 0x8) pDrvCtrl->tx_pkt_cnt--;
         }
         else
         {
             DM9000_IN_REG( 0x02, tx_status );
			       while(tx_status & 0x1){DM9000_IN_REG( 0x02, tx_status );}
         }
        		
        /*if not complete tranmission*/	
		    if(pDrvCtrl->tx_pkt_cnt>0)
		    {	    
		      /* Set TX length to DM9000 */
          DM9000_OUT_REG( 0xfc, pDrvCtrl->queue_pkt_len & 0xff );
          DM9000_OUT_REG( 0xfd, (pDrvCtrl->queue_pkt_len >> 8) & 0xff );

          /* Issue TX polling command */
          DM9000_OUT_REG( 0x2, 0x01 );        /* Cleared after TX complete */
			}
    }

    /* Have netTask handle any input packets */
    if (isr_status & 0x01 )
    {

	
        if ( pDrvCtrl->rxHandling != TRUE )
        {
            pDrvCtrl->rxHandling = TRUE;
          
            netJobAdd ((FUNCPTR)dm9000Recv, (int)pDrvCtrl, 0, 0, 0, 0);
        }
    }

    /* Re-enable interrupt mask */
    DM9000_OUT_REG( 0xff, DM9000_REGFF );
    DM9000_OUT_REG( 0x05, 0x11 );
    
    /* Restore previous register address */
    DM9000_OUT_ADDR( reg_save );

    rpINTMSK &= ~1;
    intEnable (pDrvCtrl->ilevel);
}

/*******************************************************************************
*
* dm9000Recv - process the next incoming packet
*
* Handle one incoming packet.  The packet is checked for errors.
*
* RETURNS: N/A.
*/

static STATUS dm9000Recv( END_DEVICE *pDrvCtrl )   
{
    char*       pNewCluster = NULL;
    M_BLK_ID    pMblk;
    CL_BLK_ID   pClBlk;
    int DataLen; 
    UCHAR  status;
    
 while((status=dmfe_Get_NextPacket()) != 0)
 {
    /*
     * 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.
     */
     /* Get a receive frame buffer */  
   pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);
   
   /* Grab a cluster block to marry to the cluster we received. */
   pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT);
   
   /* OK we've got a spare, let's get an M_BLK_ID and marry it to the one in the ring.*/
   pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA);
   
   if(pNewCluster == NULL || pClBlk == NULL || pMblk == NULL)
   {
   	 if(pNewCluster){
   	 	netClFree(pDrvCtrl->end.pNetPool,pNewCluster);
   	  }
   	 if(pClBlk){
   	 	netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);
   	 	}
   	 if(pMblk){
   	 	netMblkFree(pDrvCtrl->end.pNetPool,pMblk);
   	 	}
   	 /* Increment the input error count */
   	 END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
   	
     return;
   }
   	
    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);

    DataLen = dmfe_Copy_RxFrame(pDrvCtrl, pNewCluster+2, status);
    
    /* Join the cluster to the MBlock */
    netClBlkJoin (pClBlk, pNewCluster, DataLen, NULL, 0, 0, 0);
    netMblkClJoin (pMblk, pClBlk);

    /*pMblk->mBlkHdr.mData += pDrvCtrl->offset;*/
    pMblk->mBlkHdr.mData += 2;
    pMblk->mBlkHdr.mLen = DataLen;
    pMblk->mBlkHdr.mFlags |= M_PKTHDR;
    pMblk->mBlkPktHdr.len = DataLen;


    /* Call the upper layer's receive routine. */
    END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);
    
    pNewCluster = NULL;
  if(pNewCluster) netClFree(pDrvCtrl->end.pNetPool,pNewCluster);
}  
    pDrvCtrl->rxHandling = FALSE;
    
    return (OK); 
       
cleanRXD:
    pDrvCtrl->rxHandling = FALSE;
    return (ERROR);
}

/*******************************************************************************
*
* dm9000Send - the driver send routine
*
* This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.
* The buffer must already have the addressing information properly installed
* in it.  This is done by a higher layer.  The last arguments are a free
* routine to be called when the device is done with the buffer and a pointer
* to the argument to pass to the free routine.
*
* RETURNS: OK, ERROR, or END_ERR_BLOCK.
*/

static STATUS dm9000Send( END_DEVICE *pV,  /* device ptr */
                          M_BLK_ID    pMblk )    /* data to send */
{
	  static UCHAR txBuf[DM9000_FRAME_BUFSIZE];
    int         oldLevel = 0;
    int         length = 0;
    int        TxStatus = 0;
  
  END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV;
      
    /*
     * Obtain exclusive access to transmitter.  This is necessary because
     * we might have more than one stack transmitting at once.
     */

    if (!(pDrvCtrl->flags & DM9000_POLLING))
    {
        END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);
    }

    /* Get data from Mblk to tx buffer. */
    length = netMblkToBufCopy (pMblk, (char *)txBuf, NULL);
    
	
    if (!(pDrvCtrl->flags & DM9000_POLLING))
  	{ 
	   oldLevel = intLock ();  /* protect dm9000Int */
	  }
	  
	  /*transmit packet*/
	  TxStatus=dmfe_Copy_TxFrame(pDrvCtrl, txBuf, length);
	  
    /* unlock interrupt*/
    if (!((pDrvCtrl->flags) & DM9000_POLLING))
        intUnlock (oldLevel);

    /* Advance our management index */
   if (!((pDrvCtrl->flags) & DM9000_POLLING))
        END_TX_SEM_GIVE (&pDrvCtrl->end);

   /*transmit packet error handle*/
   if(TxStatus == ERROR)
	 {
	 	logMsg("dm9000Send: Transmit packet is failed!\n", 0, 0, 0, 0, 0, 0);
		netMblkClChainFree (pMblk);
		END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_ERRS, +1);
		return(END_ERR_BLOCK);
	 }

    /* Bump the statistics counters. */
    END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);

    /*
     * Cleanup.  The driver must either free the packet now or
     * set up a structure so it can be freed later after a transmit
     * interrupt occurs.
     */
     netMblkClChainFree (pMblk);
     return (OK);
        
}

/*******************************************************************************
*
* dm9000Ioctl - the driver I/O control routine
*
* Process an ioctl request.
*
* RETURNS: A command specific response, usually OK or ERROR.
*/

static int dm9000Ioctl( END_DEVICE *pV,          /* device receiving command */
                        int cmd,              /* ioctl command code */
                        caddr_t data )        /* command argument */
{
    int status = 0;
    long value;

 END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV;

    switch (cmd)
    {
        case EIOCSADDR:
            if (data == NULL)
                return (EINVAL);
            bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end),
                END_HADDR_LEN(&pDrvCtrl->end));
            break;
			
        case EIOCGADDR:
            if (data == NULL)
                return (EINVAL);
            bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data,
                END_HADDR_LEN(&pDrvCtrl->end));
            break;
			
        case EIOCSFLAGS:
            value = (long)data;
            if (value < 0)
            {
                value = -(--value);
                END_FLAGS_CLR (&pDrvCtrl->end, value);
            }
            else
            {
                END_FLAGS_SET (&pDrvCtrl->end, value);
            }
            dm9000Config (pDrvCtrl);
            break;
        case EIOCGFLAGS:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -