📄 usbpegasusend.c
字号:
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 *)pNewCluster); 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, pNewCluster, len, NULL, 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); } 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.** We setup the END's Network memory pool. This code is highly generic and * very simple. We just follow the technique described in netBufLib.** RETURNS: OK or ERROR.* NOMANUAL*/STATUS pegasusEndMemInit ( PEGASUS_DEVICE * pDrvCtrl /* device to be initialized */ ) { /* * This is how we would set up and END netPool using netBufLib(1). * This code is pretty generic. */ if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof (NET_POOL))) == NULL) return (ERROR); pegasusMclBlkConfig.mBlkNum = 512; pegasusClDescTbl[0].clNum = 256; pegasusMclBlkConfig.clBlkNum = pegasusClDescTbl[0].clNum; /* Calculate the total memory for all the M-Blks and CL-Blks. */ pegasusMclBlkConfig.memSize = (pegasusMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) + (pegasusMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long))); if ((pegasusMclBlkConfig.memArea = (char *) memalign (sizeof(long), pegasusMclBlkConfig.memSize)) == NULL) return (ERROR); /* Calculate the memory size of all the clusters. */ pegasusClDescTbl[0].memSize = (pegasusClDescTbl[0].clNum * (PEGASUS_BUFSIZ + 8)) + sizeof(int); /* Allocate the memory for the clusters from cache safe memory. */ pegasusClDescTbl[0].memArea = (char *) cacheDmaMalloc (pegasusClDescTbl[0].memSize); if ((int)pegasusClDescTbl[0].memArea == NULL) { PEGASUS_LOG (PEGASUS_DBG_LOAD,"pegasusEndMemInit:system memory " "unavailable\n", 1, 2, 3, 4, 5, 6); return (ERROR); } /* Initialize the memory pool. */ if (netPoolInit(pDrvCtrl->endObj.pNetPool, &pegasusMclBlkConfig, &pegasusClDescTbl[0], pegasusClDescTblNumEnt, NULL) == ERROR) { PEGASUS_LOG (PEGASUS_DBG_LOAD, "Could not init buffering\n", 1, 2, 3, 4, 5, 6); return (ERROR); } if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool, ETHERMTU, 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; MULTI_TABLE* pList = NULL; 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; /* Then get the list of address to send to the device */ if ((error = etherMultiGet (&pDrvCtrl->endObj.multiList, pList)) == ERROR) return ERROR; /* Set the Filter!!! */ if ((error = pegasusMCastFilterSet (pDrvCtrl, (UINT8 *)pList->pTable, (pList->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 pegasusEndMCastDel ( PEGASUS_DEVICE * pDrvCtrl, /* device pointer */ char * pAddress /* new address to add */ ) { MULTI_TABLE* pList = NULL; if ((pDrvCtrl == NULL) || (pAddress == NULL)) return ERROR; /* First, add this address to the local list */ if (etherMultiDel (&pDrvCtrl->endObj.multiList, pAddress) == ERROR) return ERROR; /* Then get the list of address to send to the device */ if (etherMultiGet (&pDrvCtrl->endObj.multiList, pList) == ERROR) return ERROR; if (pegasusMCastFilterSet (pDrvCtrl, (UINT8 *)pList->pTable, (pList->len) / 6) == ERROR) return ERROR; return (OK); }/***************************************************************************** pegasusEndMCastGet - get the multicast address list for the device** This routine gets the multicast list of whatever the driver* is already listening for.** RETURNS: OK or ERROR.*/LOCAL STATUS pegasusEndMCastGet ( PEGASUS_DEVICE * pDrvCtrl, /* device pointer */ MULTI_TABLE * pTable /* address table to be filled in */ ) { return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable)); }/***************************************************************************** pegasusEndIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, usually OK or ERROR.*/int pegasusEndIoctl ( PEGASUS_DEVICE * pDrvCtrl, /* device receiving command */ int cmd, /* ioctl command code */ caddr_t data /* command argument */ ) { int error = 0; long value; switch (cmd) { case EIOCSADDR : /* Set Device Address */ if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR (&pDrvCtrl->endObj), END_HADDR_LEN (&pDrvCtrl->endObj)); break; case EIOCGADDR : /* Get Device Address */ if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR (&pDrvCtrl->endObj), (char *)data, END_HADDR_LEN (&pDrvCtrl->endObj)); break; case EIOCSFLAGS : /* Set Device Flags */ value = (long)data; if (value < 0) { value = -(--value); END_FLAGS_CLR (&pDrvCtrl->endObj, value); } else { END_FLAGS_SET (&pDrvCtrl->endObj, value); } pegasusEndConfig (pDrvCtrl); break; case EIOCGFLAGS: /* Get Device Flags */ *(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj); break; case EIOCPOLLSTART : /* Begin polled operation */ return EINVAL; /* Not supported */ case EIOCPOLLSTOP : /* End polled operation */ return EINVAL; /* Not supported */ case EIOCGMIB2 : /* return MIB information */ if (data == NULL) return (EINVAL); bcopy ((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data, sizeof(pDrvCtrl->endObj.mib2Tbl)); break; case EIOCGFBUF : /* return minimum First Buffer for chaining */ if (data == NULL) return (EINVAL); *(int *)data = PEGASUS_MIN_FBUF; break; case EIOCMULTIADD : /* Add a Multicast Address */ if (data == NULL) return (EINVAL); if (pegasusEndMCastAdd (pDrvCtrl, (char *)data) == ERROR) return ERROR; break; case EIOCMULTIDEL : /* Delete a Multicast Address */ if (data == NULL) return (EINVAL); if (pegasusEndMCastDel (pDrvCtrl, (char *)data) == ERROR) return ERROR; break; case EIOCMULTIGET : /* Get the Multicast List */ if (data == NULL) return (EINVAL); if (pegasusEndMCastGet (pDrvCtrl, (MULTI_TABLE *)data) == ERROR) return ERROR; break; default: error = EINVAL; } return (error); }/***************************************************************************** usbPegasusEndUnload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -