📄 usbpegasusend.c
字号:
{ PEGASUS_LOG (PEGASUS_DBG_TX," pegasusEndSend : " "Could not allocate memory \n", 0, 0, 0, 0, 0, 0); return ERROR; } /* copy the MBlk chain to a buffer */ noOfBytes = netMblkToBufCopy(pMblk,(char *)pBuf+2,NULL); PEGASUS_LOG (PEGASUS_DBG_LOAD, "pegasusEndSend: %d bytes to be sent.\n", noOfBytes, 0, 0, 0, 0, 0); if (noOfBytes == 0) return ERROR; /* * Padding : how much to pad is decided by trial and error. * Note that we need not add any extra bytes in the buffer. * since we are not using those bytes, they can be any junk * whick is already in the buffer. * We are just interested in the count. */ if (noOfBytes < 60) noOfBytes = 60; /* (Required by the device) Fill in the Length in the first Two Bytes */ *(UINT16 *)pBuf = noOfBytes; /* Transmit the data */ if (pegasusSend (pDrvCtrl, pBuf, noOfBytes+2) == ERROR) return ERROR; PEGASUS_LOG (PEGASUS_DBG_TX, "pegasusEndSend: Pkt submitted for tx.\n", 0, 0, 0, 0, 0, 0); /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1); /* * Cleanup. The driver frees the packet now. */ netMblkClChainFree (pMblk); return (OK); }/***************************************************************************** usbPegasusFreeRtn - pegasus Cluster Free Routine** The pegasus driver does not use the netBufLib to free the cluster blocks.* We do nothing when netBufLib is done with them because we allocate the * our buffers as IRP buffers. The USB stack manages these buffers instead* of netBufLib.** RETURNS: N/A.* NOMANUAL*/void usbPegasusFreeRtn (void) { ; /* We do nothing here. */ }/***************************************************************************** pegasusEndRecv - process the next incoming packet** pegasusRecv is called by the pegasusIRPCallBack() upon successful execution* of an input IRP. This means we got some proper data. This function will be * called with the pointer to be buffer and the length of data.* What we do here is to construct an MBlk strcuture with the data received * and pass it onto the upper layer.** RETURNS: N/A.* NOMANUAL*/STATUS pegasusEndRecv ( PEGASUS_DEVICE * pDrvCtrl, /* device structure */ UINT8 * pData, /* pointer to data buffer */ UINT32 len /* length of data */ ) { char * pNewCluster; /* Clusuter to store the data */ CL_BLK_ID pClBlk; /* Control block to "control" the cluster */ M_BLK_ID pMblk; /* and an MBlk to complete a MBlk contruct */ PEGASUS_LOG (PEGASUS_DBG_RX, "pegasusEndRecv called...Entered len=%d \n", len, 0, 0, 0, 0, 0); /* Add one to our unicast data. */ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1); pNewCluster = (char *)pData; /* Grab a cluster block to marry to the cluster we received. */ if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL) { netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pData); PEGASUS_LOG (PEGASUS_DBG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); PEGASUS_LOG (PEGASUS_DBG_RX, "netClBlkGet...Error\n", 0, 0, 0, 0, 0, 0); goto cleanRXD; } /* * Let's get an M_BLK_ID and marry it to the one in the ring. */ if ((pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) { netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk); netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pData); PEGASUS_LOG (PEGASUS_DBG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); PEGASUS_LOG (PEGASUS_DBG_RX, "mBlkGet...Error\n", 0, 0, 0, 0, 0, 0); goto cleanRXD; } END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1); /* Join the cluster to the MBlock */ if(netClBlkJoin (pClBlk, pData, len, (FUNCPTR) usbPegasusFreeRtn, 0, 0, 0) == NULL) { PEGASUS_LOG (PEGASUS_DBG_MCAST, "netClBlkJoin Failed...Error\n", 0, 0, 0, 0, 0, 0); } if(netMblkClJoin (pMblk, pClBlk) == NULL) { PEGASUS_LOG (PEGASUS_DBG_RX, "mMblkClJoin...Error\n", 0, 0, 0, 0, 0, 0); } bcopy (pData, pData+2, len & ~0xc000); pMblk->mBlkHdr.mData += 2; pMblk->mBlkHdr.mLen = len; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkPktHdr.len = len; /* Call the upper layer's receive routine. */ END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk); cleanRXD: return OK; }/***************************************************************************** pegasusEndMemInit - initialize memory for the device.** Setup the END's Network memory pool. The memory allocation is done once* when the device is first inserted. Cluster block and M-Block memory area's* are created and sorted in global structures:** pegasusMclBlkConfig* and * pegasusClDescTbl* * the netPool is created and stored in the global pointer:** pUsbPegasusNetPool* * All subsequent insertions will reuse these memory area's. ** RETURNS: OK or ERROR.* NOMANUAL*/STATUS pegasusEndMemInit ( PEGASUS_DEVICE * pDrvCtrl /* device to be initialized */ ) { if (usbPegasusEndMemoryIsNotSetup) { pegasusMclBlkConfig.mBlkNum = PEGASUS_M_BLK_NUM; pegasusClDescTbl[0].clNum = PEGASUS_CL_NUM; pegasusMclBlkConfig.clBlkNum = pegasusClDescTbl[0].clNum; /* Calulate the memory size for the mBlks and cBlks. */ pegasusMclBlkConfig.memSize = (pegasusMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) + (pegasusMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof (long))); /* Allocate the memory */ pegasusMclBlkConfig.memArea = \ OSS_MALLOC (pegasusMclBlkConfig.memSize); if (pegasusMclBlkConfig.memArea == NULL) { PEGASUS_LOG (PEGASUS_DBG_LOAD,"pegasusEndMemInit:system memory " "unavailable for mBlk clBlk area\n", 1, 2, 3, 4, 5, 6); return (ERROR); } /* Calulate the memory size for the clusters. */ pegasusClDescTbl[0].memSize = (pegasusClDescTbl[0].clNum * (PEGASUS_BUFSIZ+ 8 + sizeof(int))); /* Allocate the memory */ pegasusClDescTbl[0].memArea = OSS_MALLOC (pegasusClDescTbl[0].memSize); if (pegasusClDescTbl[0].memArea == NULL) { /* Fatal, free the previously alloced area and return */ PEGASUS_LOG (PEGASUS_DBG_LOAD,"pegasusEndMemInit:system memory " "unavailable for cluster area\n", 1, 2, 3, 4, 5, 6); OSS_FREE (pegasusMclBlkConfig.memArea); return (ERROR); } /* * If we've made it here both memory area's have been succesfully * alloc'd, now initialize the memory pool */ /* Allocate an END netPool */ pUsbPegasusNetPool = OSS_MALLOC (sizeof (NET_POOL)); if (pUsbPegasusNetPool == NULL) { /* Fatal, free the previously alloced areas and return */ PEGASUS_LOG (PEGASUS_DBG_LOAD,"pegasusEndMemInit:system memory " "unavailable for netPool\n", 1, 2, 3, 4, 5, 6); OSS_FREE (pegasusMclBlkConfig.memArea); OSS_FREE (pegasusClDescTbl[0].memArea); return (ERROR); } /* Now initialize the pool */ if (netPoolInit (pUsbPegasusNetPool, &pegasusMclBlkConfig, &pegasusClDescTbl[0], pegasusClDescTblNumEnt, NULL) == ERROR) { /* Fatal, free the previously alloced areas and return */ PEGASUS_LOG (PEGASUS_DBG_LOAD, "Could not init buffering\n", 1, 2, 3, 4, 5, 6); OSS_FREE (pegasusMclBlkConfig.memArea); OSS_FREE (pegasusClDescTbl[0].memArea); return (ERROR); } /* * Mark the memory setup flag as false so we don't try to * setup memory again. */ usbPegasusEndMemoryIsNotSetup = FALSE; } /* end of initial memory setup */ pDrvCtrl->endObj.pNetPool = pUsbPegasusNetPool; if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool, PEGASUS_BUFSIZ, FALSE)) == NULL) { PEGASUS_LOG (PEGASUS_DBG_LOAD, "netClPoolIdGet() not successfull \n", 1, 2, 3, 4, 5, 6); return (ERROR); } PEGASUS_LOG (PEGASUS_DBG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6); return OK; }/***************************************************************************** pegasusEndConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous/ broadcast etc modes, and * changing the multicast interface list.** RETURNS: N/A.*/LOCAL STATUS pegasusEndConfig ( PEGASUS_DEVICE * pDrvCtrl /* device to be re-configured */ ) { UINT8 bitmap = 0x00; MULTI_TABLE * pList = NULL; /* Set the modes asked for. */ if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_PROMISC) { PEGASUS_LOG (PEGASUS_DBG_IOCTL, "Setting Promiscuous mode on!\n", 1, 2, 3, 4, 5, 6); bitmap |= PACKET_TYPE_PROMISCOUS; } if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_MULTICAST) { PEGASUS_LOG (PEGASUS_DBG_IOCTL, "Setting Multicast mode On!\n", 1, 2, 3, 4, 5, 6); bitmap |= PACKET_TYPE_MULTICAST; } if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_ALLMULTI) { PEGASUS_LOG (PEGASUS_DBG_IOCTL, "Setting ALLMULTI mode On!\n", 1, 2, 3, 4, 5, 6); bitmap |= PACKET_TYPE_ALL_MULTICAST; } if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_BROADCAST) { PEGASUS_LOG (PEGASUS_DBG_IOCTL, "Setting Broadcast mode On!\n", 1, 2, 3, 4, 5, 6); bitmap |= PACKET_TYPE_BROADCAST; } /* Set up address filter for multicasting. */ if (END_MULTI_LST_CNT(&pDrvCtrl->endObj) > 0) { /* get the list of address to send to the device */ if (etherMultiGet (&pDrvCtrl->endObj.multiList, pList) == ERROR) return ERROR; /* Set the Filter!!! */ if (pegasusMCastFilterSet(pDrvCtrl,(UINT8 *)pList->pTable, (pList->len) / 6) == ERROR) return ERROR; } return OK; }/***************************************************************************** pegasusEndMCastAdd - add a multicast address for the device** This routine adds a multicast address to whatever the chip is already * listening for. The usb Ethernet device specifically requires that even * if we want a small modification (addtion or removal) of the filter list,* we download the entire list to the device. We use the generic etherMultiLib* functions and then call the pegasusMCastFilterSet() to achieve the* functionality.** RETURNS: OK or ERROR.*/LOCAL STATUS pegasusEndMCastAdd ( PEGASUS_DEVICE * pDrvCtrl, /* device pointer */ char * pAddress /* new address to add */ ) { int error; char multiArray [6*6]; MULTI_TABLE multiTable; if ((pDrvCtrl == NULL) || (pAddress == NULL)) return ERROR; /* First, add this address to the local list */ if ((error = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddress)) == ERROR) return ERROR; /* Initialize multi table and array */ multiTable.len = sizeof (multiArray); multiTable.pTable = multiArray; /* Then get the list of address to send to the device */ if ((error = etherMultiGet (&pDrvCtrl->endObj.multiList, &multiTable)) == ERROR) return ERROR; /* Set the Filter!!! */ if ((error = pegasusMCastFilterSet (pDrvCtrl, (UINT8 *) multiTable.pTable, (multiTable.len) / 6)) == ERROR) return ERROR; return (OK); }/***************************************************************************** pegasusEndMCastDel - delete a multicast address for the device** This routine removes a multicast address from whatever the driver * is listening for. The usb Ethernet device specifically requires that even * if we want a small modification (addtion or removal) of the filter list,* we download the entire list to the device. We use the generic etherMultiLib* functions and then call the pegasusMCastFilterSet() to achieve the* functionality.** RETURNS: OK or ERROR.*/LOCAL STATUS pegasusE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -