📄 if_lnpci.c
字号:
tmd = pDrvCtrl->tring + pDrvCtrl->tindex; LN_CACHE_INVALIDATE (tmd, TMD_SIZ); if ( ( (PCISWAP(tmd->tbuf_tmd1) & TMD1_OWN) != 0) || ( ( (pDrvCtrl->tindex + 1) & (pDrvCtrl->tsize - 1)) == pDrvCtrl->dindex)) { m_freem (pMbuf); pDrvCtrl->idr.ac_if.if_oerrors++; break; } /* Get pointer to transmit buffer */ buf = (char *) (pDrvCtrl->tmd_ring.t_bufs + (pDrvCtrl->tindex * LN_BUFSIZ)); /* Copy packet from MBUFs to transmit buffer. */ bcopy_from_mbufs (buf, pMbuf, len, pDrvCtrl->memWidth); /* Ensure we send a legal size frame. */ len = max (ETHERSMALL, len); /* place a transmit request */ oldLevel = intLock (); /* disable ints during update */ tmd->tbuf_tmd3 = 0; /* clear buffer error status */ /* negative message byte count */ tmd->tbuf_tmd1 &= PCISWAP(~TMD1_BCNT_MSK); tmd->tbuf_tmd1 |= PCISWAP((TMD1_CNST | TMD1_BCNT_MSK) & -len); tmd->tbuf_tmd1 |= PCISWAP(TMD1_ENP); /* buffer is end of packet */ tmd->tbuf_tmd1 |= PCISWAP(TMD1_STP); /* buffer is start of packet */ tmd->tbuf_tmd1 &= PCISWAP(~TMD1_DEF); /* clear status bit */ tmd->tbuf_tmd1 &= PCISWAP(~TMD1_MORE); tmd->tbuf_tmd1 &= PCISWAP(~TMD1_ERR); tmd->tbuf_tmd1 |= PCISWAP(TMD1_OWN); /* Flush the write pipe */ CACHE_PIPE_FLUSH (); intUnlock (oldLevel); /* now lnInt won't get confused */ /* Advance our management index */ pDrvCtrl->tindex = (pDrvCtrl->tindex + 1) & (pDrvCtrl->tsize - 1); /* kick start the transmitter, if selected */ if (lnKickStartTx) lnCsrWrite (pDrvCtrl, 0, (CSR0_INEA | CSR0_TDMD)); pDrvCtrl->flags &= ~LS_START_OUTPUT_FLAG; /* Bump the statistic counter. */ pDrvCtrl->idr.ac_if.if_opackets++; /* bump the statistic counter. */ } return; }#endif/********************************************************************************* lnIoctl - the driver I/O control routine** Process an ioctl request.*/static int lnIoctl ( IDR *ifp, int cmd, caddr_t data ) { int error = 0; switch (cmd) { case SIOCSIFADDR: ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN (data)->sin_addr; arpwhohas (ifp, &IA_SIN (data)->sin_addr); break; case SIOCSIFFLAGS: /* No further work to be done */ break; default: error = EINVAL; } return (error); }/********************************************************************************* lnChipReset - hardware reset of chip (stop it)*/static int lnChipReset ( DRV_CTRL *pDrvCtrl ) { ULONG * dv = (ULONG *)pDrvCtrl->devAdrs; /* Enable 32 bit access by doing a 32 bit write */ * (dv) = 0; lnCsrWrite (pDrvCtrl, CSR(0), CSR0_STOP); lnBcrWrite (pDrvCtrl, BCR(20), BCR20_SWSTYLE_PCNET); return (OK); }/********************************************************************************* lnCsrWrite - select and write a CSR register**/static void lnCsrWrite ( DRV_CTRL * pDrvCtrl, /* driver control */ int reg, /* register to select */ ULONG value /* value to write */ ) { ULONG *dv = (ULONG *)pDrvCtrl->devAdrs; /* select CSR */ *(dv+RAPOffset) = PCISWAP(((ULONG)reg & 0x000000FF)); /* write val to CSR */ *(dv+CSROffset) = PCISWAP(((ULONG)value & 0x0000FFFF)); }/********************************************************************************* lnCsrRead - select and read a CSR register**/static ULONG lnCsrRead ( DRV_CTRL * pDrvCtrl, /* driver control */ int reg /* register to select */ ) { ULONG *dv = (ULONG *)pDrvCtrl->devAdrs; *(dv+RAPOffset) = PCISWAP(((ULONG)reg & 0x000000FF)); /* select CSR */ /* get contents of CSR */ return ( PCISWAP(*(dv+CSROffset)) & (0x0000FFFF)); }/********************************************************************************* lnBcrWrite - select and write a CSR register**/static void lnBcrWrite ( DRV_CTRL * pDrvCtrl, /* driver control */ int reg, /* register to select */ ULONG value /* value to write */ ) { ULONG *dv = (ULONG *)pDrvCtrl->devAdrs; /* select CSR */ *(dv+RAPOffset) = PCISWAP(((ULONG)reg & 0x000000FF)); /* write val to BCR */ *(dv+BDPOffset) = PCISWAP(((ULONG)value & 0x0000FFFF)); }/******************************************************************** * * lnRestartSetup - setup memory descriptors and turn on chip * * Initializes all the shared memory structures and turns on the chip. */LOCAL STATUS lnRestartSetup ( DRV_CTRL *pDrvCtrl ) { ULONG stat = 0; char *buf; int loopy; int timeoutCount = 0; ln_ib *ib; ln_rmd *rmd; ln_tmd *tmd; void *pTemp; /* Set up the Rx descriptors */ rmd = pDrvCtrl->rring; /* receive ring */ buf = pDrvCtrl->rmd_ring.r_bufs; for (loopy = 0; loopy < pDrvCtrl->rsize; loopy++) { pTemp = LN_CACHE_VIRT_TO_PHYS (buf); /* convert to physical addr */ pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp)); rmd->rbuf_adr = PCISWAP((ULONG) pTemp); /* bits 31:00 of buf addr */ rmd->rbuf_rmd1 = 0; /* neg of buffer byte count */ rmd->rbuf_rmd1 = PCISWAP((RMD1_BCNT_MSK & -(pDrvCtrl->bufSize)) | RMD1_CNST); rmd->rbuf_mcnt = 0; /* no message byte count yet */ rmd->rbuf_rmd1 |= PCISWAP(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 = LN_CACHE_VIRT_TO_PHYS (buf); /* convert to physical addr */ pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp)); tmd->tbuf_adr = PCISWAP((ULONG) pTemp); /* bits 31:00 of buf addr */ tmd->tbuf_tmd1 = PCISWAP(TMD1_CNST); /* no message byte count yet */ tmd->tbuf_tmd2 = 0; /* no error status yet */ tmd->tbuf_tmd1 |= PCISWAP(TMD1_ENP); /* buffer is end of packet */ tmd->tbuf_tmd1 |= PCISWAP(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 */ ib = pDrvCtrl->ib; ib->lnIBMode = 0; /* chip will be in normal receive mode */#if (_BYTE_ORDER == _BIG_ENDIAN) bcopy ((char *)pDrvCtrl->idr.ac_enaddr, ib->lnIBPadr, 6);#else swab ((char *)pDrvCtrl->idr.ac_enaddr, ib->lnIBPadr, 4); swab ((char *)&pDrvCtrl->idr.ac_enaddr[4], &ib->lnIBPadr[6], 2);#endif /* _BYTE_ORDER == _BIG_ENDIAN */ pTemp = LN_CACHE_VIRT_TO_PHYS ( pDrvCtrl->rring ); /* point to Rx ring */ pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp)); ib->lnIBRdra = PCISWAP((ULONG)pTemp); ib->lnIBMode |= PCISWAP((IB_MODE_RLEN_MSK & (pDrvCtrl->rpo2 << 20))); pTemp = LN_CACHE_VIRT_TO_PHYS ( pDrvCtrl->tring ); /* point to Tx ring */ pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp)); ib->lnIBTdra = PCISWAP((ULONG)pTemp); ib->lnIBMode |= PCISWAP((IB_MODE_TLEN_MSK & (pDrvCtrl->tpo2 << 28))); /* Flush the write pipe */ CACHE_PIPE_FLUSH (); lnCsrWrite (pDrvCtrl, 0, CSR0_STOP); /* set the stop bit */ /* set the bus mode to little endian */ lnCsrWrite (pDrvCtrl, 3, lnPciCSR_3B); /* Point the device to the initialization block */ pTemp = LN_CACHE_VIRT_TO_PHYS ( pDrvCtrl->ib ); pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp)); lnCsrWrite (pDrvCtrl, 2, (((ULONG)pTemp >> 16) & 0x0000ffff)); lnCsrWrite (pDrvCtrl, 1, ((ULONG)pTemp & 0x0000ffff)); lnCsrWrite (pDrvCtrl, 0, CSR0_INIT); /* init chip (read IB) */ while (((stat = lnCsrRead (pDrvCtrl, 0)) & (CSR0_IDON | CSR0_ERR)) == 0) { if (timeoutCount++ > 0x10000) break; taskDelay(100); } if ((stat & CSR0_ERR) == CSR0_ERR) { if ((stat & CSR0_MERR) == CSR0_MERR) { logMsg ("lnPci: Lance memory error while initialization:\t0x%x\n", stat, 0,0,0,0,0); } else { logMsg ("lnPci: Lance error while initialization:\t0x%x\n", stat, 0,0,0,0,0); } } /* log chip initialization failure */ if ( (stat & CSR0_ERR) || (timeoutCount >= 0x10000) ) { logMsg ("lnPci%d: Device initialization failed\n", pDrvCtrl->idr.ac_if.if_unit, 0,0,0,0,0); return (ERROR); } /* Device is initialized. Start transmitter and receiver. The device * RAP register is left selecting CSR 0. */ lnCsrWrite(pDrvCtrl, 0, CSR0_IDON | CSR0_INEA | CSR0_STRT); sysLanIntEnable (pDrvCtrl->ilevel); /* enable LANCE interrupts */ pDrvCtrl->idr.ac_if.if_flags |= (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS); return (OK); }/********************************************************************************* lnRestart - 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.*/static void lnRestart ( DRV_CTRL *pDrvCtrl ) { printf ("lnPci: device reset\n"); if (lnChipReset (pDrvCtrl) == ERROR) /* reset lance device */ { logMsg ("lnPci: Device failed to reset\n", 0,0,0,0,0,0); return; } lnRestartSetup (pDrvCtrl); return; }#ifdef BSD43_DRIVER#include "sys/socket.h"/********************************************************************************* convertDestAddr - converts socket addr into enet addr and packet type**/static BOOL convertDestAddr ( IDR *pIDR, /* ptr to i/f data record */ SOCK *pDestSktAddr, /* ptr to a generic sock addr */ char *pDestEnetAddr, /* where to write enet addr */ u_short *pPacketType, /* where to write packet type */ MBUF *pMbuf /* ptr to mbuf data */ ) { /***** Internet family *****/ { struct in_addr destIPAddr; /* not used */ int trailers; /* not supported */ if (pDestSktAddr->sa_family == AF_INET) { *pPacketType = ETHERTYPE_IP; /* stuff packet type */ destIPAddr = ((struct sockaddr_in *) pDestSktAddr)->sin_addr; if (!arpresolve (pIDR, pMbuf, &destIPAddr, pDestEnetAddr, &trailers)) return (FALSE); /* if not yet resolved */ return (TRUE); } } /***** Generic family *****/ { ENET_HDR *pEnetHdr; if (pDestSktAddr->sa_family == AF_UNSPEC) { pEnetHdr = (ENET_HDR *) pDestSktAddr->sa_data; /* ptr to hdr */ bcopy (pEnetHdr->dst, pDestEnetAddr, 6); /* copy dst addr */ *pPacketType = pEnetHdr->type; /* copy type */ return (TRUE); } } /* Unsupported family */ return (FALSE); } /* End of convertDestAddr() *//* END OF FILE */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -