📄 adm_phy.c
字号:
} /* * 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; } phy_reg_read(ADM_PHYBASE(phyUnit), ADM_PHYADDR(phyUnit), ADM_PHY_STATUS, &phyHwStatus); DRV_PRINT(DRV_DEBUG_PHYSETUP, ("eth%d: Phy Status=%4.4x\n", ethUnit, phyHwStatus)); } /* 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); /* WAN port */ 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); #if 0 /* print all the switch registers */ int smi_addr_start = 0x0, smi_addr; int reg_start = 0x00, reg; unsigned short val = 0; printf("------------------------mv6063 registers---------------------\n"); for (reg = reg_start; reg < 0x20; reg ++) { printf("%02x\t", reg); for (smi_addr = smi_addr_start; smi_addr < 0x10; smi_addr ++) { phy_reg_read(0, smi_addr, reg, &val); printf("%04X ", val & 0xffff); if (smi_addr == 0x7) printf("- "); } printf("\n"); }#endif /* * XXX *//* phy_reg_write(0, 0, 0x10, 0x50); */ return (liveLinks > 0);}/******************************************************************************** adm_phyIsDuplexFull - Determines whether the phy ports associated with the* specified device are FULL or HALF duplex.** RETURNS:* 1 --> FULL* 0 --> HALF*/intadm_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); phy_reg_read(phyBase, phyAddr, ADM_LINK_PARTNER_ABILITY, &phyHwStatus); if ((phyHwStatus & ADM_LINK_100BASETX_FULL_DUPLEX) || (phyHwStatus & ADM_LINK_10BASETX_FULL_DUPLEX)) { return TRUE; } } } return FALSE;}/******************************************************************************** adm_phyIsSpeed100 - Determines the speed of phy ports associated with the* specified device.** RETURNS:* TRUE --> 100Mbit* FALSE --> 10Mbit*/BOOLadm_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); phy_reg_read(phyBase, phyAddr, ADM_LINK_PARTNER_ABILITY, &phyHwStatus); if (phyHwStatus & ADM_LINK_100BASETX) { return _100BASET; } } } return _10BASET;}/******************************************************************************* adm_phyCheckStatusChange -- checks for significant changes in PHY state.** A "significant change" is:* dropped link (e.g. ethernet cable unplugged) OR* autonegotiation completed + link (e.g. ethernet cable plugged in)** When a PHY is plugged in, phyLinkGained is called.* When a PHY is unplugged, phyLinkLost is called.*/intadm_phyIsUp(int ethUnit){ int phyUnit; uint16_t phyHwStatus; ipPhyInfo_t *lastStatus; int linkCount = 0; int lostLinks = 0; int gainedLinks = 0; uint32_t phyBase; uint32_t phyAddr; /* it seems this function isn't called by anybody. */ /* by lqm, 08Apr08 */ printf("adm_phyIsUp %d\n", ethUnit); for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) { if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } phyBase = ADM_PHYBASE(phyUnit); phyAddr = ADM_PHYADDR(phyUnit); lastStatus = &ipPhyInfo[phyUnit]; phy_reg_read(phyBase, phyAddr, ADM_PHY_STATUS, &phyHwStatus); 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)) { //printf("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}#define adm_counter_parse(_reg, _cnt, _cnthi) do { \ phy_reg_read(0, ((_reg##L & (0x1f << 5)) >> 5), (_reg##L & 0x1f), &_cnt); \ phy_reg_read(0, ((_reg##H & (0x1f << 5)) >> 5), (_reg##H & 0x1f), &_cnthi); \}while(0);voidadm_get_counters(){ int count, counthi; adm_counter_parse(P0_TX, count, counthi); printf("P0 Tx: %10d ", (counthi << 16)|count); adm_counter_parse(P0_TXB, count, counthi); printf("P0 TxB: %#x ", (counthi << 16)|count); adm_counter_parse(P0_RX, count, counthi); printf("P0 Rx: %10d ", (counthi << 16)|count); adm_counter_parse(P0_ERR, count, counthi); printf("P0 ERR: %10d\n", (counthi << 16)|count); adm_counter_parse(P5_TX, count, counthi); printf("P5 Tx: %10d ", (counthi << 16)|count); adm_counter_parse(P5_TXB, count, counthi); printf("P5 TxB: %#x ", (counthi << 16)|count); adm_counter_parse(P5_RX, count, counthi); printf("P5 Rx: %10d ", (counthi << 16)|count); adm_counter_parse(P5_ERR, count, counthi); printf("P5 ERR: %10d\n", (counthi << 16)|count);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -