📄 velocity_hw.c
字号:
/* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * * This software is copyrighted by and is the sole property of * VIA Networking Technologies, Inc. This software may only be used * in accordance with the corresponding license agreement. Any unauthorized * use, duplication, transmission, distribution, or disclosure of this * software is expressly forbidden. * * This software is provided by VIA Networking Technologies, Inc. "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 VIA Networking Technologies, Inc. * be liable for any direct, indirect, incidental, special, exemplary, or * consequential damages. * * * File: velocity_hw.c * * Purpose: Describe what this file is going to do. * * Author: Guard Kuo * * Date: May 04, 2005 * * Functions: * List all the functions this module provides. * (This section is omitted in the header of ".h" files) * * Revision History: * mm-dd-yyyy Revisor's Name: Whenever you made some changes, * leave a record here. * (This section is omitted in the header of ".h" files) * */ #include "velocity_hw.h"#include "velocity_mac.h"#include "velocity_desc.h"#include "velocity_mii.h"void velocity_shutdown(struct velocity_hw *hw) { mac_disable_int(hw); CSR_WRITE_4(hw, CR0_STOP,MAC_REG_CR0_SET); CSR_WRITE_2(hw, 0xFFFF, MAC_REG_TDCSR_CLR); CSR_WRITE_1(hw, 0xFF, MAC_REG_RDCSR_CLR); SafeDisableMiiAutoPoll(hw); mac_clear_isr(hw);}BOOL velocity_soft_reset(struct velocity_hw *hw) { int i=0; CSR_WRITE_4(hw, CR0_SFRST, MAC_REG_CR0_SET); for (i=0;i<W_MAX_TIMEOUT;i++) { udelay(5); if (!DWORD_REG_BITS_IS_ON(hw, CR0_SFRST, MAC_REG_CR0_SET)) break; } if (i==W_MAX_TIMEOUT) { CSR_WRITE_4(hw, CR0_FORSRST, MAC_REG_CR0_SET); /* delay 2ms */ mdelay(2); } return TRUE;}void enable_flow_control_ability(struct velocity_hw *hw){ switch (hw->sOpts.flow_cntl) { case FLOW_CNTL_DEFAULT: if (BYTE_REG_BITS_IS_ON(hw, PHYSR0_RXFLC, MAC_REG_PHYSR0)) CSR_WRITE_4(hw, CR0_FDXRFCEN, MAC_REG_CR0_SET); else CSR_WRITE_4(hw, CR0_FDXRFCEN, MAC_REG_CR0_CLR); if (BYTE_REG_BITS_IS_ON(hw, PHYSR0_TXFLC, MAC_REG_PHYSR0)) CSR_WRITE_4(hw, CR0_FDXTFCEN, MAC_REG_CR0_SET); else CSR_WRITE_4(hw, CR0_FDXTFCEN, MAC_REG_CR0_CLR); break; case FLOW_CNTL_TX: CSR_WRITE_4(hw, CR0_FDXTFCEN, MAC_REG_CR0_SET); CSR_WRITE_4(hw, CR0_FDXRFCEN, MAC_REG_CR0_CLR); break; case FLOW_CNTL_RX: CSR_WRITE_4(hw, CR0_FDXRFCEN, MAC_REG_CR0_SET); CSR_WRITE_4(hw, CR0_FDXTFCEN, MAC_REG_CR0_CLR); break; case FLOW_CNTL_TX_RX: CSR_WRITE_4(hw, CR0_FDXTFCEN, MAC_REG_CR0_SET); CSR_WRITE_4(hw, CR0_FDXRFCEN, MAC_REG_CR0_SET); break; case FLOW_CNTL_DISABLE: CSR_WRITE_4(hw, CR0_FDXRFCEN, MAC_REG_CR0_CLR); CSR_WRITE_4(hw, CR0_FDXTFCEN, MAC_REG_CR0_CLR); break; default: break; }}U32 check_connectiontype(struct velocity_hw *hw){ U32 status = 0; U8 byPHYSR0; byPHYSR0 = CSR_READ_1(hw, MAC_REG_PHYSR0); if(!(byPHYSR0 & PHYSR0_LINKGD)) { status |= VELOCITY_LINK_FAIL; return status; } if(hw->sOpts.spd_dpx == SPD_DPX_AUTO){ status |= VELOCITY_AUTONEG_ENABLE; if (byPHYSR0 & PHYSR0_FDPX) status |= VELOCITY_DUPLEX_FULL; if (byPHYSR0 & PHYSR0_SPDG) status |= VELOCITY_SPEED_1000; if (byPHYSR0 & PHYSR0_SPD10) status |= VELOCITY_SPEED_10; else status |= VELOCITY_SPEED_100; } else{ switch(hw->sOpts.spd_dpx) { case SPD_DPX_100_HALF: status |= VELOCITY_SPEED_100; break; case SPD_DPX_100_FULL: status |= VELOCITY_SPEED_100|VELOCITY_DUPLEX_FULL; break; case SPD_DPX_10_HALF: status |= VELOCITY_SPEED_10; break; case SPD_DPX_10_FULL: status |= VELOCITY_SPEED_10|VELOCITY_DUPLEX_FULL; break; default: status = 0; } } return status;}U32 mii_check_media_mode(struct velocity_hw *hw){ U32 status = 0; U16 wANAR; if (!MII_REG_BITS_IS_ON(BMSR_LNK,MII_REG_BMSR, hw)) status |= VELOCITY_LINK_FAIL; if (MII_REG_BITS_IS_ON(G1000CR_1000FD, MII_REG_G1000CR, hw)) status |= (VELOCITY_SPEED_1000|VELOCITY_DUPLEX_FULL); else if (MII_REG_BITS_IS_ON(G1000CR_1000, MII_REG_G1000CR, hw)) status |= VELOCITY_SPEED_1000; else { velocity_mii_read(hw, MII_REG_ANAR, &wANAR); if (wANAR & ANAR_TXFD) status |= (VELOCITY_SPEED_100|VELOCITY_DUPLEX_FULL); else if (wANAR & ANAR_TX) status |= VELOCITY_SPEED_100; else if (wANAR & ANAR_10FD) status |= (VELOCITY_SPEED_10|VELOCITY_DUPLEX_FULL); else status |= (VELOCITY_SPEED_10); } if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, hw)) { velocity_mii_read(hw, MII_REG_ANAR, &wANAR); if ((wANAR & (ANAR_TXFD|ANAR_TX|ANAR_10FD|ANAR_10)) ==(ANAR_TXFD|ANAR_TX|ANAR_10FD|ANAR_10)) { if (MII_REG_BITS_IS_ON(G1000CR_1000|G1000CR_1000FD, MII_REG_G1000CR, hw)) status |= VELOCITY_AUTONEG_ENABLE; } } return status;}/************************************************************************* MII access , media link mode setting functions************************************************************************/void mii_init(struct velocity_hw *hw, U32 mii_status) { U16 wBMCR; switch (PHYID_GET_PHY_ID(hw->dwPHYId)) { case PHYID_CICADA_CS8201: /* Reset to hardware default */ MII_REG_BITS_OFF((ANAR_ASMDIR|ANAR_PAUSE), MII_REG_ANAR, hw); /* turn on ECHODIS bit in NWay-forced full mode and turn off it in // NWay-forced half mode for NWay-forced v.s. legacy-forced issue */ if (hw->mii_status & VELOCITY_DUPLEX_FULL) MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR, hw); else MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR, hw); /* Turn on Link/Activity LED enable bit for CIS8201 */ MII_REG_BITS_ON(PLED_LALBE, MII_REG_PLED, hw); break; case PHYID_VT3216_32BIT: case PHYID_VT3216_64BIT: /* Reset to hardware default */ MII_REG_BITS_ON((ANAR_ASMDIR|ANAR_PAUSE), MII_REG_ANAR, hw); /* turn on ECHODIS bit in NWay-forced full mode and turn off it in // NWay-forced half mode for NWay-forced v.s. legacy-forced issue */ if (hw->mii_status & VELOCITY_DUPLEX_FULL) MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR, hw); else MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR, hw); break; case PHYID_MARVELL_1000: case PHYID_MARVELL_1000S: /* Assert CRS on Transmit */ MII_REG_BITS_ON(PSCR_ACRSTX,MII_REG_PSCR, hw); /*Reset to hardware default*/ MII_REG_BITS_ON((ANAR_ASMDIR|ANAR_PAUSE),MII_REG_ANAR, hw); break; default: ; } velocity_mii_read(hw, MII_REG_BMCR,&wBMCR); if (wBMCR & BMCR_ISO) { wBMCR &=~BMCR_ISO; velocity_mii_write(hw, MII_REG_BMCR, wBMCR); }}U16 set_mii_flow_control(struct velocity_hw *hw){ /* Enable or Disable PAUSE in ANAR */ switch(hw->sOpts.flow_cntl) { case FLOW_CNTL_DEFAULT: if (PHYID_GET_PHY_ID(hw->dwPHYId) == PHYID_CICADA_CS8201) { /* hardware default PAUSE/ASMDIR value in CIS8201 is (0,0) */ /*MII_REG_BITS_OFF((ANAR_ASMDIR|ANAR_PAUSE), MII_REG_ANAR, hw);*/ return ANAR_ASMDIR|ANAR_PAUSE; } else if ((PHYID_GET_PHY_ID(hw->dwPHYId) == PHYID_VT3216_32BIT) || (PHYID_GET_PHY_ID(hw->dwPHYId) == PHYID_VT3216_64BIT)) { /* hardware default PAUSE/ASMDIR value in VT3216 is (1,1) */ /*MII_REG_BITS_ON((ANAR_ASMDIR|ANAR_PAUSE), MII_REG_ANAR, hw);*/ return ANAR_ASMDIR|ANAR_PAUSE; } else { /* Do nothing */ } break; case FLOW_CNTL_TX: /*MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, hw);*/ /*MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, hw);*/ return ANAR_ASMDIR; break; case FLOW_CNTL_RX: /*MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, hw); MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, hw);*/ return ANAR_PAUSE|ANAR_ASMDIR; break; case FLOW_CNTL_TX_RX: /*MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, hw); MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, hw);*/ return ANAR_PAUSE|ANAR_ASMDIR; break; case FLOW_CNTL_DISABLE: MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, hw); MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, hw); return 0; break; default: return 0; break; } return 0;}/*// Get the media mode stored in EEPROM or module options*/U32 velocity_get_opt_media_mode(struct velocity_hw *hw){ U32 status = 0; switch (hw->sOpts.spd_dpx) { case SPD_DPX_AUTO: status=VELOCITY_AUTONEG_ENABLE; break; case SPD_DPX_100_FULL: status=VELOCITY_SPEED_100|VELOCITY_DUPLEX_FULL; break; case SPD_DPX_10_FULL: status=VELOCITY_SPEED_10|VELOCITY_DUPLEX_FULL; break; case SPD_DPX_100_HALF: status=VELOCITY_SPEED_100; break; case SPD_DPX_10_HALF: status=VELOCITY_SPEED_10; break; } hw->mii_status=status; return status;}BOOL velocity_mii_read(struct velocity_hw *hw, U8 byIdx, PU16 pdata){ WORD ww; /* disable MIICR_MAUTO, so that mii addr can be set normally */ SafeDisableMiiAutoPoll(hw); CSR_WRITE_1(hw, byIdx, MAC_REG_MIIADR); BYTE_REG_BITS_ON(hw, MIICR_RCMD, MAC_REG_MIICR); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(CSR_READ_1(hw, MAC_REG_MIICR) & MIICR_RCMD)) break; } *pdata = CSR_READ_2(hw, MAC_REG_MIIDATA); EnableMiiAutoPoll(hw); if (ww == W_MAX_TIMEOUT) return FALSE; return TRUE;}BOOL velocity_mii_write(struct velocity_hw *hw, BYTE byMiiAddr, WORD wData){ WORD ww; /* disable MIICR_MAUTO, so that mii addr can be set normally */ SafeDisableMiiAutoPoll(hw); /* MII reg offset */ CSR_WRITE_1(hw, byMiiAddr, MAC_REG_MIIADR); /* set MII data */ CSR_WRITE_2(hw, wData, MAC_REG_MIIDATA); /* turn on MIICR_WCMD */ BYTE_REG_BITS_ON(hw, MIICR_WCMD, MAC_REG_MIICR); /* W_MAX_TIMEOUT is the timeout period */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { udelay(5); if (!(CSR_READ_1(hw, MAC_REG_MIICR) & MIICR_WCMD)) break; } EnableMiiAutoPoll(hw); if (ww == W_MAX_TIMEOUT) return FALSE; return TRUE;}void init_flow_control_register(struct velocity_hw *hw) { /* Set {XHITH1, XHITH0, XLTH1, XLTH0} in FlowCR1 to {1, 0, 1, 1} depend on RD=64, and Turn on XNOEN in FlowCR1 */ CSR_WRITE_4(hw, (CR0_XONEN|CR0_XHITH1|CR0_XLTH1|CR0_XLTH0), MAC_REG_CR0_SET); CSR_WRITE_4(hw, (CR0_FDXTFCEN|CR0_FDXRFCEN|CR0_HDXFCEN|CR0_XHITH0), MAC_REG_CR0_CLR); /* Set TxPauseTimer to 0xFFFF */ CSR_WRITE_2(hw, 0xFFFF, MAC_REG_PAUSE_TIMER); /* Initialize RBRDU to Rx buffer count. */ CSR_WRITE_2(hw, hw->sOpts.nRxDescs, MAC_REG_RBRDU);}void mac_get_cam_mask(struct velocity_hw *hw, PU8 pbyMask, VELOCITY_CAM_TYPE cam_type) { int i; /*Select CAM mask*/ BYTE_REG_BITS_SET(hw, CAMCR_PS_CAM_MASK,CAMCR_PS1|CAMCR_PS0, MAC_REG_CAMCR); if (cam_type==VELOCITY_VLAN_ID_CAM) CSR_WRITE_1(hw, CAMADDR_VCAMSL, MAC_REG_CAMADDR); else CSR_WRITE_1(hw, 0, MAC_REG_CAMADDR); /* read mask */ for (i=0;i<8;i++) *pbyMask++ = CSR_READ_1(hw, MAC_REG_MAR+i); /* disable CAMEN */ CSR_WRITE_1(hw, 0, MAC_REG_CAMADDR); /*Select mar*/ BYTE_REG_BITS_SET(hw, CAMCR_PS_MAR,CAMCR_PS1|CAMCR_PS0, MAC_REG_CAMCR);}void mac_set_cam_mask(struct velocity_hw *hw, PU8 pbyMask, VELOCITY_CAM_TYPE cam_type) { int i; /*Select CAM mask*/ BYTE_REG_BITS_SET(hw, CAMCR_PS_CAM_MASK,CAMCR_PS1|CAMCR_PS0, MAC_REG_CAMCR); if (cam_type==VELOCITY_VLAN_ID_CAM) CSR_WRITE_1(hw, CAMADDR_CAMEN|CAMADDR_VCAMSL, MAC_REG_CAMADDR); else CSR_WRITE_1(hw, CAMADDR_CAMEN, MAC_REG_CAMADDR); for (i=0;i<8;i++) { CSR_WRITE_1(hw, *pbyMask++, MAC_REG_MAR+i); } /* disable CAMEN */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -