📄 rhine_vmns.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, ¶m->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, ¶m->u.mcam[i][0], RHINE_MULTICAST_CAM); } rhine_get_cam_mask(pInfo, ¶m->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) ¶m->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) ¶m->u.vcam[i-param->offset], RHINE_VLAN_ID_CAM); } rhine_get_cam_mask(pInfo, ¶m->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 + -