📄 templateend.c
字号:
* Cleanup. The driver must either free the packet now or * set up a structure so it can be freed later after a transmit * interrupt occurs. */ if (freeNow) netMblkClChainFree (pMblk); return (OK); }/********************************************************************************* templateIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, usually OK or ERROR.*/LOCAL int templateIoctl ( END_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 MAC address */ if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end), END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCGADDR: /* get MAC address */ if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data, END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCSFLAGS: /* set (or clear) flags */ value = (long)data; if (value < 0) { value = -value; value--; END_FLAGS_CLR (&pDrvCtrl->end, value); } else { END_FLAGS_SET (&pDrvCtrl->end, value); } templateConfig (pDrvCtrl); break; case EIOCGFLAGS: /* get flags */ *(int *)data = END_FLAGS_GET(&pDrvCtrl->end); break; case EIOCPOLLSTART: /* Begin polled operation */ templatePollStart (pDrvCtrl); break; case EIOCPOLLSTOP: /* End polled operation */ templatePollStop (pDrvCtrl); break; case EIOCGMIB2: /* return MIB information */ if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl)); break; case EIOCGFBUF: /* return minimum First Buffer for chaining */ if (data == NULL) return (EINVAL); *(int *)data = TEMPLATE_MIN_FBUF; break; default: /* unknown request */ error = EINVAL; } return (error); }/******************************************************************************** templateConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A.*/LOCAL void templateConfig ( END_DEVICE *pDrvCtrl /* device to be re-configured */ ) { /* Set promiscuous mode if it's asked for. */ if (END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC) { DRV_LOG (DRV_DEBUG_IOCTL, "Setting promiscuous mode on!\n", 1, 2, 3, 4, 5, 6); } else { DRV_LOG (DRV_DEBUG_IOCTL, "Setting promiscuous mode off!\n", 1, 2, 3, 4, 5, 6); } /* Set up address filter for multicasting. */ if (END_MULTI_LST_CNT(&pDrvCtrl->end) > 0) { templateAddrFilterSet (pDrvCtrl); } /* TODO - shutdown device completely */ /* TODO - reset all device counters/pointers, etc. */ /* TODO - initialise the hardware according to flags */ return; }/******************************************************************************** templateAddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the endAddrAdd() routine) and sets the* device's filter correctly.** RETURNS: N/A.*/void templateAddrFilterSet ( END_DEVICE *pDrvCtrl /* device to be updated */ ) { ETHER_MULTI* pCurr; pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end); while (pCurr != NULL) { /* TODO - set up the multicast list */ pCurr = END_MULTI_LST_NEXT(pCurr); } /* TODO - update the device filter list */ }/********************************************************************************* templatePollRcv - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device.** RETURNS: OK upon success. EAGAIN is returned when no packet is available.*/LOCAL STATUS templatePollRcv ( END_DEVICE * pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk /* ptr to buffer */ ) { u_short stat; char* pPacket; int len; DRV_LOG (DRV_DEBUG_POLL_RX, "templatePollRcv\n", 1, 2, 3, 4, 5, 6); stat = templateStatusRead (pDrvCtrl); /* TODO - If no packet is available return immediately */ if (!(stat & TEMPLATE_RINT)) { DRV_LOG (DRV_DEBUG_POLL_RX, "templatePollRcv no data\n", 1, 2, 3, 4, 5, 6); return (EAGAIN); } /* Get packet and length from device buffer/descriptor */ pPacket = NULL; /* DUMMY CODE */ len = 64; /* DUMMY CODE */ /* Upper layer must provide a valid buffer. */ if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT))) { DRV_LOG (DRV_DEBUG_POLL_RX, "PRX bad mblk\n", 1, 2, 3, 4, 5, 6); return (EAGAIN); } /* TODO - clear any status bits that may be set. */ /* TODO - Check packet and device for errors */ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); /* TODO - Process device packet into net buffer */ bcopy (pPacket, pMblk->m_data, len); pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */ pMblk->mBlkHdr.mLen = len; /* set the data len */ pMblk->mBlkPktHdr.len = len; /* set the total len */ /* TODO - Done with packet, clean up and give it to the device. */ DRV_LOG (DRV_DEBUG_POLL_RX, "templatePollRcv OK\n", 1, 2, 3, 4, 5, 6); DRV_LOG (DRV_DEBUG_POLL_RX, "templatePollRcv OK\n", 1, 2, 3, 4, 5, 6); return (OK); }/********************************************************************************* templatePollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device.** RETURNS: OK upon success. EAGAIN if device is busy.*/LOCAL STATUS templatePollSend ( END_DEVICE* pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk /* packet to send */ ) { int len; u_short stat; DRV_LOG (DRV_DEBUG_POLL_TX, "templatePollSend\n", 1, 2, 3, 4, 5, 6); /* TODO - test to see if tx is busy */ stat = templateStatusRead (pDrvCtrl); /* dummy code */ if ((stat & TEMPLATE_TINT) == 0) return ((STATUS) EAGAIN); /* TODO - Process the net buffer into a device transmit packet */ len = max (ETHERSMALL, pMblk->m_len); /* TODO - transmit packet */ /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); DRV_LOG (DRV_DEBUG_POLL_TX, "leaving templatePollSend\n", 1, 2, 3, 4, 5, 6); return (OK); }/******************************************************************************* templateMCastAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS templateMCastAdd ( END_DEVICE *pDrvCtrl, /* device pointer */ char* pAddress /* new address to add */ ) { int error; if ((error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress)) == ENETRESET) templateConfig (pDrvCtrl); return (OK); }/******************************************************************************* templateMCastDel - delete a multicast address for the device** This routine removes a multicast address from whatever the driver* is listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS templateMCastDel ( END_DEVICE *pDrvCtrl, /* device pointer */ char* pAddress /* address to be deleted */ ) { int error; if ((error = etherMultiDel (&pDrvCtrl->end.multiList, (char *)pAddress)) == ENETRESET) templateConfig (pDrvCtrl); return (OK); }/******************************************************************************* templateMCastGet - 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 templateMCastGet ( END_DEVICE *pDrvCtrl, /* device pointer */ MULTI_TABLE* pTable /* address table to be filled in */ ) { return (etherMultiGet (&pDrvCtrl->end.multiList, pTable)); }/********************************************************************************* templateStop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS templateStop ( END_DEVICE *pDrvCtrl /* device to be stopped */ ) { STATUS result = OK; END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); /* TODO - stop/disable the device. */ SYS_INT_DISCONNECT (pDrvCtrl, (FUNCPTR)templateInt, (int)pDrvCtrl, &result); if (result == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "Could not disconnect interrupt!\n", 1, 2, 3, 4, 5, 6); } return (result); }/******************************************************************************** templateUnload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.** RETURNS: OK or ERROR.*/LOCAL STATUS templateUnload ( END_DEVICE* pDrvCtrl /* device to be unloaded */ ) { END_OBJECT_UNLOAD (&pDrvCtrl->end); /* TODO - Free any shared DMA memory */ return (OK); }/********************************************************************************* templatePollStart - start polled mode operations** RETURNS: OK or ERROR.*/LOCAL STATUS templatePollStart ( END_DEVICE * pDrvCtrl /* device to be polled */ ) { int oldLevel; oldLevel = intLock (); /* disable ints during update */ /* TODO - turn off interrupts */ pDrvCtrl->flags |= TEMPLATE_POLLING; intUnlock (oldLevel); /* now templateInt won't get confused */ DRV_LOG (DRV_DEBUG_POLL, "STARTED\n", 1, 2, 3, 4, 5, 6); templateConfig (pDrvCtrl); /* reconfigure device */ return (OK); }/********************************************************************************* templatePollStop - 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 templatePollStop ( END_DEVICE * pDrvCtrl /* device to be polled */ ) { int oldLevel; oldLevel = intLock (); /* disable ints during register updates */ /* TODO - re-enable interrupts */ pDrvCtrl->flags &= ~TEMPLATE_POLLING; intUnlock (oldLevel); templateConfig (pDrvCtrl); DRV_LOG (DRV_DEBUG_POLL, "STOPPED\n", 1, 2, 3, 4, 5, 6); return (OK); }/********************************************************************************* templateReset - reset device** RETURNS: N/A.*/LOCAL void templateReset ( END_DEVICE *pDrvCtrl ) { /* TODO - reset the controller */ }/********************************************************************************* templateStatusRead - get current device state/status** RETURNS: status bits.*/LOCAL UINT templateStatusRead ( END_DEVICE *pDrvCtrl ) { /* TODO - read and return status bits/register */ return (0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -