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

📄 rhine_vmns.c

📁 联想网卡驱动 linux环境下编写 初写驱动的同志参考以下
💻 C
字号:
/***************************************************************************** ***************************************************************************** Copyright (c) 2001 - 2002, VIA Technologies, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without  modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice,     this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice,    this list of conditions and the following disclaimer in the documentation     and/or other materials provided with the distribution. 3. Neither the name of VIA Technologies, Inc. nor the names of its contributors     may be used to endorse or promote products derived from this software     without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ***************************************************************************** ****************************************************************************/#include "rhine.h"#include "rhine_cfg.h"#include "vmns_drv.h"typedef VMNS_DRV_STATUS (*VMNS_IOCTL_FUNCTION) (struct net_device*, PVMNS_DRV_SIOC_HEADER);#define DECLARE_FUNC(x) \	static VMNS_DRV_STATUS x(struct net_device*,PVMNS_DRV_SIOC_HEADER)DECLARE_FUNC(vmns_drv_identify);DECLARE_FUNC(vmns_drv_commit);DECLARE_FUNC(vmns_drv_disconnect);DECLARE_FUNC(vmns_drv_exit_vmns);DECLARE_FUNC(vmns_drv_set_callback);DECLARE_FUNC(vmns_drv_query_status);DECLARE_FUNC(vmns_drv_set_status);DECLARE_FUNC(vmns_drv_set_mcam);DECLARE_FUNC(vmns_drv_get_mcam);DECLARE_FUNC(vmns_drv_set_vcam);DECLARE_FUNC(vmns_drv_set_mode);DECLARE_FUNC(vmns_drv_get_mode);DECLARE_FUNC(vmns_drv_get_vcam);#ifdef vmns_drv_read_regDECLARE_FUNC(vmns_drv_read_reg);#endifstaticstruct {	VMNS_DRV_OPCODE			opcode;	VMNS_IOCTL_FUNCTION 	function;	}   func_table[]	= 	{	{VMNS_DRV_OPCODE_IDENTIFY,  		vmns_drv_identify},	{VMNS_DRV_OPCODE_COMMIT,			vmns_drv_commit},	{VMNS_DRV_OPCODE_DISCONNECT,		vmns_drv_disconnect},	{VMNS_DRV_OPCODE_VMNS_EXIT,			vmns_drv_exit_vmns},	{VMNS_DRV_OPCODE_SET_CALLBACK,		vmns_drv_set_callback},	{VMNS_DRV_OPCODE_SET_MCAM,			vmns_drv_set_mcam},	{VMNS_DRV_OPCODE_GET_MCAM,			vmns_drv_get_mcam},	{VMNS_DRV_OPCODE_SET_VCAM,			vmns_drv_set_vcam},	{VMNS_DRV_OPCODE_GET_VCAM,			vmns_drv_get_vcam},	{VMNS_DRV_OPCODE_SET_MODE,			vmns_drv_set_mode},		{VMNS_DRV_OPCODE_GET_MODE,			vmns_drv_get_mode},			{VMNS_DRV_OPCODE_QUERY_STATUS,		vmns_drv_query_status},	{VMNS_DRV_OPCODE_SET_STATUS,		vmns_drv_set_status},	{VMNS_DRV_OPCODE_LAST,				NULL}};int vmns_process_ioctl(struct net_device* dev, PVMNS_DRV_SIOC_HEADER pParams) {	int i;	for (i=0;func_table[i].opcode!=VMNS_DRV_OPCODE_LAST;i++) 		if (pParams->OpCode==func_table[i].opcode) {			pParams->ret_status=func_table[i].function(dev,pParams);			if (pParams->ret_status==VMNS_DRV_STATUS_OK) 				return 0;			else				return -EAGAIN;						}		return -EOPNOTSUPP;	}static VMNS_DRV_STATUS vmns_drv_identify(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PRHINE_INFO 		pInfo = dev->priv;	pInfo->flags|=RHINE_FLAGS_VMNS_CONNECTED;		memcpy(((PVMNS_DRV_SIOC_IDENTIFY) hdr)->Signature2,		VMNS_DRV_SIGNATURE,strlen(VMNS_DRV_SIGNATURE)+1);			((PVMNS_DRV_SIOC_IDENTIFY) hdr)->version2.major=MAJOR_VERSION;	((PVMNS_DRV_SIOC_IDENTIFY) hdr)->version2.minor=MINOR_VERSION;	((PVMNS_DRV_SIOC_IDENTIFY) hdr)->revisionID = pInfo->byRevId;			return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUS vmns_drv_exit_vmns(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PRHINE_INFO 		pInfo = dev->priv;	if (dev->stop(dev)!=0) 		return VMNS_DRV_STATUS_BUSY;					pInfo->flags &= (~RHINE_FLAGS_VMNS_COMMITTED);	pInfo->flags &= (~RHINE_FLAGS_VMNS_CONNECTED);		pInfo->multicast_limit =32;	return VMNS_DRV_STATUS_OK;		}	static VMNS_DRV_STATUS vmns_drv_commit(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PRHINE_INFO 		pInfo = dev->priv;			if (pInfo->flags & RHINE_FLAGS_VMNS_COMMITTED)		return VMNS_DRV_STATUS_BUSY;			pInfo->flags|=RHINE_FLAGS_VMNS_COMMITTED;	pInfo->multicast_limit -=4;	return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUS vmns_drv_disconnect(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PRHINE_INFO 		pInfo = dev->priv;	PVMNS_DRV_PRIVATE	vpriv=GET_VMNS_PRIVATE(pInfo);	pInfo->flags &=~(RHINE_FLAGS_VMNS_COMMITTED|RHINE_FLAGS_VMNS_CONNECTED);	vpriv->notify=NULL;	pInfo->multicast_limit =32;		return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUS vmns_drv_set_callback(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PRHINE_INFO 		pInfo = dev->priv;	PVMNS_DRV_PRIVATE	vpriv=GET_VMNS_PRIVATE(pInfo);	PVMNS_DRV_SIOC_CALLBACK param=(PVMNS_DRV_SIOC_CALLBACK) hdr;	vpriv->notify=param->func;		return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUS vmns_drv_query_status(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PVMNS_DRV_SIOC_QUERY_STATUS param=(PVMNS_DRV_SIOC_QUERY_STATUS) hdr;	PRHINE_INFO	pInfo=(PRHINE_INFO) dev->priv;	U32	mii_status=rhine_check_media_mode(pInfo);	switch(param->status_id) {	case QUERY_LINK_STATUS:		if (mii_status & RHINE_LINK_FAIL)			param->u.link_status=LINK_FAIL;		else if (mii_status & RHINE_DUPLEX_FULL)			param->u.link_status=LINK_FULL_DUPLEX;		else			param->u.link_status=LINK_HALF_DUPLEX;			break;	case QUERY_SPEED_STATUS:		if (mii_status & RHINE_SPEED_100)			param->u.speed_status=SPEED_100;		else			param->u.speed_status=SPEED_10;		break;	default:		return VMNS_DRV_STATUS_FAIL;	}	return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUS vmns_drv_set_status(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PVMNS_DRV_SIOC_SET_STATUS param=(PVMNS_DRV_SIOC_SET_STATUS) hdr;	switch(param->status_id) {	case SET_LINK_STATUS:		break;	case SET_SPEED_STATUS:		break;	default:		return VMNS_DRV_STATUS_FAIL;	}		return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUSvmns_drv_set_mcam(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PRHINE_INFO 		pInfo = dev->priv;	PVMNS_DRV_SIOC_SET_MCAM param=(PVMNS_DRV_SIOC_SET_MCAM) hdr;	U32 	oldmask;	int 	i;	rhine_get_cam_mask(pInfo, &oldmask, RHINE_MULTICAST_CAM);		if ((param->offset+param->num) >32 ) {		return VMNS_DRV_STATUS_FAIL;			}	for (i=param->offset;i<(param->offset+param->num);i++) {		rhine_set_cam(pInfo, i, &param->u.mcam[i-param->offset][0], 			RHINE_MULTICAST_CAM);		oldmask|=(1<<i);	}		rhine_set_cam_mask(pInfo,(oldmask & param->cam_mask), RHINE_MULTICAST_CAM);		return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUSvmns_drv_get_mcam(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PRHINE_INFO 		pInfo = dev->priv;	PVMNS_DRV_SIOC_GET_MCAM param=(PVMNS_DRV_SIOC_GET_MCAM) hdr;	int i;			if ((param->offset+param->num) >32 ) {		return VMNS_DRV_STATUS_FAIL;			}		for (i=param->offset;i<(param->offset+param->num);i++)  {		rhine_get_cam(pInfo, i, &param->u.mcam[i][0], RHINE_MULTICAST_CAM);	}		rhine_get_cam_mask(pInfo, &param->cam_mask, RHINE_MULTICAST_CAM);			return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUSvmns_drv_set_vcam(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PVMNS_DRV_SIOC_SET_VCAM param=(PVMNS_DRV_SIOC_SET_VCAM) hdr;	PRHINE_INFO 		pInfo = dev->priv;	int i;	U32			oldmask;	rhine_get_cam_mask(pInfo, &oldmask, RHINE_VLAN_ID_CAM);	if ((param->offset+param->num) >32 ) {		return VMNS_DRV_STATUS_FAIL;			}		for (i=param->offset;i<(param->offset+param->num);i++)  {		rhine_set_cam(pInfo, i, (PU8) &param->u.vcam[i-param->offset],					RHINE_VLAN_ID_CAM);		oldmask|=(1<<i);	}	rhine_set_cam_mask(pInfo,(oldmask & param->cam_mask), RHINE_VLAN_ID_CAM);	return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUSvmns_drv_get_vcam(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PRHINE_INFO 		pInfo = dev->priv;	PVMNS_DRV_SIOC_GET_VCAM param=(PVMNS_DRV_SIOC_GET_VCAM) hdr;	int i;		if ((param->offset+param->num) >32 ) {		return VMNS_DRV_STATUS_FAIL;			}	for (i=param->offset;i<param->offset+param->num;i++)  {		rhine_get_cam(pInfo, i, (PU8) &param->u.vcam[i-param->offset],			RHINE_VLAN_ID_CAM);	}	rhine_get_cam_mask(pInfo, &param->cam_mask, RHINE_VLAN_ID_CAM);	return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUSvmns_drv_set_mode(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PRHINE_INFO 			pInfo = dev->priv;	PVMNS_DRV_PRIVATE		vpriv=GET_VMNS_PRIVATE(pInfo);	PVMNS_DRV_SIOC_SET_MODE	param=(PVMNS_DRV_SIOC_SET_MODE) hdr;	vmns_set_mode(dev,vpriv,param->mode);	return VMNS_DRV_STATUS_OK;}static VMNS_DRV_STATUSvmns_drv_get_mode(struct net_device* dev, PVMNS_DRV_SIOC_HEADER hdr) {	PRHINE_INFO 			pInfo = dev->priv;	PVMNS_DRV_PRIVATE		vpriv=GET_VMNS_PRIVATE(pInfo);	PVMNS_DRV_SIOC_GET_MODE	param=(PVMNS_DRV_SIOC_GET_MODE) hdr;	param->mode=vpriv->mode;	return VMNS_DRV_STATUS_OK;}void vmns_set_mode(struct net_device* dev, PVMNS_DRV_PRIVATE vpriv,	unsigned long mode) {			PRHINE_INFO 		pInfo = dev->priv;	PMAC_REGS			pMacRegs=pInfo->pMacRegs;	vpriv->mode=mode;	if (mode & VMNS_DRV_MODE_DISAU)		BYTE_REG_BITS_ON(CR1_DISAU,&pMacRegs->byCR1);	else 		BYTE_REG_BITS_OFF(CR1_DISAU,&pMacRegs->byCR1);		if (mode & VMNS_DRV_MODE_PQEN)		BYTE_REG_BITS_ON(TCR_PQEN,&pMacRegs->byTCR);	else 		BYTE_REG_BITS_OFF(TCR_PQEN,&pMacRegs->byTCR);		if (mode & VMNS_DRV_MODE_RTGOPT)		BYTE_REG_BITS_ON(TCR_RTGOPT,&pMacRegs->byTCR);	else		BYTE_REG_BITS_OFF(TCR_RTGOPT,&pMacRegs->byTCR);				if (mode & VMNS_DRV_MODE_DISAB)		BYTE_REG_BITS_OFF(RCR_AB,&pMacRegs->byRCR);	else		BYTE_REG_BITS_ON(RCR_AB,&pMacRegs->byRCR);		if (mode & VMNS_DRV_MODE_DISAM)		BYTE_REG_BITS_OFF(RCR_AM,&pMacRegs->byRCR);	else		BYTE_REG_BITS_ON(RCR_AM,&pMacRegs->byRCR);}

⌨️ 快捷键说明

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