📄 sn83932end.c
字号:
**/LOCAL STATUS sn83932MCastAddrAdd ( DRV_CTRL * pDrvCtrl, char * pAddr ) { int retVal; /* Sanity Check */ if (pDrvCtrl == NULL) return EINVAL;#ifdef DEBUG SN_LOGMSG ("sn83932McastAddrAdd - %x:%x:%x:%x:%x:%x\n", pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5]);#endif if (pDrvCtrl->endData.nMulti == MAX_MCASTS) return ERROR; retVal = etherMultiAdd (&pDrvCtrl->endData.multiList, pAddr); if (retVal == ENETRESET) { pDrvCtrl->endData.nMulti++; snCamMcastLoad (pDrvCtrl); retVal = OK; }#ifdef DEBUG SN_LOGMSG ("Mcast Done\n", 0,0,0,0,0,0);#endif return ((retVal == OK) ? OK : ERROR); }/********************************************************************************* sn83932MCastAddrDel - delete a multicast address for the device** This routine deletes a multicast address from the current list of* multicast addresses.** NOMANUAL*/LOCAL STATUS sn83932MCastAddrDel ( DRV_CTRL * pDrvCtrl, char * pAddr ) { int retVal; /* Sanity Check */ if (pDrvCtrl == NULL) return EINVAL;#ifdef DEBUG SN_LOGMSG ("sn83932astAddrDel%x:%x:%x:%x:%x:%x\n",pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5]);#endif retVal = etherMultiDel (&pDrvCtrl->endData.multiList, pAddr); if (retVal == ENETRESET) { pDrvCtrl->endData.nMulti--; snCamMcastLoad (pDrvCtrl); retVal = OK; } return ((retVal == OK) ? OK : ERROR); }/********************************************************************************* sn83932MCastAddrGet - get the current multicast address list** This routine returns the current multicast address list in <pTable>** NOMANUAL*/LOCAL STATUS sn83932MCastAddrGet ( DRV_CTRL * pDrvCtrl, MULTI_TABLE * pTable ) { /* Sanity Check */ if (pDrvCtrl == NULL) return EINVAL;#ifdef DEBUG SN_LOGMSG ("sn83932astAddrGet\n", 0, 0, 0, 0, 0, 0);#endif return (etherMultiGet (&pDrvCtrl->endData.multiList, pTable)); }/********************************************************************************* snPollStart - Put the device into polling mode. We first wait until any* outstanding interrupt requests are processed normally.** RETURNS: N/A** NOMANUAL*/LOCAL void snPollStart ( DRV_CTRL * pDrvCtrl ) { int intLevel; /* if offline, then only set flag */ if (!pDrvCtrl->online) { pDrvCtrl->flags |= SN_POLLING; return; } if (pDrvCtrl->flags & SN_POLLING) return; intLevel = intLock(); pDrvCtrl->pDev->imr = 0; /*SL* &= ~SN_IMR_DATA; */ /* Mark device as polling */ pDrvCtrl->flags |= SN_POLLING; intUnlock (intLevel); } /********************************************************************************* snPollStop - Put the device into interrupt mode. This is the default mode * for the device. Nothing is done if the device is not in polling mode. ** RETURNS: N/A**/LOCAL void snPollStop ( DRV_CTRL *pDrvCtrl ) { int intLevel; intLevel = intLock(); /* Mark device as polling */ pDrvCtrl->flags &= ~SN_POLLING; /* Mask in data interrupts */ pDrvCtrl->pDev->imr = pDrvCtrl->imr;#ifdef LED_DEBUG PutLED ('I', 0);#endif intUnlock (intLevel); } /********************************************************************************* snIfConfig - Config the device according to allowable interface flag* revisions by the application. This is called from within the* Ioctl call to register IF flag changes.** RETURNS: N/A**/LOCAL void snIfConfig ( DRV_CTRL * pDrvCtrl, int flags ) { u_char *pDrvFlags; /* ptr to the device's local flags */ pDrvFlags = &pDrvCtrl->flags; if (flags & IFF_PROMISC) { if (!(*pDrvFlags & SN_PROMISC)) {/* Put device into promiscuous mode */ pDrvCtrl->pDev->rcr |= PRO; *pDrvFlags |= IFF_PROMISC; } } else { if (flags & SN_PROMISC) {/* Turn off promiscuous mode */ pDrvCtrl->pDev->rcr &= ~PRO; *pDrvFlags &= ~IFF_PROMISC; } } if (flags & IFF_ALLMULTI) { if (!(*pDrvFlags & SN_ALLMULTI)) {/* Accept ALL multicast packets */ pDrvCtrl->pDev->rcr |= AMC; *pDrvFlags |= SN_ALLMULTI; } } else { if (flags & SN_ALLMULTI) {/* Filter multicasts according to multicast entries */ pDrvCtrl->pDev->rcr &= ~AMC; *pDrvFlags &= ~SN_ALLMULTI; } } }/*============================================================================* * T R A N S M I T R O U T I N E S *============================================================================*//********************************************************************************* sn83932Send - the driver send routine** This routine takes a NET_BUFFER and sends off the data within the NET_BUFFER.* The data must already have the addressing information properly installed* in it. This is done by a higher layer. The last arguments are a free* routine to be called when the device is done with the buffer and a pointer* to the argument to pass to the free routine. Supports NET_BUFFER chaining. ** RETURNS: OK or ERROR.* NOMANUAL*/LOCAL STATUS sn83932Send ( DRV_CTRL * pDrvCtrl, /* device record ptr */ M_BLK_ID pMblk /* data to be sent */ ) { TX_DESC * pTXD; /* Tx descriptor to be used */ u_long addr; int totalLength = 0; /* keep track of total length * of the mblk chain */ M_BLK_ID pChunk; /* tmp mblk to travel * the chain */ int count =0; BOOL No_Mblk =FALSE; /* set in case all the data * is contained in the first * mblk of a chain */ BOOL Exceed = FALSE; /* set if num of mblks in a * chain exceed max fragments * a tx desc can habdle */ char* pBuf; int intLevel; /* Sanity Check */ if (pDrvCtrl == NULL) return EINVAL;#ifdef LED_DEBUG PutLED ('x',2)#endif if (pDrvCtrl->flags & SN_POLLING) { return (EINVAL); } if (pDrvCtrl->txBlocked) return (END_ERR_BLOCK); /* count the number of cluster in the chain */ pChunk=pMblk; while(pChunk!= NULL) { if(pChunk->mBlkHdr.mLen > 0) count++; pChunk=pChunk->mBlkHdr.mNext; } if(count >= MAX_TX_FRAGS) { /* allocate a cluster from the cluster pool of MTU size */ pBuf = netClusterGet(pDrvCtrl->endData.pNetPool, pDrvCtrl->pClPoolId[1]); if(pBuf == NULL) { /* if cluster not available free cluster */ netMblkClChainFree(pMblk); END_M2_OUTDISCARDS (&pDrvCtrl->endData); return (EINVAL); }#ifdef PULI_LED_DEBUG PutLED('E',3);#endif Exceed=TRUE; } /*free mblk*/ /* * Obtain exclusive access to transmitter. This is necessary because * we might have more than one stack transmitting at once. */ END_TX_SEM_TAKE (&pDrvCtrl->endData, WAIT_FOREVER); /* See if transmit descriptor is available */ pTXD = pDrvCtrl->pTXDFree; if (pTXD->flag == IN_USE) { /* No room - clean-up & return */#ifdef DEBUG SN_LOGMSG("transmit descriptor in use\n",0,0,0,0,0,0); #endif if(Exceed) netClFree(pDrvCtrl->endData.pNetPool,pBuf); END_M2_OUTDISCARDS (&pDrvCtrl->endData); /* Release the TX semaphore */ END_TX_SEM_GIVE (&pDrvCtrl->endData); intLevel = intLock(); pDrvCtrl->txBlocked = TRUE; intUnlock (intLevel); return (END_ERR_BLOCK); } /* No room */ /* Mark this descriptor as "in use" */ pTXD->flag = IN_USE; pTXD->status = 0; /* * Build a transmit descriptor. * Loop thru each fragment in the mbuf chain and stuff our info. */ /* * loop through the chain until last mblk is pointing to NULL, * consider clusters only if their length is positive number and if not, * get the next mblk */ if(Exceed) { count=0; if(pMblk->mBlkHdr.mData[5] & 0x01) END_M2_OUTNUCAST (&pDrvCtrl->endData); else END_M2_OUTUCAST (&pDrvCtrl->endData); /* * copy all the data in each mblk of the chain to the newly * allocate cluster */ totalLength = netMblkToBufCopy(pMblk,pBuf,NULL); /*Free mblk chain after copying */ netMblkClChainFree(pMblk); CACHE_USER_FLUSH(pBuf,totalLength); /* set the data pointers and the correponding size of each fragment */ addr = (u_long) CACHE_DMA_VIRT_TO_PHYS (pBuf); pTXD->frag [count].frag_ptr0 = (u_long) addr & UMASK; pTXD->frag [count].frag_ptr1 = (u_long) addr >> 16; pTXD->frag [count].frag_size = totalLength; count++; /* Record the buffer's free routine for later invocation */ pDrvCtrl->freeBuf[pTXD->number].pfreeRtn = (FUNCPTR)netClFree; pDrvCtrl->freeBuf[pTXD->number].pSpare1= pDrvCtrl->endData.pNetPool; pDrvCtrl->freeBuf[pTXD->number].pSpare2=pBuf; } else /* * loop through the chain until last mblk is pointing to NULL, * consider clusters only if their length is positive number * and if not, * get the next mblk */ { pChunk =pMblk; for(count=0;pChunk != NULL;) { /* if all the data is contained in the first mblk */ if((pChunk->mBlkHdr.mLen == pMblk->mBlkPktHdr.len) && pChunk==pMblk) No_Mblk=TRUE; if (pChunk->mBlkHdr.mLen <= 0) { pChunk =pChunk->mBlkHdr.mNext; continue; } /* * Check if frame contains a broadcast/multicast destination * address. Update appropriate MIB variable accordingly. */ if ((count == 0) && (pChunk->mBlkHdr.mData[5] & 0x01)) END_M2_OUTNUCAST (&pDrvCtrl->endData); else END_M2_OUTUCAST (&pDrvCtrl->endData);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -