/* Set RGMII mode */
reg_val = REGR16(DP_RGMIICT); 
reg_val |= (1 << 7);
REGW16(DP_RGMIICT, reg_val);

/* Set MDI mode manually */
reg_val = REGR16(DP_PHYCR);
if (mdix == 0) {
    printf("Setting MDI connection manually\n");
    reg_val &= ~(3 << 5);
} else { 
    printf("Setting MDIX connection\n");
    reg_val &= ~(3 << 5);
    reg_val |= (1 << 5);
}
REGW16(DP_PHYCR, reg_val);

/* Set-up BMCR */
reg_val = REGR16(DP_BMCR);

/* Set-up speed */
printf("Speed: ");
switch (speed) {
    case 1000:
        printf("1000BaseT\n");
        reg_val |= (0x1 << 6); /* Set 1000BaseT*/
        reg_val &= ~(0x1 << 13);
        break;
    case 100:
        printf("100BaseT\n");
        reg_val &= ~(0x1 << 6); /* Set 100BaseT*/
        reg_val |= 0x1 << 13;
        break;
    case 10:
        printf("10BaseT\n");
        reg_val &= ~(0x1 << 6); /* Set 10BaseT*/
        reg_val &= ~(0x1 << 13);
        break;
};

/* Set-up auto negotiation */
printf("Autoneg : %s\n", auto_neg ? "ON" : "OFF");
if (!auto_neg) {
    reg_val &= ~(0x1 << 12); /* Disable auto-negotiation */
} else {
    reg_val |= (0x1 << 12); /* Enable auto-negotiation */
}

/* Set-up duplex type */
printf("Duplex : %s\n", duplex_type == full_duplex ? "FULL" : "HALF");
if (duplex_type == full_duplex) {
    reg_val |= 0x1 << 8; /* Full duplex */
} else {
    reg_val &= ~(0x1 << 8); /* Half duplex */
}

REGW16(DP_BMCR, reg_val);

/* Soft reset */
reg_val = REGR16(DP_BMCR);
reg_val |= 0x1 << 15;
REGW16(DP_BMCR, reg_val);

printf("Waiting for reset to complete ...\n");
do {
    reg_val = REGR16(DP_BMCR);
} while (reg_val & (1 << 15));

/* Wait for link training to complete */
printf("Link status 0x%x\n", REGR16(DP_PHYSTS));
printf("Waiting for link to be up ..\n");
while (!(REGR16(DP_PHYSTS) & (1 << 10)));

printf("BMCR 0x%x\n", REGR16(DP_BMCR));

/* PRBS count mode */
REGW16_FIELD(DP_BISCR, PRBS_COUNT_MODE, 1);

/* PRBS generate packet */
REGW16_FIELD(DP_BISCR, GEN_PRBS_PACKET, 1);

/* Disable PCS loop-back */
REGW16_FIELD(DP_BISCR, PCS_LOOPBACK, 0);

/* Non-PCS loop-back */
{

    switch(loop_back) {
        case BISCR_LOOPBACK_MODE_digital_loop:
            printf("Digital loop-back\n");
            break;
        case BISCR_LOOPBACK_MODE_analog_loop:
            printf("Analog loop-back\n");
            break;
        case BISCR_LOOPBACK_MODE_external_loop:
            printf("External loop-back\n");
            break;
        case BISCR_LOOPBACK_MODE_reverse_loop: 
            printf("Reverse loop-back\n");
            break;
    };

    REGW16_FIELD(DP_BISCR, LOOPBACK_MODE, loop_back);
}

printf("<<<<<<<<<<<<<<<<<<<< Reg dump >>>>>>>>>>>>>>>>>>>>\n");
printf("DP_PHYIDR1 0x%x\n", REGR16(DP_PHYIDR1));
printf("DP_RGMIICT 0x%x\n", REGR16(DP_RGMIICT));
printf("DP_PHYCR 0x%x\n", REGR16(DP_PHYCR));
printf("DP_RGMIIDCTL 0x%x\n", REGR16(DP_RGMIIDCTL));
printf("DP_BMCR 0x%x\n", REGR16(DP_BMCR));
printf("DP_BISCR 0x%x\n", REGR16(DP_BISCR));
printf("==================================================\n");

/* Enable packet generation */
REGW16_FIELD(DP_BISCR, PACKET_GEN_EN, 1);

/* Wait for lock to release */
do {
    if (REGR16_FIELD(DP_STS2, PRBS_LOCK) == 1)
        locked = 1;
    if (--count == 0) {
        break;
    }
} while (!locked);


if (REGR16_FIELD(DP_STS2, PRBS_LOCK_LOST) == 1)
    lost_lock = 1;

byte_cnt = REGR16(DP_BICSR1);

/* Stop and clear PRB counter */
REGW16(DP_BICSR1, 0x3);

/* In continous mode error is checked once packet generator is disabled */
REGW16_FIELD(DP_BISCR, PACKET_GEN_EN, 0);
err_byte_cnt = REGR16_FIELD(DP_BICSR2, PRBS_ERR_CNT);

if (REGR16_FIELD(DP_STS2, PKT_GEN_BUSY) == 1)
    busy = 1;

printf("Busy bit 0x%x, Locked status 0x%x\n",
            REGR16_FIELD(DP_STS2, PKT_GEN_BUSY),
            REGR16_FIELD(DP_STS2, PRBS_LOCK));

locked = REGR16_FIELD(DP_STS2, PRBS_LOCK);
if (locked)
    printf("Locked\n");

if (busy)
    printf("Busy\n");

if (lost_lock)
    printf("lost lock\n");


printf("Byte count %d Error byte count %d\n", byte_cnt, err_byte_cnt);
