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

📄 if_lnisa.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    ULONG	memSize,	/* used if memory pool is NOT malloc()'d */    int		memWidth,	/* byte-width of data (-1 = any width)     */    int		mode,		/* See CONFIG_LNISA in config.h */    int		dmaChan		/* DMA channel to use */    )    {    DRV_CTRL     *pDrvCtrl;    unsigned int sz;           /* temporary size holder */    char         *pTurkey;     /* start of the LANCE memory pool */    int i;#ifdef IP_ADDR_STORED_IN_EEPROM    char ipStr[BOOT_ADDR_LEN];    char *subNetMaskStr;    char scratchStr[BOOT_ADDR_LEN];    UINT32 ipAddr = 0;    BOOT_PARAMS bootParams;#endif /* IP_ADDR_STORED_IN_EEPROM */    /* Sanity check the unit number */    if (unit < 0 || unit >= MAX_UNITS)        return (ERROR);    /*     * The DMA channel must be one of 5,6 or 7 as it has      * to be a 16 bit channel.     */    if((dmaChan < 5) || (dmaChan > 7))      return ERROR;    /* Ensure single invocation per system life */    pDrvCtrl = & drvCtrl [unit];    if (pDrvCtrl->attached)        return (OK);    /*      * Fill pDrvCtrl->devAdrs out now as it is used by lnCsrXXXX and      * lnIdpXXXX functions for register access.     */    pDrvCtrl->devAdrs    = (LN_DEVICE *)devAdrs; /* LANCE I/O address */    /* set DMA channel to cascade mode to enable device as ISA bus master */    sysOutByte (0xd6,(0xc0 | (dmaChan - 4)));     sysOutByte (0xd4,(dmaChan - 4)); /* enable DMA channel */    /*      * Examine ISACSR3 for a valid EEPROM. If the EEPROM is invalid bring the     * device out of PnP mode using the Software Relocatable key code. This      * will allow the user to program the EEPROM with valid information using      * the function lnIsa_eeprog().     */     if(lnIdpRead(pDrvCtrl,ISACSR3) != EE_VALID)     {       printf("\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n");       printf("Ethernet Device EEPROM invalid\n");       printf("Use lnIsa_eeprog(pDrvCtrl,ENET_HI,ENET_MID,ENET_LO");#ifdef IP_ADDR_STORED_IN_EEPROM       printf(",\"IP ADDRESS (Dot Notation)\")\n");#else       printf("\n");#endif       printf("to initialize EEPROM: pDrvCtrl = %p\n",pDrvCtrl);       printf("\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n");       lnIsaPnPInitiation(); /* send AMD961 SW relocation key */       lnIsaPnPSetup(devAdrs,(UINT8)ilevel,(UINT8)INT_TYPE_LNISA,		     (UINT8)dmaChan);       for(i = 0; i < 6; i++)	 lnEnetAddr[i] = 0; /* invalidate enet addr */       return ERROR;     }     else     {       /* EEPROM is Valid, so read out the Ethernet Address */       lnCsrWrite(pDrvCtrl,0,4); /* make sure device is stopped */       WR_EE_REG(EE_EN); /* enable EEPROM access */       EE_TIMEOUT;       *(UINT16 *)(&lnEnetAddr[4]) = ntohs(lnIsa_eeread16(pDrvCtrl,2));       *(UINT16 *)(&lnEnetAddr[2]) = ntohs(lnIsa_eeread16(pDrvCtrl,1));       *(UINT16 *)(&lnEnetAddr[0]) = ntohs(lnIsa_eeread16(pDrvCtrl,0));#ifdef IP_ADDR_STORED_IN_EEPROM       ipAddr = lnIsa_eeread16(pDrvCtrl,EE_WORD_LEN_MIN+1);       ipAddr = ipAddr << 16;       ipAddr |= lnIsa_eeread16(pDrvCtrl,EE_WORD_LEN_MIN);       sprintf(ipStr,"%d.%d.%d.%d",(ipAddr&0x000000ff),	       ((ipAddr&0x0000ff00)>>8),((ipAddr&0x00ff0000)>> 16),	       ((ipAddr&0xff000000)>> 24));       if((ipAddr == 0x0) || (ipAddr == 0xffffffff))       {	 printf("\n\nInvalid IP Address: %s\n\n",ipStr);	 return ERROR;       }       if((ipAddr != 0) && (ipAddr != 0xffffffff))       {	 bootStringToStruct(BOOT_LINE_ADRS, &bootParams);	 /* get current subnet mask*/	 subNetMaskStr = strstr(&bootParams.ead[0],":"); 	 if(subNetMaskStr != NULL)	   sprintf(scratchStr,"%s%s",ipStr,subNetMaskStr);	 else	   sprintf(scratchStr,"%s",ipStr);	 sprintf(&bootParams.ead[0],"%s",scratchStr);	 bootStructToString(BOOT_LINE_ADRS, &bootParams); /* update bootline */       }#endif /* IP_ADDR_STORED_IN_EEPROM */       WR_EE_REG(0);	/* Disable EEPROM access */     }     #ifdef LNISA_DEBUG    printf("\ndevAdrs = %p, ivec = %d, ilevel = %d\n",devAdrs,ivec,ilevel);    printf("memAdrs = %p, memSize = %x, memWidth = %d\n",memAdrs, memSize,	   memWidth);    printf("Ethernet Address: %02x:%02x:%02x:%02x:%02x:%02x\n",lnEnetAddr[0],	   lnEnetAddr[1],lnEnetAddr[2],lnEnetAddr[3],lnEnetAddr[4],	   lnEnetAddr[5]);    printf("IP Address = %08x = %s\n",ipAddr,ipStr);#endif    /* Publish the interface data record */    ether_attach    (                    & pDrvCtrl->idr.ac_if,                    unit,                    "lnIsa",                    (FUNCPTR) NULL,                    (FUNCPTR) lnIoctl,                    (FUNCPTR) lnOutput,                    (FUNCPTR) lnReset                    );    /* Create the transmit semaphore. */    pDrvCtrl->TxSem = semMCreate    (                                    SEM_Q_PRIORITY |                                    SEM_DELETE_SAFE |                                    SEM_INVERSION_SAFE                                    );    if (pDrvCtrl->TxSem == NULL)        {        printf ("lnIsa: error creating transmitter semaphore\n");        return (ERROR);        }    { /***** Establish size of shared memory region we require *****/    if ((int) memAdrs != NONE)  /* specified memory pool */        {        /*         * With a specified memory pool we want to maximize         * lnRsize and lnTsize         */        sz = (memSize - (RMD_SIZ + TMD_SIZ + sizeof (ln_ib)))               / ((2 * LN_BUFSIZ) + RMD_SIZ + TMD_SIZ);        sz >>= 1;               /* adjust for roundoff */        for (lnRsize = 0; sz != 0; lnRsize++, sz >>= 1)            ;        lnTsize = lnRsize;      /* lnTsize = lnRsize for convenience */        }    /* limit ring sizes to reasonable values */    if (lnRsize < 2)        lnRsize = 2;            /* 4 buffers is reasonable min */    if (lnRsize > 7)        lnRsize = 7;            /* 128 buffers is max for chip */    /* limit ring sizes to reasonable values */    if (lnTsize < 2)        lnTsize = 2;            /* 4 buffers is reasonable min */    if (lnTsize > 7)        lnTsize = 7;            /* 128 buffers is max for chip */    /* Add it all up */    sz = (sizeof (ln_ib)) +         ( ((1 << lnRsize) + 1) * RMD_SIZ ) +         (LN_BUFSIZ << lnRsize) +         ( ((1 << lnTsize) + 1) * TMD_SIZ ) +         (LN_BUFSIZ << lnTsize) +         6;                        /* allow for alignment adjustment */    }    { /***** Establish a region of shared memory *****/    /* OK. We now know how much shared memory we need.  If the caller     * provides a specific memory region, we check to see if the provided     * region is large enough for our needs.  If the caller did not     * provide a specific region, then we attempt to allocate the memory     * from the system, using the cache aware allocation system call.     */    switch ( (int) memAdrs )        {        default :       /* caller provided memory */            if ( memSize < sz )     /* not enough space */                {                printf ( "lnIsa: not enough memory provided\n" );                return ( ERROR );                }            pTurkey = memAdrs;             /* set the beginning of pool */            /* assume pool is cache coherent, copy null structure */            pDrvCtrl->cacheFuncs = cacheNullFuncs;            break;        case NONE :     /* get our own memory */            /* Because the structures that are shared between the device             * and the driver may share cache lines, the possibility exists             * that the driver could flush a cache line for a structure and             * wipe out an asynchronous change by the device to a neighboring             * structure. Therefore, this driver cannot operate with memory             * that is not write coherent.  We check for the availability of             * such memory here, and abort if the system did not give us what             * we need.             */            if (!CACHE_DMA_IS_WRITE_COHERENT ())                {                printf ( "lnIsa: device requires cache coherent memory\n" );                return (ERROR);                }            pTurkey = (char *) cacheDmaMalloc ( sz );            if ((int)pTurkey == NULL)                {                printf ( "lnIsa: system memory unavailable\n" );                return (ERROR);                }            /* copy the DMA structure */            pDrvCtrl->cacheFuncs = cacheDmaFuncs;            break;        }    }    /*                        Turkey Carving     *                        --------------     *     *                          LOW MEMORY     *     *             |-------------------------------------|     *             |       The initialization block      |     *             |         (sizeof (ln_ib))            |     *             |-------------------------------------|     *             |         The Rx descriptors          |     *             | (1 << lnRsize) * sizeof (ln_rmd)|     *             |-------------------------------------|     *             |          The receive buffers        |     *             |       (LN_BUFSIZ << lnRsize)        |     *             |-------------------------------------|     *             |         The Tx descriptors          |     *             | (1 << lnTsize) * sizeof (ln_tmd)|     *             |-------------------------------------|     *             |           The transmit buffers      |     *             |       (LN_BUFSIZ << lnTsize)        |     *             |-------------------------------------|     */    /* Save some things */    pDrvCtrl->memBase  = (char *)((ULONG)pTurkey & 0xffff0000);    pDrvCtrl->memWidth = memWidth;    pDrvCtrl->bufSize = LN_BUFSIZ;    if ((int) memAdrs == NONE)        pDrvCtrl->flags |= LS_MEM_ALLOC_FLAG;    { /***** Carve up the turkey *****/    /* First let's clean the whole turkey */    bzero ( (char *) pTurkey, (int) sz );    /* carve out initialization block */    pDrvCtrl->ib = (ln_ib *)pTurkey;    sz = sizeof (ln_ib);                /* size of initialization block */    /* carve out receive message descriptor (RMD) ring structure */    pDrvCtrl->rpo2 = lnRsize;              /* remember for lnConfig */    pDrvCtrl->rsize = (1 << lnRsize);      /* receive ring size */    /* make it 16 byte aligned */    pDrvCtrl->rring = (ln_rmd *) (((int)pDrvCtrl->ib + sz + 0x0f) & ~0x0f);    sz = (1 << lnRsize) * RMD_SIZ;    pDrvCtrl->rmd_ring.r_bufs = (char *)((int)pDrvCtrl->rring + sz);    sz = (LN_BUFSIZ << lnRsize);   /* room for all the receive buffers */    /* carve out transmit message descriptor (TMD) ring structure */    pDrvCtrl->tpo2 = lnTsize;              /* remember for lnConfig */    pDrvCtrl->tsize = (1 << lnTsize);      /* transmit ring size */    pDrvCtrl->tring = (ln_tmd *) (((int)pDrvCtrl->rmd_ring.r_bufs + sz + 0x0f)				  & ~0x0f);    sz = (1 << lnTsize) * TMD_SIZ;    /* carve out transmit buffer space */    pDrvCtrl->tmd_ring.t_bufs = (char *)((int)pDrvCtrl->tring + sz);    }    /* Save some values */    pDrvCtrl->ivec       = ivec;                 /* interrupt vector */    pDrvCtrl->ilevel     = ilevel;               /* interrupt level */    pDrvCtrl->devAdrs    = (LN_DEVICE *)devAdrs; /* LANCE I/O address */    /* Obtain our Ethernet address and save it */    bcopy ((char *) lnEnetAddr, (char *)pDrvCtrl->idr.ac_enaddr, 6);    { /***** Device Initialization *****/    if (lnChipReset (pDrvCtrl) == ERROR)	/* reset lance device */    	{	logMsg ("lnIsa: cannot Reset device:\n",0,0,0,0,0,0);	return (ERROR);	}    if (intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(ivec),lnInt,(int)pDrvCtrl)        == ERROR)        return (ERROR);    { /* Initialize all shared memory structures */    ln_rmd  *rmd;    ln_tmd  *tmd;    char    *buf;    ln_ib   *ib;    ULONG    pTemp;    int     loopy;    /* Set up the Rx descriptors */    rmd = pDrvCtrl->rring;                      /* receive ring */    buf = pDrvCtrl->rmd_ring.r_bufs;    for (loopy = 0; loopy < pDrvCtrl->rsize; loopy++)    {      pTemp = (ULONG)LN_CACHE_VIRT_TO_PHYS(buf);/* convert to physical addr */      rmd->rbuf_adr = (USHORT)(pTemp & 0x0000ffff); /* bits 15:00 buf addr */      rmd->rbuf_rmd1 = (USHORT)((pTemp & 0x00ff0000) >> 16); /* bits 7:0 */      /* neg of buffer byte count */      rmd->rbuf_bcnt = ((RMD2_BCNT_MSK & -(pDrvCtrl->bufSize)) | RMD2_MBO);      rmd->rbuf_mcnt = 0;			/* no message byte count yet */      rmd->rbuf_rmd1 |= RMD1_OWN;	/* buffer now owned by LANCE */      rmd++;					/* step to next descriptor */      buf += (pDrvCtrl->bufSize);		/* step to the next buffer */    }    pDrvCtrl->rindex = 0;    /* Setup the Tx descriptors */    tmd = pDrvCtrl->tring;                 /* transmit ring */    buf = pDrvCtrl->tmd_ring.t_bufs;    for (loopy = 0; loopy < pDrvCtrl->tsize; loopy++)    {      pTemp = (ULONG)LN_CACHE_VIRT_TO_PHYS(buf); /* convert to physical addr */      tmd->tbuf_adr = (USHORT) (pTemp & 0x0000ffff); /* bits 15:00 of addr */      tmd->tbuf_tmd1 = (USHORT)((pTemp & 0x00ff0000) >> 16); /* bits 7:0 */      tmd->tbuf_tmd2 = 0;		/* no length of Tx Buf yet */      tmd->tbuf_tmd3 = 0;		/* clear status bits */      tmd->tbuf_tmd1 |= TMD1_ENP;	/* buffer is end of packet */      tmd->tbuf_tmd1 |= TMD1_STP;	/* buffer is start of packet */      tmd++;					/* step to next descriptor */      buf += (pDrvCtrl->bufSize);		/* step to next buffer */    }    pDrvCtrl->tindex = pDrvCtrl->dindex = 0;    /* Setup the initialization block */    lnIdpWrite(pDrvCtrl,2, (0x100 | (mode & 0x3))); /* set up mode */    ib = pDrvCtrl->ib;    ib->lnIBMode = 0;        /* chip will be in normal receive mode */    bcopy ((char *)&pDrvCtrl->idr.ac_enaddr[0],&ib->lnIBPadr[0], 6);    pTemp =(ULONG)LN_CACHE_VIRT_TO_PHYS(pDrvCtrl->rring);/* point to Rx ring */    ib->lnIBRdraLow = (USHORT)(pTemp & 0x0000ffff);    ib->lnIBRdraHigh = (UCHAR)((pTemp & 0x00ff0000) >> 16);    ib->lnRLEN =  pDrvCtrl->rpo2<<5;    pTemp =(ULONG)LN_CACHE_VIRT_TO_PHYS(pDrvCtrl->tring);/* point to Tx ring */    ib->lnIBTdraLow = (USHORT)(pTemp & 0x0000ffff);    ib->lnIBTdraHigh = (UCHAR)((pTemp & 0x00ff0000) >> 16);    ib->lnTLEN = pDrvCtrl->tpo2<<5;    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    }    { /* Start the device */    USHORT	stat = 0;    ULONG	pTemp;    int		timeoutCount = 0;    lnCsrWrite (pDrvCtrl, 0, CSR0_STOP);	/* set the stop bit */    /* Point the device to the initialization block */    pTemp = (ULONG)LN_CACHE_VIRT_TO_PHYS ( pDrvCtrl->ib );    lnCsrWrite (pDrvCtrl, 2, (USHORT)((pTemp >> 16) & 0x000000ff));    lnCsrWrite (pDrvCtrl, 1, (USHORT)(pTemp & 0x0000ffff));    lnCsrWrite (pDrvCtrl, 0, CSR0_INIT);            /* init chip (read IB) */    while (((stat = lnCsrRead (pDrvCtrl, 0)) & (CSR0_IDON | CSR0_ERR)) == 0)        {        if (timeoutCount++ > 5) 	  break;        taskDelay(sysClkRateGet());        }    if ((stat & CSR0_ERR) == CSR0_ERR)	{	if ((stat & CSR0_MERR)  == CSR0_MERR)	    {	    printf ("Lance Memory error during initialization:\t0x%x\n",		    stat);	    }	else	    {

⌨️ 快捷键说明

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