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

📄 motcpmend.c

📁 860最小系统的bsp
💻 C
📖 第 1 页 / 共 5 页
字号:
	  netMblkClChainFree(pMblk); 
	  if(send5==1)
	  MOTCPMLOGMSG(("motCpmEndSend5 \n", 0, 0, 0, 0, 0, 0));
         return (ERROR);
        }

    #endif	
    length = netMblkToBufCopy (pMblk, (char *)pBuf, NULL);
  
   /* length = pMblk->mBlkPktHdr.len;*/

   /* netMblkToBufCopy (pMblk, (u_char*)(pTxBd->dataPointer), NULL);*/
	
   /* netMblkClChainFree(pMblk); */
   
  
	
   pTxBd->dataPointer = (u_char *) pBuf;
    
    /* padding mechanism in Rev A is buggy - do in software */
    
    if (length < FRAME_MIN)
        {
        pad = pTxBd->dataPointer + length;
        for (; length != FRAME_MIN; length++, pad++)
            *pad = 0x88;
	
        }
    
    pTxBd->dataLength = length;
    
	
    oldLevel = intLock ();	/* disable ints during update */
    
    if (pTxBd->statusMode & SCC_ETHER_TX_BD_W)
    	{
    
        pTxBd->statusMode = SCC_ETHER_TX_BD_I | SCC_ETHER_TX_BD_PAD |
            SCC_ETHER_TX_BD_L | SCC_ETHER_TX_BD_TC  |
            SCC_ETHER_TX_BD_W | SCC_ETHER_TX_BD_R;
    	}
    else
    	{ 
    	
        pTxBd->statusMode = SCC_ETHER_TX_BD_I | SCC_ETHER_TX_BD_PAD |
            SCC_ETHER_TX_BD_L | SCC_ETHER_TX_BD_TC  |
            SCC_ETHER_TX_BD_R;
    	}
    
   pDrvCtrl->freeRtn[pDrvCtrl->ether.txBdNext] = (FUNCPTR) netClFree;

  pDrvCtrl->freeData[pDrvCtrl->ether.txBdNext].arg1 =
                              pDrvCtrl->endObject.pNetPool;   
  pDrvCtrl->freeData[pDrvCtrl->ether.txBdNext].arg2 =  pBuf;

    /* incr BD count */
    
    pDrvCtrl->ether.txBdNext = (pDrvCtrl->ether.txBdNext + 1) %
        pDrvCtrl->ether.txBdNum;
    
    /* Unlock interrupts */
    
    intUnlock (oldLevel);
  
    /* release semaphore */

	
    END_TX_SEM_GIVE (&pDrvCtrl->endObject);

    /* Bump the statistic counter. */

   netMblkClChainFree(pMblk); 

    END_ERR_ADD (&pDrvCtrl->endObject, MIB2_OUT_UCAST, +1);
if(send6==1)
    MOTCPMLOGMSG(("motCpmEndSend_Over \n", 0, 0, 0, 0, 0, 0)); 
	
    return (OK);
    }

/*******************************************************************************
*
* motCpmEndIoctl - network interface control routine
*
* This routine implements the network interface control functions.
* It handles EIOCSIFADDR, EIOCGADDR, EIOCSFLAGS, EIOCGFLAGS,
* EIOCPOLLSTART, EIOCPOLLSTOP, EIOCGMIB2 and EIOCGFBUF commands.
*
* RETURNS: OK if successful, otherwise EINVAL.
*/

LOCAL int motCpmEndIoctl
    (
    END_CTRL *	pDrvCtrl,	/* pointer to END_CTRL structure */
    int		cmd,		/* command to process */
    caddr_t	data		/* pointer to data */ 
    )
    {
    int         error   = 0;            /* error value */
    long 	value;
    END_OBJ *	pEndObj	= &pDrvCtrl->endObject;

    MOTCPMLOGMSG(("motCpmEndIoctl with command = 0x%x \n", cmd, 0, 0, 0, 0, 0));

    switch (cmd)
        {
	case EIOCSADDR:
	    if (data == NULL)
	    	error = EINVAL;
	    bcopy ((char *)data, (char *)END_HADDR(pEndObj),
			END_HADDR_LEN(pEndObj));
	    break;

        case EIOCGADDR:
	    if (data == NULL)
	    	error = EINVAL;
	     else
	     	bcopy ((char *)END_HADDR(pEndObj), (char *)data,
		 	END_HADDR_LEN(pEndObj));
	  	break;
   
	case EIOCSFLAGS:
	    value = (long) data;
	    if (value < 0)
		{
		value = -value;
		value--;
		END_FLAGS_CLR (pEndObj, value);
		}
	    else
		END_FLAGS_SET (pEndObj, value);

	    /* set promisc bit off flags */

	    if (END_FLAGS_GET(pEndObj) & IFF_PROMISC)
		pDrvCtrl->ether.pSccReg->psmr |= SCC_ETHER_PSMR_PRO;
	    else
		pDrvCtrl->ether.pSccReg->psmr &= ~SCC_ETHER_PSMR_PRO;
	    break;

	case EIOCGFLAGS:
	    if (data == NULL)
		error = EINVAL;
	    else
	    	*(int *)data = END_FLAGS_GET(pEndObj);
	    break;

	case EIOCPOLLSTART:
	    error = motCpmEndPollStart (pDrvCtrl);
	    break;

	case EIOCPOLLSTOP:
	    error = motCpmEndPollStop (pDrvCtrl);
	    break;

	case EIOCGMIB2:
	    if (data == NULL)
	    	error = EINVAL;
	    else
		bcopy((char *)&pDrvCtrl->endObject.mib2Tbl, (char *)data,
			sizeof(pDrvCtrl->endObject.mib2Tbl));
	    break;

        case EIOCGFBUF:
	    if (data == NULL)
		error =  EINVAL;
	    else
		*(int *)data = LENGTH_MIN_FBUF;
	    break;

        default:
            error = EINVAL;
        }

    return (error);
    }

/*******************************************************************************
*
* motCpmEndMCastAddrAdd - add a multicast address for the device
*
* This routine adds a multicast address to whatever the driver
* is already listening for. 
*
* To add an address in the processor group address hash filter, we use
* the SET GROUP ADDRESS command. This command can be executed at any 
* time, regadless of whether the Ethernet channel is enabled.
*
* RETURNS : OK or ERROR
*/

LOCAL STATUS motCpmEndMCastAddrAdd
    (
    END_CTRL *  pDrvCtrl,	/* pointer to END_CTRL structure */
    char *      pAddr		/* Address to add to the table. */
    )
    {
    STATUS error;

    MOTCPMLOGMSG(("motCpmEndMCastAddrAdd %x:%x:%x:%x:%x:%x \n", 
		 pAddr[5], pAddr[4], pAddr[3], 
		 pAddr[2], pAddr[1], pAddr[0]));

    error = etherMultiAdd (&pDrvCtrl->endObject.multiList, pAddr);

    if (error == ENETRESET)
	{
	pDrvCtrl->endObject.nMulti++;

	/* Set the multicast address */

	motCpmMCastFilterSet (pDrvCtrl, pAddr);

	error = OK;
	}

    return ((error == OK) ? OK : ERROR);
    }

/*******************************************************************************
*
* motCpmEndMCastAddrDel - delete a multicast address for the device
*
* This routine deletes a multicast address from the current list of
* multicast addresses.
*
* RETURNS : OK or ERROR
*/

LOCAL STATUS motCpmEndMCastAddrDel
    (
    END_CTRL *  pDrvCtrl,	/* pointer to END_CTRL structure */
    char *      pAddr		/* Address to delete from the table. */
    )
    {
    STATUS error;

    MOTCPMLOGMSG(("motCpmEndMCastDel %x:%x:%x:%x:%x:%x \n", 
		 pAddr[5], pAddr[4], pAddr[3], 
		 pAddr[2], pAddr[1], pAddr[0]));

    error = etherMultiDel (&pDrvCtrl->endObject.multiList, pAddr);

    if (error == ENETRESET)
	{
	pDrvCtrl->endObject.nMulti--;
	motCpmMCastConfig (pDrvCtrl);
	error = OK;
	}

    return ((error == OK) ? OK : ERROR);
    }

/*******************************************************************************
*
* motCpmEndMCastAddrGet - get the current multicast address list
*
* This routine returns the current multicast address list in <pTable>
*
*/

LOCAL STATUS motCpmEndMCastAddrGet
    (
    END_CTRL *  pDrvCtrl,	/* pointer to END_CTRL structure */
    MULTI_TABLE *pTable		/* table to fill in with addresses */
    )
    {
    MOTCPMLOGMSG(("motCpmEndMCastAddrGet \n", 0, 0, 0, 0, 0, 0));

    return (etherMultiGet (&pDrvCtrl->endObject.multiList, pTable));
    }

/*******************************************************************************
*
* motCpmEndPollStart - start polling mode
*
* This routine starts polling mode by disabling ethernet interrupts and
* setting the polling flag in the END_CTRL stucture.
*
* It is necessary to empty transmit queue before entering polling mode
* because M_BLK_ID free routine used in interrupt mode could be unusable 
* in this mode (could use kernel calls). 
*
* RETURNS: OK or ERROR if already in polling mode.
*/

LOCAL STATUS motCpmEndPollStart
    (
    END_CTRL    *pDrvCtrl	/* pointer to END_CTRL structure */
    )
    {
    int 	intLevel;
    int		txBdIndex;
    SCC_BUF *	pTxBd;

    MOTCPMLOGMSG(("motCpmEndPollStart \n", 0, 0, 0, 0, 0, 0));

    /* Lock interrupts */

    intLevel = intLock();

    /* clean transmit queue */

    txBdIndex = pDrvCtrl->txBdIndexC;

    while (txBdIndex != pDrvCtrl->ether.txBdNext)
	{
	pTxBd = & pDrvCtrl->ether.txBdBase[txBdIndex];

	/* Spin until frame buffer is sent */

	while (pTxBd->statusMode & SCC_ETHER_TX_BD_R)
	    ;

	/* Check for transmit errors */

	if (pTxBd->statusMode & (SCC_ETHER_TX_BD_RL | SCC_ETHER_TX_BD_UN |
 				SCC_ETHER_TX_BD_CSL | SCC_ETHER_TX_BD_LC))
	    {
	    /* An error has occured, restart the transmitter */

	    pDrvCtrl->txStop = TRUE;

	    motCpmTxRestart (pDrvCtrl);
	    }

	/* increment txBdIndex */

	txBdIndex = (txBdIndex + 1) % pDrvCtrl->ether.txBdNum;
	}
    
    /* free all transmit buffer and update transmit queue */

    motCpmCleanTxBdQueue (pDrvCtrl);

    /* Now, transmit queue is empty. We can enter polling mode. */
    /* mask off the receive and transmit interrupts */
    
    pDrvCtrl->ether.pSccReg->sccm = 0;

    /* Set the polling flag */

    pDrvCtrl->polling = TRUE;

    /* Unlock interrupts */

    intUnlock (intLevel);

    return (OK);
    }

/*******************************************************************************
*
* motCpmEndPollStop - stop polling mode
*
* This routine stops polling mode by enabling ethernet interrupts and
* resetting the polling flag in the END_CTRL structure.
*
* RETURNS: OK always
*/

LOCAL STATUS motCpmEndPollStop
    (
    END_CTRL    *pDrvCtrl	/* pointer to END_CTRL structure */
    )
    {
    int         intLevel;

    MOTCPMLOGMSG(("motCpmEndPollStop \n", 0, 0, 0, 0, 0, 0));

    /* lock interrupt  */

    intLevel = intLock();

    /* reset the SCC's interrupt status bit */

    *CPM_CISR(pDrvCtrl->regBase) = pDrvCtrl->ether.intMask;

    /* enable this SCC's interrupt */

    *CPM_CIMR(pDrvCtrl->regBase) |= pDrvCtrl->ether.intMask;

    /* reset the status bits */

    pDrvCtrl->ether.pSccReg->scce = 0xffff;

    /* enables the receive and transmit interrupts */

   

   pDrvCtrl->ether.pSccReg->sccm = SCC_ETHER_SCCX_RXF | SCC_ETHER_SCCX_TXE |
				    SCC_ETHER_SCCX_TXB;

    /* reset the polling flag */

    pDrvCtrl->polling = FALSE;

    /* unlock interrupt  */

    intUnlock (intLevel);

    return (OK);
    }

/******************************************************************************
*
* motCpmEndPollSend - transmit a packet in polled mode
*
* This routine is called by a user to try and send a packet on the
* device. It sends a packet directly on the network from the caller without
* going through the normal processes of queuing a pacet on an output queue
* and the waiting for the device to decide to transmit it.

⌨️ 快捷键说明

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