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

📄 ln97xend.c

📁 vxWorks下AMD973芯片的驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRdp, PCI_SWAP (value));

    CACHE_PIPE_FLUSH ();

    intUnlock (level);
    }

/*******************************************************************************
*
* ln97xCsrRead - select and read a CSR register
*
* This routine selects a register to read, through the RAP register and
* then reads the CSR value from the RDP register.
*
* RETURNS: N/A
*/

LOCAL UINT32 ln97xCsrRead
    (
    LN_97X_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */
    int			reg  	 /* register to select */
    )
    {
    int 		level;
    UINT32 		result;
    
    level = intLock ();
    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP (reg));
    CACHE_PIPE_FLUSH ();
    SYS_IN_LONG (pDrvCtrl, pDrvCtrl->pRdp, result);
    intUnlock (level);

    return (PCI_SWAP (result) & 0x0000FFFF);
    }

/*******************************************************************************
*
* ln97xBcrWrite - select and write a BCR register
*
* This routine writes the bus configuration register. It first selects the
* BCR register to write through the RAP register and then it writes the value
* to the BDP register.
*
* RETURNS: N/A
*/

LOCAL void ln97xBcrWrite
    (
    LN_97X_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */
    int 		reg,     /* BCR register to select */
    UINT32 		value    /* BCR value to write */
    )
    {
    int 		level;

    reg &= 0xff;

    value &=0xffff;

    level = intLock ();

    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP(reg));
    CACHE_PIPE_FLUSH ();

    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pBdp, PCI_SWAP(value));
    intUnlock (level);
    }

/*******************************************************************************
*
* ln97xBcrRead - select and read a BCR register
*
* This routine reads the bus configuration register. It first selects the
* BCR register to read through the RAP register and then it reads the value
* from the BDP register.
*
* RETURNS: N/A
*/

LOCAL UINT32 ln97xBcrRead
    (
    LN_97X_DRV_CTRL *	pDrvCtrl,		/* driver control */
    int		reg			/* register to select */
    )
    {
    int level;
    UINT32 result;
    
    level = intLock ();

    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP (reg));

    SYS_IN_LONG (pDrvCtrl, pDrvCtrl->pBdp, result);

    intUnlock (level);

    return (PCI_SWAP (result) & 0x0000FFFF);
    }

/*******************************************************************************
*
* ln97xRestartSetup - setup memory descriptors and turn on chip
*
* This routine initializes all the shared memory structures and turns on
* the chip.
*
* RETURNS OK/ERROR
*/

LOCAL STATUS ln97xRestartSetup
    (
    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */
    )
    {  
    int         	rsize;	/* recv ring length */
    int         	tsize;	/* xmit ring length */
    LN_TMD *    	pTmd;

    /* reset the device */

    ln97xReset (pDrvCtrl);

    /* setup Rx buffer descriptors  - align on 000 boundary */

    rsize = pDrvCtrl->rringLen;

    /* 
     * setup Tx buffer descriptors  - 
     *      save unaligned location and align on 000 boundary 
     */

    pTmd = pDrvCtrl->pTring;
    tsize = pDrvCtrl->tringLen;

    /* setup the initialization block */

    pDrvCtrl->ib = (LN_IB *)pDrvCtrl->pShMem;
    
    DRV_LOG (DRV_DEBUG_LOAD, "Init block @ 0x%X\n",
             (int)(pDrvCtrl->ib), 2, 3, 4, 5, 6);

    bcopy ((char *) END_HADDR(&pDrvCtrl->endObj), pDrvCtrl->ib->lnIBPadr, 6);

    CACHE_PIPE_FLUSH ();

    /* point to Rx ring */

    LN_ADDR_TO_IB_RMD (pDrvCtrl->pRring, pDrvCtrl->ib, rsize);

    /* point to Tx ring */

    LN_ADDR_TO_IB_TMD (pDrvCtrl->pTring, pDrvCtrl->ib, tsize);

    DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);

    /* reconfigure the device */

    ln97xConfig (pDrvCtrl);

    return (OK);
    }

/*******************************************************************************
*
* ln97xRestart - restart the device after a fatal error
*
* This routine takes care of all the messy details of a restart.  The device
* is reset and re-initialized.  The driver state is re-synchronized.
*
* RETURNS: N/A
*/

LOCAL void ln97xRestart
    (
    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */
    )
    {
    ln97xReset (pDrvCtrl);

    ln97xRestartSetup (pDrvCtrl);

    /* set the flags to indicate readiness */

    END_OBJ_READY (&pDrvCtrl->endObj,
                    IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST
                    | IFF_MULTICAST);
    }

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

LOCAL void ln97xConfig
    (
    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */
    )
    {
    UINT16 		stat;
    void * 		pTemp;
    LN_RMD *		pRmd;
    LN_TMD *		pTmd;
    int 		ix;
    int 		timeoutCount = 0;   
    UINT32      dataTemp;
    /*UINT32      tCSRValue[126]; */
     
	/************************************/

    /* Set promiscuous mode if it's asked for. */

    if (END_FLAGS_GET (&pDrvCtrl->endObj) & IFF_PROMISC)
        {
        DRV_LOG (DRV_DEBUG_LOAD, "Setting promiscuous mode on!\n",
                 1, 2, 3, 4, 5, 6);

        /* chip will be in promiscuous mode */

        pDrvCtrl->ib->lnIBMode |= 0x00800000;
        }
    else
        {
        DRV_LOG (DRV_DEBUG_LOAD, "Setting promiscuous mode off!\n",
                 1, 2, 3, 4, 5, 6);
        }

    
    dataTemp = PCI_SWAP (pDrvCtrl->ib->lnIBMode);			
	dataTemp |= 0x00000180;
	pDrvCtrl->ib->lnIBMode = PCI_SWAP (dataTemp);

	/**********************************/

	CACHE_PIPE_FLUSH ();
    ln97xCsrWrite (pDrvCtrl, 0, CSR0_STOP);     /* set the stop bit */

    /* Set up address filter for multicasting. */

    if (END_MULTI_LST_CNT (&pDrvCtrl->endObj) > 0)
        {
        ln97xAddrFilterSet (pDrvCtrl);
        }

    /* set the bus mode to little endian */

    ln97xCsrWrite (pDrvCtrl, 3, pDrvCtrl->csr3B);

    /* set the Bus Timeout to a long time */
    /* This allows other stuff to hog the bus a bit more */
	
    ln97xCsrWrite (pDrvCtrl, 100, BUS_LATENCY_COUNT  );

	
	ln97xBcrWrite (pDrvCtrl, BCR(22), (MAX_LAT_COUNT<<8) | MIN_GNT_COUNT);
    ln97xCsrWrite(pDrvCtrl, CSR(80), (CSR80_RCVFW<<12)|(CSR80_XMSTP<<10)|(CSR80_XMTFW<<8));

    dataTemp = ln97xBcrRead(pDrvCtrl, BCR(18));
    dataTemp |=(BCR18_BREADE| BCR18_BWRITE |BCR18_MEMCMD);
    ln97xBcrWrite (pDrvCtrl, BCR(18), dataTemp);

	/***************************************/
	/* Setup LED controls */

   
    dataTemp = ln97xBcrRead (pDrvCtrl, BCR(2));
	dataTemp = dataTemp & 0xff7f;
    ln97xBcrWrite (pDrvCtrl, BCR(2), (dataTemp |BCR2_LEDPE));
    ln97xBcrWrite (pDrvCtrl, BCR(4), 0x00c0);
    ln97xBcrWrite (pDrvCtrl, BCR(5), 0x0084);
    ln97xBcrWrite (pDrvCtrl, BCR(6), 0x1088);
    ln97xBcrWrite (pDrvCtrl, BCR(7), 0x0090);
    ln97xBcrWrite (pDrvCtrl, BCR(2), (dataTemp &(~BCR2_LEDPE)));
    
    /***************************************/

    pRmd = pDrvCtrl->pRring;

    for (ix = 0; ix < pDrvCtrl->rringSize; ix++, pRmd++)
        {
        LN_CLEAN_RXD (pRmd);
        }
    pDrvCtrl->rmdIndex = 0;

    pTmd = pDrvCtrl->pTring;

    for (ix = 0; ix < pDrvCtrl->tringSize; ix++, pTmd++)
        {
        pTmd->tBufAddr = 0;                    /* no message byte count yet */
	pTemp = (void *)(TMD1_CNST | TMD1_ENP | TMD1_STP);
        pTmd->tBufTmd1 = (UINT32) PCI_SWAP (pTemp);
        LN_TMD_CLR_ERR (pTmd);
        }

    pDrvCtrl->tmdIndex = 0;
    pDrvCtrl->tmdIndexC = 0;

    /* Point the device to the initialization block */

    pTemp = LN_CACHE_VIRT_TO_PHYS (pDrvCtrl->ib);
    pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));

    ln97xCsrWrite (pDrvCtrl, CSR(2), (((ULONG)pTemp >> 16) & 0x0000ffff));
    ln97xCsrWrite (pDrvCtrl, CSR(1), ((ULONG)pTemp & 0x0000ffff));
    ln97xCsrWrite (pDrvCtrl, CSR(0), CSR0_INIT);    /* init chip (read IB) */

    /* hang until Initialization DONe, ERRor, or timeout */

  while (((stat = ln97xCsrRead (pDrvCtrl, 0)) & (CSR0_IDON | CSR0_ERR)) == 0)
        {
        if (timeoutCount++ > 0x100)
            break;

        taskDelay (2 * timeoutCount);
        }

    DRV_LOG (DRV_DEBUG_LOAD, "Timeoutcount %d\n", timeoutCount,
             2, 3, 4, 5, 6);

    /* log chip initialization failure */

    if (((stat & CSR0_ERR) == CSR0_ERR) || (timeoutCount >= 0x10000))
        {
        DRV_LOG (DRV_DEBUG_LOAD, "%s: Device initialization failed\n",
                 (int)END_DEV_NAME(&pDrvCtrl->endObj), 0,0,0,0,0);
        return;
        }
   	
    if (!(pDrvCtrl->flags & LS_POLLING))
        ln97xCsrWrite (pDrvCtrl, 0, CSR0_INTMASK | CSR0_STRT);
    else
        ln97xCsrWrite (pDrvCtrl, 0, CSR0_STRT);
    }

/******************************************************************************
*
* ln97xAddrFilterSet - set the address filter for multicast addresses
*
* This routine goes through all of the multicast addresses on the list
* of addresses (added with the ln97xAddrAdd() routine) and sets the
* device's filter correctly.
*
* RETURNS: N/A
*/

LOCAL void ln97xAddrFilterSet
    (
    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */
    )
    {
    ETHER_MULTI * 	pCurr;
    LN_IB *		pIb;
    UINT8 *		pCp;
    UINT8 		byte;
    UINT32 		crc;
    int 		len;
    int 		count;

    pIb = pDrvCtrl->ib;

    LN_ADDRF_CLEAR (pIb);

    pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->endObj);

    while (pCurr != NULL)
	{
	pCp = (UINT8 *)&pCurr->addr;

	crc = 0xffffffff;

	for (len = LN_LA_LEN; --len >= 0;)
	    {
	    byte = *pCp++;

            for (count = 0; count < LN_LAF_LEN; count++)
		{
		if ((byte & 0x01) ^ (crc & 0x01))
		    {
		    crc >>= 1;
		    crc = crc ^ LN_CRC_POLYNOMIAL;
		    }
		else
		    {
		    crc >>= 1;
		    }
		byte >>= 1;
		}
	    }

	/* Just want the 6 most significant bits. */

	crc = LN_CRC_TO_LAF_IX (crc);

	/* Turn on the corresponding bit in the filter. */

	LN_ADDRF_SET (pIb, crc);

	pCurr = END_MULTI_LST_NEXT(pCurr);
	}
    }

/*******************************************************************************
*
* ln97xPollReceive - routine to receive a packet in polled mode.
*
* This routine is called by a user to try and get a packet from the
* device. This routine return OK if it is successful in getting the packet
*
* RETURNS: OK or EAGAIN.
*/

LOCAL STATUS ln97xPollReceive
    (
    LN_97X_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */
    M_BLK_ID 		pMblk
    )
    {
    LN_RMD *		pRmd;
    UINT16 		stat;
    char * 		pPacket;
    int 		len;

    DRV_LOG (DRV_DEBUG_

⌨️ 快捷键说明

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