📄 if_dcfast.c
字号:
dcCsrWrite (devAdrs, CSR9, 0); /* reset rom pointer */ while (len > 0) { for (ix = 0; ix < 10; ix++) /* try at least 10 times */ { if ((csr9Value = dcCsrRead (devAdrs, CSR9)) & CSR9_DNV) { eRomReady = FALSE; DELAY(500); } else { *enetAdrs++ = (UCHAR) csr9Value; len--; eRomReady = TRUE; break; } } } if (!eRomReady) return (ERROR); else return (OK); }/********************************************************************************* RCP : New utility for DEC21140* dc21140EnetAddrGet - gets the ethernet address from the ROM register ** This routine gets the last two bytes of the ethernet address from the ROM* register and concantenates this value to the predefined values for DEC PMCs..* This routine returns the ethernet address into the pointer supplied to it.** The procedure could be expanded in the future to allow for modification of* Ethernet addresses in the serial ROM. It will have to be modified to* accomodate the differences in the onboard 100Mb/s ethernet on future * Motorola products.* * RETURNS: OK/ERROR*/LOCAL STATUS dc21140EnetAddrGet ( ULONG devAdrs, /* device base I/O address */ char * enetAdrs, /* pointer to the ethernet address */ int len /* number of bytes to read */ ) { int i,ix, /* index register */ tmpInt; /* temporary int */ union mixed { char Char[4]; /* temporary 2 by char */ USHORT Short[2]; /* temporary USHORT */ ULONG Long; /* temporay ULONG */ } tmp; for (i = DEC_PMC_POS, ix = 0; i<(3+DEC_PMC_POS); i++, ix++) { if ((tmp.Short[0] = dcReadRom (devAdrs, i)) == ERROR) return (ERROR); enetAdrs[ix++] = tmp.Char[1]; enetAdrs[ix] = tmp.Char[0]; } tmpInt = -1; return (OK); }/********************************************************************************* dcFltrFrmXmit - Transmit the setup filter frame.** This routine transmits the setup filter frame.* The setup frame is not transmitted actually over the wire. The setup frame* which is transmitted is 192 bytes. The tranmitter should be in an on state* before this function is called. This call has been coded so that the * setup frame can be transmitted after the chip is done with the * intialization taking into consideration for adding multicast support.* * RETURNS: OK/ERROR*/LOCAL int dcFltrFrmXmit ( DRV_CTRL * pDrvCtrl, /* pointer to device control structure */ char * pPhysAdrsTbl, /* pointer to physical address table */ int tblLen /* size of the physical address table */ ) { DC_TDE * tmd; /* pointer to Tx ring descriptor */ ULONG * pBuff; /* pointer to the Xmit buffer */ int status = OK; /* intialize status as OK */ ULONG csr7Val; /* value in CSR7 */ semTake (pDrvCtrl->TxSem, WAIT_FOREVER); if (dcFltrFrmSetup (pDrvCtrl, pPhysAdrsTbl, tblLen) != OK) { status = ERROR; /* not able to set up filter frame */ goto setupDone; /* set up done */ } /* See if next TXD is available */ tmd = pDrvCtrl->txRing + pDrvCtrl->txIndex; DC_CACHE_INVALIDATE (tmd, TMD_SIZ); if ( ((tmd->tDesc0 & PCISWAP(TDESC0_OWN)) != 0) || ( ((pDrvCtrl->txIndex + 1) % pDrvCtrl->dcNumTds) == pDrvCtrl->txDiIndex ) ) { status = ERROR; /* not able to set up filter frame */ goto setupDone; /* set up done */ } /* Get pointer to transmit buffer */ pBuff = DC_CACHE_PHYS_TO_VIRT(PCI_TO_MEM_PHYS(PCISWAP(tmd->tDesc2))); /* copy into Xmit buffer */ bcopyLongs ((char *)pDrvCtrl->pFltrFrm, (char *)pBuff, FLTR_FRM_SIZE_ULONGS); tmd->tDesc0 = 0; /* clear buffer error status */ tmd->tDesc1 |= PCISWAP(TDESC1_SET); /* frame type as set up */ tmd->tDesc1 &= PCISWAP(~TDESC1_TBS1_MSK); tmd->tDesc1 |= PCISWAP(TDESC1_TBS1_PUT(FLTR_FRM_SIZE)); tmd->tDesc0 = PCISWAP(TDESC0_OWN); /* give ownership to device */ CACHE_PIPE_FLUSH (); /* Flush the write pipe */ /* Advance our management index */ pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->dcNumTds; pDrvCtrl->txDiIndex = (pDrvCtrl->txDiIndex + 1) % pDrvCtrl->dcNumTds; csr7Val = dcCsrRead (pDrvCtrl->devAdrs, CSR7); dcCsrWrite(pDrvCtrl->devAdrs, CSR7, 0); /* mask interrupts */ if (dcKickStartTx) dcCsrWrite(pDrvCtrl->devAdrs, CSR1, CSR1_TPD); /* xmit poll demand */ /* wait for the own bit to change */ while (tmd->tDesc0 & PCISWAP (TDESC0_OWN)) ; tmd->tDesc0 = 0; /* clear status bits */ tmd->tDesc1 &= PCISWAP(~TDESC1_SET); dcCsrWrite(pDrvCtrl->devAdrs, CSR7, csr7Val); /* restore value */ setupDone: /* Release exclusive access. */ semGive (pDrvCtrl->TxSem); return (status); }/********************************************************************************* dcFltrFrmSetup - set up the filter frame.** This routine sets up the filter frame to filter the physical addresses* on the incoming frames. The setup filter frame buffer is 192 bytes. This* setup frame needs to be transmitted before transmitting and receiving * any frames. * * RETURNS: OK/ERROR*/LOCAL int dcFltrFrmSetup ( DRV_CTRL * pDrvCtrl, /* pointer to device control structure */ char * pPhysAdrsTbl, /* pointer to physical address table */ int tblLen /* size of the physical address table */ ) { int ix; /* index variable */ int jx; /* inner index variable */ ULONG * pFltrFrm; /* pointer to the filter frame */ USHORT * pPhysAddrs; /* pointer to the physical addresses */ if (tblLen > FLTR_FRM_ADRS_NUM) return (ERROR); pFltrFrm = pDrvCtrl->pFltrFrm; for (ix = 0; ix < FLTR_FRM_SIZE_ULONGS; ix++) *pFltrFrm++ = FLTR_FRM_DEF_ADRS; pFltrFrm = pDrvCtrl->pFltrFrm; pPhysAddrs = (USHORT *) (pPhysAdrsTbl); for (ix = 0; ix < tblLen; ix++) { for (jx = 0; jx < (FLTR_FRM_ADRS_SIZE/sizeof (USHORT)); jx++) {#if (_BYTE_ORDER == _BIG_ENDIAN) *pFltrFrm = (*pPhysAddrs << 16);#else *pFltrFrm = ((LSB(*pPhysAddrs) << 8) | MSB(*pPhysAddrs));#endif pPhysAddrs++; pFltrFrm++; } } return (OK); }#include "sys/socket.h"/********************************************************************************* convertDestAddr - converts socket addr into enet addr and packet type**/LOCAL 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 *//********************************************************************************* RCP : New utility for DEC21140* dcReadRom - reads an specified entry in the Serial ROM ** This routine uses the line number passed to the function and returns* the two bytes of information that is associated with it. This will later* be used by the dc21140GetEthernetAdr function. It can also be used to * review the ROM contents itself.** The function must first send some initial bit paterns to the CSR9 which * contains the Serial ROM Control bits. Then the line index into the ROM* will be evaluated bit by bit to program the ROM. The 2 bytes of data* will be extracted and processed into a normal pair of bytes. * * RETURNS: Short Value in ROM/ERROR*/#define BASE CSR9_SSR_FLAG|CSR9_SWO_FLAGUSHORT dcReadRom ( ULONG devAdrs, /* device base I/O address */ UCHAR lineCnt /* Serial ROM line Number */ ) { int ix, /* index register */ intCnt; /* address loop count */ USHORT tmpShort; ULONG tmpLong; /* Is the line offset valid, and if so, how large is it */ if (lineCnt > SROM_SIZE || lineCnt < 0) { printf ("dcReadRom FAILED, bad lineCnt\n"); return (ERROR); } if (lineCnt < 64) { intCnt = 6; lineCnt = lineCnt << 2; /* Prepare lineCnt for processing */ } else intCnt = 8;/* Command the Serial ROM to the correct Line *//* Preamble of Command */ dcCsrWrite (devAdrs, CSR9, 0x00000000|BASE); /* Command 1 */ NSDELAY (30); dcCsrWrite (devAdrs, CSR9, 0x00000001|BASE); /* Command 2 */ NSDELAY (50); dcCsrWrite (devAdrs, CSR9, 0x00000003|BASE); /* Command 3 */ NSDELAY (250); dcCsrWrite (devAdrs, CSR9, 0x00000001|BASE); /* Command 4 */ NSDELAY (100);/* Command Phase */ dcCsrWrite (devAdrs, CSR9, 0x00000005|BASE); /* Command 5 */ NSDELAY (150); dcCsrWrite (devAdrs, CSR9, 0x00000007|BASE); /* Command 6 */ NSDELAY (250); dcCsrWrite (devAdrs, CSR9, 0x00000005|BASE); /* Command 7 */ NSDELAY (250); dcCsrWrite (devAdrs, CSR9, 0x00000007|BASE); /* Command 8 */ NSDELAY (250); dcCsrWrite (devAdrs, CSR9, 0x00000005|BASE); /* Command 9 */ NSDELAY (100); dcCsrWrite (devAdrs, CSR9, 0x00000001|BASE); /* Command 10 */ NSDELAY (150); dcCsrWrite (devAdrs, CSR9, 0x00000003|BASE); /* Command 11 */ NSDELAY (250); dcCsrWrite (devAdrs, CSR9, 0x00000001|BASE); /* Command 12 */ NSDELAY (100); /* Address Phase */ for (ix=0; ix < intCnt; ix++) { tmpLong = (lineCnt & 0x80)>>5; /* Extract and move bit to bit 3)/* Write the command */ dcCsrWrite (devAdrs, CSR9, tmpLong | 0x00000001|BASE);/* Command 13 */ NSDELAY (150); dcCsrWrite (devAdrs, CSR9, tmpLong | 0x00000003|BASE);/* Command 14 */ NSDELAY (250); dcCsrWrite (devAdrs, CSR9, tmpLong | 0x00000001|BASE);/* Command 15 */ NSDELAY (100); lineCnt = lineCnt<<1; /* Adjust significant address bit */ } NSDELAY (150);/* Data Phase */ tmpShort =0; for (ix=15; ix >= 0; ix--) {/* Write the command */ dcCsrWrite (devAdrs, CSR9, 0x00000003|BASE); /* Command 16 */ NSDELAY (100);/* Extract the data */ tmpShort |= (((dcCsrRead (devAdrs, CSR9) & 0x00000008)>>3) <<ix); /* Command 17 */ NSDELAY (150); dcCsrWrite (devAdrs, CSR9, 0x00000001|BASE); /* Command 18 */ NSDELAY (250); }/* Finish up command */ dcCsrWrite (devAdrs, CSR9, 0x00000000); /* Command 19 */ NSDELAY (100); return (tmpShort); }/* RCP: Function to read all of serial rom and store the data in the data struc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -