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

📄 velocity_hw.c

📁 VIA千兆网卡芯片VT6122的linux驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    CSR_WRITE_1(hw, 0, MAC_REG_CAMADDR);    /*Select CAM mask */    BYTE_REG_BITS_SET(hw, CAMCR_PS_MAR,CAMCR_PS1|CAMCR_PS0,        MAC_REG_CAMCR);}void mac_set_cam(struct velocity_hw *hw, int idx, PU8 addr,    VELOCITY_CAM_TYPE cam_type) {    int i;    /*Select CAM mask*/    BYTE_REG_BITS_SET(hw, CAMCR_PS_CAM_DATA,CAMCR_PS1|CAMCR_PS0, MAC_REG_CAMCR);    idx&=(64-1);    if (cam_type==VELOCITY_VLAN_ID_CAM)        CSR_WRITE_1(hw, CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, MAC_REG_CAMADDR);    else        CSR_WRITE_1(hw, CAMADDR_CAMEN|idx, MAC_REG_CAMADDR);    if (cam_type==VELOCITY_VLAN_ID_CAM)        CSR_WRITE_2(hw, *((PU16) addr), MAC_REG_MAR);    else {        for (i=0;i<6;i++) {            CSR_WRITE_1(hw, *addr++,MAC_REG_MAR+i);        }    }    BYTE_REG_BITS_ON(hw, CAMCR_CAMWR, MAC_REG_CAMCR);    udelay(10);    CSR_WRITE_1(hw, 0, MAC_REG_CAMADDR);    /*Select CAM mask*/    BYTE_REG_BITS_SET(hw, CAMCR_PS_MAR,CAMCR_PS1|CAMCR_PS0, MAC_REG_CAMCR);}void mac_get_cam(struct velocity_hw *hw, int idx, PU8 addr,    VELOCITY_CAM_TYPE cam_type) {    int i;    /*Select CAM mask*/    BYTE_REG_BITS_SET(hw, CAMCR_PS_CAM_DATA,CAMCR_PS1|CAMCR_PS0,        MAC_REG_CAMCR);    idx&=(64-1);    if (cam_type==VELOCITY_VLAN_ID_CAM)        CSR_WRITE_1(hw, CAMADDR_CAMEN | CAMADDR_VCAMSL|idx, MAC_REG_CAMADDR);    else        CSR_WRITE_1(hw, CAMADDR_CAMEN |idx, MAC_REG_CAMADDR);    BYTE_REG_BITS_ON(hw, CAMCR_CAMRD, MAC_REG_CAMCR);    udelay(10);    if (cam_type==VELOCITY_VLAN_ID_CAM)        *((PU16) addr)=CSR_READ_2(hw, MAC_REG_MAR);    else        for (i=0;i<6;i++, addr++)            *((PU8)addr)=CSR_READ_1(hw, MAC_REG_MAR+i);    CSR_WRITE_1(hw, 0, MAC_REG_CAMADDR);    /*Select CAM mask*/    BYTE_REG_BITS_SET(hw, CAMCR_PS_MAR,CAMCR_PS1|CAMCR_PS0,        MAC_REG_CAMCR);}void mac_wol_reset(struct velocity_hw *hw) {	    /* Turn off SWPTAG right after leaving power mode */    BYTE_REG_BITS_OFF(hw, STICKHW_SWPTAG,MAC_REG_STICKHW);    /* clear sticky bits */    BYTE_REG_BITS_OFF(hw, (STICKHW_DS1|STICKHW_DS0),                            MAC_REG_STICKHW);    BYTE_REG_BITS_OFF(hw, CHIPGCR_FCGMII,MAC_REG_CHIPGCR);    BYTE_REG_BITS_OFF(hw, CHIPGCR_FCMODE,MAC_REG_CHIPGCR);    /* disable force PME-enable */    CSR_WRITE_1(hw, WOLCFG_PMEOVR, MAC_REG_WOLCFG_CLR);    /* disable power-event config bit */    CSR_WRITE_2(hw, 0xFFFF, MAC_REG_WOLCR0_CLR);    /* clear power status */    CSR_WRITE_2(hw, 0xFFFF, MAC_REG_WOLSR0_CLR);}void SafeDisableMiiAutoPoll (struct velocity_hw *hw) {    WORD    ww;    /* turn off MAUTO */    CSR_WRITE_1(hw, 0, MAC_REG_MIICR);    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {        udelay(1);        if (BYTE_REG_BITS_IS_ON(hw, MIISR_MIDLE, MAC_REG_MIISR))            break;    }}void EnableMiiAutoPoll(struct velocity_hw* hw) {    int     ii;    CSR_WRITE_1(hw, 0, MAC_REG_MIICR);    CSR_WRITE_1(hw, MIIADR_SWMPL, MAC_REG_MIIADR);    for (ii=0; ii<W_MAX_TIMEOUT; ii++) {        udelay(1);        if (BYTE_REG_BITS_IS_ON(hw, MIISR_MIDLE, MAC_REG_MIISR))            break;    }    CSR_WRITE_1(hw, MIICR_MAUTO, MAC_REG_MIICR);    for (ii=0; ii<W_MAX_TIMEOUT; ii++) {        udelay(1);        if (!BYTE_REG_BITS_IS_ON(hw, MIISR_MIDLE, MAC_REG_MIISR))            break;    }}void velocity_init_cam_filter(struct velocity_hw *hw){    /* turn on MCFG_PQEN, turn off MCFG_RTGOPT */    WORD_REG_BITS_SET(hw, MCFG_PQEN, MCFG_RTGOPT, MAC_REG_MCFG0);    WORD_REG_BITS_ON(hw, MCFG_VIDFR, MAC_REG_MCFG0);    /* Disable all CAM */    memset(hw->abyVCAMMask, 0, sizeof(U8)*8);    memset(hw->abyMCAMMask, 0, sizeof(U8)*8);    mac_set_cam_mask(hw,hw->abyVCAMMask,VELOCITY_VLAN_ID_CAM);    mac_set_cam_mask(hw,hw->abyMCAMMask,VELOCITY_MULTICAST_CAM);    /* Enable first VCAM */    if (hw->flags & VELOCITY_FLAGS_TAGGING) {        /* if Tagging option is enabled and VLAN ID is not zero, then turn on MCFG_RTGOPT also */        if (hw->sOpts.vid != 0)            WORD_REG_BITS_ON(hw, MCFG_RTGOPT, MAC_REG_MCFG0);        mac_set_cam(hw, 0, (PU8)&(hw->sOpts.vid), VELOCITY_VLAN_ID_CAM);        hw->abyVCAMMask[0] |= 1;        mac_set_cam_mask(hw, hw->abyVCAMMask, VELOCITY_VLAN_ID_CAM);    }    else {        U16	wTemp = 0;		mac_set_cam(hw, 0, (PU8)&wTemp, VELOCITY_VLAN_ID_CAM);	    wTemp = 1;		mac_set_cam_mask(hw, (PU8)&(wTemp), VELOCITY_VLAN_ID_CAM);    }}void velocity_update_hw_mibs(struct velocity_hw *hw) {    U32 dwTmp;    int i;    BYTE_REG_BITS_ON(hw, MIBCR_MIBFLSH, MAC_REG_MIBCR);    while (BYTE_REG_BITS_IS_ON(hw, MIBCR_MIBFLSH, MAC_REG_MIBCR));    BYTE_REG_BITS_ON(hw, MIBCR_MPTRINI, MAC_REG_MIBCR);    for (i=0;i<HW_MIB_SIZE;i++) {        dwTmp=CSR_READ_4(hw, MAC_REG_MIBREAD) & 0x00FFFFFFUL;        hw->adwHWMIBCounters[i]+=dwTmp;    }}void velocity_rx_reset(struct velocity_hw *hw){    int         i;    hw->iCurrRDIdx = 0;    /* init state, all RD is chip's */    for(i=0; i<hw->sOpts.nRxDescs; i++)        hw->aRDRing[i].rdesc0 |= cpu_to_le32(RDESC0_OWN);    CSR_WRITE_2(hw, hw->sOpts.nRxDescs, MAC_REG_RBRDU);    CSR_WRITE_4(hw, hw->rd_pool_dma, MAC_REG_RDBASE_LO);    CSR_WRITE_2(hw, 0, MAC_REG_RDINDX);    CSR_WRITE_2(hw, hw->sOpts.nRxDescs-1, MAC_REG_RDCSIZE);}void velocity_print_link_status(struct velocity_hw *hw) {    if (hw->mii_status & VELOCITY_LINK_FAIL) {        VELOCITY_HW_PRT(hw, MSG_LEVEL_INFO, "failed to detect cable link.\n");    }    else {        if (hw->sOpts.spd_dpx == SPD_DPX_AUTO) {            VELOCITY_HW_PRT(hw, MSG_LEVEL_INFO, "Link auto-negotiation");        	if (hw->mii_status & VELOCITY_SPEED_1000)            	VELOCITY_PRT(hw->msglevel, MSG_LEVEL_INFO," speed 1000M bps");	        else if (hw->mii_status & VELOCITY_SPEED_100)    		    VELOCITY_PRT(hw->msglevel, MSG_LEVEL_INFO," speed 100M bps");	        else    		    VELOCITY_PRT(hw->msglevel, MSG_LEVEL_INFO," speed 10M bps");	        if (hw->mii_status & VELOCITY_DUPLEX_FULL)    	        VELOCITY_PRT(hw->msglevel, MSG_LEVEL_INFO, " full duplex\n");        	else            	VELOCITY_PRT(hw->msglevel, MSG_LEVEL_INFO, " half duplex\n");    	}    	else {    		VELOCITY_HW_PRT(hw, MSG_LEVEL_INFO,	"Link forced");            switch(hw->sOpts.spd_dpx) {            	case SPD_DPX_100_HALF:            		VELOCITY_PRT(hw->msglevel, MSG_LEVEL_INFO, " speed 100M bps half duplex\n");            		break;            	case SPD_DPX_100_FULL:            		VELOCITY_PRT(hw->msglevel, MSG_LEVEL_INFO, " speed 100M bps full duplex\n");            		break;            	case SPD_DPX_10_HALF:            		VELOCITY_PRT(hw->msglevel, MSG_LEVEL_INFO, " speed 10M bps half duplex\n");            		break;            	case SPD_DPX_10_FULL:            		VELOCITY_PRT(hw->msglevel, MSG_LEVEL_INFO, " speed 10M bps full duplex\n");            		break;            	default:            		break;			}		}	}}int velocity_set_media_mode(struct velocity_hw *hw, SPD_DPX_OPT spd_dpx){    U16 wANARMask;    U16 wOrigANAR, wOrigG1000CR;    U16 wANAR=0, wG1000CR=0;    U32 status=VELOCITY_LINK_UNCHANGE;    velocity_mii_read(hw, MII_REG_ANAR, &wOrigANAR);    velocity_mii_read(hw, MII_REG_G1000CR, &wOrigG1000CR);    wANARMask = wOrigANAR;    wANARMask &= ~(ANLPAR_ASMDIR|ANLPAR_PAUSE|ANAR_TXFD|ANAR_TX|ANAR_10FD|ANAR_10);    wOrigANAR &= (ANLPAR_ASMDIR|ANLPAR_PAUSE|ANAR_TXFD|ANAR_TX|ANAR_10FD|ANAR_10);    wOrigG1000CR &= (G1000CR_1000FD|G1000CR_1000);    /* Set mii link status */    wANAR = set_mii_flow_control(hw);    if (PHYID_GET_PHY_ID(hw->dwPHYId) == PHYID_CICADA_CS8201) {        MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR, hw);    }        /* if connection type is AUTO */    if (spd_dpx == SPD_DPX_AUTO) {        /*VELOCITY_HW_PRT(hw, MSG_LEVEL_INFO, "Velocity is AUTO mode\n");*/        /* auto */        wANAR |= (ANAR_TXFD|ANAR_TX|ANAR_10FD|ANAR_10);        wG1000CR |= (G1000CR_1000FD|G1000CR_1000);    	/* clear force MAC mode bit */    	BYTE_REG_BITS_OFF(hw, CHIPGCR_FCMODE, MAC_REG_CHIPGCR);        /* set duplex mode of MAC according to duplex mode of MII */        MII_REG_BITS_ON(BMCR_SPEED1G, MII_REG_BMCR, hw);        if(wOrigANAR != wANAR || wOrigG1000CR != wG1000CR) {            wANAR |= wANARMask;            velocity_mii_write(hw, MII_REG_ANAR, wANAR);            MII_REG_BITS_ON(G1000CR_1000FD|G1000CR_1000, MII_REG_G1000CR, hw);            /* enable AUTO-NEGO mode */            MII_REG_BITS_ON((BMCR_AUTO | BMCR_REAUTO), MII_REG_BMCR, hw);                        /* Link changed */            status = VELOCITY_LINK_CHANGE;        }    }    else {        U8  byCHIPGCR;        /* 1. if it's 3119, disable frame bursting in halfduplex mode and        //    enable it in fullduplex mode        // 2. set correct MII/GMII and half/full duplex mode in CHIPGCR        // 3. only enable CD heart beat counter in 10HD mode        // set force MAC mode bit */        BYTE_REG_BITS_ON(hw, CHIPGCR_FCMODE, MAC_REG_CHIPGCR);        byCHIPGCR = CSR_READ_1(hw, MAC_REG_CHIPGCR);        byCHIPGCR &= ~CHIPGCR_FCGMII;        if( spd_dpx == SPD_DPX_100_FULL || spd_dpx == SPD_DPX_10_FULL ){            byCHIPGCR |= CHIPGCR_FCFDX;            CSR_WRITE_1(hw, byCHIPGCR, MAC_REG_CHIPGCR);            /*VELOCITY_HW_PRT(hw, MSG_LEVEL_INFO, "Set Velocity to forced full mode\n");*/            if (hw->byRevId < REV_ID_VT3216_A0)                BYTE_REG_BITS_OFF(hw, TCR_TB2BDIS, MAC_REG_TCR);        }        else {            byCHIPGCR &= ~CHIPGCR_FCFDX;            /*VELOCITY_HW_PRT(hw, MSG_LEVEL_INFO, "Set Velocity to forced half mode\n");*/            CSR_WRITE_1(hw, byCHIPGCR, MAC_REG_CHIPGCR);            if (hw->byRevId < REV_ID_VT3216_A0)                BYTE_REG_BITS_ON(hw, TCR_TB2BDIS, MAC_REG_TCR);        }        /* No force 1000Mbps */        wG1000CR=0;        switch(spd_dpx)        {            case SPD_DPX_100_HALF:                wANAR |= ANLPAR_TX;                break;            case SPD_DPX_100_FULL:                wANAR |= ANLPAR_TXFD;                break;            case SPD_DPX_10_HALF:                wANAR |= ANLPAR_10;                break;            case SPD_DPX_10_FULL:                wANAR |= ANLPAR_10FD;                break;            default:                break;        }                if(wANAR != wOrigANAR || wG1000CR != wOrigG1000CR)        {            wANAR |= wANARMask;            velocity_mii_write(hw, MII_REG_ANAR, wANAR);            MII_REG_BITS_OFF(G1000CR_1000FD|G1000CR_1000, MII_REG_G1000CR, hw);            /* enable AUTO-NEGO mode */            MII_REG_BITS_ON((BMCR_AUTO | BMCR_REAUTO), MII_REG_BMCR, hw);                       /* Link changed */            status = VELOCITY_LINK_CHANGE;        }    }    return status;}void velocity_adaptive_init(struct velocity_hw *hw){    hw->IntMask = INT_MASK_DEF;    /*------------------------------------------------------------    // [1.18] Adaptive Interrupt    // Set Tx Interrupt Suppression Threshold: 31 (0x001F) */    CSR_WRITE_1(hw, CAMCR_PS0, MAC_REG_CAMCR);    CSR_WRITE_2(hw, 0x001F, MAC_REG_ISR_CTL);    /*pInfo->IntMask &= ~(ISR_PTXI | ISR_PTX0I | ISR_PTX1I | ISR_PTX2I | ISR_PTX3I);*/    /* Set Rx Interrupt Suppression Threshold: 31 (0x001F) */    CSR_WRITE_1(hw, CAMCR_PS1, MAC_REG_CAMCR);    CSR_WRITE_2(hw, 0x001F, MAC_REG_ISR_CTL);    /*pInfo->IntMask &= ~ISR_PRXI;*/    /* Select page to interrupt hold timer */    CSR_WRITE_1(hw, 0x00, MAC_REG_CAMCR);    /* Modify IMR */    hw->IntMask &= ~(ISR_PTXI | ISR_PTX0I | ISR_PTX1I | ISR_PTX2I | ISR_PTX3I | ISR_PRXI);    /* Enable Memory-Read-Line, both VT3119 and VT3216    // ==> DCFG1_XMRL = 0 */    BYTE_REG_BITS_OFF(hw, DCFG1_XMRL, MAC_REG_DCFG1);}void velocity_init_register_reset( struct velocity_hw *hw){    /* reset RX to prevent RX pointer not on the 4X location */    velocity_rx_reset(hw);    mac_rx_queue_run(hw);    mac_rx_queue_wake(hw);    CSR_WRITE_4(hw, CR0_STOP, MAC_REG_CR0_CLR);    CSR_WRITE_4(hw, (CR0_DPOLL|CR0_TXON|CR0_RXON|CR0_STRT), MAC_REG_CR0_SET);    if (velocity_set_media_mode(hw,hw->sOpts.spd_dpx)!=VELOCITY_LINK_CHANGE) {        hw->mii_status = check_connectiontype(hw);        velocity_print_link_status(hw);    }    enable_flow_control_ability(hw);    mac_clear_isr(hw);}void velocity_init_register_cold( struct velocity_hw *hw){    int i;    U32 mii_status;    mac_set_rx_thresh(hw, hw->sOpts.rx_thresh);    mac_set_dma_length(hw, hw->sOpts.DMA_length);    CSR_WRITE_1(hw, (WOLCFG_SAM | WOLCFG_SAB), MAC_REG_WOLCFG_SET);    /* back off algorithm use original IEEE standard */    BYTE_REG_BITS_SET(hw, CFGB_OFSET,        (CFGB_CRANDOM | CFGB_CAP | CFGB_MBA | CFGB_BAKOPT),        MAC_REG_CFGB);    /* enable MII auto-polling */    EnableMiiAutoPoll(hw);        velocity_adaptive_init(hw);    CSR_WRITE_4(hw, hw->rd_pool_dma, MAC_REG_RDBASE_LO);    CSR_WRITE_2(hw, hw->sOpts.nRxDescs-1, MAC_REG_RDCSIZE);    mac_rx_queue_run(hw);    mac_rx_queue_wake(hw);    CSR_WRITE_2(hw, hw->sOpts.nTxDescs-1, MAC_REG_TDCSIZE);    for (i=0;i<hw->nTxQueues;i++) {        CSR_WRITE_4(hw, hw->td_pool_dma[i], (MAC_REG_TDBASE_LO+(i*4)) );        mac_tx_queue_run(hw,i);    }    velocity_init_cam_filter(hw);    init_flow_control_register(hw);    CSR_WRITE_4(hw, CR0_STOP, MAC_REG_CR0_CLR);    CSR_WRITE_4(hw, (CR0_DPOLL|CR0_TXON|CR0_RXON|CR0_STRT), MAC_REG_CR0_SET);    mii_status = velocity_get_opt_media_mode(hw);    mac_clear_isr(hw);    mii_init(hw, mii_status);#ifdef LINUX        if (velocity_set_media_mode(hw,hw->sOpts.spd_dpx) != VELOCITY_LINK_CHANGE) {        hw->mii_status = check_connectiontype(hw);        velocity_print_link_status(hw);    }#else    velocity_set_media_mode(hw,hw->sOpts.spd_dpx);#endif    enable_flow_control_ability(hw);    mac_hw_mibs_init(hw);    mac_write_int_mask(hw->IntMask, hw);    mac_clear_isr(hw);}

⌨️ 快捷键说明

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