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
/******************************************************************************
*
* ip_phySetup - reset and setup the PHY switch.
*
* Resets each PHY port.
*
* RETURNS:
*    TRUE  --> at least 1 PHY with LINK
*    FALSE --> no LINKs on this ethernet unit
*/
BOOL
ip_phySetup(int ethUnit)
{
    int     phyUnit;
    UINT16  phyHwStatus;
    UINT16  timeout;
    int     liveLinks = 0;
    UINT32  phyBase = 0;
    BOOL    foundPhy = FALSE;
    UINT32  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);

        phyRegWrite(phyBase, phyAddr, IP_PHY_CONTROL,
                    IP_CTRL_SOFTWARE_RESET);
    }
    /*
     * After the phy is reset, it takes a little while before
     * it can respond properly.
     */
    sysMsDelay(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);
        
        phyRegWrite(phyBase, phyAddr, IP_AUTONEG_ADVERT,
                                        IP_ADVERTISE_ALL);
        phyRegWrite(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 = phyRegRead(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;
            }

            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 < 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, 
            phyRegRead(IP_PHYBASE(phyUnit),
                       IP_PHYADDR(phyUnit),
                       IP_PHY_STATUS)));
    }

    ip_VLANInit(ethUnit);

    return (liveLinks > 0);
}
Exemple #3
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  value;
    UINT32  phyBase;
    UINT32  phyAddr;

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

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

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

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

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

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

    phyBase = IP_GLOBALREGBASE;

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

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

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

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

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

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

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

        printf("Reg %02d (0x%02x) %s = 0x%08x\n",
               ipPhy31GlobalRegisterTable[i].regNum,
               ipPhy31GlobalRegisterTable[i].regNum,
               ipPhy31GlobalRegisterTable[i].regIdString,
               value);
    }
}
Exemple #4
0
/******************************************************************************
*
* ip_VLANInit - initialize "port-based VLANs" for the specified enet unit.
*/
LOCAL void
ip_VLANInit(int ethUnit)
{
    int     phyUnit;
    UINT32  phyBase;
    UINT32  phyReg;

    phyBase = IP_GLOBALREGBASE;
    
    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
        if (IP_ETHUNIT(phyUnit) != ethUnit) {
            continue;
        }
        phyRegWrite(phyBase, IP_GLOBAL_PHY29_ADDR, 
                    IP_GLOBAL_PHY29_24_REG + ((phyUnit == 5) ? (phyUnit + 1) : phyUnit),
                                    IP_VLAN_TABLE_SETTING(phyUnit));
        
#if CONFIG_VENETDEV   
        if (IP_IS_ENET_PORT(phyUnit)) {
            if (IP_IS_WAN_PORT(phyUnit)) {
                
                /* WAN port */
                phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_1_REG);
                phyReg = phyReg & ~((1 << phyUnit) << IP_VLAN1_OUTPUT_PORT_MASK_S);
                phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_1_REG, phyReg);
                
                phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_2_REG);
                phyReg = phyReg | ((1 << phyUnit) << IP_VLAN2_OUTPUT_PORT_MASK_S);
                phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_2_REG, phyReg);
            
            } else {
                
                /* LAN ports */
                phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_1_REG);
                phyReg = phyReg | ((1 << phyUnit) << IP_VLAN1_OUTPUT_PORT_MASK_S);
                phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_1_REG, phyReg);
                
                phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_2_REG);
                phyReg = phyReg & ~((1 << phyUnit) << IP_VLAN2_OUTPUT_PORT_MASK_S);
                phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_2_REG, phyReg);
                
            }
            /* WAN & LAN removes VLAN tags */
            phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY29_ADDR, 
                                    IP_GLOBAL_PHY29_23_REG);
            phyReg = phyReg | ((1 << phyUnit) << IP_PORTX_REMOVE_TAG_S);
            phyReg = phyReg & ~((1 << phyUnit) << IP_PORTX_ADD_TAG_S);
            phyRegWrite(phyBase, IP_GLOBAL_PHY29_ADDR, 
                                    IP_GLOBAL_PHY29_23_REG, phyReg);

        } else {
            /* CPU port */
            phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_1_REG);
            phyReg = phyReg | ((1 << phyUnit) << IP_VLAN1_OUTPUT_PORT_MASK_S);
            phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_1_REG, phyReg);

            phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_2_REG);
            phyReg = phyReg | ((1 << phyUnit) << IP_VLAN2_OUTPUT_PORT_MASK_S);
            phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, 
                                    IP_GLOBAL_PHY30_2_REG, phyReg);

            phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY29_ADDR, 
                                    IP_GLOBAL_PHY29_23_REG);
            phyReg = phyReg | (1 << IP_PORT5_ADD_TAG_S);
            phyReg = phyReg & ~(1 << IP_PORT5_REMOVE_TAG_S);
            phyRegWrite(phyBase, IP_GLOBAL_PHY29_ADDR, 
                                    IP_GLOBAL_PHY29_23_REG, phyReg);
        }
#else
        /* Send all packets to all ports */
        phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG);
        phyReg = phyReg | ((1 << phyUnit) << IP_VLAN1_OUTPUT_PORT_MASK_S);
        phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG, phyReg);
#endif
    }
    phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG);
    phyReg = phyReg | TAG_VLAN_ENABLE;
    phyReg = phyReg & ~VID_INDX_SEL_M;
    phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG, phyReg);

}