?? esmcend.c
字號:
if (clConfig.memArea == NULL) { free (pDev->endObj.pNetPool); pDev->endObj.pNetPool = NULL; return (ERROR); } clDesc.memArea = (char *) malloc (clDesc.memSize); if (clDesc.memArea == NULL) { free (clConfig.memArea); free (pDev->endObj.pNetPool); pDev->endObj.pNetPool = NULL; return (ERROR); } /* Initialize the net buffer pool with transmit buffers */ if (netPoolInit (pDev->endObj.pNetPool, &clConfig, &clDesc, 1, NULL) == ERROR) { free (clDesc.memArea); free (clConfig.memArea); free (pDev->endObj.pNetPool); pDev->endObj.pNetPool = NULL; return (ERROR); } pDev->clPoolId = clPoolIdGet (pDev->endObj.pNetPool, ESMC_BUFSIZ + pDev->offset, FALSE); DRV_LOG (DRV_DEBUG_FN_TRACE | DRV_DEBUG_MEM_INIT, "%s%d: esmcMemInit: %d clusters\n", (int) DEV_NAME, pDev->unit, clNum, 4, 5, 6); //sleep(2); return (OK); }/******************************************************************************** update_crc - helper routine **/LOCAL unsigned long update_crc(unsigned char byte, unsigned long current_crc){ unsigned int bit; unsigned char ah; unsigned char carry; ah = 0; for(bit = 0 ; bit < 8 ; bit++) { carry = current_crc >> 31; current_crc <<= 1; ah = ((ah << 1) | carry) ^ byte; if( ah & 1 ) current_crc ^= 0x4c11db7; ah >>= 1; byte >>= 1; } return current_crc;} /******************************************************************************** esmcAddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the esmcMCastAdd() routine) and sets the* device's filter correctly.** RETURNS: N/A.*/LOCAL void esmcAddrFilterSet ( ESMC_DEVICE * pDev /* device pointer */ ) { unsigned char *pCp; unsigned long crc; int len; ETHER_MULTI * pCurr; DRV_LOG (DRV_DEBUG_FN_TRACE, "%s%d: esmcAddrFilterSet\n", (int) DEV_NAME, pDev->unit, 3, 4, 5, 6); pDev->mcastFilter[0] = 0x00; pDev->mcastFilter[1] = 0x00; pDev->mcastFilter[2] = 0x00; pDev->mcastFilter[3] = 0x00; pDev->mcastFilter[4] = 0x00; pDev->mcastFilter[5] = 0x00; pDev->mcastFilter[6] = 0x00; pDev->mcastFilter[7] = 0x00; for (pCurr = END_MULTI_LST_FIRST (&pDev->endObj); pCurr != NULL; pCurr = END_MULTI_LST_NEXT(pCurr)) { /* * AUTODIN-II */ pCp = (unsigned char *)&pCurr->addr; crc = 0xffffffff; for (len = 6; --len >= 0;) crc = update_crc(*pCp++, crc); /* Just want the 6 most significant bits. */ crc = crc >> 26; /* Turn on the corresponding bit in the filter. */ pDev->mcastFilter [crc >> 3] |= (1 << (crc & 0x07)); } }/******************************************************************************** esmcConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A.*/LOCAL void esmcConfig ( ESMC_DEVICE * pDev /* device to be re-configured */ ) { USHORT val; USHORT i; DRV_LOG (DRV_DEBUG_FN_TRACE | DRV_DEBUG_CONFIG, "%s%d: esmcConfig: flags=%x\n", (int) DEV_NAME, pDev->unit, pDev->flags, 4, 5, 6); /* reset the chip */ esmcChipReset(pDev); /* get/set interface */ ESMC_SWITCH_BANK (pDev,1); val = READ_WORD(pDev, ESMC_CONFIG); if(pDev->config == ATTACHMENT_DEFAULT) /* EEPROM */ { if (val & ESMC_CFG_AUI_SELECT) /* EEPROM - AUI */ pDev->config = ATTACHMENT_AUI; else /* EEPROM - RJ45 */ { pDev->config = ATTACHMENT_RJ45; WRITE_WORD(pDev,ESMC_CONFIG, val); } } else if (pDev->config == ATTACHMENT_AUI) /* AUI */ { WRITE_WORD (pDev,ESMC_CONFIG, val | ESMC_CFG_AUI_SELECT); } else if (pDev->config == ATTACHMENT_RJ45) /* RJ45 */ { WRITE_WORD (pDev,ESMC_CONFIG, val & ~ESMC_CFG_AUI_SELECT); } if(END_MULTI_LST_CNT(&pDev->endObj) > 0) esmcAddrFilterSet (pDev); if(END_FLAGS_GET(&pDev->endObj) & IFF_PROMISC) { ESMC_SWITCH_BANK (pDev,0); val = READ_WORD(pDev, ESMC_RCR); WRITE_WORD(pDev, ESMC_RCR, val | 0x02 ); DRV_LOG (DRV_DEBUG_CONFIG | DRV_DEBUG_IOCTL, "%s%d: Setting promiscuous mode on!\n", (int) DEV_NAME, pDev->unit, 3, 4, 5, 6); } if(END_FLAGS_GET(&pDev->endObj) & IFF_ALLMULTI) { ESMC_SWITCH_BANK (pDev,0); val = READ_WORD(pDev, ESMC_RCR); WRITE_WORD(pDev, ESMC_RCR, val | 0x04); DRV_LOG (DRV_DEBUG_CONFIG | DRV_DEBUG_IOCTL, "%s%d: Setting all multicast mode on!\n", (int) DEV_NAME, pDev->unit, 3, 4, 5, 6); } /* Program ethernet address */ ESMC_SWITCH_BANK (pDev,1); for(i = 0 ; i < 6 ; i+= 2) { val = pDev->enetAddr[i] | (pDev->enetAddr[i+1] << 8); WRITE_WORD (pDev,ESMC_ADDR_0 + i ,val); } /* Program multicast mask */ ESMC_SWITCH_BANK (pDev,3); for(i = 0 ; i < 8 ; i+=2) { val = pDev->mcastFilter[i] | (pDev->mcastFilter[i+1] << 8); WRITE_WORD (pDev, ESMC_MULTICAST0 + i,val); } ESMC_SWITCH_BANK (pDev,2); return; }/******************************************************************************** esmcPollStart - start polled mode operations** RETURNS: OK or ERROR.*/LOCAL STATUS esmcPollStart ( ESMC_DEVICE *pDev ) { int oldLevel; DRV_LOG (DRV_DEBUG_FN_TRACE | DRV_DEBUG_POLL, "%s%d: esmcPollStart\n", (int) DEV_NAME, pDev->unit, 3, 4, 5, 6); oldLevel = intLock (); ESMC_SWITCH_BANK (pDev,2); WRITE_WORD(pDev,ESMC_INTERRUPT_, 0); /* mask all interrupts */ pDev->flags |= END_POLLING; intUnlock (oldLevel); return (OK); }/******************************************************************************** esmcPollStop - stop polled mode operations** This function terminates polled mode operation. The device returns to* interrupt mode.** The device interrupts are enabled, the current mode flag is switched* to indicate interrupt mode and the device is then reconfigured for* interrupt operation.** RETURNS: OK or ERROR.*/LOCAL STATUS esmcPollStop ( ESMC_DEVICE *pDev ) { int oldLevel; DRV_LOG (DRV_DEBUG_FN_TRACE | DRV_DEBUG_POLL, "%s%d: esmcPollStop\n", (int) DEV_NAME, pDev->unit, 3, 4, 5, 6); oldLevel = intLock (); ESMC_SWITCH_BANK (pDev,2); /* int enable */ WRITE_WORD (pDev, ESMC_INTERRUPT_, pDev->imask); pDev->flags &= ~END_POLLING; intUnlock (oldLevel); return (OK); }/********************************************************************************* esmcIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, usually OK or ERROR.*/LOCAL int esmcIoctl ( END_OBJ * pObj, /* device receiving command */ int cmd, /* ioctl command code */ caddr_t data /* command argument */ ) { ESMC_DEVICE *pDev = (ESMC_DEVICE *)pObj; int error = 0; long value; DRV_LOG (DRV_DEBUG_FN_TRACE | DRV_DEBUG_IOCTL, "%s%d: esmcIoctl: cmd=0x%0x\n", (int) DEV_NAME, pDev->unit, cmd, 4, 5, 6); //DRV_LOG (DRV_DEBUG_FN_TRACE | DRV_DEBUG_IOCTL, "DEBUG : EIOCGNPT = 0x%x\n",EIOCGNPT,2,3,4,5,6);// DRV_LOG (DRV_DEBUG_FN_TRACE | DRV_DEBUG_IOCTL, \// "EIOCSADDR = 0x%x, \// EIOCGADDR = 0x%x, \// EIOCSADDR = 0x%x, \// EIOCGFLAGS = 0x%x, \// EIOCPOLLSTART = 0x%x, \// EIOCPOLLSTOP = 0x%x, \// \n", \// EIOCGADDR, EIOCGADDR, EIOCSADDR, EIOCGFLAGS, EIOCPOLLSTART,EIOCPOLLSTOP);// // DRV_LOG (DRV_DEBUG_FN_TRACE | DRV_DEBUG_IOCTL, \// "EIOCGMIB2 = 0x%x, \// EIOCGHDRLEN = 0x%x,\n", \// EIOCGMIB2, EIOCGHDRLEN,3,4,5,6); switch ((unsigned)cmd) { case EIOCSADDR: /* set MAC address */ if (data == NULL) error = EINVAL; else { bcopy ((char *)data, (char *)END_HADDR(&pDev->endObj), END_HADDR_LEN(&pDev->endObj)); } DRV_LOG(DRV_DEBUG_IOCTL, "%s%d: EIOCSADDR result = %d\n", (int) DEV_NAME, pDev->unit, error, 4, 5, 6); break; case EIOCGADDR: /* get MAC address */ if (data == NULL) error = EINVAL; else { bcopy ((char *)END_HADDR(&pDev->endObj), (char *)data, END_HADDR_LEN(&pDev->endObj)); } DRV_LOG (DRV_DEBUG_IOCTL, "%s%d: EIOCGADDR result = %d\n", (int) DEV_NAME, pDev->unit, error, 4, 5, 6); break; case EIOCSFLAGS: /* set (or clear) flags */ value = (long)data; if (value < 0) { value = -value; value--; END_FLAGS_CLR (&pDev->endObj, value); } else { END_FLAGS_SET (&pDev->endObj, value); } DRV_LOG (DRV_DEBUG_IOCTL, "%s%d: EIOCSFLAGS flags = 0x%0x\n", (int) DEV_NAME, pDev->unit, value, 4, 5, 6); esmcConfig (pDev); break; case EIOCGFLAGS: /* get flags */ *(int *)data = END_FLAGS_GET(&pDev->endObj); DRV_LOG (DRV_DEBUG_IOCTL, "%s%d: EIOCGFLAGS flags = 0x%0x\n", (int) DEV_NAME, pDev->unit, *(int *)data, 4, 5, 6); break; case EIOCPOLLSTART: /* Begin polled operation */ DRV_LOG (DRV_DEBUG_IOCTL, "%s%d: EIOCPOLLSTART\n", (int) DEV_NAME, pDev->unit, 3, 4, 5, 6); esmcPollStart (pDev); break; case EIOCPOLLSTOP: /* End polled operation */ DRV_LOG (DRV_DEBUG_IOCTL, "%s%d: EIOCPOLLSTOP\n", (int) DEV_NAME, pDev->unit, 3, 4, 5, 6); esmcPollStop (pDev); break; case EIOCGMIB2: /* return MIB information */ if (data == NULL) error = EINVAL; else { bcopy((char *)&pDev->endObj.mib2Tbl, (char *)data, sizeof(pDev->endObj.mib2Tbl)); } DRV_LOG (DRV_DEBUG_IOCTL, "%s%d: EIOCGMIB2 result = %d\n", (int) DEV_NAME, pDev->unit, error, 4, 5, 6); break; case EIOCGHDRLEN: if (data == NULL) error = EINVAL; else *(int *)data = SIZEOF_ETHERHEADER; DRV_LOG (DRV_DEBUG_IOCTL, "%s%d: EIOCGHDRLEN result = %d\n", (int) DEV_NAME, pDev->unit,error, 4, 5, 6); break; default: /* unknown request */ DRV_LOG (DRV_DEBUG_IOCTL, "%s%d: Unknown request\n", (int) DEV_NAME, pDev->unit,3, 4, 5, 6); error = EINVAL; } //sleep(2); return (error); }/******************************************************************************** esmcHandleRcvInt - ISR to handle the receive interrupt** RETURNS: N/A.*/LOCAL void esmcHandleRcvInt( ESMC_DEVICE *pDev){ unsigned char *pBuf;#ifdef ESMC_USE_ISR_COPY CLUSTER_NODE *pNode;#else unsigned short *pCur; unsigned short packetNo; unsigned short statusRx; unsigned short len; unsigned short i; unsigned short val; unsigned long ldata;#endif /* ESMC_USE_ISR_COPY */ int oldLevel; CL_BLK_ID pClBlk; M_BLK_ID pMblk; /* MBLK to send upstream */ DRV_LOG (DRV_DEBUG_FN_TRACE | DRV_DEBUG_RX, "%s%d: esmcHandleRcvInt\n", (int) DEV_NAME, pDev->unit, 3, 4, 5, 6);#ifdef ESMC_USE_ISR_COPY /* Loop until busy queue is empty */ while (lstCount(&pDev->busyClusters)) { /* Fetch the next busy cluster node */ oldLevel = intLock(); pNode = (CLUSTER_NODE *) lstGet(&pDev->busyClusters); intUnlock(oldLevel); if (pNode == NULL) break; /* Get the cluster pointer */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -