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

📄 velocity_hw.c

📁 VIA千兆网卡芯片VT6122的linux驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 + -