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

📄 veriphy.c

📁 Vitesse 24port gigabit Switch Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/*

    Copyright (c) 2004-2005 Vitesse Semiconductor Corporation "Vitesse".  
    All Rights Reserved.  Unpublished rights reserved under the copyright laws
    of the United States of America, other countries and international treaties.
    The software is provided without a fee. Permission to use, copy, store and 
    modify, the software and its source code is granted. Permission to integrate
    into other products, disclose, transmit and distribute the software in an
    absolute machine readable format (e.g. HEX file) is also granted. 

    The source code of the software may not be disclosed, transmitted or
    distributed without the written permission of Vitesse. The software and its
    source code may only be used in products utilizing a Vitesse VSC73xx product.
 
    This copyright notice must appear in any copy, modification, disclosure,
    transmission or distribution of the software. Vitesse retains all ownership,
    copyright, trade secret and proprietary rights in the software.  

    THIS SOFTWARE HAS BEEN PROVIDED "AS IS," WITHOUT EXPRESS OR IMPLIED WARRANTY
    INCLUDING, WITHOUT LIMITATION, IMPLIED WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR USE AND NON-INFRINGEMENT.

*/

#include "common.h"
#include "timer.h"
#include "phydrv.h"
#include "misc2.h"
#include <string.h>
#include "veriphy.h"
#include "main.h"
#include "print.h"
#include "hwconf.h"
#include "hwport.h"
#include "h2reg.h"
#include "h2io.h"

#if TRANSIT_VERIPHY

/* ************************************************************************ **
 *
 *
 * Defines
 *
 *
 *
 * ************************************************************************ */

#define schar   signed char


#define EXCL_COEFFS 0
#define INCL_COEFFS 1

/* Constants used for anomaly search */

#define MAX_ABS_COEFF_ANOM_INVALID_NOISE  70
#define MAX_ABS_COEFF_LEN_INVALID_NOISE  180

/*
** Constants used for interpreting results.
*/
#define NO_CABLE__MAX_TAP 7

#define SAME_LOC__TAP_TOLERANCE 3

/* ************************************************************************ **
 *
 *
 * Typedefs and enums
 *
 *
 *
 * ************************************************************************ */


typedef enum {
    VERIPHY_STATE_IDLE,
    VERIPHY_STATE_INIT_0,
    VERIPHY_STATE_INIT_1,
    VERIPHY_STATE_INIT_LINK_DOWN,
    VERIPHY_STATE_INIT_ANOMSEARCH_0,
    VERIPHY_STATE_ANOMSEARCH_0,
    VERIPHY_STATE_ANOMSEARCH_1,
    VERIPHY_STATE_ANOMSEARCH_2,
    VERIPHY_STATE_DONE
} veriphy_state_t;

/* ************************************************************************ **
 *
 *
 * Prototypes for local functions
 *
 *
 *
 * ************************************************************************ */

static void ffe_init (uchar port_no);
static void xc_search(uchar port_no, uchar subchan, uchar firstCoeff, uchar numCoeffs, uchar locFirst, uchar prefix);
static void checkValidity(uchar port_no, uchar subchan);
static void get_anom_thresh(uchar tap);
static ushort readAvgECNCECVar(uchar port_no, uchar subchan, uchar firstCoeff, uchar numCoeffs, uchar incl_coeffs);
static void enable_EC_var_delay_force_val(uchar port_no, uchar status);
static void set_blip_search(uchar port_no, ushort reg_val);
static void set_EcVarForceIdle(uchar port_no, uchar value);
static void write_rclk125_gating(uchar port_no, uchar value);
static ushort abs_w(short x);

/* ************************************************************************ **
 *
 *
 * Local data
 *
 *
 *
 * ************************************************************************ */

static uchar tsk_state;
static uchar tsk_aux_delay;

static bit tsk_valid_flag;  /* VeriPHY result validity flag */
static bit tsk_linkup_flag; /* linkUp flag indicating VeriPHY search mode */

static uchar tsk_ecAllZerosCount;
static uchar tsk_ecAllZerosCountPrev;
static uchar tsk_ecAllZerosAccum;

static uchar tsk_stat [4];     /* status for pairs A-D (0-3), 4-bit unsigned number, see below */
static uchar tsk_loc [4];      /* length/fault location for pairs A-D (0-3), 8-bit unsgn */
static short tsk_strength [4]; /* fault strength for pairs A-D (0-3), 14-bit signed int. */


static short tsk_log2VGAx256;  /* log2(VGA gain scalefactor)*256 (0 for link-down case) */    

static short tsk_thresh[2];
static schar tsk_signFlip;


static short idata coeff_tab [8]; /* temporary storage for 8 EC/NC coefficients */

static uchar xdata spyder_icpu_stopped [3] = {0, 0, 0};


/* ************************************************************************ */
void veriphy_start (uchar port_no, veriphy_parms_t *veriphy_parms_ptr)
/* ------------------------------------------------------------------------ --
 * Purpose     :
 * Remarks     : 
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    memset(veriphy_parms_ptr, 0, sizeof(veriphy_parms_t));
    veriphy_parms_ptr->state = VERIPHY_STATE_INIT_0;

    if ((port_no < 8) || (port_no > 15)) {
        if (!spyder_icpu_stopped[port_no / 8]) {
            phy_write(port_no, 31, 0x0010);
            phy_write_masked(port_no, 0, 0, 0x8000);
            phy_write(port_no, 31, 0x0000);

            spyder_icpu_stopped[port_no / 8] = TRUE;

            h2_write(MIIM, 1, MIIMPRES, 0x46);
        }
    }
    else {
        h2_write(MIIM, 0, MIIMPRES, 0x46);
    }

    if ((port_no < 8) || (port_no > 15)) {
        veriphy_parms_ptr->media_sel_save = (phy_read(port_no, 23) >> 6) & 0x03;
        phy_write_masked(port_no, 23, 0x0080, 0x00c0);
    }

    else {
    }
}

/* ************************************************************************ */
void veriphy_done (uchar port_no, veriphy_parms_t *veriphy_parms_ptr)
/* ------------------------------------------------------------------------ --
 * Purpose     :
 * Remarks     : 
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    if ((port_no < 8) || (port_no > 15)) {
        if (spyder_icpu_stopped[port_no / 8]) {
            phy_write(port_no, 31, 0x0010);
            phy_write_masked(port_no, 0, 0x8000, 0x8000);
            phy_write(port_no, 31, 0x0000);

            spyder_icpu_stopped[port_no / 8] = FALSE;

            h2_write(MIIM, 1, MIIMPRES, 0x20);
        }
    }
    else {
        h2_write(MIIM, 0, MIIMPRES, 0x20);
    }

    if ((port_no < 8) || (port_no > 15)) {
        phy_write_masked(port_no, 23, veriphy_parms_ptr->media_sel_save << 6, 0x00c0);
    }
    else {
    }
}


/* ************************************************************************ */
uchar veriphy_run (uchar port_no, veriphy_parms_t *veriphy_parms_ptr)
/* ------------------------------------------------------------------------ --
 * Purpose     :
 * Remarks     : 
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    uchar prev_stat;
    uchar idx;
    uchar subchan;
    uchar result;
    schar vga_gain;

    tsk_state = veriphy_parms_ptr->state;
    tsk_aux_delay = veriphy_parms_ptr->aux_delay;
    tsk_ecAllZerosCount = veriphy_parms_ptr->ecAllZerosCount;
    tsk_ecAllZerosCountPrev = veriphy_parms_ptr->ecAllZerosCountPrev;
    tsk_ecAllZerosAccum = veriphy_parms_ptr->ecAllZerosAccum;
    memcpy(&tsk_stat, &veriphy_parms_ptr->stat, sizeof(tsk_stat));
    memcpy(&tsk_loc, &veriphy_parms_ptr->loc, sizeof(tsk_loc));
    memcpy(&tsk_strength, &veriphy_parms_ptr->strength, sizeof(tsk_strength));
    tsk_log2VGAx256 = veriphy_parms_ptr->log2VGAx256;
    tsk_thresh[0] = veriphy_parms_ptr->thresh[0];
    tsk_thresh[1] = veriphy_parms_ptr->thresh[1];
    tsk_linkup_flag = ((veriphy_parms_ptr->flags & 0x01) != 0);
    tsk_valid_flag = ((veriphy_parms_ptr->flags & 0x02) != 0);
    tsk_signFlip = veriphy_parms_ptr->signFlip;

    switch (tsk_state) {

    case VERIPHY_STATE_INIT_0:
        write_rclk125_gating(port_no, 1); /* Disable RClk125 gating */

        phy_write_ext(port_no, 24, 0x8000);       /* Trigger VeriPHY */
        tsk_state = VERIPHY_STATE_INIT_1;
        result = VERIPHY_WAIT_750_MSEC;
        break;

    case VERIPHY_STATE_INIT_1:
        tsk_linkup_flag = ((phy_read(port_no, 17) & (ushort) 1 << 12) != 0);

        if ((phy_read_ext(port_no, 24) & ((ushort) 1 << 15)) == 0) {
            phy_write_tp_bit(port_no, 12, 0, 1);
            write_rclk125_gating(port_no, 0);  /* Re-enable RClk125 gating */
            result = VERIPHY_DONE_ANOMALY;         /* Link was up, but has gone down after trigger */
        }
        else {
            if (!tsk_linkup_flag) {
                tsk_state = VERIPHY_STATE_INIT_LINK_DOWN;
                tsk_aux_delay = 0;
            } 
            else {
                /* Speed up blip-searches:  EcVarTrainingTime = 56, */
                /*   EcVarTrainingGain = 1, EcVarShowtimeGain = 3 */
                set_blip_search(port_no, 0x0387);

                /* Extract VGA gain for subchannel A */
                phy_read_tr(port_no, 0x0ff0);
                vga_gain = (char) (tr_raw_data[2] >> 4);
                if (tr_raw_data[1] & 0x01) {
                    vga_gain -= 16;
                }
        
                tsk_log2VGAx256 = 750 + (22 * (int) vga_gain) + ((3 * vga_gain + 4) >> 3);

                tsk_state = VERIPHY_STATE_INIT_ANOMSEARCH_0;
            }
            result = VERIPHY_CONTINUE;
        }
        break;

    case VERIPHY_STATE_INIT_LINK_DOWN:
        /* Wait for MrSpeedStatus[1:0] to become 2 (LinkControl1000 asserted) */
        if (((((uchar) phy_read(port_no, 28) >> 3) & 0x03) != 2) && (tsk_aux_delay < 250)) {
            tsk_aux_delay++;
            result = VERIPHY_WAIT_10_MSEC;
        }
        else {

            /* Initialize FFE for link-down operation */
            ffe_init(port_no);

            /* Speed up blip-searches:  EcVarTrainingTime = 56, */
            /*   EcVarTrainingGain = 0, EcVarShowtimeGain = 0 */
            set_blip_search(port_no, 0x0380);
            /* Set EnableECvarDelayForce/Val */
            enable_EC_var_delay_force_val(port_no, TRUE);
            
            tsk_log2VGAx256 = 0;
            tsk_state = VERIPHY_STATE_INIT_ANOMSEARCH_0;
            result = VERIPHY_CONTINUE;
        }
        break;

    case VERIPHY_STATE_INIT_ANOMSEARCH_0:
        tsk_ecAllZerosCount = 0;
        tsk_ecAllZerosAccum = 0;
        // fall through

    case VERIPHY_STATE_ANOMSEARCH_0:
        tsk_ecAllZerosCountPrev = tsk_ecAllZerosCount;

        set_EcVarForceIdle(port_no, 1);
        // tr_raw_write_reg_0_3_4(0); /* EcVar[A-D]InputSel = EC */
        tr_raw_data[0] = 0;
        tr_raw_data[1] = 0;
        tr_raw_data[2] = 0;
        phy_write_tr(port_no, 0x0188);
        set_EcVarForceIdle(port_no, 0);

        tsk_state = VERIPHY_STATE_ANOMSEARCH_1;
        result = VERIPHY_WAIT_500_MSEC;  /* allow blip time to train to anomaly location */
        break;
    case VERIPHY_STATE_ANOMSEARCH_1:
        for (idx = 0; idx < 4; ++idx) {
            // ecVarBestDelay_Check_State = TrRawRead(subchan, 3, 0x20);
            phy_read_tr(port_no, ((ushort) idx << 11) | 0x01c0);
            // if ((ecVarBestDelay_Check_State & 0xff0080) == 0xf00080) {
            if ((tr_raw_data[0] == 0xf0) && (tr_raw_data[2] & 0x80)) {
                tsk_ecAllZerosCount = tsk_ecAllZerosCountPrev + 1;
                tsk_stat[idx] = 0;
                tsk_loc[idx]  = 0;
                tsk_strength[idx] = 0;
            }
        }
        if (tsk_ecAllZerosCount != 0) {
            if (tsk_ecAllZerosCount == tsk_ecAllZerosCountPrev) {
                tsk_ecAllZerosAccum  += tsk_ecAllZerosCount - 1;
                tsk_ecAllZerosCount   = 0;
                tsk_ecAllZerosCountPrev   = 0;
            }
            if (!tsk_linkup_flag) {
                ffe_init(port_no);
            }
        }
        if (tsk_ecAllZerosCount != tsk_ecAllZerosCountPrev) {
            if ((tsk_ecAllZerosAccum + tsk_ecAllZerosCount) < 10) {
                tsk_state = VERIPHY_STATE_ANOMSEARCH_0;
                result = VERIPHY_CONTINUE;
            }
            else {
                tsk_state = VERIPHY_STATE_DONE; /* pnc */
                result = VERIPHY_CONTINUE;
            }
        }
        else {
            tsk_state = VERIPHY_STATE_ANOMSEARCH_2;
            result = VERIPHY_WAIT_200_MSEC; /* allow blip time to train to anomaly location */
        }
        break;

    case VERIPHY_STATE_ANOMSEARCH_2:
        for (subchan = 0; subchan < 4; ++subchan) {
            prev_stat = tsk_stat[subchan];

            if (prev_stat < 8 || prev_stat >= 12) { /* Keep cross-pair shorts */
                tsk_signFlip = 0;
                // ecVarBestDelay_Check_State = TrRawRead(subchan, 3, 0x20);
                phy_read_tr(port_no, ((ushort) subchan << 11) | 0x01c0);
                // if (ecVarBestDelay_Check_State & 128) {     /*found anything? */
                if (tr_raw_data[2] & 128) {     /*found anything? */
                    /* ecVarBestDelay signals something really found (maybe < thresh) */
                    // ecVarDelay = (uchar) high_w(ecVarBestDelay_Check_State);
                    idx = 72 + tr_raw_data[0];
                    get_anom_thresh(idx + 4);
                    xc_search(port_no, subchan, 72, 8, idx, 0);
                    if ((prev_stat == 0) && (tsk_stat[subchan] != 0)) {
                        checkValidity(port_no, subchan);
                        prev_stat = tsk_stat[subchan];
                    }
                }
                for (idx = 72 - 8; idx >= 8; idx -= 8) {
                    get_anom_thresh(idx + 4);
                    xc_search(port_no, subchan, idx, 8, idx, 0);
                    if ((prev_stat == 0) && (tsk_stat[subchan] != 0)) {
                        checkValidity(port_no, subchan);
                        prev_stat = tsk_stat[subchan];
                    }
                }
                /* for EC, conditionally extend search down to 6th tap */
                get_anom_thresh(6);
                xc_search(port_no, subchan, 4, 4, 4, 6);
                if ((prev_stat == 0) && (tsk_stat[subchan] != 0)) {
                    checkValidity(port_no, subchan);
                }
            }
        }
        // fall through

    case VERIPHY_STATE_DONE:
        /* 
        ** Restore PHY to normal (non-VeriPHY) operation
        */

        /*- Restore blip-searches to default:  EcVarTrainingTime = 244, */
        /*-            EcVarTrainingGain = 1, EcVarShowtimeGain = 3    */
        set_blip_search(port_no, 0x0f47);

        phy_write_tp_bit(port_no, 12, 0, 1); // Luton 


        if (!tsk_linkup_flag) {
            tsk_valid_flag = TRUE;

            enable_EC_var_delay_force_val(port_no, FALSE);
        }

⌨️ 快捷键说明

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