📄 sn83932end.c
字号:
if (data == NULL) return EINVAL; *(int *)data = MIN_1STXMTBUF_SIZE; break; default:#ifdef DEBUG SN_LOGMSG ("Undefined Command - Return\n", 0, 0, 0, 0, 0, 0);#endif return EINVAL; }#ifdef DEBUG SN_LOGMSG ("Done\n", 0, 0, 0, 0, 0, 0);#endif return 0; }/********************************************************************************* sn83932MCastAddrAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for. * NOMANUAL**/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 = NULL; /* Sanity Check */ if (pDrvCtrl == NULL) { netMblkClChainFree(pMblk); /* free the given mBlk chain */ errno = EINVAL; return (ERROR); }#ifdef LED_DEBUG PutLED ('x',2)#endif /* * 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); if (pDrvCtrl->flags & SN_POLLING) { netMblkClChainFree(pMblk); /* free the given mBlk chain */ errno = EINVAL; END_TX_SEM_GIVE (&pDrvCtrl->endData); return (ERROR); } if (pDrvCtrl->txBlocked) { END_TX_SEM_GIVE (&pDrvCtrl->endData); 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) { END_M2_OUTDISCARDS (&pDrvCtrl->endData); pDrvCtrl->txBlocked = TRUE; END_TX_SEM_GIVE (&pDrvCtrl->endData); return (END_ERR_BLOCK); }#ifdef PULI_LED_DEBUG PutLED('E',3);#endif Exceed=TRUE; } /*free mblk*/ /* 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,(UINT8 *)pBuf); END_M2_OUTDISCARDS (&pDrvCtrl->endData); pDrvCtrl->txBlocked = TRUE; /* Release the TX semaphore */ END_TX_SEM_GIVE (&pDrvCtrl->endData); 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -