⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lan9118.c

📁 2410平台vxworks下的lan9118驱动。
💻 C
📖 第 1 页 / 共 4 页
字号:
    }    if(initString[0] == EOS) {        bcopy((char *)DRV_NAME, initString, DRV_NAME_LEN);        return NULL;    }	/* allocate the device structure */	pDrvCtrl = (END_DEVICE *)calloc(sizeof(END_DEVICE), 1);	if(pDrvCtrl == NULL) goto errorExit;    pDrvCtrl->unit = 0;    pDrvCtrl->ilevel = LAN9118_INT_LEVEL;    pDrvCtrl->ivec = LAN9118_INT_VECTOR;    pDrvCtrl->resetting = FALSE;	pDrvCtrl->enetAddr[0] = 0x4000;    pDrvCtrl->enetAddr[1] = 0x1b45;    pDrvCtrl->enetAddr[2] = 0x0dd2;	/* initialize the END and MIB2 parts of the structure	 * The M2 element must come from m2Lib.h	 * This lan9118 is set up for a DIX type ethernet device. */	if(	(END_OBJ_INIT(&pDrvCtrl->end, (DEV_OBJ*)pDrvCtrl, DRV_NAME, pDrvCtrl->unit,		&lan9118FuncTable,DRV_DESC) == ERROR)		||		(END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,		(UCHAR*)&(pDrvCtrl->enetAddr[0]), 6, ETHERMTU,END_SPEED) == ERROR)) {		goto errorExit;	}	/* Perform memory allocation/distribution */	if(lan9118MemInit(pDrvCtrl) == ERROR) {        goto errorExit;	}	/* reset and reconfigure the device */	lan9118Reset(pDrvCtrl);	lan9118Config(pDrvCtrl);	/* set the flags to indicate readiness */	END_OBJ_READY(&pDrvCtrl->end, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST);    p_end_device = pDrvCtrl;	return (&(pDrvCtrl->end));errorExit:	if(p_end_device != NULL) {        free((char *)p_end_device);	}	return NULL;}int get_interrupt = 0;int get_event = 0;/* lan9118_interrupt - lan9118 interrupt process in task level. */STATUS lan9118_interrupt    (        END_DEVICE * pDrvCtrl    ){    U32 interrupt_status = 0;    get_interrupt += 1;    /* get the interrupt status. */    interrupt_status = lan9118_reg_read(LAN9118_REG_OFFSET_INT_STS);    if (interrupt_status & 0x00000008){ /* some data in rx fifo. */        /* receive. */        lan9118_receive(pDrvCtrl);        get_event += 1;    }    if (interrupt_status & 0x00004000){        /* receive error. */        printf("RX ERROR!!!\n");        get_event += 1;    }    if (interrupt_status & 0x00002000){        /* transmit error. */        printf("TX ERROR!!!\n");        get_event += 1;    }    lan9118_reg_write(LAN9118_REG_OFFSET_INT_STS, interrupt_status);    return OK;}/* * lan9118Start - start the device * * This function calls BSP functions to connect interrupts and start the * device running in interrupt mode. * * RETURNS: OK or ERROR * */STATUS lan9118Start	(		END_DEVICE* pDrvCtrl	/* device ID */	){    int temp_int;    ringid_rx = rngCreate(sizeof(struct_end_rx_frame)*1024*4);    if (ringid_rx == NULL) {        return ERROR;    }	/* TODO  - start the device, enabling interrupts */	/* enable pins for net interrupt. */	lan9118_pin_enable();	/* install isr. */	if(intConnect(INUM_TO_IVEC(pDrvCtrl->ivec), lan9118Int, (int)pDrvCtrl) == ERROR)	{		return ERROR;	}	END_FLAGS_SET(&pDrvCtrl->end, IFF_UP | IFF_RUNNING);	/* create semaphore for tx. */    semid_lan9118_tx_mux = semBCreate(SEM_Q_FIFO, SEM_FULL);    if(semid_lan9118_tx_mux == NULL) {		return ERROR;	}    /* create semaphore for rx. */    pDrvCtrl->semid_rx = semBCreate(SEM_Q_FIFO, SEM_FULL);    if(pDrvCtrl->semid_rx == NULL) {        semDelete(semid_lan9118_tx_mux);		return ERROR;	}    /* enable interrupt. */	intEnable(pDrvCtrl->ilevel);    /* enable interrupt of lan9118. */    /* enable master interrupt, and irq pin. set irq active fall edge. */    lan9118_reg_write(LAN9118_REG_OFFSET_IRQ_CFG, 0x00000101);	return OK;}/* * lan9118Send - the driver send routine * * This routine takes a M_BLK_ID sends off the data in the M_BLK_ID. * The buffer 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. * * RETURNS: OK, ERROR, or END_ERR_BLOCK. */STATUS lan9118Send	(		END_DEVICE*	pDrvCtrl,	/* device ptr */		M_BLK_ID	pMblk		/* data to send */	){    static UCHAR p_src_buf[END_BUFSIZ];    int	old_level = 0;    int	length = 0;    STATUS	tx_status = ERROR;    semTake(semid_lan9118_tx_mux,WAIT_FOREVER);    if(pDrvCtrl->resetting)	return END_ERR_BLOCK;    END_TX_SEM_TAKE(&pDrvCtrl->end, WAIT_FOREVER);    /* Get data from Mblk to tx buffer. */    length = netMblkToBufCopy(pMblk, (char*)p_src_buf, NULL);    netMblkClChainFree(pMblk);	tx_status = lan9118_send((U32 *)p_src_buf, length);    if(tx_status != length) {		/* transmit failed. */		printf("END_ERR_BLOCK!!!\n");        semGive(semid_lan9118_tx_mux);		return END_ERR_BLOCK;	}    END_TX_SEM_GIVE(&pDrvCtrl->end);	/* Bump the statistics counters. */	END_ERR_ADD(&pDrvCtrl->end, MIB2_OUT_UCAST, +1);    semGive(semid_lan9118_tx_mux);	return OK;}/* * lan9118Ioctl - the driver I/O control routine * * Process an ioctl request. * * RETURNS: A command specific response, usually OK or ERROR. */int lan9118Ioctl	(		END_DEVICE* pDrvCtrl,	/* device receiving command */		int cmd,		/* ioctl command code */		caddr_t data		/* command argument */	){	int error = 0;	long value;	switch((unsigned)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);		}		lan9118Config (pDrvCtrl);		break;	case EIOCGFLAGS:	/* get flags */		*(int *)data = END_FLAGS_GET(&pDrvCtrl->end);		break;	case EIOCPOLLSTART:	/* Begin polled operation */		lan9118PollStart(pDrvCtrl);		break;	case EIOCPOLLSTOP:	/* End polled operation */		lan9118PollStop(pDrvCtrl);		break;	case EIOCGMIB2233:	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 = lan9118_MIN_FBUF;		break;        case EIOCGHDRLEN:		if(data == NULL) return EINVAL;		*(int *)data = EH_SIZE;		break;	default:		/* unknown request */		error = EINVAL;	}	return error;}/* * lan9118PollRcv - routine to receive a packet in polled mode. * * Polled mode operation takes place without any kernel or other OS * services available.  Use extreme care to insure that this code does not * call any kernel services.  Polled mode is only for WDB system mode use. * Kernel services, semaphores, tasks, etc, are not available during WDB * system mode. * * The WDB agent polls the device constantly looking for new data.  Typically * the device has a ring of RFDs to receive incoming packets.  This routine * examines the ring for any new data and copies it to the provided mblk. * The concern here is to keep the device supplied with empty buffers at all * time. * * RETURNS: OK upon success.  EAGAIN is returned when no packet is available. * A return of ERROR indicates a hardware fault or no support for polled mode * at all. */STATUS lan9118PollRcv	(		END_DEVICE*	pDrvCtrl,	/* device to be polled */		M_BLK_ID	pMblk		/* ptr to buffer */	){	return OK;}/* * lan9118PollSend - routine to send a packet in polled mode. * * Polled mode operation takes place without any kernel or other OS * services available.  Use extreme care to insure that this code does not * call any kernel services.  Polled mode is only for WDB system mode use. * Kernel services, semaphores, tasks, etc, are not available during WDB * system mode. * * A typical implementation is to set aside a fixed buffer for polled send * operation.  Copy the mblk data to the buffer and pass the fixed buffer * to the device.  Performance is not a consideration for polled operations. * * An alternate implementation is a synchronous one.  The routine accepts * user data but does not return until the data has actually been sent.  If an * error occurs, the routine returns EAGAIN and the user will retry the request. * * If the device returns OK, then the data has been sent and the user may free * the associated mblk.  The driver never frees the mblk in polled mode. * The calling routine will free the mblk upon success. * * RETURNS: OK upon success.  EAGAIN if device is busy or no resources. * A return of ERROR indicates a hardware fault or no support for polled mode * at all. */STATUS lan9118PollSend	(		END_DEVICE*	pDrvCtrl,	/* device to be polled */		M_BLK_ID	pMblk		/* packet to send */	){	return OK;}/* * lan9118MCastAdd - 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. */STATUS lan9118MCastAdd	(		END_DEVICE* pDrvCtrl,	/* device pointer */		char* pAddress		/* new address to add */	){	int error;	if((error = etherMultiAdd(&pDrvCtrl->end.multiList, pAddress)) == ENETRESET)	{		lan9118Config(pDrvCtrl);	}	return OK;}/* * lan9118MCastDel - 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. */STATUS lan9118MCastDel	(		END_DEVICE* pDrvCtrl,	/* device pointer */		char* pAddress		/* address to be deleted */	){	int error;	if((error = etherMultiDel(&pDrvCtrl->end.multiList, (char*)pAddress)) == ENETRESET)	{		lan9118Config(pDrvCtrl);	}	return OK;}/* * lan9118MCastGet - 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. */STATUS lan9118MCastGet	(		END_DEVICE*	pDrvCtrl,	/* device pointer */		MULTI_TABLE*	pTable		/* address table to be filled in */	){	return(etherMultiGet(&pDrvCtrl->end.multiList, pTable));}/* * lan9118Stop - stop the device * * This function calls BSP functions to disconnect interrupts and stop * the device from operating in interrupt mode. * * RETURNS: OK or ERROR. */STATUS lan9118Stop	(		END_DEVICE* pDrvCtrl	/* device to be stopped */	){    END_FLAGS_CLR(&pDrvCtrl->end, IFF_UP | IFF_RUNNING);    /* TODO - stop/disable the device. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -