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

📄 dm9000end.c

📁 操作系统中的一找你个的相关的淡淡的码源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            *(int *)data = END_FLAGS_GET(&pDrvCtrl->end);
            break;
        case EIOCMULTIADD:
            status = dm9000MCastAdd ((void*)pDrvCtrl, (char *) data);
            break;
        case EIOCMULTIDEL:
            status = dm9000MCastDel((void*)pDrvCtrl, (char *) data);
            break;
        case EIOCMULTIGET:
            status = dm9000MCastGet ((void*)pDrvCtrl, (MULTI_TABLE *) data);
            break;
        case EIOCPOLLSTART:   /* Begin polled operation */
            dm9000PollStart ((void*)pDrvCtrl);
            break;
        case EIOCPOLLSTOP:  /* End polled operation */
            dm9000PollStop ((void*)pDrvCtrl);
            break;
        case EIOCGMIB2:     /* return MIB information */
            if (data == NULL)
                return (EINVAL);
            bcopy((char *)&pDrvCtrl->end.mib2Tbl,(char *)data,
                sizeof(pDrvCtrl->end.mib2Tbl));
            break;
        case EIOCGFBUF:     /* return minimum First Buffer for chaining */
            if (data == NULL)
                return (EINVAL);
            *(int *)data = DM9000_MIN_FBUF;					
            break;
        case EIOCGHDRLEN:
		        if(data == NULL) return EINVAL;
		        *(int *)data = EH_SIZE;
		        break;
		
        default:
            status = EINVAL;
    }
    return (status);
}


/******************************************************************************
*
* dm9000Config - reconfigure the interface under us.
*
* Reconfigure the interface setting promiscuous mode, and changing the
* multicast interface list.
*
* RETURNS: N/A.
*/

static void dm9000Config( END_DEVICE *pDrvCtrl ) /* device to be re-configured */
{
    /* Set promiscuous mode if it's asked for. */
    if (END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC)
    {
#ifdef DM_DEBUG_PRINT
         logMsg ("dm9000Config() Setting promiscuous mode on!\n", 0, 0, 0, 0, 0, 0);
#endif
    }
    else
    {
#ifdef DM_DEBUG_PRINT
        logMsg ("dm9000Config() Setting promiscuous mode off!\n", 0, 0, 0, 0, 0, 0);
#endif
     
     /* Set up address filter for multicasting. */
        dm9000AddrFilterSet (pDrvCtrl);
    }

   /*initialise the hardware according to flags */
   dmfe_config_dm9000( pDrvCtrl, 2 );
    
   return;
}

/******************************************************************************
*
* dm9000AddrFilterSet - 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.
*/

static void dm9000AddrFilterSet( END_DEVICE *pDrvCtrl )
{
    ETHER_MULTI* pCurr;
    
    unsigned long crc; 
    unsigned long hash_table[4];
    
    /*Get the first Mcast address from Mcast list */
    pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end);

    while (pCurr != NULL)
    {
        pCurr = END_MULTI_LST_NEXT(pCurr);     
    }

}

/*******************************************************************************
*
* dm9000PollRcv - routine to receive a packet in polled mode.
*
* This routine is called by a user to try and get a packet from the
* device.
*
* RETURNS: OK upon success.  EAGAIN is returned when no packet is available.
*/

static STATUS dm9000PollRcv( END_DEVICE *pV,  /* device to be polled */
                             M_BLK_ID   pMblk )     /* ptr to buffer */
{
    u_short stat;
    char* pPacket;
    int len = 64;

     END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV; 
     
#ifdef DM_DEBUG_PRINT
    logMsg("dm9000PollRcv()\n", 0, 0, 0, 0, 0, 0);
#endif

    stat = dm9000StatusRead (pDrvCtrl);
    /* TODO - If no packet is available return immediately */

    if( !(stat&DM9000_RXRDY) )
    {
        logMsg("dm9000PollRcv: no data.\n", 0, 0, 0, 0, 0, 0);
        return (EAGAIN);
    }

    /* Upper layer must provide a valid buffer. */
    if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT)))
    {
        logMsg("dm9000PollRcv: PRX bad mblk.\n", 0, 0, 0, 0, 0, 0);
        return (EAGAIN);
    }


    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);

    /* TODO - Process device packet into net buffer */
    while(dmfe_Get_NextPacket() != 0)
    {
     len = dmfe_Copy_RxFrame( pDrvCtrl, pMblk->mBlkHdr.mData+2, 0 );
    }

    if(len == ERROR)
    {
        logMsg("dm9000PollRcv: packet receive FAIL.\n", 0, 0, 0, 0, 0, 0);
        return (EAGAIN);
    }

    pMblk->mBlkHdr.mData += 2;
    pMblk->mBlkHdr.mFlags |= M_PKTHDR;  /* set the packet header */
    pMblk->mBlkHdr.mLen = len;          /* set the data len */
    pMblk->mBlkPktHdr.len = len;        /* set the total len */


    return (OK);
}

/*******************************************************************************
*
* dm9000PollSend - routine to send a packet in polled mode.
*
* This routine is called by a user to try and send a packet on the
* device.
*
* RETURNS: OK upon success.  EAGAIN if device is busy.
*/

static STATUS dm9000PollSend( END_DEVICE *pV,         /* device to be polled */
                              M_BLK_ID   pMblk )      /* packet to send */
{    
	  static UCHAR txBuf[DM9000_FRAME_BUFSIZE];
    int         len,lastone;
    u_short     stat;

     END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV; 
         
#ifdef DM_DEBUG_PRINT
    logMsg("dm9000PollSend: dm9000PollSend()\n", 0, 0, 0, 0, 0, 0);
#endif

    /* TODO - test to see if tx is busy */
    stat = dm9000StatusRead (pDrvCtrl);             /* dummy code */
    if ((stat & (DM9000_TINT|DM9000_TFULL)) == 0)
        return ((STATUS) EAGAIN);

   /* Get data from Mblk to tx buffer. */
    len = netMblkToBufCopy (pMblk, (char*)txBuf, NULL);
    len = max (len, ETHERSMALL);
    
    /*transmit packet*/
    lastone = intLock();
    dmfe_Copy_TxFrame(pDrvCtrl, txBuf ,len);
    /*check a Completion Flag*/
    intUnlock( lastone );
    /* Bump the statistic counter. */
    END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);

    /* Free the data if it was accepted by device */

    netMblkClFree (pMblk);
#ifdef  DM_DEBUG_PRINT
    logMsg("dm9000PollSend: leaving dm9000PollSend.\n", 0, 0, 0, 0, 0, 0);
#endif
    return (OK);
}

/*****************************************************************************
*
* dm9000MCastAdd - 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.
*/

static STATUS dm9000MCastAdd( END_DEVICE *pV,      /* device pointer */
                              char *pAddress )           /* new address to add */
{
     END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV;  

    if ((etherMultiAdd (&pDrvCtrl->end.multiList,pAddress)) == ENETRESET)
    {
      dm9000Config(pDrvCtrl);
    }
 
    return (OK);
}

/*****************************************************************************
*
* dm9000MCastDel - 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.
*/

static STATUS dm9000MCastDel( END_DEVICE *pV,  /* device pointer */
                              char *pAddress )       /* address to be deleted */
{
    
     END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV;
     
    if ((etherMultiDel (&pDrvCtrl->end.multiList, (char *)pAddress)) == ENETRESET)
    {
     dm9000Config(pDrvCtrl);
    }

    return (OK);
}

/*****************************************************************************
*
* dm9000MCastGet - 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.
*/

static STATUS dm9000MCastGet( END_DEVICE *pV,  /* device pointer */
                              MULTI_TABLE *pTable )  /* address table to be filled in */
{
     END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV;
     
    return (etherMultiGet (&pDrvCtrl->end.multiList, pTable));
}

/*******************************************************************************
*
* dm9000Stop - stop the device
*
* This function calls BSP functions to disconnect interrupts and stop
* the device from operating in interrupt mode.
*
* RETURNS: OK or ERROR.
*/

static STATUS dm9000Stop( END_DEVICE *pV )     /* device to be stopped */
{
     END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV;
     
     intDisable(pDrvCtrl->ilevel);
 
    /* TODO - stop/disable the device. */
     dmfe_Stop_Chip( pDrvCtrl );
    
     return (OK);
}

/******************************************************************************
*
* dm9000Unload - 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.
*/

static STATUS dm9000Unload( END_DEVICE *pV )   /* device to be unloaded */
{
     END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV;
     
#ifdef DM_DEBUG_PRINT
    logMsg("dm9000Unload()\n", 0, 0, 0, 0, 0, 0);
#endif

    END_OBJECT_UNLOAD (&pDrvCtrl->end);

    /* TODO - Free any shared DMA memory */
    return (OK);
}

/*******************************************************************************
*
* dm9000PollStart - start polled mode operations
*
* RETURNS: OK or ERROR.
*/

static STATUS dm9000PollStart( END_DEVICE *pV )    /* device to be polled */
{
     int         lastone;
    
     END_DEVICE *pDrvCtrl;
     pDrvCtrl=(END_DEVICE *)pV;
     
     lastone = intLock ();          
    
    /* TODO - turn off interrupts */
    (pDrvCtrl->flags) |= DM9000_POLLING;

    dm9000Reset( pDrvCtrl );
    dm9000Config( pDrvCtrl );       /* reconfigure device */

    intUnlock (lastone);            /* now dm9000Int won't get confused */

    logMsg("dm9000PollStart Poll Mode Start.\n", 0, 0, 0, 0, 0, 0);


    return (OK);
}

/*******************************************************************************
*
* dm9000PollStop - 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.
*/

static STATUS dm9000PollStop( END_DEVICE *pV ) /* device to be polled */
{
    int         lastone;
 
    END_DEVICE *pDrvCtrl;
    pDrvCtrl=(END_DEVICE *)pV;
     
    lastone = intLock ();  /* disable ints during register updates */

    (pDrvCtrl->flags) &= ~DM9000_POLLING;

    dm9000Reset( pDrvCtrl );
    dm9000Config( pDrvCtrl );       /* reconfigure device */

    intUnlock (lastone);

    logMsg ("dm9000PollStart Poll Mode Stop.\n", 0, 0, 0, 0, 0, 0);

    return (OK);
}

/*******************************************************************************
*
* dm9000Reset - reset device
*
* RETURNS: N/A.
*/

static void dm9000Reset( END_DEVICE *pDrvCtrl )
{
    dmfe_reset_dm9000( pDrvCtrl );
}

/*******************************************************************************
*
* dm9000StatusRead - get current device state/status
*
* RETURNS: status bits.
*/

static UINT dm9000StatusRead( END_DEVICE *pDrvCtrl )
{
    /* TODO - read and return status bits/register */
    UINT retv = 0;
    UCHAR status = 0;
    UCHAR rxbyte = 0;

    DM9000_IN_REG( 0xfe, status );
    DM9000_OUT_REG( 0xfe, status );
    DM9000_IN_REG( 0xf0, rxbyte ); /* Dummy read */
    DM9000_IN_REG( 0xf0, rxbyte ); /* Got most updated data */

    if( !((pDrvCtrl->flags) & DM9000_POLLING) )       
        retv |= DM9000_RXON;

    if( status & 0x01 )
        retv |= DM9000_RINT;

    if( status & 0x02 )
        retv |= DM9000_TINT;

    if( pDrvCtrl->tx_pkt_cnt > 2 )                  
        retv |= DM9000_TFULL;

    if( rxbyte == DM9000_PKT_RDY )
        retv |= DM9000_RXRDY;
    return (retv);
}

static void dmfe_reset_dm9000( END_DEVICE *dev )
{

⌨️ 快捷键说明

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