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

📄 if_sn.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* That was easy.  Now we request some memory from the system.     * For now, we are taking a simple approach.  We simply request one     * big region, large enough to ensure that we can position our shared     * area in a single 64k page.  This approach will waste memory, but     * blame the board designers who picked the SONIC without realizing     * that the device has this weird restriction.     */    if (!CACHE_DMA_IS_WRITE_COHERENT ())        return (ERROR);    pDrvCtrl->pMem = cacheDmaMalloc (pDrvCtrl->shMemSize + 0x00010000);    if (pDrvCtrl->pMem == NULL)                 /* no memory, so abort */        return (ERROR);    /* Find start of 64k page in the region.  This becomes start of our     * region.     */    pDrvCtrl->pShMem = (char *)                       (((u_long)pDrvCtrl->pMem & 0xffff0000) + 0x00010000);    } /* Block end */    { /***** Carve up the shared area into specific areas *****/    /* Block local variables */    char *pCur;    pCur = pDrvCtrl->pShMem;                /* start of shared area */    pDrvCtrl->CDA = (u_long) pCur;          /* CAM area */    pCur += CAM_SIZE;                       /* advance the pointer */    pDrvCtrl->RSA = (u_long) pCur;          /* receive resource table */    pCur += RRA_SIZE;                       /* advance the pointer */    pDrvCtrl->REA = (u_long) pCur;          /* save end pointer */    pDrvCtrl->RDA = (u_long) pCur;          /* receive descriptor area */    pCur += RDA_SIZE;                       /* advance the pointer */    pDrvCtrl->pTDA = (TX_DESC *)pCur;       /* transmit descriptor area */    pCur += TDA_SIZE;                       /* advance the pointer */    pDrvCtrl->RBA1 = (u_long) pCur;         /* Receive Buffer 1 */    pCur += RX_BUF_SIZE + RX_BUF_EXTRA;     /* advance the pointer */    pDrvCtrl->RBA2 = (u_long) pCur;         /* Receive Buffer 2 */    pCur += RX_BUF_SIZE + RX_BUF_EXTRA;     /* advance the pointer */    pDrvCtrl->RBA3 = (u_long) pCur;         /* Receive Buffer 3 */    pCur += RX_BUF_SIZE + RX_BUF_EXTRA;     /* advance the pointer */    pDrvCtrl->RBA4 = (u_long) pCur;         /* Receive Buffer 4 */    } /* Block end */#ifdef SN_DEBUG    if (SN_DEBUG_INIT)        {        /* Dump all the resultant region pointers */        logMsg ("snattach: pDrvCtrl=%x RRA=%x RDA=%x TDA=%x\n",                (int)pDrvCtrl, pDrvCtrl->RSA,                pDrvCtrl->RDA, (int)pDrvCtrl->pTDA, 0, 0);        logMsg ("snattach: RBA1=%x RBA2=%x RBA3=%x RBA4=%x\n",                pDrvCtrl->RBA1, pDrvCtrl->RBA2,		pDrvCtrl->RBA3, pDrvCtrl->RBA4, 0, 0);        }#endif /* SN_DEBUG */    { /***** Perform device initialization *****/    snChipReset (pDrvCtrl);                 /* reset device */    sysEnetInit (unit);                     /* do any board specific set up */    sysEnetIntDisable (unit);               /* board specific int disable */                                            /* connect interrupt */    (void) intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(ivec),snIntr,unit);    {  /* init the Tx descriptors */    int loopy;    TX_DESC *pTXD;    pTXD = pDrvCtrl->pTDA;                      /* get initial ptr */    bzero ((char *)pTXD, TDA_SIZE);             /* zero the whole enchilada */    loopy = NUM_TX_DESC;    while (loopy--)                             /* loop thru each */        {        pTXD->pLink = pTXD + 1;                 /* link to next */        pTXD++;                                 /* bump to next */        }    /* The link field of the last desc is special; it needs to point     * back to the first desc.  So, we fix it here.     */    (--pTXD)->pLink = pDrvCtrl->pTDA;    pDrvCtrl->pTXDFree = pDrvCtrl->pTDA;              /* initial value */    pDrvCtrl->pTXDReclaim = pDrvCtrl->pTDA;           /* initial value */    }    {  /* init the Rx buffer descriptors */    RRA_DESC *pRRAD;                            /* RRA working descriptor */    /* Build the RRA */    pRRAD = (RRA_DESC *)pDrvCtrl->RSA;           /* get ptr to first entry */    /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA1);    pRRAD->buff_ptr0 = temp & UMASK;    pRRAD->buff_ptr1 = temp >> 16;    /* Stuff word count; least significant 16 bits, then most significant 16 */    pRRAD->buff_wc0 = RX_BUF_SIZE >> 1 & UMASK;    pRRAD->buff_wc1 = RX_BUF_SIZE >> 1 >> 16;    pRRAD++;                                    /* bump to next entry */    /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA2);    pRRAD->buff_ptr0 = (u_long) temp & UMASK;    pRRAD->buff_ptr1 = (u_long) temp >> 16;    /* Stuff word count; least significant 16 bits, then most significant 16 */    pRRAD->buff_wc0 = RX_BUF_SIZE >> 1 & UMASK;    pRRAD->buff_wc1 = RX_BUF_SIZE >> 1 >> 16;    pRRAD++;                                    /* bump to next entry */    /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA3);    pRRAD->buff_ptr0 = (u_long) temp & UMASK;    pRRAD->buff_ptr1 = (u_long) temp >> 16;    /* Stuff word count; least significant 16 bits, then most significant 16 */    pRRAD->buff_wc0 = RX_BUF_SIZE >> 1 & UMASK;    pRRAD->buff_wc1 = RX_BUF_SIZE >> 1 >> 16;    pRRAD++;                                    /* bump to next entry */    /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA4);    pRRAD->buff_ptr0 = (u_long) temp & UMASK;    pRRAD->buff_ptr1 = (u_long) temp >> 16;    /* Stuff word count; least significant 16 bits, then most significant 16 */    pRRAD->buff_wc0 = RX_BUF_SIZE >> 1 & UMASK;    pRRAD->buff_wc1 = RX_BUF_SIZE >> 1 >> 16;    }    { /* Setup the Rx frame descriptors */    RX_DESC *pRXD;                              /* Rx working descriptor */    pRXD = (RX_DESC *) pDrvCtrl->RDA;           /* get initial ptr */    bzero ((char *)pRXD, RDA_SIZE);             /* zero the whole tomato */    pDrvCtrl->pRXDNext = pRXD;                  /* start from the start! */    pDrvCtrl->pRXDLast =                        /* stuff ptr to last */                    (RX_DESC *) ((u_long)pRXD + RDA_SIZE - RX_DESC_SIZ);    while (pRXD <= pDrvCtrl->pRXDLast)          /* loop thru each */        {        pRXD->in_use = NOT_IN_USE;              /* set NOT_IN_USE */        pRXD->link =                            /* set link */            (RX_DESC *) CACHE_DMA_VIRT_TO_PHYS (pRXD + 1);        pRXD++;                                 /* bump to next */        }    /* The link field of the last desc is special; it points nowhere,     * but must mark the end-of-list.  So, we fix it here.     */    pDrvCtrl->pRXDLast->link = RX_EOL;    }    /* Enable device interrupts at system level */    sysEnetIntEnable (unit);    /* Bring up the device */    snChipInit (pDrvCtrl);    } /* Block end */    /* Set flags */    pDrvCtrl->attached = TRUE;    pDrvCtrl->sn_ac.ac_if.if_flags |= (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);    return (OK);    } /* End of snattach() *//********************************************************************************* snReset - reset the interface** Mark interface as inactive & reset the chip* This is one of the routines that can be called from "outside" via* the interface structure.* Cannot be called before the attach, since DRV_CTRL ptr would be NULL.*/LOCAL void snReset (unit)    int unit;    {    DRV_CTRL *pDrvCtrl;#ifdef SN_DEBUG    if (SN_DEBUG_INIT)        logMsg ("sn: Reset: unit=%d\n", unit, 0, 0, 0, 0, 0);#endif /* SN_DEBUG */    pDrvCtrl = & drvCtrl [unit];    pDrvCtrl->sn_if.if_flags = 0;    snChipReset (pDrvCtrl);                            /* reset device */    }/********************************************************************************* snChipReset - Place chip in Reset mode*/LOCAL void snChipReset (pDrvCtrl)    DRV_CTRL *pDrvCtrl;    {    pDrvCtrl->pDev->cr = RST;    pDrvCtrl->pDev->rsc = 0;  /* set the sequence counter to zero */    }/********************************************************************************* snChipInit - hardware init of chip (init & start it)*/LOCAL void snChipInit (pDrvCtrl)    DRV_CTRL *pDrvCtrl;    {    SONIC *pDev;                            /* ptr to the device regs */    u_long temp;    pDev = pDrvCtrl->pDev;#ifdef SN_DEBUG    if (SN_DEBUG_INIT)        logMsg ("sn: Chip init: pDrvCtrl=0x%X\n", (int)pDrvCtrl, 0, 0, 0, 0, 0);#endif /* SN_DEBUG */    pDev->cr = RST;                     /* Turn ON RESET */                                        /* Data Control */    pDev->dcr = snDcr;    if (snDcr2)	pDev->dcr2 = snDcr2;    pDev->imr = 0;                      /* All Interrupts off */    pDev->isr = 0x7fff;                 /* Clear ISR */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RSA);    pDev->urra = temp >> 16;            /* Upper RSA */    pDev->rsa = temp & UMASK;           /* Lower RSA */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->REA);    pDev->rea = temp & UMASK;           /* Lower REA */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RSA);    pDev->rrp = temp & UMASK;           /* point to first desc */    pDev->rwp = temp & UMASK;           /* point to first desc */    pDev->rsc = 0;    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RDA);    pDev->urda = temp >> 16;            /* Upper RDA */    pDev->crda = temp & UMASK;          /* Lower RDA */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->pTDA);    pDev->utda = temp >> 16;            /* first TXD */    pDev->ctda = temp & UMASK;    pDev->cr = RST_OFF;                 /* Turn OFF RESET */    pDev->cr = RRRA;                    /* prime with RRA read */    snCamInit (pDrvCtrl);               /* Initialize the CAM */    pDev->rcr = BRD;    if (pDev->imr & TCEN)	{	pDev->wt0 = pDrvCtrl->ticks & 0xffff;	pDev->wt1 = pDrvCtrl->ticks >> 16;	pDev->cr = ST;	}    pDev->imr = (pDrvCtrl->imr |= PRXEN); /* Enable these IRQ's */    pDev->cr = RXEN;                    /* Turn on Receiver */    }/********************************************************************************* snCamInit - put the local Ethernet address in the CAM** First we set up a data area with the enet addr, then we tell the device* where it is and command the device to read it.  When the device is done,* it will interrupt us.  We wait for this interrupt with a semaphore that* will be given by the interrupt handler.*/LOCAL void snCamInit (pDrvCtrl)    DRV_CTRL *pDrvCtrl;    {    SONIC *pDev;                         /* ptr to the device regs */    int jj;    u_long *CamData;    CamData = (unsigned long *) pDrvCtrl->CDA;    pDev = pDrvCtrl->pDev;    jj = 0;    CamData [jj++] = 0;                            /* Entry 0 */    CamData [jj++] = pDrvCtrl->sn_enaddr [1] << 8 | pDrvCtrl->sn_enaddr [0];    CamData [jj++] = pDrvCtrl->sn_enaddr [3] << 8 | pDrvCtrl->sn_enaddr [2];    CamData [jj++] = pDrvCtrl->sn_enaddr [5] << 8 | pDrvCtrl->sn_enaddr [4];    CamData [jj]   = 0x1;                          /* Enable entry 0 */    pDev->cdc = 1;                                 /* One entry */    pDev->cdp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->CDA) & UMASK;    pDev->cr = LCAM;                               /* issue "load CAM" cmd */    /* Wait for operation to complete.  A "dead time" loop here is deemed     * OK, since we are in initialization phase, and will only do this     * once.     */    while (!(pDev->isr & LCD))        ;    pDev->isr = LCD;                        /* clear the event flag */    }/********************************************************************************* snIoctl - the driver I/O control function** Process an ioctl request.* This is one of the routines that can be called from "outside" via* the interface structure.* Cannot be called before the attach, since DRV_CTRL ptr would be NULL.*/LOCAL int snIoctl (IDR *pIDR, int cmd, caddr_t data)    {    int error;    error = 0;#ifdef SN_DEBUG    if (SN_DEBUG_INIT)	logMsg ("sn: Ioctl: pIDR=0x%x, cmd=0x%x, data=0x%x\n",               (int)pIDR, (int)cmd, (int)data, 0, 0, 0);#endif /* SN_DEBUG */    switch (cmd)        {        case SIOCSIFADDR:            ((struct arpcom *)pIDR)->ac_ipaddr = IA_SIN (data)->sin_addr;            arpwhohas (pIDR, &IA_SIN (data)->sin_addr);            break;        case SIOCSIFFLAGS:            /* Flags are set outside this module. No additional work to do. */            break;        default:            error = EINVAL;        }    return (error);    }/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SECTION: Transmit related routines *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/#ifdef BSD43_DRIVER/********************************************************************************* snOutput - adds new output to the driver's queue and calls output routine** This is the driver output rotuine.  This is one of the routines that is* called from "outside" via the interface structure, ifnet.*/LOCAL int snOutput (pIfnet, pMbuf, pDest)    IFNET *pIfnet;    MBUF *pMbuf;    SOCK *pDest;    {    DRV_CTRL *pDrvCtrl;    int spl;    pDrvCtrl = & drvCtrl [pIfnet->if_unit];    spl = splnet ();    if (IF_QFULL (&pIfnet->if_snd))                /* If the queue is full */        snStartOutput (pIfnet->if_unit);    splx (spl);    return (ether_output (pIfnet, pMbuf, pDest, (FUNCPTR) snStartOutput,              &pDrvCtrl->sn_ac));    }/*******************************************************************************

⌨️ 快捷键说明

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