📄 auend.c
字号:
UINT32 addr; DRV_LOG (DRV_DEBUG_TX, "auSend\n", 1, 2, 3, 4, 5, 6); /* check device mode */ if (pDrvCtrl->flags & AU_POLLING) { netMblkClChainFree (pMblk); errno = EINVAL; return (ERROR); } /* * Obtain exclusive access to transmitter. This is necessary because * we might have more than one stack transmitting at once. */ END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); /* Advance our management index (first) */ index = pDrvCtrl->tmdIndex; if (AU_TX_ADDRESS(index) & 0x03) { /* Are we still on the first chunk? */ DRV_LOG (DRV_DEBUG_TX, "Out of TMDs! addr=%08x astat=%08x stat=%08x\n", AU_TX_ADDRESS(index) & ~0x1f, AU_TX_ADDRESS(index) & 0x1f, AU_TX_STATUS(index), 4, 5, 6);#ifdef DRV_DEBUG auDump (pDrvCtrl->unit);#endif pDrvCtrl->txBlocked = TRUE; END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (END_ERR_BLOCK); } pBuf = pDrvCtrl->pTxMem[index]; DRV_LOG (DRV_DEBUG_TX, "pBuf = 0x%X\n", (int)pBuf, 2, 3, 4, 5, 6); if (pBuf == NULL) { pDrvCtrl->txBlocked = TRUE; END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (END_ERR_BLOCK); } /* copy and release the packet */ len = netMblkToBufCopy (pMblk, pBuf, NULL); netMblkClChainFree (pMblk); if (len < ETHERSMALL) { /* Pad to ETHERSMALL with zeros, required by H/W */ bzero (&pBuf[len], ETHERSMALL - len); len = ETHERSMALL; } addr = ((UINT32)AU_CACHE_VIRT_TO_PHYS(pDrvCtrl->pTxMem[index]) | 1); AU_TX_LENGTH(index) = len; AU_TX_STATUS(index) = 0; AU_TX_ADDRESS(index) = addr; SYS_WB_FLUSH(); DRV_LOG (DRV_DEBUG_TX, "auSend: index %d len %d\n", index, len, 3, 4, 5, 6); DRV_LOG (DRV_DEBUG_TX, "auSend dst=%02x:%02x:%02x:%02x:%02x:%02x\n", pBuf[0]&0xff, pBuf[1]&0xff, pBuf[2]&0xff, pBuf[3]&0xff, pBuf[4]&0xff, pBuf[5]&0xff); DRV_LOG (DRV_DEBUG_TX, "auSend src=%02x:%02x:%02x:%02x:%02x:%02x\n", pBuf[6]&0xff, pBuf[7]&0xff, pBuf[8]&0xff, pBuf[9]&0xff, pBuf[10]&0xff, pBuf[11]&0xff); /* Advance our management index */ index = (pDrvCtrl->tmdIndex + 1) & (pDrvCtrl->tringSize - 1); pDrvCtrl->tmdIndex = index; /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1); END_TX_SEM_GIVE (&pDrvCtrl->endObj); DRV_LOG (DRV_DEBUG_TX, "auSend Done\n", 1, 2, 3, 4, 5, 6); return (OK); }/********************************************************************************* auIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS OK or ERROR value*/LOCAL int auIoctl ( AU_DRV_CTRL * pDrvCtrl, /* device to be initialized */ int cmd, /* ioctl command to execute */ caddr_t data /* data to get or set */ ) { long value; int error = 0; switch (cmd) { case EIOCSADDR: if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->endObj), END_HADDR_LEN (&pDrvCtrl->endObj)); break; case EIOCGADDR: if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR (&pDrvCtrl->endObj), (char *)data, END_HADDR_LEN (&pDrvCtrl->endObj)); break; case EIOCSFLAGS: value = (long)data; if (value < 0) { value = -value; value--; /* HELP: WHY ??? */ END_FLAGS_CLR (&pDrvCtrl->endObj, value); } else { END_FLAGS_SET (&pDrvCtrl->endObj, value); } auConfig (pDrvCtrl); break; case EIOCGFLAGS: *(int *)data = END_FLAGS_GET (&pDrvCtrl->endObj); break; case EIOCMULTIADD: error = auMCastAddrAdd (pDrvCtrl, (char *) data); break; case EIOCMULTIDEL: error = auMCastAddrDel (pDrvCtrl, (char *) data); break; case EIOCMULTIGET: error = auMCastAddrGet (pDrvCtrl, (MULTI_TABLE *) data); break; case EIOCPOLLSTART: error = auPollStart (pDrvCtrl); break; case EIOCPOLLSTOP: error = auPollStop (pDrvCtrl); break; case EIOCGMIB2: if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data, sizeof(pDrvCtrl->endObj.mib2Tbl)); break; case EIOCGFBUF: if (data == NULL) return (EINVAL); *(int *)data = AU_MIN_FBUF; break; case EIOCGMWIDTH: if (data == NULL) return (EINVAL); *(int *)data = 4; break; case EIOCGHDRLEN: if (data == NULL) return (EINVAL); *(int *)data = 14; break; default: error = EINVAL; } return (error); }/********************************************************************************* auReset - hardware reset of chip (stop it)** This routine is responsible for resetting the device and switching into* 32 bit mode.** RETURNS: OK/ERROR*/LOCAL int auReset ( AU_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { int i; DRV_LOG (DRV_DEBUG_LOAD, "auReset\n", 1, 2, 3, 4, 5, 6); /* Reset MAC & DMA units */ AU_MAC_ENABLE = 0; /* setup Rx memory pointers */ pDrvCtrl->rmdIndex = 0; for (i = 0; i < pDrvCtrl->rringSize; ++i) { AU_RX_STATUS(i) = 0; AU_RX_ADDRESS(i) = 0; } /* setup Tx memory pointers */ pDrvCtrl->tmdIndex = 0; pDrvCtrl->tmdLastIndex = 0; for (i = 0; i < pDrvCtrl->tringSize; ++i) { AU_TX_STATUS(i) = 0; AU_TX_LENGTH(i) = 0; AU_TX_ADDRESS(i) = 0; } SYS_WB_FLUSH(); return (OK); }/********************************************************************************* auRestartSetup - 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 auRestartSetup ( AU_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { DRV_LOG (DRV_DEBUG_LOAD, "auRestartSetup\n", 1, 2, 3, 4, 5, 6); /* reset the device */ auReset (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6); /* reconfigure the device */ auConfig (pDrvCtrl); return (OK); }/********************************************************************************* auRestart - 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 auRestart ( AU_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { auRestartSetup (pDrvCtrl); /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST); }/******************************************************************************** auConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A*/LOCAL void auConfig ( AU_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { UCHAR * enetAddr; int i; DRV_LOG (DRV_DEBUG_LOAD, "auConfig\n", 1, 2, 3, 4, 5, 6); /* 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->flags |= AU_PROMISCUOUS_FLAG; } else { DRV_LOG (DRV_DEBUG_LOAD, "Setting promiscuous mode off!\n", 1, 2, 3, 4, 5, 6); pDrvCtrl->flags &= ~AU_PROMISCUOUS_FLAG; } /* Set up address filter for multicasting. */ if (END_MULTI_LST_CNT (&pDrvCtrl->endObj) > 0) { auAddrFilterSet (pDrvCtrl); } /* Enable the MAC */ AU_MAC_ENABLE = AU_MAC_ENABLE_CLOCKS_ONLY; SYS_WB_FLUSH(); AU_MAC_ENABLE = AU_MAC_ENABLE_NORMAL & ~AU_MAC_ENABLE_TS; SYS_WB_FLUSH(); /* Configure the MAC */#if (_BYTE_ORDER == _BIG_ENDIAN) AU_MAC_CONTROL = AU_MAC_CONTROL_EM_BIG | AU_MAC_CONTROL_DO;#else AU_MAC_CONTROL = AU_MAC_CONTROL_DO;#endif enetAddr = pDrvCtrl->enetAddr; AU_MAC_ADDRESS_HIGH = (enetAddr[5] << 8) | enetAddr[4]; AU_MAC_ADDRESS_LOW = ((enetAddr[3] << 24) | (enetAddr[2] << 16) | (enetAddr[1] << 8) | (enetAddr[0] << 0)); DRV_LOG (DRV_DEBUG_LOAD, "mac addr %08x %08x\n", AU_MAC_ADDRESS_HIGH, AU_MAC_ADDRESS_LOW, 0, 0, 0, 0); DRV_LOG (DRV_DEBUG_LOAD, "multi addr %08x %08x\n", AU_MULTICAST_HASH_ADDRESS_HIGH, AU_MULTICAST_HASH_ADDRESS_LOW, 0, 0, 0, 0); /* Configure MII */ /* Setup RxD and TxD pointers */ pDrvCtrl->rmdIndex = (AU_RX_ADDRESS(0) >> 2) & 0x03; pDrvCtrl->tmdIndex = (AU_TX_ADDRESS(0) >> 2) & 0x03; pDrvCtrl->tmdLastIndex = pDrvCtrl->tmdIndex;#ifdef AU_PROMISCUOS_MODE /* Handle promiscuous mode */ if (pDrvCtrl->flags & AU_PROMISCUOUS_FLAG) AU_MAC_CONTROL |= AU_MAC_CONTROL_PR;#endif for (i = 0; i < pDrvCtrl->rringSize; ++i) AU_RX_ADDRESS(i) = ((UINT32) AU_CACHE_VIRT_TO_PHYS(pDrvCtrl->pRxMem[i])) | 1; /* Enable transmit and receive */ AU_MAC_CONTROL |= AU_MAC_CONTROL_TE | AU_MAC_CONTROL_RE; SYS_WB_FLUSH(); }/******************************************************************************** auAddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the auAddrAdd() routine) and sets the* device's filter correctly.** RETURNS: N/A*/LOCAL void auAddrFilterSet ( AU_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { ETHER_MULTI * pCurr; UINT8 * pCp; UINT8 byte; UINT32 crc; int len; int count; pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->endObj); while (pCurr != NULL) { pCp = (UINT8 *)&pCurr->addr; crc = 0xffffffff; for (len = AU_LA_LEN; --len >= 0;) { byte = *pCp++; for (count = 0; count < AU_LAF_LEN; count++) { if ((byte & 0x01) ^ (crc & 0x01)) { crc >>= 1; crc = crc ^ AU_CRC_POLYNOMIAL; } else { crc >>= 1; } byte >>= 1; } } /* Just want the 6 most significant bits. */ crc = AU_CRC_TO_LAF_IX (crc); pCurr = END_MULTI_LST_NEXT(pCurr); } }/********************************************************************************* auPollReceive - 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 auPollReceive ( AU_DRV_CTRL * pDrvCtrl, /* device to be initialized */ M_BLK_ID pMblk ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -