Exemple #1
0
/******************************************************************************
*
* ip_VLANInit - initialize "port-based VLANs" for the specified enet unit.
*/
static void
ip_VLANInit(int ethUnit)
{
    int     phyUnit;
    uint32_t  phyBase;
    uint32_t  phyReg;

    phyBase = IP_GLOBALREGBASE;
    
    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
        if (IP_ETHUNIT(phyUnit) != ethUnit) {
            continue;
        }
        phy_reg_write(phyBase, IP_GLOBAL_PHY29_ADDR, 
                    IP_GLOBAL_PHY29_24_REG + ((phyUnit == 5) ? (phyUnit + 1) : phyUnit),
                                    IP_VLAN_TABLE_SETTING(phyUnit));
        
        /* Send all packets to all ports */
        phyReg = phy_reg_read(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG);
        phyReg = phyReg | ((1 << phyUnit) << IP_VLAN1_OUTPUT_PORT_MASK_S);
        phy_reg_write(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG, phyReg);
    }
    phyReg = phy_reg_read(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG);
    phyReg = phyReg | TAG_VLAN_ENABLE;
    phyReg = phyReg & ~VID_INDX_SEL_M;
    phy_reg_write(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG, phyReg);

}
Exemple #2
0
BOOL
adm_phySpeed(int ethUnit)
{
    int     phyUnit;
    uint16_t  phyHwStatus;
    uint32_t  phyBase;
    uint32_t  phyAddr;

    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        if (adm_phyIsLinkAlive(phyUnit)) {

            phyBase = ADM_PHYBASE(phyUnit);
            phyAddr = ADM_PHYADDR(phyUnit);

            phyHwStatus = phy_reg_read(phyBase, phyAddr, ADM_LINK_PARTNER_ABILITY);

            if (phyHwStatus & ADM_LINK_100BASETX) {
                return AG7100_PHY_SPEED_100TX;
            }
        }
    }

    return AG7100_PHY_SPEED_10T;
}
Exemple #3
0
/******************************************************************************
*
* adm_phyIsDuplexFull - Determines whether the phy ports associated with the
* specified device are FULL or HALF duplex.
*
* RETURNS:
*    1  --> FULL
*    0 --> HALF
*/
int
adm_phyIsFullDuplex(int ethUnit)
{
    int     phyUnit;
    uint32_t  phyBase;
    uint32_t  phyAddr;
    uint16_t  phyHwStatus;

    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        if (adm_phyIsLinkAlive(phyUnit)) {

            phyBase = ADM_PHYBASE(phyUnit);
            phyAddr = ADM_PHYADDR(phyUnit);

            phyHwStatus = phy_reg_read(phyBase, phyAddr, ADM_LINK_PARTNER_ABILITY);
            if ((phyHwStatus & ADM_LINK_100BASETX_FULL_DUPLEX) || 
                (phyHwStatus & ADM_LINK_10BASETX_FULL_DUPLEX)) {
                return TRUE;
            }
        }
        return -1;
    }

    return FALSE;

}
Exemple #4
0
unsigned int 
athrs_ar8033_phy_read(int ethUnit, unsigned int phy_addr, unsigned int reg_addr)
{
  
  return phy_reg_read(0x1,phy_addr,reg_addr);
 
}
Exemple #5
0
/******************************************************************************
*
* ip_phyIsDuplexFull - Determines whether the phy ports associated with the
* specified device are FULL or HALF duplex.
*
* RETURNS:
*    1  --> FULL
*    0 --> HALF
*/
int
ip_phyIsFullDuplex(int ethUnit)
{
    int     phyUnit;
    uint32_t  phyBase;
    uint32_t  phyAddr;
    uint16_t  phyHwStatus;

    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        if (ip_phyIsLinkAlive(phyUnit)) {

            phyBase = IP_PHYBASE(phyUnit);
            phyAddr = IP_PHYADDR(phyUnit);

            phyHwStatus = phy_reg_read(phyBase, phyAddr, IP_LINK_PARTNER_ABILITY);
            printk("ipPhy.c: phyHwStatus 0x%x\n",phyHwStatus);
            if ((phyHwStatus & IP_LINK_100BASETX_FULL_DUPLEX) || 
                (phyHwStatus & IP_LINK_10BASETX_FULL_DUPLEX)) {
                return TRUE;
            }
        }
        return -1;
    }

    return FALSE;

}
Exemple #6
0
/******************************************************************************
*
* adm_phyIsLinkAlive - test to see if the specified link is alive
*
* RETURNS:
*    TRUE  --> link is alive
*    FALSE --> link is down
*/
BOOL
adm_phyIsLinkAlive(int phyUnit)
{
    uint16_t phyHwStatus;
    uint32_t phyBase;
    uint32_t phyAddr;

    phyBase = ADM_PHYBASE(phyUnit);
    phyAddr = ADM_PHYADDR(phyUnit);

    phyHwStatus = phy_reg_read(phyBase, phyAddr, ADM_PHY_STATUS);

    if (phyHwStatus & ADM_STATUS_LINK_PASS) {
        return TRUE;
    } else {
        return FALSE;
    }
}
Exemple #7
0
int ethernetext_chk_link_mode(void) {
    int32_t  link;
    uint16_t data;

    if ((phy_id & M_PHY_ID) == PHY_ID_LAN8710A) {
        data = phy_reg_read(PHY_SP_CTL_STS_REG);
        switch (((uint32_t)data >> 2) & 0x00000007) {
            case 0x0001:
                link = HALF_10M;
                break;
            case 0x0005:
                link = FULL_10M;
                break;
            case 0x0002:
                link = HALF_TX;
                break;
            case 0x0006:
                link = FULL_TX;
                break;
            default:
                link = NEGO_FAIL;
                break;
        }
    } else {
Exemple #8
0
int
adm_phyIsUp(int ethUnit)
{

    int           phyUnit;
    uint16_t        phyHwStatus;
    admPhyInfo_t   *lastStatus;
    int           linkCount   = 0;
    int           lostLinks   = 0;
    int           gainedLinks = 0;
    uint32_t        phyBase;
    uint32_t        phyAddr;

    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = ADM_PHYBASE(phyUnit);
        phyAddr = ADM_PHYADDR(phyUnit);


        lastStatus = &admPhyInfo[phyUnit];
        phyHwStatus = phy_reg_read(phyBase, phyAddr, ADM_PHY_STATUS);

        if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */
            /* See if we've lost link */
            if (phyHwStatus & ADM_STATUS_LINK_PASS) {
                linkCount++;
            } else {
                lostLinks++;
#ifdef COBRA_TODO
                mv_flushATUDB(phyUnit);
#endif
                DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d down\n",
                                               ethUnit, phyUnit));
                lastStatus->isPhyAlive = FALSE;
            }
        } else { /* last known link status was DEAD */
            /* Check for AutoNegotiation complete */
            if (ADM_AUTONEG_DONE(phyHwStatus)) {
                //printk("autoneg done\n");
                gainedLinks++;
                linkCount++;
                DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d up\n",
                                               ethUnit, phyUnit));
                lastStatus->isPhyAlive = TRUE;
            }
        }
    }

    return (linkCount);

#if 0
    if (linkCount == 0) {
        if (lostLinks) {
            /* We just lost the last link for this MAC */
            phyLinkLost(ethUnit);
        }
    } else {
        if (gainedLinks == linkCount) {
            /* We just gained our first link(s) for this MAC */
            phyLinkGained(ethUnit);
        }
    }
#endif
}
Exemple #9
0
BOOL
adm_phySetup(int ethUnit)
{
    int     phyUnit, global;
    uint16_t  phyHwStatus;
    uint16_t  timeout;
    int     liveLinks = 0;
    uint32_t  phyBase = 0;
    BOOL    foundPhy = FALSE;
    uint32_t  phyAddr;
    static int inited = 0;
    
    /* Reset PHYs*/
    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = ADM_PHYBASE(phyUnit);
        phyAddr = ADM_PHYADDR(phyUnit);

        phy_reg_write(phyBase, phyAddr, ADM_PHY_CONTROL,
                    ADM_CTRL_SOFTWARE_RESET);
    }
    /*
     * After the phy is reset, it takes a little while before
     * it can respond properly.
     */
    sysMsDelay(300);

    /* See if there's any configuration data for this enet */
    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = ADM_PHYBASE(phyUnit);
        foundPhy = TRUE;
        break;
    }

    if (!foundPhy) {
        return FALSE; /* No PHY's configured for this ethUnit */
    }

    /* start auto negogiation on each phy */
    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = ADM_PHYBASE(phyUnit);
        phyAddr = ADM_PHYADDR(phyUnit);
        
        phy_reg_write(phyBase, phyAddr, ADM_AUTONEG_ADVERT,
                                        ADM_ADVERTISE_ALL);

        phy_reg_write(phyBase, phyAddr, ADM_PHY_CONTROL,
                    ADM_CTRL_AUTONEGOTIATION_ENABLE | ADM_CTRL_START_AUTONEGOTIATION);
    }

    /*
     * Wait up to .75 seconds for ALL associated PHYs to finish
     * autonegotiation.  The only way we get out of here sooner is
     * if ALL PHYs are connected AND finish autonegotiation.
     */
    timeout=5;
    for (phyUnit=0; (phyUnit < ADM_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }
        for (;;) {
            phyBase = ADM_PHYBASE(phyUnit);
            phyAddr = ADM_PHYADDR(phyUnit);

            phyHwStatus = phy_reg_read(phyBase, phyAddr, ADM_PHY_STATUS);

            if (ADM_AUTONEG_DONE(phyHwStatus)) {
                DRV_PRINT(DRV_DEBUG_PHYSETUP,
                          ("Port %d, Neg Success\n", phyUnit));
                break;
            }
            if (timeout == 0) {
                DRV_PRINT(DRV_DEBUG_PHYSETUP,
                          ("Port %d, Negogiation timeout\n", phyUnit));
                break;
            }
            if (--timeout == 0) {
                DRV_PRINT(DRV_DEBUG_PHYSETUP,
                          ("Port %d, Negogiation timeout\n", phyUnit));
                break;
            }

            sysMsDelay(150);
        }
    }

    /*
     * All PHYs have had adequate time to autonegotiate.
     * Now initialize software status.
     *
     * It's possible that some ports may take a bit longer
     * to autonegotiate; but we can't wait forever.  They'll
     * get noticed by mv_phyCheckStatusChange during regular
     * polling activities.
     */
    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        if (adm_phyIsLinkAlive(phyUnit)) {
            liveLinks++;
            ADM_IS_PHY_ALIVE(phyUnit) = TRUE;
        } else {
            ADM_IS_PHY_ALIVE(phyUnit) = FALSE;
        }

        DRV_PRINT(DRV_DEBUG_PHYSETUP,
            ("eth%d: Phy Status=%4.4x\n",
            ethUnit, 
            phy_reg_read(ADM_PHYBASE(phyUnit),
                       ADM_PHYADDR(phyUnit),
                       ADM_PHY_STATUS)));
    }

    /*
     * XXX
     */
    phy_reg_write(0, 0, 0x10, 0x50);
    return (liveLinks > 0);
}
Exemple #10
0
BOOL
adm_phySetup(int ethUnit)
{
    int     phyUnit;
    uint16_t  phyHwStatus;
    uint16_t  timeout;
    int     liveLinks = 0;
    uint32_t  phyBase = 0;
    BOOL    foundPhy = FALSE;
    uint32_t  phyAddr;
    
    /* Reset PHYs*/
    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = ADM_PHYBASE(phyUnit);
        phyAddr = ADM_PHYADDR(phyUnit);

        phy_reg_write(phyBase, phyAddr, ADM_PHY_CONTROL,
                    ADM_CTRL_SOFTWARE_RESET);
    }
    /*
     * After the phy is reset, it takes a little while before
     * it can respond properly.
     */
    mdelay(300);

    /* See if there's any configuration data for this enet */
    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = ADM_PHYBASE(phyUnit);
        foundPhy = TRUE;
        break;
    }

    if (!foundPhy) {
        return FALSE; /* No PHY's configured for this ethUnit */
    }

    /* start auto negogiation on each phy */
    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = ADM_PHYBASE(phyUnit);
        phyAddr = ADM_PHYADDR(phyUnit);
        
        phy_reg_write(phyBase, phyAddr, ADM_AUTONEG_ADVERT,
                                        ADM_ADVERTISE_ALL);

        phy_reg_write(phyBase, phyAddr, ADM_PHY_CONTROL,
                    ADM_CTRL_AUTONEGOTIATION_ENABLE | ADM_CTRL_START_AUTONEGOTIATION);
    }

    /*
     * Wait up to .75 seconds for ALL associated PHYs to finish
     * autonegotiation.  The only way we get out of here sooner is
     * if ALL PHYs are connected AND finish autonegotiation.
     */
    timeout=5;
    for (phyUnit=0; (phyUnit < ADM_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }
        for (;;) {
            phyBase = ADM_PHYBASE(phyUnit);
            phyAddr = ADM_PHYADDR(phyUnit);

            phyHwStatus = phy_reg_read(phyBase, phyAddr, ADM_PHY_STATUS);

            if (ADM_AUTONEG_DONE(phyHwStatus)) {
                DRV_PRINT(DRV_DEBUG_PHYSETUP,
                          ("Port %d, Neg Success\n", phyUnit));
                break;
            }
            if (timeout == 0) {
                DRV_PRINT(DRV_DEBUG_PHYSETUP,
                          ("Port %d, Negogiation timeout\n", phyUnit));
                break;
            }
            if (--timeout == 0) {
                DRV_PRINT(DRV_DEBUG_PHYSETUP,
                          ("Port %d, Negogiation timeout\n", phyUnit));
                break;
            }

            mdelay(150);
        }
    }

    /*
     * All PHYs have had adequate time to autonegotiate.
     * Now initialize software status.
     *
     * It's possible that some ports may take a bit longer
     * to autonegotiate; but we can't wait forever.  They'll
     * get noticed by mv_phyCheckStatusChange during regular
     * polling activities.
     */
    for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) {
        if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        if (adm_phyIsLinkAlive(phyUnit)) {
            liveLinks++;
            ADM_IS_PHY_ALIVE(phyUnit) = TRUE;
        } else {
            ADM_IS_PHY_ALIVE(phyUnit) = FALSE;
        }

        DRV_PRINT(DRV_DEBUG_PHYSETUP,
            ("eth%d: Phy Status=%4.4x\n",
            ethUnit, 
            phy_reg_read(ADM_PHYBASE(phyUnit),
                       ADM_PHYADDR(phyUnit),
                       ADM_PHY_STATUS)));
    }

#ifdef CONFIG_MV6060
	/* added by lsz 30Apri07 to configure port vlan registers */
	
/****************************************************************************
	Port VLan:
	
	 ---------------------------------------------------------------
	|	| Port6	         | Port5	| Port4	        | Port3	        | Port2	        | Port1	        | Port0	|
	 ---------------------------------------------------------------
	| Port0	|	0	|	1	|	0	|	0	|	0	|	0	|	0	|
	 ---------------------------------------------------------------
	| Port1	|	0	|	1	|	1	|	1	|	1	|	0	|	0	|
	 ---------------------------------------------------------------
	| Port2	|	0	|	1	|	1	|	1	|	0	|	1	|	0	|
	 ---------------------------------------------------------------
	| Port3	|	0	|	1	|	1	|	0	|	1	|	1	|	0	|
	 ---------------------------------------------------------------
	| Port4	|	0	|	1	|	0	|	1	|	1	|	1	|	0	|
	 ---------------------------------------------------------------
	| Port5	|	0	|	0	|	1	|	1	|	1	|	1	|	1	|
	 ---------------------------------------------------------------
	| Port6	|	0	|	0	|	0	|	0	|	0	|	0	|	0	|
	 ---------------------------------------------------------------
	 
	Port 0:		Wan
	Port 1~4:	Lan

	e.g. Port 0 is 010 0000, i.e. 0x20.
****************************************************************************/
	#define PORT_VALN_MAP_REG	0x06
	uint32_t portAddr[7] = {0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE};
	
	phy_reg_write(0, portAddr[0], PORT_VALN_MAP_REG, 0x103E);
	phy_reg_write(0, portAddr[1], PORT_VALN_MAP_REG, 0x103D);
	phy_reg_write(0, portAddr[2], PORT_VALN_MAP_REG, 0x103B);
	phy_reg_write(0, portAddr[3], PORT_VALN_MAP_REG, 0x1037);
	phy_reg_write(0, portAddr[4], PORT_VALN_MAP_REG, 0x102F);
	phy_reg_write(0, portAddr[5], PORT_VALN_MAP_REG, 0x101F);

/*	phy_reg_write(0, portAddr[0], PORT_VALN_MAP_REG, 0x1020);
	phy_reg_write(0, portAddr[1], PORT_VALN_MAP_REG, 0x103C);
	phy_reg_write(0, portAddr[2], PORT_VALN_MAP_REG, 0x103A);
	phy_reg_write(0, portAddr[3], PORT_VALN_MAP_REG, 0x1036);
	phy_reg_write(0, portAddr[4], PORT_VALN_MAP_REG, 0x102E);
	phy_reg_write(0, portAddr[5], PORT_VALN_MAP_REG, 0x101F);*/
	//phy_reg_write(0, portAddr[6], PORT_VALN_MAP_REG, 0x0000);
	
	/* added by lsz to configure header mode registers */
	#define PORT_CONTROL_REG	0x04
	uint16_t reg_data = 0x8803;	/* Flow Control | Header Mode | Forwarding */
	
	phy_reg_write(0, portAddr[0], PORT_CONTROL_REG, 0x8003);
	phy_reg_write(0, portAddr[1], PORT_CONTROL_REG, 0x8003);
	phy_reg_write(0, portAddr[2], PORT_CONTROL_REG, 0x8003);
	phy_reg_write(0, portAddr[3], PORT_CONTROL_REG, 0x8003);
	phy_reg_write(0, portAddr[4], PORT_CONTROL_REG, 0x8003);
	phy_reg_write(0, portAddr[5], PORT_CONTROL_REG, 0x8003);
	phy_reg_write(0, 0x1E, PORT_CONTROL_REG, reg_data);

#else
    /*
     * XXX
     */
    phy_reg_write(0, 0, 0x10, 0x50);
#endif
    return (liveLinks > 0);
}
Exemple #11
0
int ethernetext_init(ethernet_cfg_t *p_ethcfg) {
    int32_t  i;
    uint16_t val;

    CPGSTBCR7 &= ~(CPG_STBCR7_BIT_MSTP74);  /* enable ETHER clock */

    /* P4_2(PHY Reset) */
    GPIOP4      &= ~0x0004;         /* Outputs low level */
    GPIOPMC4    &= ~0x0004;         /* Port mode */
    GPIOPM4     &= ~0x0004;         /* Output mode */

    /* GPIO P1  P1_14(ET_COL) */
    GPIOPMC1    |=  0x4000;
    GPIOPFCAE1  &= ~0x4000;
    GPIOPFCE1   |=  0x4000;
    GPIOPFC1    |=  0x4000;

    /* P3_0(ET_TXCLK), P3_3(ET_MDIO), P3_4(ET_RXCLK), P3_5(ET_RXER), P3_6(ET_RXDV) */
    GPIOPMC3    |=  0x0079;
    GPIOPFCAE3  &= ~0x0079;
    GPIOPFCE3   &= ~0x0079;
    GPIOPFC3    |=  0x0079;
    GPIOPIPC3   |=  0x0079;

    /* P5_9(ET_MDC) */
    GPIOPMC5    |=  0x0200;
    GPIOPFCAE5  &= ~0x0200;
    GPIOPFCE5   &= ~0x0200;
    GPIOPFC5    |=  0x0200;
    GPIOPIPC5   |=  0x0200;

    /* P10_1(ET_TXER), P10_2(ET_TXEN), P10_3(ET_CRS), P10_4(ET_TXD0), P10_5(ET_TXD1) */
    /* P10_6(ET_TXD2), P10_7(ET_TXD3), P10_8(ET_RXD0), P10_9(ET_RXD1), P10_10(ET_RXD2), P10_11(ET_RXD3) */
    GPIOPMC10   |=  0x0FFE;
    GPIOPFCAE10 &= ~0x0FFE;
    GPIOPFCE10  |=  0x0FFE;
    GPIOPFC10   |=  0x0FFE;
    GPIOPIPC10  |=  0x0FFE;

    /* Resets the E-MAC,E-DMAC */
    lan_reg_reset();

    /* PHY Reset */
    GPIOP4      &= ~0x0004;         /* P4_2 Outputs low level */
    wait_100us(250);                /* 25msec */
    GPIOP4      |=  0x0004;         /* P4_2 Outputs high level */
    wait_100us(100);                /* 10msec */

    /* Resets the PHY-LSI */
    phy_reg_write(BASIC_MODE_CONTROL_REG, 0x8000);
    for (i = 10000; i > 0; i--) {
        val = phy_reg_read(BASIC_MODE_CONTROL_REG);
        if (((uint32_t)val & 0x8000uL) == 0) {
            break;                  /* Reset complete */
        }
    }

    phy_id = ((uint32_t)phy_reg_read(PHY_IDENTIFIER1_REG) << 16)
           |  (uint32_t)phy_reg_read(PHY_IDENTIFIER2_REG);

    Interrupt_priority = p_ethcfg->int_priority;
    p_recv_cb_fnc      = p_ethcfg->recv_cb;
    start_stop         = 1;

    if (p_ethcfg->ether_mac != NULL) {
        (void)memcpy(mac_addr, p_ethcfg->ether_mac, sizeof(mac_addr));
    } else {
		ethernet_address(mac_addr); /* Get MAC Address */
    }

    return 0;
}
Exemple #12
0
/*****************************************************************************
*
* ip_phyShow - Dump the state of a PHY.
* There are two sets of registers for each phy port:
*  "phy registers" and
*  "switch port registers"
* We dump 'em all, plus the switch global registers.
*/
void
ip_phyShow(int phyUnit)
{
    int     i;
    uint16_t  value;
    uint32_t  phyBase;
    uint32_t  phyAddr;

    if (!ip_validPhyId(phyUnit)) {
        return;
    }

    phyBase        = IP_PHYBASE(phyUnit);
    phyAddr        = IP_PHYADDR(phyUnit);

    printk("PHY state for PHY%d (enet%d, phyBase 0x%8x, phyAddr 0x%x)\n",
           phyUnit,
           IP_ETHUNIT(phyUnit),
           IP_PHYBASE(phyUnit),
           IP_PHYADDR(phyUnit));

    printk("PHY Registers:\n");
    for (i=0; i < ipPhyNumRegs; i++) {

        value = phy_reg_read(phyBase, phyAddr, ipPhyRegisterTable[i].regNum);

        printk("Reg %02d (0x%02x) %s = 0x%08x\n",
               ipPhyRegisterTable[i].regNum,
               ipPhyRegisterTable[i].regNum,
               ipPhyRegisterTable[i].regIdString,
               value);
    }

    phyBase = IP_GLOBALREGBASE;

    printk("Switch Global Registers:\n");
    printk("Phy29 Registers:\n");
    for (i=0; i < ipPhy29GlobalNumRegs; i++) {

        value = phy_reg_read(phyBase, IP_GLOBAL_PHY29_ADDR,
                           ipPhy29GlobalRegisterTable[i].regNum);

        printk("Reg %02d (0x%02x) %s = 0x%08x\n",
               ipPhy29GlobalRegisterTable[i].regNum,
               ipPhy29GlobalRegisterTable[i].regNum,
               ipPhy29GlobalRegisterTable[i].regIdString,
               value);
    }

    printk("Phy30 Registers:\n");
    for (i=0; i < ipPhy30GlobalNumRegs; i++) {

        value = phy_reg_read(phyBase, IP_GLOBAL_PHY30_ADDR,
                           ipPhy30GlobalRegisterTable[i].regNum);

        printk("Reg %02d (0x%02x) %s = 0x%08x\n",
               ipPhy30GlobalRegisterTable[i].regNum,
               ipPhy30GlobalRegisterTable[i].regNum,
               ipPhy30GlobalRegisterTable[i].regIdString,
               value);
    }
    printk("Phy31 Registers:\n");
    for (i=0; i < ipPhy31GlobalNumRegs; i++) {

        value = phy_reg_read(phyBase, IP_GLOBAL_PHY31_ADDR,
                           ipPhy31GlobalRegisterTable[i].regNum);

        printk("Reg %02d (0x%02x) %s = 0x%08x\n",
               ipPhy31GlobalRegisterTable[i].regNum,
               ipPhy31GlobalRegisterTable[i].regNum,
               ipPhy31GlobalRegisterTable[i].regIdString,
               value);
    }
}
Exemple #13
0
BOOL
ip_phySetup(int ethUnit)
{
    int     phyUnit;
    uint16_t  phyHwStatus;
    uint16_t  timeout;
    int     liveLinks = 0;
    uint32_t  phyBase = 0;
    BOOL    foundPhy = FALSE;
    uint32_t  phyAddr;
    
    /* Reset PHYs*/
    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = IP_PHYBASE(phyUnit);
        phyAddr = IP_PHYADDR(phyUnit);

        phy_reg_write(phyBase, phyAddr, IP_PHY_CONTROL,
                    IP_CTRL_SOFTWARE_RESET);
    }
    /*
     * After the phy is reset, it takes a little while before
     * it can respond properly.
     */
    mdelay(300);
    /* Verify that the switch is what we think it is, and that it's ready */
    ip_verifyReady(ethUnit);

    /* See if there's any configuration data for this enet */
    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
        if (IP_ETHUNIT(phyUnit) != ethUnit) {
            continue;
        }

        phyBase = IP_PHYBASE(phyUnit);
        foundPhy = TRUE;
        break;
    }

    if (!foundPhy) {
        return FALSE; /* No PHY's configured for this ethUnit */
    }

#ifdef COBRA_TODO
    /* Initialize global switch settings */

    /* Initialize the aging time */

    /* Set the learning properties */
#endif

    /* start auto negogiation on each phy */
    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = IP_PHYBASE(phyUnit);
        phyAddr = IP_PHYADDR(phyUnit);
        
        phy_reg_write(phyBase, phyAddr, IP_AUTONEG_ADVERT,
                                        IP_ADVERTISE_ALL);
        phy_reg_write(phyBase, phyAddr, IP_PHY_CONTROL,
                    IP_CTRL_AUTONEGOTIATION_ENABLE | IP_CTRL_START_AUTONEGOTIATION);
    }

    /*
     * Wait up to .75 seconds for ALL associated PHYs to finish
     * autonegotiation.  The only way we get out of here sooner is
     * if ALL PHYs are connected AND finish autonegotiation.
     */
    timeout=5;
    for (phyUnit=0; (phyUnit < IP_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) {
        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }
        for (;;) {
            phyBase = IP_PHYBASE(phyUnit);
            phyAddr = IP_PHYADDR(phyUnit);

            phyHwStatus = phy_reg_read(phyBase, phyAddr, IP_PHY_STATUS);

            if (IP_AUTONEG_DONE(phyHwStatus)) {
                DRV_PRINT(DRV_DEBUG_PHYSETUP,
                          ("Port %d, Neg Success\n", phyUnit));
                break;
            }
            if (timeout == 0) {
                DRV_PRINT(DRV_DEBUG_PHYSETUP,
                          ("Port %d, Negogiation timeout\n", phyUnit));
                break;
            }
            if (--timeout == 0) {
                DRV_PRINT(DRV_DEBUG_PHYSETUP,
                          ("Port %d, Negogiation timeout\n", phyUnit));
                break;
            }

            mdelay(150);
        }
    }

    /*
     * All PHYs have had adequate time to autonegotiate.
     * Now initialize software status.
     *
     * It's possible that some ports may take a bit longer
     * to autonegotiate; but we can't wait forever.  They'll
     * get noticed by mv_phyCheckStatusChange during regular
     * polling activities.
     */
    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        if (ip_phyIsLinkAlive(phyUnit)) {
            liveLinks++;
            IP_IS_PHY_ALIVE(phyUnit) = TRUE;
        } else {
            IP_IS_PHY_ALIVE(phyUnit) = FALSE;
        }

        DRV_PRINT(DRV_DEBUG_PHYSETUP,
            ("eth%d: Phy Status=%4.4x\n",
            ethUnit, 
            phy_reg_read(IP_PHYBASE(phyUnit),
                       IP_PHYADDR(phyUnit),
                       IP_PHY_STATUS)));
    }

    ip_VLANInit(ethUnit);

    return (liveLinks > 0);
}
Exemple #14
0
static void
ip_verifyReady(int ethUnit)
{
    int     phyUnit;
    uint32_t  phyBase = 0;
    uint32_t  phyAddr;
    uint16_t  phyID1;
    uint16_t  phyID2;

    /*
     * The first read to the Phy port registers always fails and
     * returns 0.   So get things started with a bogus read.
     */
    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = IP_PHYBASE(phyUnit);
        phyAddr = IP_PHYADDR(phyUnit);
    
        phyID1 = phy_reg_read(phyBase, phyAddr, IP_PHY_ID1); /* returns 0 */
        break;
    }

    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        /*******************/
        /* Verify phy port */
        /*******************/
        phyBase = IP_PHYBASE(phyUnit);
        phyAddr = IP_PHYADDR(phyUnit);
    
        phyID1 = phy_reg_read(phyBase, phyAddr, IP_PHY_ID1);
        if (phyID1 != IP_PHY_ID1_EXPECTATION) {
            DRV_PRINT(DRV_DEBUG_PHYERROR,
                      ("Invalid PHY ID1 for enet%d port%d.  Expected 0x%04x, read 0x%04x\n",
                       ethUnit,
                       phyUnit,
                       IP_PHY_ID1_EXPECTATION,
                       phyID1));
            return;
        }
    
        phyID2 = phy_reg_read(phyBase, phyAddr, IP_PHY_ID2);
        if ((phyID2 & IP_OUI_LSB_MASK) != IP_OUI_LSB_EXPECTATION) {
            DRV_PRINT(DRV_DEBUG_PHYERROR,
                      ("Invalid PHY ID2 for enet%d port %d.  Expected 0x%04x, read 0x%04x\n",
                       ethUnit,
                       phyUnit,
                       IP_OUI_LSB_EXPECTATION,
                       phyID2));
            return;
        }
    
        DRV_PRINT(DRV_DEBUG_PHYSETUP,
                  ("Found PHY enet%d port%d: model 0x%x revision 0x%x\n",
                   ethUnit,
                   phyUnit,
                   (phyID2 & IP_MODEL_NUM_MASK) >> IP_MODEL_NUM_SHIFT,
                   (phyID2 & IP_REV_NUM_MASK) >> IP_REV_NUM_SHIFT));
    
    }
}