📄 mvphy.c
字号:
ethUnit, phyUnit)); lastStatus->isPhyAlive = TRUE; } } } 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); } }}/******************************************************************************* mv_phySet - Modify the value of a PHY register (debug only).*/voidmv_phySet(int phyUnit, UINT32 regnum, UINT32 value){ UINT32 phyBase; UINT32 phyAddr; if (mv_validPhyId(phyUnit)) { phyBase = MV_PHYBASE(phyUnit); phyAddr = MV_PHYADDR(phyUnit); phyRegWrite(phyBase, phyAddr, regnum, value); }}#if 1//DEBUG/* Define the registers of interest for a phyShow command */typedef struct mvRegisterTableEntry_s { UINT32 regNum; char *regIdString;} mvRegisterTableEntry_t;mvRegisterTableEntry_t mvPhyRegisterTable[] = { {MV_PHY_CONTROL, "PHY Control "}, {MV_PHY_STATUS, "PHY Status "}, {MV_PHY_ID1, "PHY Identifier 1 "}, {MV_PHY_ID2, "PHY Identifier 2 "}, {MV_AUTONEG_ADVERT, "Auto-Negotiation Advertisement "}, {MV_LINK_PARTNER_ABILITY, "Link Partner Ability "}, {MV_AUTONEG_EXPANSION, "Auto-Negotiation Expansion "}, {MV_NEXT_PAGE_TRANSMIT, "Next Page Transmit "}, {MV_LINK_PARTNER_NEXT_PAGE, "Link Partner Next Page "}, {MV_PHY_SPECIFIC_CONTROL_1, "PHY-Specific Control Register 1 "}, {MV_PHY_SPECIFIC_STATUS, "PHY-Specific Status "}, {MV_PHY_INTERRUPT_ENABLE, "PHY Interrupt Enable "}, {MV_PHY_INTERRUPT_STATUS, "PHY Interrupt Status "}, {MV_PHY_INTERRUPT_PORT_SUMMARY, "PHY Interrupt Port Summary "}, {MV_RECEIVE_ERROR_COUNTER, "Receive Error Counter "}, {MV_LED_PARALLEL_SELECT, "LED Parallel Select "}, {MV_LED_STREAM_SELECT_LEDS, "LED Stream Select "}, {MV_PHY_LED_CONTROL, "PHY LED Control "}, {MV_PHY_MANUAL_LED_OVERRIDE, "PHY Manual LED Override "}, {MV_VCT_CONTROL, "VCT Control "}, {MV_VCT_STATUS, "VCT Status "}, {MV_PHY_SPECIFIC_CONTROL_2, "PHY-Specific Control Register 2 "},};int mvPhyNumRegs = sizeof(mvPhyRegisterTable) / sizeof(mvPhyRegisterTable[0]);mvRegisterTableEntry_t mvSwitchPortRegisterTable[] = { {MV_PORT_STATUS, "Port Status "}, {MV_SWITCH_ID, "Switch ID "}, {MV_PORT_CONTROL, "Port Control "}, {MV_PORT_BASED_VLAN_MAP, "Port-Based VLAN Map "}, {MV_PORT_ASSOCIATION_VECTOR, "Port Association Vector "}, {MV_RX_COUNTER, "RX Counter "}, {MV_TX_COUNTER, "TX Counter "},};int mvSwitchPortNumRegs = sizeof(mvSwitchPortRegisterTable) / sizeof(mvSwitchPortRegisterTable[0]);mvRegisterTableEntry_t mvSwitchGlobalRegisterTable[] = { {MV_SWITCH_GLOBAL_STATUS, "Switch Global Status "}, {MV_SWITCH_MAC_ADDR0, "Switch MAC Addr 0 & 1 "}, {MV_SWITCH_MAC_ADDR2, "Switch MAC Addr 2 & 3 "}, {MV_SWITCH_MAC_ADDR4, "Switch MAC Addr 4 & 5 "}, {MV_SWITCH_GLOBAL_CONTROL, "Switch Global Control "}, {MV_ATU_CONTROL, "ATU Control "}, {MV_ATU_OPERATION, "ATU Operation "}, {MV_ATU_DATA, "ATU Data "}, {MV_ATU_MAC_ADDR0, "ATU MAC Addr 0 & 1 "}, {MV_ATU_MAC_ADDR2, "ATU MAC Addr 2 & 3 "}, {MV_ATU_MAC_ADDR4, "ATU MAC Addr 4 & 5 "},};int mvSwitchGlobalNumRegs = sizeof(mvSwitchGlobalRegisterTable) / sizeof(mvSwitchGlobalRegisterTable[0]);void my_mvPhyShow(int ethUnit){ int phyUnit; for (phyUnit=0; (phyUnit < MV_PHY_MAX); phyUnit++) { if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } mv_phyShow(phyUnit); }}/******************************************************************************* mv_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.*/voidmv_phyShow(int phyUnit){ int i; UINT16 value; UINT32 phyBase; UINT32 phyAddr; UINT32 switchPortAddr; if (!mv_validPhyId(phyUnit)) { return; } phyBase = MV_PHYBASE(phyUnit); phyAddr = MV_PHYADDR(phyUnit); switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); printk("PHY state for PHY%d (ethmac%d, phyBase 0x%8x, phyAddr 0x%x, switchAddr 0x%x)\n", phyUnit, MV_ETHUNIT(phyUnit), MV_PHYBASE(phyUnit), MV_PHYADDR(phyUnit), MV_SWITCH_PORT_ADDR(phyUnit)); printk("PHY Registers:\n"); for (i=0; i < mvPhyNumRegs; i++) { value = phyRegRead(phyBase, phyAddr, mvPhyRegisterTable[i].regNum); printk("Reg %02d (0x%02x) %s = 0x%08x\n", mvPhyRegisterTable[i].regNum, mvPhyRegisterTable[i].regNum, mvPhyRegisterTable[i].regIdString, value); }#if 0 printk("Switch Port Registers:\n"); for (i=0; i < mvSwitchPortNumRegs; i++) { value = phyRegRead(phyBase, switchPortAddr, mvSwitchPortRegisterTable[i].regNum); printk("Reg %02d (0x%02x) %s = 0x%08x\n", mvSwitchPortRegisterTable[i].regNum, mvSwitchPortRegisterTable[i].regNum, mvSwitchPortRegisterTable[i].regIdString, value); } printk("Switch Global Registers:\n"); for (i=0; i < mvSwitchGlobalNumRegs; i++) { value = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, mvSwitchGlobalRegisterTable[i].regNum); printk("Reg %02d (0x%02x) %s = 0x%08x\n", mvSwitchGlobalRegisterTable[i].regNum, mvSwitchGlobalRegisterTable[i].regNum, mvSwitchGlobalRegisterTable[i].regIdString, value); }#endif }/******************************************************************************* mv_switchPortSet - Modify the value of a switch port register (debug only).*/voidmv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value){ UINT32 phyBase; UINT32 switchPortAddr; if (mv_validPhyId(phyUnit)) { phyBase = MV_PHYBASE(phyUnit); switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); phyRegWrite(phyBase, switchPortAddr, regnum, value); }} /******************************************************************************* mv_switchGlobalSet - Modify the value of a switch global register* (debug only).*/voidmv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value){ UINT32 phyBase; if (mv_validPhyId(phyUnit)) { phyBase = MV_PHYBASE(phyUnit); phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, regnum, value); }}/******************************************************************************* mv_showATUDB - Dump the contents of the Address Translation Unit DataBase* for the PHY switch associated with the specified phy.*/voidmv_showATUDB(int phyUnit){ UINT32 phyBase; UINT16 ATUData; UINT16 ATUMac0; UINT16 ATUMac2; UINT16 ATUMac4; int portVec; int entryState; if (!mv_validPhyId(phyUnit)) { printk("Invalid port number: %d\n", phyUnit); return; } phyBase = MV_PHYBASE(phyUnit); /* Wait for previous operation (if any) to complete */ mv_waitWhileATUBusy(phyBase); /* Initialize ATU MAC to all 1's */ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0, 0xffff); phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2, 0xffff); phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4, 0xffff); printk(" MAC ADDRESS EntryState PortVector\n"); for(;;) { /* Tell hardware to get next MAC info */ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, MV_ATU_OP_GET_NEXT | MV_ATU_IS_BUSY); mv_waitWhileATUBusy(phyBase); ATUData = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_DATA); entryState = (ATUData & MV_ENTRYSTATE_MASK) >> MV_ENTRYSTATE_SHIFT; if (entryState == 0) { /* We've hit the end of the list */ break; } ATUMac0 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0); ATUMac2 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2); ATUMac4 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4); portVec = (ATUData & MV_PORTVEC_MASK) >> MV_PORTVEC_SHIFT; printk("%02x:%02x:%02x:%02x:%02x:%02x 0x%02x 0x%02x\n", ATUMac0 >> 8, /* MAC byte 0 */ ATUMac0 & 0xff, /* MAC byte 1 */ ATUMac2 >> 8, /* MAC byte 2 */ ATUMac2 & 0xff, /* MAC byte 3 */ ATUMac4 >> 8, /* MAC byte 4 */ ATUMac4 & 0xff, /* MAC byte 5 */ entryState, portVec); } }voidmv_setATUDB(int phyUnit, char *macaddr, int dbNum){ UINT32 phyBase; UINT16 ATUData; UINT16 ATUMac0; UINT16 ATUMac2; UINT16 ATUMac4; UINT16 atu_operation; int portVec; int entryState; if (!mv_validPhyId(phyUnit)) { printk("Invalid port number: %d\n", phyUnit); return; } phyBase = MV_PHYBASE(phyUnit); /* Wait for previous operation (if any) to complete */ mv_waitWhileATUBusy(phyBase); phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_DATA, 0x20f); mv_waitWhileATUBusy(phyBase); /* Initialize ATU MAC to all 1's */ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0, *(unsigned short *)(macaddr)); phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2, *(unsigned short *)(macaddr + 2 )); phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4, *(unsigned short *)(macaddr + 4 )); atu_operation = MV_ATU_OP_PURGE_ENTRY | MV_ATU_IS_BUSY | dbNum; phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, atu_operation); }LOCAL BOOL countingGoodFrames;/******************************************************************************* mv_countGoodFrames - starts counting GOOD RX/TX frames per port*/voidmv_countGoodFrames(int phyUnit){ UINT32 phyBase; UINT16 globalControl; if (mv_validPhyId(phyUnit)) { /* * Guarantee that counters are cleared by * forcing CtrMode to toggle and end on GOODFRAMES. */ phyBase = MV_PHYBASE(phyUnit); /* Read current Switch Global Control Register */ globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_SWITCH_GLOBAL_CONTROL); /* Set CtrMode to count BAD frames */ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | MV_CTRMODE_BADFRAMES); /* Push new value out to hardware */ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_SWITCH_GLOBAL_CONTROL, globalControl); /* Now toggle CtrMode to count GOOD frames */ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | MV_CTRMODE_GOODFRAMES); /* Push new value out to hardware */ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_SWITCH_GLOBAL_CONTROL, globalControl); countingGoodFrames = TRUE; }}/******************************************************************************* mv_countBadFrames - starts counting BAD RX/TX frames per port*/voidmv_countBadFrames(int phyUnit){ UINT32 phyBase; UINT16 globalControl; if (mv_validPhyId(phyUnit)) { /* * Guarantee that counters are cleared by * forcing CtrMode to toggle and end on BADFRAMES. */ phyBase = MV_PHYBASE(phyUnit); /* Read current Switch Global Control Register */ globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_SWITCH_GLOBAL_CONTROL); /* Set CtrMode to count GOOD frames */ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | MV_CTRMODE_GOODFRAMES); /* Push new value out to hardware */ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_SWITCH_GLOBAL_CONTROL, globalControl); /* Now toggle CtrMode to count BAD frames */ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | MV_CTRMODE_BADFRAMES); /* Push new value out to hardware */ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_SWITCH_GLOBAL_CONTROL, globalControl); countingGoodFrames = FALSE; }}/******************************************************************************* mv_showFrameCounts - shows current GOOD/BAD Frame counts*/voidmv_showFrameCounts(int phyUnit){ UINT16 rxCounter; UINT16 txCounter; UINT32 phyBase; UINT32 switchPortAddr; if (!mv_validPhyId(phyUnit)) { return; } phyBase = MV_PHYBASE(phyUnit); switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); rxCounter = phyRegRead(phyBase, switchPortAddr, MV_RX_COUNTER); txCounter = phyRegRead(phyBase, switchPortAddr, MV_TX_COUNTER); printk("port%d %s frames: receive: %05d transmit: %05d\n", phyUnit, (countingGoodFrames ? "good" : "error"), rxCounter, txCounter);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -