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

📄 veriphy.c

📁 Vitesse 24port gigabit Switch Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
        else { /*- Link-up mode VeriPHY now completed, read valid bit! */
            delay_1(3 + 1); /* Wait valid flag to complete. 3msec required, so add 1 to be sure */
            if ((phy_read_ext(port_no, 24) & ((ushort) 1 << 14)) != 0) {
                tsk_valid_flag = TRUE;
            }
        }

        /* Re-enable RClk125 gating */
        write_rclk125_gating(port_no, 0);


        if ( (tsk_stat[0] == 4 || tsk_stat[0] == 1) && tsk_loc[0] <= NO_CABLE__MAX_TAP &&
             (tsk_stat[1] == 4 || tsk_stat[1] == 1) && tsk_loc[1] <= NO_CABLE__MAX_TAP &&
             (tsk_stat[2] == 4 || tsk_stat[2] == 1) && tsk_loc[2] <= NO_CABLE__MAX_TAP &&
             (tsk_stat[3] == 4 || tsk_stat[3] == 1) && tsk_loc[3] <= NO_CABLE__MAX_TAP )
        {
            result = VERIPHY_DONE_UNPLUGGED; /* Nothing plugged into jack */
        }
        else
        {
            // Pairs A & B will have to be used to decide the status
            result = (tsk_stat[0] != 0 || tsk_stat[1] != 0);

            // Check if we should ignore pairs C & D
            if ( ( (tsk_loc[2] == tsk_loc[3]                                    ) ||
                   (tsk_loc[2] <  tsk_loc[3] && (tsk_loc[2] + SAME_LOC__TAP_TOLERANCE) >= tsk_loc[3]) ||
                   (tsk_loc[3] <  tsk_loc[2] && (tsk_loc[3] + SAME_LOC__TAP_TOLERANCE) >= tsk_loc[2]) )
              && ( (tsk_stat[2] <= 4 && tsk_stat[3] == tsk_stat[2]) ||
                   (tsk_stat[2] <= 2 && tsk_stat[3] == 4           ) ||
                   (tsk_stat[3] <= 2 && tsk_stat[2] == 4           ) ) )
            {
                // Pairs C & D have compatible anomalies (or lack of anomalies) near
                // the same location. This may occur when plugged into a 10/100
                // Ethernet PHY (or a gigabit National PHY).  As a result, we cannot
                // declare the cable bad based on this configuration of C/D status
            }
            else // Use pairs C & D status to determine good/bad
            {
                result = (result || tsk_stat[2] != 0 || tsk_stat[3] != 0);
            }
            result |= VERIPHY_DONE_MASK;
        }

#if 0
        print_str("port = 0x");
        print_hex_b(port_no);
        print_str(" stat = ");
        print_hex_b(tsk_stat[0]);
        print_str(", ");
        print_hex_b(tsk_stat[1]);
        print_str(", ");
        print_hex_b(tsk_stat[2]);
        print_str(", ");
        print_hex_b(tsk_stat[3]);
        print_str(" loc = ");
        print_hex_b(tsk_loc[0]);
        print_str(", ");
        print_hex_b(tsk_loc[1]);
        print_str(", ");
        print_hex_b(tsk_loc[2]);
        print_str(", ");
        print_hex_b(tsk_loc[3]);
        if (tsk_valid_flag) {
            print_str(" valid");
        }
        else {
            print_str(" not valid");
        }

        print_str(" result = 0x");
        print_hex_b(result);
        print_cr_lf();
#endif
        break;
    default:
        result = VERIPHY_DONE_ANOMALY;
        break;
    }

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

    return result;
}

static void checkValidity(uchar port_no, uchar subchan)
{
    uchar retry;
    ushort maxAbsCoeff;
#define RETRY_MAX_ABS_COEFF_LT (ushort) 1
//#define MAX_RETRIES 4
#define MAX_RETRIES 70


    if (tsk_linkup_flag) {
        return;
    }

    /* EcVarForceDelayVal = 232 - 72, EcVarForceDelay = 1 */
    // tr_raw_write_reg_0_3_4(((ushort) (232 - 72) << 1) | 1);
    tr_raw_data[0] = 0;
    tr_raw_data[1] = (232 - 72) >> 7;
    tr_raw_data[2] = ((232 - 72) << 1) | 1;
    phy_write_tr(port_no, 0x188);

    set_EcVarForceIdle(port_no, 0x02 << subchan);  /* EcVar<subchan>ForceIdle = 1 */
    set_EcVarForceIdle(port_no, 0);                /* EcVar<subchan>ForceIdle = 0 */
    delay_1(1 + 1);
    // tr_raw_write_reg_0_3_4(0);            /* remove forced delay */
    tr_raw_data[0] = 0;
    tr_raw_data[1] = 0;
    tr_raw_data[2] = 0;
    phy_write_tr(port_no, 0x188);

    for (retry = 0; retry < 100; retry++) {
        if ((maxAbsCoeff = readAvgECNCECVar(port_no, subchan, 72, 8, EXCL_COEFFS)) >=
            RETRY_MAX_ABS_COEFF_LT) {
            break;
        }
        delay_1(2 + 1);
    }

    set_EcVarForceIdle(port_no, 0x02 << subchan);  /* EcVar<subchan>ForceIdle = 1 */
    set_EcVarForceIdle(port_no, 0);                /* EcVar<subchan>ForceIdle = 0 */

    if ((retry > MAX_RETRIES) || 
        (maxAbsCoeff > MAX_ABS_COEFF_ANOM_INVALID_NOISE)) {
        tsk_stat[subchan] = 0;
        tsk_loc[subchan]  = 0;
        tsk_strength[subchan] = 0;
    }
}

static void xc_search(uchar port_no, uchar subchan, uchar firstCoeff, uchar numCoeffs, uchar locFirst, uchar prefix)
{
    uchar idx;
    short strength_tmp;
    short coeff_tmp;
    short s;
    uchar locAbs;
    bit loc_crit;

    (void) readAvgECNCECVar(port_no, subchan, firstCoeff, numCoeffs, INCL_COEFFS);
    while (numCoeffs-- != 0) {
        idx = numCoeffs;
        locAbs = locFirst + idx;

        coeff_tmp = coeff_tab[idx];
        if (abs_w(coeff_tmp) > tsk_thresh[1]) {
            s = (short)(32L*(long)coeff_tmp/(long)tsk_thresh[1]);
            strength_tmp = tsk_strength[subchan];
            loc_crit = (tsk_loc[subchan] <= (locAbs + 3));

            if ((abs_w(s) <= abs_w(strength_tmp) || (locAbs < prefix))) {
                if ((tsk_signFlip < 0) && (tsk_stat[subchan] < 4) && loc_crit) {
                    if ((coeff_tmp > 0) && (strength_tmp < 0)) {
                        tsk_stat[subchan] = 2;
                        tsk_signFlip = 2;
                        if (locAbs < prefix) {
                            tsk_loc[subchan] = locAbs;
                        }
                    } 
                    else if ((coeff_tmp < 0) && (strength_tmp > 0)) {
                        tsk_stat[subchan] = 1;
                        tsk_signFlip = 2;
                        if (locAbs < prefix) {
                            tsk_loc[subchan] = locAbs;
                        }
                    }
                }
            } 
            else { /* magnitude is largest seen so far & not in prefix taps */
                if (coeff_tmp < -tsk_thresh[0]) {
                    if (loc_crit && (tsk_strength[subchan] > 0)) {
                        tsk_signFlip = 2;
                    }
                    tsk_stat[subchan] = 1;
                } 
                else if (coeff_tmp > tsk_thresh[0]) {
                    if (loc_crit && (tsk_strength[subchan] < 0)) {
                        tsk_signFlip = 2;
                    }
                    tsk_stat[subchan] = 2;
                } 
                else {
                    tsk_stat[subchan] = 4;
                }
                tsk_loc[subchan] = locAbs;
                tsk_strength[subchan] = s;
            }
        }
        tsk_signFlip = tsk_signFlip - 1;
    }
}

static void get_anom_thresh(uchar tap)
{
    short log2ThreshX256;
    schar sh;
    uchar j;

    log2ThreshX256 = 542 - (8 * (short) tap) + tsk_log2VGAx256;

    tsk_thresh[0] = 256 + LOW_BYTE(log2ThreshX256);
    sh = (schar) (log2ThreshX256 >> 8);
    if (sh >= 0) {
        tsk_thresh[0] <<= sh;
    } 
    else {
        tsk_thresh[0] >>= -sh;
        if (tsk_thresh[0] < 23) {
            tsk_thresh[0] = 23;
        }
    }

    if (tsk_linkup_flag) {
        tsk_thresh[1]  = tsk_thresh[0] >> 1;    /* anomaly = 1/2 open/short when link up   */
    } 
    else {
        tsk_thresh[1] = 0;
        for (j = 0; j < 5; ++j) {       /* anomaly = 1/3 open/short when link down */
            tsk_thresh[1] = (tsk_thresh[1] + tsk_thresh[0] + 2) >> 2;
        }
    }
    if (tsk_thresh[1] < 15) {
        tsk_thresh[1] = 15;
    }

    /* Limit anomaly threshold to 12 lsbs less than tap range for each EC tap */
    if ((tsk_thresh[1] > 1012) && (tap >= 32)) {
        tsk_thresh[1] = 1012;
    }
    else if ((tsk_thresh[1] > 4084) && (tap >= 16)) {
        tsk_thresh[1] = 4084;
    }
    else if (tsk_thresh[1] > 8180) {
        tsk_thresh[1] = 8180;
    }
}

static void set_EcVarForceIdle (uchar port_no, uchar value)
{
    // TrRawWrite(0, 3, 2, value);
    tr_raw_data[0] = 0;
    tr_raw_data[1] = 0;
    tr_raw_data[2] = value;
    phy_write_tr(port_no, 0x0184);
}


static ushort readAvgECNCECVar(uchar port_no, uchar subchan, uchar firstCoeff, uchar numCoeffs, uchar incl_coeffs)
{
    uchar i;
    uchar j;
    short cur_coeff;
    ushort maxAbsC;
    ushort reg_val;
#define NUM_REPEAT 4
#define SCALE_FACTOR 2

    maxAbsC = 0;

    if (incl_coeffs != 0) {
        /* Normal read & store coefficients */
        /* Clear coefficients to be averaged */
        memset(coeff_tab, 0, 16);
    }

    /* Accumulate coefficients (pre-scaling when necessay for dynamic range) */
    phy_page_tr(port_no);
    for (i = 0; i < NUM_REPEAT; ++i) {
        reg_val = (5 << 13) | ((ushort) subchan << 11) | ((ushort) firstCoeff << 1);
        for (j = 0; j < numCoeffs; ++j) {
//            phy_write(port_no, 16, (5 << 13) | ((ushort) subchan << 11) | ((ushort) (j & 0xc0) << 1) | ((j & 0x3f) << 1));
//            phy_write(port_no, 16, (5 << 13) | ((ushort) subchan << 11) | ((ushort) j << 1));
            phy_write(port_no, 16, reg_val);
            reg_val += 2;

            cur_coeff = phy_read(port_no, 17); /* low part only */
            if ( cur_coeff & 0x2000 ) {
                cur_coeff -= 0x4000;
            }

            if (incl_coeffs) {
                coeff_tab[j] += cur_coeff;
            }
            else {
                if (abs_w(cur_coeff) > maxAbsC) {
                    maxAbsC = abs_w(cur_coeff);
                }
            }
        }
    }
    phy_page_std(port_no);

    if (incl_coeffs) {
#if NUM_REPEAT == 3
        /* Complete averaging by scaling coefficients */
        for (j = 0; j < 8; ++j) {
            cur_coeff = 0;
            for (i = 0; i < 5; ++i) {
                cur_coeff = (cur_coeff >> 2) + coeff_tab[j];
            }
            coeff_tab[j] = (cur_coeff + 2) >> 2;
        }
#else
        for (j = 0; j < 8; ++j) {
            coeff_tab[j] >>= SCALE_FACTOR;
        }
#endif
    }

    /* Return max(ABS(all coeffs. Read)) */
    return maxAbsC;
}

static void ffe_init (uchar port_no)
{
    /* FFE settings for anomaly search */
    schar code ffe_settings_anomsea [16] = {
        0,   0,   0,   0,
        1,   3,  -3,  -1,
        0,   0,   0,   0,
        0,   0,   0,   0
    };
    uchar j;
#define ffe_settings ffe_settings_anomsea

    // TrRawWrite(0, 4, 0x20, 0x0100);        /* Set FfeWriteAllSubchans */
    tr_raw_data[0] = 0;
    tr_raw_data[1] = 0x01;
    tr_raw_data[2] = 0;
    phy_write_tr(port_no, 0x0240);

    for (j = 0; j < 16; ++j) {
        // TrRawWrite(0, 4, j, (unsigned long)((long)ffe_settings[j] << 9));
        tr_raw_data[0] = (uchar) (ffe_settings[j] >> 7);
        tr_raw_data[1] = (uchar) (ffe_settings[j] << 1);
        tr_raw_data[2] = 0;
        phy_write_tr(port_no, 0x0200 | (j << 1));
    }
    // TrRawWrite(0, 4, 0x20, 0x0000);        /* Clear FfeWriteAllSubchans */
    tr_raw_data[0] = 0;
    tr_raw_data[1] = 0;
    tr_raw_data[2] = 0;
    phy_write_tr(port_no, 0x0240);
}

static void enable_EC_var_delay_force_val (uchar port_no, uchar status)
{
    phy_read_tr(port_no, 0x0f86);
    if (status) {
        /* Set EnableECvarDelayForce/Val */
        tr_raw_data[0] |= 0x30;
        // TrRawWrite(1, 15, 0x03, TrRawRead(1, 15, 0x03)  | 0x300000L);
    }
    else {
        tr_raw_data[0] &= ~0x30;
        /* Clear EnableECvarDelayForce/Val */
        // TrRawWrite(1, 15, 0x03, TrRawRead(1, 15, 0x03) & ~0x300000L);
    }
    phy_write_tr(port_no, 0x0f86);
}

static void write_rclk125_gating (uchar port_no, uchar value)
{
    phy_write_tp_bit(port_no, 8, 9, value);
}

static void set_blip_search (uchar port_no, ushort reg_val)
{
    // TrRawWrite(0, 3, 8, reg_val);
    tr_raw_data[0] = 0;
    tr_raw_data[1] = HIGH_BYTE(reg_val);
    tr_raw_data[2] = LOW_BYTE(reg_val);
    phy_write_tr(port_no, 0x0190);
}

static ushort abs_w (short x)
{
    if (x < 0) {
        return (-x);
    }
    else {
        return x;
    }
}
#endif











⌨️ 快捷键说明

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