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

📄 elt3c509end.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
    (    void  * 	pEnd,	        /* device pointer */    M_BLK_ID 	pMblk		/* packet to send */    )    {    int			len;    int *		pLenMask;    char *		pBuf;    ELT3C509_DEVICE * 	pDrvCtrl;    UINT16		txStatus;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    SYS_IN_WORD (pDrvCtrl, pDrvCtrl->port + TX_FREE_BYTES, txStatus);    if (txStatus >= TX_IDLE_COUNT)        {        pBuf = pDrvCtrl->pTxCluster; 	/* pointer to the transmit cluster */        pLenMask = (UINT32 *)pBuf;                /* allow space for the preamble the trasmit buffer is 1520 */        pBuf += sizeof(UINT32);        len = netMblkToBufCopy(pMblk, pBuf, NULL);        len = max(len, ETHERSMALL);		/* set the packet size */        *pLenMask = len | TX_F_INTERRUPT;	/* set the preamble */        len = (len + TX_F_PREAMBLE_SIZE + 3) & TX_F_DWORD_MASK;        /* place a transmit request */        SYS_OUT_WORD_STRING (pDrvCtrl, pDrvCtrl->port + DATA_REGISTER, 				(short *)pLenMask, len / 2);        /* read the tranmsit status */        SYS_IN_BYTE (pDrvCtrl, pDrvCtrl->port + TX_STATUS, txStatus);        /* wait until tramit is complete */        while (!(txStatus & TX_S_COMPLETE))            {            SYS_IN_BYTE (pDrvCtrl, pDrvCtrl->port + TX_STATUS, txStatus);            }	/* clear old status */        SYS_OUT_BYTE (pDrvCtrl, pDrvCtrl->port + TX_STATUS, 0);        }    else        {        ENDLOGMSG(("Error in Send, not enough TxFreeBytes\n",1,2,3,4,5,6));        return (EAGAIN);        }        /* Bump the statistic counter. */    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);    ENDLOGMSG (("Poll Send complete\n",1,2,3,4,5,6));    return (OK);    }/********************************************************************************* elt3c509PollStart - start polled mode operations** This function starts polled mode operation.** The device interrupts are disabled, the current mode flag is switched* to indicate Polled mode and the device is reconfigured.** RETURNS: OK or ERROR.*/LOCAL STATUS elt3c509PollStart    (    ELT3C509_DEVICE * pDrvCtrl	/* device to be polled */    )    {    int         oldLevel;        oldLevel = intLock ();          /* disable ints during update */    pDrvCtrl->flags |= ELT3C_POLLING;    intUnlock (oldLevel);   /* now elt3c509Int won't get confused */    elt3c509IntDisable (pDrvCtrl);    ENDLOGMSG (("STARTED\n", 1, 2, 3, 4, 5, 6));    elt3c509Config (pDrvCtrl);	/* reconfigure device */    return (OK);    }/********************************************************************************* elt3c509PollStop - 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 elt3c509PollStop    (    ELT3C509_DEVICE * pDrvCtrl	/* device structure */    )    {    int         oldLevel;    oldLevel = intLock ();	/* disable ints during register updates */    pDrvCtrl->flags &= ~ELT3C_POLLING;    intUnlock (oldLevel);    elt3c509IntEnable (pDrvCtrl);    elt3c509Config (pDrvCtrl);    ENDLOGMSG (("STOPPED\n", 1, 2, 3, 4, 5, 6));    return (OK);    }/********************************************************************************* elt3c509IntEnable - enable board to cause interrupts** Because the board has maskable status, this routine can simply set the* mask to all ones.  We set all the bits symbolically; the effect is the* same.  Note that the interrupt latch is not maskable; if none of the other* mask bits are set, no interrupts will occur at all.  Only those interrupts* whose status bits are enabled will actually occur.  Note that the "intMask"* field in the device control structure is really the status mask.** RETURNS: N/A.*/LOCAL void elt3c509IntEnable    (    ELT3C509_DEVICE * pDrvCtrl	/* device structure */    )    {    UINT16  status;    SYS_IN_BYTE (pDrvCtrl, pDrvCtrl->port + ELT3C509_STATUS, status);    status &= 0x00ff;    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                  ACK_INTERRUPT | status);    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND, MASK_INTERRUPT |                  ADAPTER_FAILURE | TX_COMPLETE | TX_AVAILABLE | RX_COMPLETE |                  RX_EARLY | INTERRUPT_REQ | UPDATE_STATS);    }/********************************************************************************* elt3c509IntDisable - prevent board from causing interrupts** This routine simply sets all the interrupt mask bits to zero.* It is intended for guarding board-critical sections.** RETURNS: N/A.*/LOCAL void elt3c509IntDisable    (    ELT3C509_DEVICE * pDrvCtrl	/* device structure */    )    {    UINT16  status;    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                  MASK_INTERRUPT | 0);    SYS_IN_BYTE (pDrvCtrl, pDrvCtrl->port + ELT3C509_STATUS, status);    status &= 0x00ff;    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                  ACK_INTERRUPT | status);    }/********************************************************************************* elt3c509TxStart - turn on board's transmit function** RETURNS: N/A.*/LOCAL void elt3c509TxStart    (    ELT3C509_DEVICE *  pDrvCtrl	/* device structure */    )    {    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND, TX_ENABLE);    }/********************************************************************************* elt3c509RxStart - enable board to start receiving** RETURNS: N/A.*/LOCAL void elt3c509RxStart    (    ELT3C509_DEVICE *  pDrvCtrl	/* device structure */    )    {    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                  SET_RX_FILTER | pDrvCtrl->rxFilter);    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND, RX_ENABLE);    }/********************************************************************************* elt3c509Reset - reset the elt3c509 interface** Mark interface as inactive and reset the adapter.** RETURNS: N/A.*/LOCAL void elt3c509Reset    (    ELT3C509_DEVICE * pDrvCtrl	/* device structure */    )    {    elt3c509IntDisable (pDrvCtrl);	/* prevent device from interrupting */    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND, RX_RESET);    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND, TX_RESET);    }/********************************************************************************* elt3c509StatFlush - flush the board's statistics registers to statistics* block Called when the board reports that its statistics registers are getting* full, or when someone wants to see the current statistics (to fully update* the statistics block).** Note that reading a statistics register zeroes it in the hardware.* Note also that zeroing all the registers is necessary and sufficient* to clear the interrupt condition.** Must be called with board or system interrupts disabled.** RETURNS: N/A.*/LOCAL void elt3c509StatFlush    (    ELT3C509_DEVICE * pDrvCtrl	/* device structure */    )    {    int         port;    UINT16	tempCounter;    port = pDrvCtrl->port;    SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND,                  SELECT_WINDOW | WIN_STATISTICS);    SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, STATS_DISABLE);    SYS_IN_BYTE (pDrvCtrl, port+CARRIER_LOSTS, tempCounter);    pDrvCtrl->elt3c509Stat.nocarriers += tempCounter & 0x0f;    SYS_IN_BYTE (pDrvCtrl, port+SQE_FAILURES, tempCounter);    pDrvCtrl->elt3c509Stat.heartbeats += tempCounter & 0x0f;    SYS_IN_BYTE (pDrvCtrl, port+MULT_COLLISIONS, tempCounter);    pDrvCtrl->elt3c509Stat.multcollisions += tempCounter & 0x3f;    SYS_IN_BYTE (pDrvCtrl, port+ONE_COLLISIONS, tempCounter);    pDrvCtrl->elt3c509Stat.collisions +=  tempCounter & 0x3f;    SYS_IN_BYTE (pDrvCtrl, port+LATE_COLLISIONS, tempCounter);    pDrvCtrl->elt3c509Stat.latecollisions += tempCounter;    SYS_IN_BYTE (pDrvCtrl, port+RECV_OVERRUNS, tempCounter);    pDrvCtrl->elt3c509Stat.rxoverruns += tempCounter;    SYS_IN_BYTE (pDrvCtrl, port+GOOD_TRANSMITS, tempCounter);    pDrvCtrl->elt3c509Stat.txnoerror += tempCounter;    SYS_IN_BYTE (pDrvCtrl, port+GOOD_RECEIVES, tempCounter);    pDrvCtrl->elt3c509Stat.rxnoerror += tempCounter;    SYS_IN_BYTE (pDrvCtrl, port+TX_DEFERRALS, tempCounter);    pDrvCtrl->elt3c509Stat.deferring += tempCounter;    /* Must read all the registers to be sure to clear the interrupt */    SYS_IN_WORD (pDrvCtrl, port + BYTES_RECEIVED, tempCounter);    SYS_IN_WORD (pDrvCtrl, port + BYTES_TRANSMITTED, tempCounter);    SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, STATS_ENABLE);    SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND,                  SELECT_WINDOW | WIN_OPERATING);    }/********************************************************************************* elt3c509IntMaskSet - enable specific status conditions to cause interrupts** Sets bit(s) in the intMask field of the device control structure and in* the board's "read zero mask" where a one bit enables the corresponding* status condition to be read and to cause an interrupt.** RETURNS: N/A.*/LOCAL void elt3c509IntMaskSet    (    ELT3C509_DEVICE * 	pDrvCtrl,	/* device structure */    int 		maskBits	/* mask bits */    )    {    elt3c509IntDisable (pDrvCtrl);    pDrvCtrl->intMask |= maskBits;    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                  MASK_STATUS | pDrvCtrl->intMask);    elt3c509IntEnable (pDrvCtrl);    }/********************************************************************************* elt3c509Activate - attempt to activate the adapter with given address** The 3Com 3C509 ISA adapter does not enable itself at power-on.  This is* left to the driver, which presumably knows which board it wants.  This* we do know, from the port field in the driver control structure.** As a helpful side effect, this routine stores the OEM Ethernet address* of the selected adapter into the driver control structure.** Note that this procedure will activate only one board of the given I/O* address; this is presumably designed in by 3Com as a helpful feature.** RETURNS: OK or ERROR.*/LOCAL STATUS elt3c509Activate    (    ELT3C509_DEVICE * pDrvCtrl    )    {    int 	adapterPort;    /* I/O address of adapter we're to look for */    int 	selectedPort;   /* I/O address of adapter we've found */    int 	addressConfig;  /* adapter's address configuration register */    int 	resourceConfig; /* adapter's resource configuration register */    char 	nodeAddress [EA_SIZE];    STATUS 	status = OK; 	/* presume OK, change if there's a problem */    adapterPort = pDrvCtrl->port;    elt3c509IdCommand (ID_PORT);             /* wake up all adapters */    SYS_OUT_BYTE (pDrvCtrl, ID_PORT, ID_SET_TAG);   /* clear all tags */    /* first see if there's a 3Com 3C5xx board out there at all */    if (elt3c509IdEepromRead (EE_A_MANUFACTURER) != MANUFACTURER_ID)        return (ERROR);    /* Identify adapters one by one until we find the right one;     * as we eliminate adapters, we tag them so they don't participate     * in the next round of contention eliminations.  Along the way,     * as part of the adapter contention process, we read out the     * station address and resource configuration.     */    do        {        elt3c509IdCommand (ID_PORT);         /* prepare for contention */        /* Now read all untagged adapters' addresses from EEPROM         * a bit at a time.  Tagged adapters ignore the reads therefore         * won't be found; we find the next untagged adapter.         */        * (UINT16 *) &nodeAddress [0] = elt3c509IdEepromRead (EE_A_OEM_NODE_0);        * (UINT16 *) &nodeAddress [2] = elt3c509IdEepromRead (EE_A_OEM_NODE_1);        * (UINT16 *) &nodeAddress [4] = elt3c509IdEepromRead (EE_A_OEM_NODE_2);        resourceConfig = elt3c509IdEepromRead (EE_A_RESOURCE);        addressConfig = elt3c509IdEepromRead (EE_A_ADDRESS);        if ((addressConfig & AC_IO_BASE_MASK) == AC_IO_BASE_EISA)            {            /* the EISA base address is the last possible one; if we hit             * this value without finding the adapter we want, we're done.             */            status = ERROR;            break;            }        selectedPort = (addressConfig & AC_IO_BASE_MASK) * AC_IO_BASE_FACTOR +                       AC_IO_BASE_ZERO;        ENDLOGMSG (("elt: activate: adapter at 0x%04x\n", selectedPort, 2, 3,                    4, 5, 6));        /* tag this adapter so if we don't want it it won't contend again */        SYS_OUT_BYTE (pDrvCtrl, ID_PORT, ID_SET_TAG + 1);        }    while (selectedPort != adapterPort);    if (status != ERROR)        {        SYS_OUT_BYTE (pDrvCtrl, ID_PORT, ID_ACTIVATE);        uswab (nodeAddress, (char *)pDrvCtrl->enetAddr, EA_SIZE);        }    return (status);    }/********************************************************************************* elt3c509IdCommand - put all adapters into ID command state** This procedure synchronizes the ID state machines of all installed 3Com* adapters in preparation for contending among them.** RETUR

⌨️ 快捷键说明

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