From 71c87a7da82129bbed56b2de3f77ef110aeb61f0 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 6 Oct 2009 15:46:24 +0100 Subject: Staging: et131x: kill SUCCESS and FAILURE defines Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_phy.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/staging/et131x/et1310_phy.h') diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h index 080656c6142c..6978b25c7e13 100644 --- a/drivers/staging/et131x/et1310_phy.h +++ b/drivers/staging/et131x/et1310_phy.h @@ -61,9 +61,6 @@ #include "et1310_address_map.h" -#define TRUEPHY_SUCCESS 0 -#define TRUEPHY_FAILURE 1 - /* MI Register Addresses */ #define MI_CONTROL_REG 0 #define MI_STATUS_REG 1 -- cgit v1.2.3 From 2907255fccc7fa9d88ecd5200c140bae86901585 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 6 Oct 2009 15:51:10 +0100 Subject: Staging: et131x: phy clean up Clean up the phy code a bit so we can see what needs doing. This involves moving blocks around and making stuff static Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_phy.c | 1158 ++++++++++++++++++----------------- drivers/staging/et131x/et1310_phy.h | 30 +- 2 files changed, 582 insertions(+), 606 deletions(-) (limited to 'drivers/staging/et131x/et1310_phy.h') diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index 6b77c541df2c..c1aedbb2469a 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -109,12 +109,12 @@ static int et131x_xcvr_init(struct et131x_adapter *adapter); * * Returns 0 on success, errno on failure (as defined in errno.h) */ -int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr, - uint8_t xcvrReg, uint16_t *value) +int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, + u8 xcvrReg, u16 *value) { struct _MAC_t __iomem *mac = &adapter->regs->mac; int status = 0; - uint32_t delay; + u32 delay; u32 miiAddr; u32 miiCmd; u32 miiIndicator; @@ -174,14 +174,16 @@ int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr, * @xcvrReg: the register to read * @value: 16-bit value to write * + * FIXME: one caller in netdev still + * * Return 0 on success, errno on failure (as defined in errno.h) */ -int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value) +int MiWrite(struct et131x_adapter *adapter, u8 xcvrReg, u16 value) { struct _MAC_t __iomem *mac = &adapter->regs->mac; int status = 0; - uint8_t xcvrAddr = adapter->Stats.xcvr_addr; - uint32_t delay; + u8 xcvrAddr = adapter->Stats.xcvr_addr; + u32 delay; u32 miiAddr; u32 miiCmd; u32 miiIndicator; @@ -210,7 +212,7 @@ int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value) /* If we hit the max delay, we could not write the register */ if (delay == 100) { - uint16_t TempValue; + u16 TempValue; dev_warn(&adapter->pdev->dev, "xcvrReg 0x%08x could not be written", xcvrReg); @@ -244,22 +246,22 @@ int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value) int et131x_xcvr_find(struct et131x_adapter *adapter) { int status = -ENODEV; - uint8_t xcvr_addr; + u8 xcvr_addr; MI_IDR1_t idr1; MI_IDR2_t idr2; - uint32_t xcvr_id; + u32 xcvr_id; /* We need to get xcvr id and address we just get the first one */ for (xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++) { /* Read the ID from the PHY */ PhyMiRead(adapter, xcvr_addr, - (uint8_t) offsetof(MI_REGS_t, idr1), + (u8) offsetof(MI_REGS_t, idr1), &idr1.value); PhyMiRead(adapter, xcvr_addr, - (uint8_t) offsetof(MI_REGS_t, idr2), + (u8) offsetof(MI_REGS_t, idr2), &idr2.value); - xcvr_id = (uint32_t) ((idr1.value << 16) | idr2.value); + xcvr_id = (u32) ((idr1.value << 16) | idr2.value); if ((idr1.value != 0) && (idr1.value != 0xffff)) { adapter->Stats.xcvr_id = xcvr_id; @@ -290,279 +292,317 @@ int et131x_setphy_normal(struct et131x_adapter *adapter) return status; } -/** - * et131x_xcvr_init - Init the phy if we are setting it into force mode - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ -static int et131x_xcvr_init(struct et131x_adapter *adapter) +void ET1310_PhyReset(struct et131x_adapter *etdev) { - int status = 0; - MI_IMR_t imr; - MI_ISR_t isr; - MI_LCR2_t lcr2; + MiWrite(etdev, PHY_CONTROL, 0x8000); +} - /* Zero out the adapter structure variable representing BMSR */ - adapter->Bmsr.value = 0; +void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down) +{ + u16 data; - MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, isr), &isr.value); + MiRead(etdev, PHY_CONTROL, &data); - MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, imr), &imr.value); + if (down == false) { + /* Power UP */ + data &= ~0x0800; + MiWrite(etdev, PHY_CONTROL, data); + } else { + /* Power DOWN */ + data |= 0x0800; + MiWrite(etdev, PHY_CONTROL, data); + } +} - /* Set the link status interrupt only. Bad behavior when link status - * and auto neg are set, we run into a nested interrupt problem - */ - imr.bits.int_en = 0x1; - imr.bits.link_status = 0x1; - imr.bits.autoneg_status = 0x1; +static void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable) +{ + u16 data; - MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, imr), imr.value); + MiRead(etdev, PHY_CONTROL, &data); - /* Set the LED behavior such that LED 1 indicates speed (off = - * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates - * link and activity (on for link, blink off for activity). - * - * NOTE: Some customizations have been added here for specific - * vendors; The LED behavior is now determined by vendor data in the - * EEPROM. However, the above description is the default. - */ - if ((adapter->eepromData[1] & 0x4) == 0) { - MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, lcr2), - &lcr2.value); - if ((adapter->eepromData[1] & 0x8) == 0) - lcr2.bits.led_tx_rx = 0x3; - else - lcr2.bits.led_tx_rx = 0x4; - lcr2.bits.led_link = 0xa; - MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, lcr2), - lcr2.value); + if (enable == true) { + /* Autonegotiation ON */ + data |= 0x1000; + MiWrite(etdev, PHY_CONTROL, data); + } else { + /* Autonegotiation OFF */ + data &= ~0x1000; + MiWrite(etdev, PHY_CONTROL, data); } +} - /* Determine if we need to go into a force mode and set it */ - if (adapter->AiForceSpeed == 0 && adapter->AiForceDpx == 0) { - if ((adapter->RegistryFlowControl == TxOnly) || - (adapter->RegistryFlowControl == Both)) { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_SET, 4, 11, NULL); - } else { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 11, NULL); - } - - if (adapter->RegistryFlowControl == Both) { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_SET, 4, 10, NULL); - } else { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 10, NULL); - } +static void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, u16 duplex) +{ + u16 data; - /* Set the phy to autonegotiation */ - ET1310_PhyAutoNeg(adapter, true); + MiRead(etdev, PHY_CONTROL, &data); - /* NOTE - Do we need this? */ - ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL); - return status; + if (duplex == TRUEPHY_DUPLEX_FULL) { + /* Set Full Duplex */ + data |= 0x100; + MiWrite(etdev, PHY_CONTROL, data); } else { - ET1310_PhyAutoNeg(adapter, false); + /* Set Half Duplex */ + data &= ~0x100; + MiWrite(etdev, PHY_CONTROL, data); + } +} - /* Set to the correct force mode. */ - if (adapter->AiForceDpx != 1) { - if ((adapter->RegistryFlowControl == TxOnly) || - (adapter->RegistryFlowControl == Both)) { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_SET, 4, 11, - NULL); - } else { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 11, - NULL); - } +static void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, u16 speed) +{ + u16 data; - if (adapter->RegistryFlowControl == Both) { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_SET, 4, 10, - NULL); - } else { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 10, - NULL); - } - } else { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 10, NULL); - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 11, NULL); - } + /* Read the PHY control register */ + MiRead(etdev, PHY_CONTROL, &data); - switch (adapter->AiForceSpeed) { - case 10: - if (adapter->AiForceDpx == 1) - TPAL_SetPhy10HalfDuplex(adapter); - else if (adapter->AiForceDpx == 2) - TPAL_SetPhy10FullDuplex(adapter); - else - TPAL_SetPhy10Force(adapter); - break; - case 100: - if (adapter->AiForceDpx == 1) - TPAL_SetPhy100HalfDuplex(adapter); - else if (adapter->AiForceDpx == 2) - TPAL_SetPhy100FullDuplex(adapter); - else - TPAL_SetPhy100Force(adapter); - break; - case 1000: - TPAL_SetPhy1000FullDuplex(adapter); - break; - } + /* Clear all Speed settings (Bits 6, 13) */ + data &= ~0x2040; - return status; + /* Reset the speed bits based on user selection */ + switch (speed) { + case TRUEPHY_SPEED_10MBPS: + /* Bits already cleared above, do nothing */ + break; + + case TRUEPHY_SPEED_100MBPS: + /* 100M == Set bit 13 */ + data |= 0x2000; + break; + + case TRUEPHY_SPEED_1000MBPS: + default: + data |= 0x0040; + break; } + + /* Write back the new speed */ + MiWrite(etdev, PHY_CONTROL, data); } -void et131x_Mii_check(struct et131x_adapter *etdev, - MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints) +static void ET1310_PhyLinkStatus(struct et131x_adapter *etdev, + u8 *link_status, + u32 *autoneg, + u32 *linkspeed, + u32 *duplex_mode, + u32 *mdi_mdix, + u32 *masterslave, u32 *polarity) { - uint8_t link_status; - uint32_t autoneg_status; - uint32_t speed; - uint32_t duplex; - uint32_t mdi_mdix; - uint32_t masterslave; - uint32_t polarity; - unsigned long flags; + u16 mistatus = 0; + u16 is1000BaseT = 0; + u16 vmi_phystatus = 0; + u16 control = 0; - if (bmsr_ints.bits.link_status) { - if (bmsr.bits.link_status) { - etdev->PoMgmt.TransPhyComaModeOnBoot = 20; + MiRead(etdev, PHY_STATUS, &mistatus); + MiRead(etdev, PHY_1000_STATUS, &is1000BaseT); + MiRead(etdev, PHY_PHY_STATUS, &vmi_phystatus); + MiRead(etdev, PHY_CONTROL, &control); - /* Update our state variables and indicate the - * connected state - */ - spin_lock_irqsave(&etdev->Lock, flags); + if (link_status) { + *link_status = + (unsigned char)((vmi_phystatus & 0x0040) ? 1 : 0); + } - etdev->MediaState = NETIF_STATUS_MEDIA_CONNECT; - etdev->Flags &= ~fMP_ADAPTER_LINK_DETECTION; + if (autoneg) { + *autoneg = + (control & 0x1000) ? ((vmi_phystatus & 0x0020) ? + TRUEPHY_ANEG_COMPLETE : + TRUEPHY_ANEG_NOT_COMPLETE) : + TRUEPHY_ANEG_DISABLED; + } - spin_unlock_irqrestore(&etdev->Lock, flags); + if (linkspeed) + *linkspeed = (vmi_phystatus & 0x0300) >> 8; - netif_carrier_on(etdev->netdev); - } else { - dev_warn(&etdev->pdev->dev, - "Link down - cable problem ?\n"); + if (duplex_mode) + *duplex_mode = (vmi_phystatus & 0x0080) >> 7; - if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { - /* NOTE - Is there a way to query this without - * TruePHY? - * && TRU_QueryCoreType(etdev->hTruePhy, 0) == EMI_TRUEPHY_A13O) { - */ - uint16_t Register18; + if (mdi_mdix) + /* NOTE: Need to complete this */ + *mdi_mdix = 0; - MiRead(etdev, 0x12, &Register18); - MiWrite(etdev, 0x12, Register18 | 0x4); - MiWrite(etdev, 0x10, Register18 | 0x8402); - MiWrite(etdev, 0x11, Register18 | 511); - MiWrite(etdev, 0x12, Register18); - } + if (masterslave) { + *masterslave = + (is1000BaseT & 0x4000) ? TRUEPHY_CFG_MASTER : + TRUEPHY_CFG_SLAVE; + } - /* For the first N seconds of life, we are in "link - * detection" When we are in this state, we should - * only report "connected". When the LinkDetection - * Timer expires, we can report disconnected (handled - * in the LinkDetectionDPC). - */ - if (!(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) || - (etdev->MediaState == NETIF_STATUS_MEDIA_DISCONNECT)) { - spin_lock_irqsave(&etdev->Lock, flags); - etdev->MediaState = - NETIF_STATUS_MEDIA_DISCONNECT; - spin_unlock_irqrestore(&etdev->Lock, - flags); + if (polarity) { + *polarity = + (vmi_phystatus & 0x0400) ? TRUEPHY_POLARITY_INVERTED : + TRUEPHY_POLARITY_NORMAL; + } +} - netif_carrier_off(etdev->netdev); - } +static void ET1310_PhyAndOrReg(struct et131x_adapter *etdev, + u16 regnum, u16 andMask, u16 orMask) +{ + u16 reg; - etdev->linkspeed = 0; - etdev->duplex_mode = 0; + /* Read the requested register */ + MiRead(etdev, regnum, ®); - /* Free the packets being actively sent & stopped */ - et131x_free_busy_send_packets(etdev); + /* Apply the AND mask */ + reg &= andMask; - /* Re-initialize the send structures */ - et131x_init_send(etdev); + /* Apply the OR mask */ + reg |= orMask; - /* Reset the RFD list and re-start RU */ - et131x_reset_recv(etdev); + /* Write the value back to the register */ + MiWrite(etdev, regnum, reg); +} - /* - * Bring the device back to the state it was during - * init prior to autonegotiation being complete. This - * way, when we get the auto-neg complete interrupt, - * we can complete init by calling ConfigMacREGS2. - */ - et131x_soft_reset(etdev); +/* Still used from _mac */ +void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, u16 action, + u16 regnum, u16 bitnum, u8 *value) +{ + u16 reg; + u16 mask = 0; - /* Setup ET1310 as per the documentation */ - et131x_adapter_setup(etdev); + /* Create a mask to isolate the requested bit */ + mask = 0x0001 << bitnum; - /* Setup the PHY into coma mode until the cable is - * plugged back in - */ - if (etdev->RegistryPhyComa == 1) - EnablePhyComa(etdev); - } + /* Read the requested register */ + MiRead(etdev, regnum, ®); + + switch (action) { + case TRUEPHY_BIT_READ: + if (value != NULL) + *value = (reg & mask) >> bitnum; + break; + + case TRUEPHY_BIT_SET: + reg |= mask; + MiWrite(etdev, regnum, reg); + break; + + case TRUEPHY_BIT_CLEAR: + reg &= ~mask; + MiWrite(etdev, regnum, reg); + break; + + default: + break; } +} - if (bmsr_ints.bits.auto_neg_complete || - (etdev->AiForceDpx == 3 && bmsr_ints.bits.link_status)) { - if (bmsr.bits.auto_neg_complete || etdev->AiForceDpx == 3) { - ET1310_PhyLinkStatus(etdev, - &link_status, &autoneg_status, - &speed, &duplex, &mdi_mdix, - &masterslave, &polarity); +void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev, + u16 duplex) +{ + u16 data; - etdev->linkspeed = speed; - etdev->duplex_mode = duplex; + /* Read the PHY 1000 Base-T Control Register */ + MiRead(etdev, PHY_1000_CONTROL, &data); - etdev->PoMgmt.TransPhyComaModeOnBoot = 20; + /* Clear Bits 8,9 */ + data &= ~0x0300; - if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { - /* - * NOTE - Is there a way to query this without - * TruePHY? - * && TRU_QueryCoreType(etdev->hTruePhy, 0)== EMI_TRUEPHY_A13O) { - */ - uint16_t Register18; + switch (duplex) { + case TRUEPHY_ADV_DUPLEX_NONE: + /* Duplex already cleared, do nothing */ + break; - MiRead(etdev, 0x12, &Register18); - MiWrite(etdev, 0x12, Register18 | 0x4); - MiWrite(etdev, 0x10, Register18 | 0x8402); - MiWrite(etdev, 0x11, Register18 | 511); - MiWrite(etdev, 0x12, Register18); - } + case TRUEPHY_ADV_DUPLEX_FULL: + /* Set Bit 9 */ + data |= 0x0200; + break; - ConfigFlowControl(etdev); + case TRUEPHY_ADV_DUPLEX_HALF: + /* Set Bit 8 */ + data |= 0x0100; + break; - if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS && - etdev->RegistryJumboPacket > 2048) - ET1310_PhyAndOrReg(etdev, 0x16, 0xcfff, - 0x2000); + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + data |= 0x0300; + break; + } - SetRxDmaTimer(etdev); - ConfigMACRegs2(etdev); - } + /* Write back advertisement */ + MiWrite(etdev, PHY_1000_CONTROL, data); +} + +static void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *etdev, + u16 duplex) +{ + u16 data; + + /* Read the Autonegotiation Register (10/100) */ + MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); + + /* Clear bits 7,8 */ + data &= ~0x0180; + + switch (duplex) { + case TRUEPHY_ADV_DUPLEX_NONE: + /* Duplex already cleared, do nothing */ + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + /* Set Bit 8 */ + data |= 0x0100; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + /* Set Bit 7 */ + data |= 0x0080; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + /* Set Bits 7,8 */ + data |= 0x0180; + break; + } + + /* Write back advertisement */ + MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); +} + +static void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev, + u16 duplex) +{ + u16 data; + + /* Read the Autonegotiation Register (10/100) */ + MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); + + /* Clear bits 5,6 */ + data &= ~0x0060; + + switch (duplex) { + case TRUEPHY_ADV_DUPLEX_NONE: + /* Duplex already cleared, do nothing */ + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + /* Set Bit 6 */ + data |= 0x0040; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + /* Set Bit 5 */ + data |= 0x0020; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + /* Set Bits 5,6 */ + data |= 0x0060; + break; } + + /* Write back advertisement */ + MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); } + /** * TPAL_SetPhy10HalfDuplex - Force the phy into 10 Base T Half Duplex mode. * @etdev: pointer to the adapter structure * * Also sets the MAC so it is syncd up properly */ -void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *etdev) +static void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *etdev) { /* Power down PHY */ ET1310_PhyPowerDown(etdev, 1); @@ -585,7 +625,7 @@ void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *etdev) * * Also sets the MAC so it is syncd up properly */ -void TPAL_SetPhy10FullDuplex(struct et131x_adapter *etdev) +static void TPAL_SetPhy10FullDuplex(struct et131x_adapter *etdev) { /* Power down PHY */ ET1310_PhyPowerDown(etdev, 1); @@ -606,7 +646,7 @@ void TPAL_SetPhy10FullDuplex(struct et131x_adapter *etdev) * TPAL_SetPhy10Force - Force Base-T FD mode WITHOUT using autonegotiation * @etdev: pointer to the adapter structure */ -void TPAL_SetPhy10Force(struct et131x_adapter *etdev) +static void TPAL_SetPhy10Force(struct et131x_adapter *etdev) { /* Power down PHY */ ET1310_PhyPowerDown(etdev, 1); @@ -635,7 +675,7 @@ void TPAL_SetPhy10Force(struct et131x_adapter *etdev) * * Also sets the MAC so it is syncd up properly. */ -void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *etdev) +static void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *etdev) { /* Power down PHY */ ET1310_PhyPowerDown(etdev, 1); @@ -661,7 +701,7 @@ void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *etdev) * * Also sets the MAC so it is syncd up properly */ -void TPAL_SetPhy100FullDuplex(struct et131x_adapter *etdev) +static void TPAL_SetPhy100FullDuplex(struct et131x_adapter *etdev) { /* Power down PHY */ ET1310_PhyPowerDown(etdev, 1); @@ -682,7 +722,7 @@ void TPAL_SetPhy100FullDuplex(struct et131x_adapter *etdev) * TPAL_SetPhy100Force - Force 100 BaseT FD mode WITHOUT using autonegotiation * @etdev: pointer to the adapter structure */ -void TPAL_SetPhy100Force(struct et131x_adapter *etdev) +static void TPAL_SetPhy100Force(struct et131x_adapter *etdev) { /* Power down PHY */ ET1310_PhyPowerDown(etdev, 1); @@ -711,7 +751,7 @@ void TPAL_SetPhy100Force(struct et131x_adapter *etdev) * * Also sets the MAC so it is syncd up properly. */ -void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *etdev) +static void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *etdev) { /* Power down PHY */ ET1310_PhyPowerDown(etdev, 1); @@ -732,7 +772,7 @@ void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *etdev) * TPAL_SetPhyAutoNeg - Set phy to autonegotiation mode. * @etdev: pointer to the adapter structure */ -void TPAL_SetPhyAutoNeg(struct et131x_adapter *etdev) +static void TPAL_SetPhyAutoNeg(struct et131x_adapter *etdev) { /* Power down PHY */ ET1310_PhyPowerDown(etdev, 1); @@ -755,418 +795,380 @@ void TPAL_SetPhyAutoNeg(struct et131x_adapter *etdev) } -/* - * The routines which follow provide low-level access to the PHY, and are used - * primarily by the routines above (although there are a few places elsewhere - * in the driver where this level of access is required). - */ - -static const uint16_t ConfigPhy[25][2] = { - /* Reg Value Register */ - /* Addr */ - {0x880B, 0x0926}, /* AfeIfCreg4B1000Msbs */ - {0x880C, 0x0926}, /* AfeIfCreg4B100Msbs */ - {0x880D, 0x0926}, /* AfeIfCreg4B10Msbs */ - {0x880E, 0xB4D3}, /* AfeIfCreg4B1000Lsbs */ - {0x880F, 0xB4D3}, /* AfeIfCreg4B100Lsbs */ - {0x8810, 0xB4D3}, /* AfeIfCreg4B10Lsbs */ +/** + * et131x_xcvr_init - Init the phy if we are setting it into force mode + * @adapter: pointer to our private adapter structure + * + * Returns 0 on success, errno on failure (as defined in errno.h) + */ +static int et131x_xcvr_init(struct et131x_adapter *adapter) +{ + int status = 0; + MI_IMR_t imr; + MI_ISR_t isr; + MI_LCR2_t lcr2; - {0x8805, 0xB03E}, /* AfeIfCreg3B1000Msbs */ - {0x8806, 0xB03E}, /* AfeIfCreg3B100Msbs */ - {0x8807, 0xFF00}, /* AfeIfCreg3B10Msbs */ + /* Zero out the adapter structure variable representing BMSR */ + adapter->Bmsr.value = 0; - {0x8808, 0xE090}, /* AfeIfCreg3B1000Lsbs */ - {0x8809, 0xE110}, /* AfeIfCreg3B100Lsbs */ - {0x880A, 0x0000}, /* AfeIfCreg3B10Lsbs */ + MiRead(adapter, (u8) offsetof(MI_REGS_t, isr), &isr.value); - {0x300D, 1}, /* DisableNorm */ + MiRead(adapter, (u8) offsetof(MI_REGS_t, imr), &imr.value); - {0x280C, 0x0180}, /* LinkHoldEnd */ + /* Set the link status interrupt only. Bad behavior when link status + * and auto neg are set, we run into a nested interrupt problem + */ + imr.bits.int_en = 0x1; + imr.bits.link_status = 0x1; + imr.bits.autoneg_status = 0x1; - {0x1C21, 0x0002}, /* AlphaM */ + MiWrite(adapter, (u8) offsetof(MI_REGS_t, imr), imr.value); - {0x3821, 6}, /* FfeLkgTx0 */ - {0x381D, 1}, /* FfeLkg1g4 */ - {0x381E, 1}, /* FfeLkg1g5 */ - {0x381F, 1}, /* FfeLkg1g6 */ - {0x3820, 1}, /* FfeLkg1g7 */ + /* Set the LED behavior such that LED 1 indicates speed (off = + * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates + * link and activity (on for link, blink off for activity). + * + * NOTE: Some customizations have been added here for specific + * vendors; The LED behavior is now determined by vendor data in the + * EEPROM. However, the above description is the default. + */ + if ((adapter->eepromData[1] & 0x4) == 0) { + MiRead(adapter, (u8) offsetof(MI_REGS_t, lcr2), + &lcr2.value); + if ((adapter->eepromData[1] & 0x8) == 0) + lcr2.bits.led_tx_rx = 0x3; + else + lcr2.bits.led_tx_rx = 0x4; + lcr2.bits.led_link = 0xa; + MiWrite(adapter, (u8) offsetof(MI_REGS_t, lcr2), + lcr2.value); + } - {0x8402, 0x01F0}, /* Btinact */ - {0x800E, 20}, /* LftrainTime */ - {0x800F, 24}, /* DvguardTime */ - {0x8010, 46}, /* IdlguardTime */ + /* Determine if we need to go into a force mode and set it */ + if (adapter->AiForceSpeed == 0 && adapter->AiForceDpx == 0) { + if (adapter->RegistryFlowControl == TxOnly || + adapter->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(adapter, + TRUEPHY_BIT_SET, 4, 11, NULL); + else + ET1310_PhyAccessMiBit(adapter, + TRUEPHY_BIT_CLEAR, 4, 11, NULL); - {0, 0} + if (adapter->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(adapter, + TRUEPHY_BIT_SET, 4, 10, NULL); + else + ET1310_PhyAccessMiBit(adapter, + TRUEPHY_BIT_CLEAR, 4, 10, NULL); -}; + /* Set the phy to autonegotiation */ + ET1310_PhyAutoNeg(adapter, true); -/* condensed version of the phy initialization routine */ -void ET1310_PhyInit(struct et131x_adapter *etdev) -{ - uint16_t data, index; + /* NOTE - Do we need this? */ + ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL); + return status; + } else { + ET1310_PhyAutoNeg(adapter, false); - if (etdev == NULL) - return; - - /* get the identity (again ?) */ - MiRead(etdev, PHY_ID_1, &data); - MiRead(etdev, PHY_ID_2, &data); - - /* what does this do/achieve ? */ - MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */ - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0006); - - /* read modem register 0402, should I do something with the return - data ? */ - MiWrite(etdev, PHY_INDEX_REG, 0x0402); - MiRead(etdev, PHY_DATA_REG, &data); - - /* what does this do/achieve ? */ - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); - - /* get the identity (again ?) */ - MiRead(etdev, PHY_ID_1, &data); - MiRead(etdev, PHY_ID_2, &data); - - /* what does this achieve ? */ - MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */ - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0006); - - /* read modem register 0402, should I do something with - the return data? */ - MiWrite(etdev, PHY_INDEX_REG, 0x0402); - MiRead(etdev, PHY_DATA_REG, &data); - - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); - - /* what does this achieve (should return 0x1040) */ - MiRead(etdev, PHY_CONTROL, &data); - MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */ - MiWrite(etdev, PHY_CONTROL, 0x1840); - - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0007); - - /* here the writing of the array starts.... */ - index = 0; - while (ConfigPhy[index][0] != 0x0000) { - /* write value */ - MiWrite(etdev, PHY_INDEX_REG, ConfigPhy[index][0]); - MiWrite(etdev, PHY_DATA_REG, ConfigPhy[index][1]); - - /* read it back */ - MiWrite(etdev, PHY_INDEX_REG, ConfigPhy[index][0]); - MiRead(etdev, PHY_DATA_REG, &data); - - /* do a check on the value read back ? */ - index++; - } - /* here the writing of the array ends... */ - - MiRead(etdev, PHY_CONTROL, &data); /* 0x1840 */ - MiRead(etdev, PHY_MPHY_CONTROL_REG, &data);/* should read 0007 */ - MiWrite(etdev, PHY_CONTROL, 0x1040); - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); -} - -void ET1310_PhyReset(struct et131x_adapter *etdev) -{ - MiWrite(etdev, PHY_CONTROL, 0x8000); -} - -void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down) -{ - uint16_t data; - - MiRead(etdev, PHY_CONTROL, &data); - - if (down == false) { - /* Power UP */ - data &= ~0x0800; - MiWrite(etdev, PHY_CONTROL, data); - } else { - /* Power DOWN */ - data |= 0x0800; - MiWrite(etdev, PHY_CONTROL, data); - } -} + /* Set to the correct force mode. */ + if (adapter->AiForceDpx != 1) { + if (adapter->RegistryFlowControl == TxOnly || + adapter->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(adapter, + TRUEPHY_BIT_SET, 4, 11, + NULL); + else + ET1310_PhyAccessMiBit(adapter, + TRUEPHY_BIT_CLEAR, 4, 11, + NULL); -void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable) -{ - uint16_t data; + if (adapter->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(adapter, + TRUEPHY_BIT_SET, 4, 10, + NULL); + else + ET1310_PhyAccessMiBit(adapter, + TRUEPHY_BIT_CLEAR, 4, 10, + NULL); + } else { + ET1310_PhyAccessMiBit(adapter, + TRUEPHY_BIT_CLEAR, 4, 10, NULL); + ET1310_PhyAccessMiBit(adapter, + TRUEPHY_BIT_CLEAR, 4, 11, NULL); + } - MiRead(etdev, PHY_CONTROL, &data); + switch (adapter->AiForceSpeed) { + case 10: + if (adapter->AiForceDpx == 1) + TPAL_SetPhy10HalfDuplex(adapter); + else if (adapter->AiForceDpx == 2) + TPAL_SetPhy10FullDuplex(adapter); + else + TPAL_SetPhy10Force(adapter); + break; + case 100: + if (adapter->AiForceDpx == 1) + TPAL_SetPhy100HalfDuplex(adapter); + else if (adapter->AiForceDpx == 2) + TPAL_SetPhy100FullDuplex(adapter); + else + TPAL_SetPhy100Force(adapter); + break; + case 1000: + TPAL_SetPhy1000FullDuplex(adapter); + break; + } - if (enable == true) { - /* Autonegotiation ON */ - data |= 0x1000; - MiWrite(etdev, PHY_CONTROL, data); - } else { - /* Autonegotiation OFF */ - data &= ~0x1000; - MiWrite(etdev, PHY_CONTROL, data); + return status; } } -void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, uint16_t duplex) +void et131x_Mii_check(struct et131x_adapter *etdev, + MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints) { - uint16_t data; + u8 link_status; + u32 autoneg_status; + u32 speed; + u32 duplex; + u32 mdi_mdix; + u32 masterslave; + u32 polarity; + unsigned long flags; - MiRead(etdev, PHY_CONTROL, &data); + if (bmsr_ints.bits.link_status) { + if (bmsr.bits.link_status) { + etdev->PoMgmt.TransPhyComaModeOnBoot = 20; - if (duplex == TRUEPHY_DUPLEX_FULL) { - /* Set Full Duplex */ - data |= 0x100; - MiWrite(etdev, PHY_CONTROL, data); - } else { - /* Set Half Duplex */ - data &= ~0x100; - MiWrite(etdev, PHY_CONTROL, data); - } -} + /* Update our state variables and indicate the + * connected state + */ + spin_lock_irqsave(&etdev->Lock, flags); -void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, uint16_t speed) -{ - uint16_t data; + etdev->MediaState = NETIF_STATUS_MEDIA_CONNECT; + etdev->Flags &= ~fMP_ADAPTER_LINK_DETECTION; - /* Read the PHY control register */ - MiRead(etdev, PHY_CONTROL, &data); + spin_unlock_irqrestore(&etdev->Lock, flags); - /* Clear all Speed settings (Bits 6, 13) */ - data &= ~0x2040; + netif_carrier_on(etdev->netdev); + } else { + dev_warn(&etdev->pdev->dev, + "Link down - cable problem ?\n"); - /* Reset the speed bits based on user selection */ - switch (speed) { - case TRUEPHY_SPEED_10MBPS: - /* Bits already cleared above, do nothing */ - break; + if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { + /* NOTE - Is there a way to query this without + * TruePHY? + * && TRU_QueryCoreType(etdev->hTruePhy, 0) == EMI_TRUEPHY_A13O) { + */ + u16 Register18; - case TRUEPHY_SPEED_100MBPS: - /* 100M == Set bit 13 */ - data |= 0x2000; - break; + MiRead(etdev, 0x12, &Register18); + MiWrite(etdev, 0x12, Register18 | 0x4); + MiWrite(etdev, 0x10, Register18 | 0x8402); + MiWrite(etdev, 0x11, Register18 | 511); + MiWrite(etdev, 0x12, Register18); + } - case TRUEPHY_SPEED_1000MBPS: - default: - data |= 0x0040; - break; - } + /* For the first N seconds of life, we are in "link + * detection" When we are in this state, we should + * only report "connected". When the LinkDetection + * Timer expires, we can report disconnected (handled + * in the LinkDetectionDPC). + */ + if (!(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) || + (etdev->MediaState == NETIF_STATUS_MEDIA_DISCONNECT)) { + spin_lock_irqsave(&etdev->Lock, flags); + etdev->MediaState = + NETIF_STATUS_MEDIA_DISCONNECT; + spin_unlock_irqrestore(&etdev->Lock, + flags); - /* Write back the new speed */ - MiWrite(etdev, PHY_CONTROL, data); -} + netif_carrier_off(etdev->netdev); + } -void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev, - uint16_t duplex) -{ - uint16_t data; + etdev->linkspeed = 0; + etdev->duplex_mode = 0; - /* Read the PHY 1000 Base-T Control Register */ - MiRead(etdev, PHY_1000_CONTROL, &data); + /* Free the packets being actively sent & stopped */ + et131x_free_busy_send_packets(etdev); - /* Clear Bits 8,9 */ - data &= ~0x0300; + /* Re-initialize the send structures */ + et131x_init_send(etdev); - switch (duplex) { - case TRUEPHY_ADV_DUPLEX_NONE: - /* Duplex already cleared, do nothing */ - break; + /* Reset the RFD list and re-start RU */ + et131x_reset_recv(etdev); - case TRUEPHY_ADV_DUPLEX_FULL: - /* Set Bit 9 */ - data |= 0x0200; - break; + /* + * Bring the device back to the state it was during + * init prior to autonegotiation being complete. This + * way, when we get the auto-neg complete interrupt, + * we can complete init by calling ConfigMacREGS2. + */ + et131x_soft_reset(etdev); - case TRUEPHY_ADV_DUPLEX_HALF: - /* Set Bit 8 */ - data |= 0x0100; - break; + /* Setup ET1310 as per the documentation */ + et131x_adapter_setup(etdev); - case TRUEPHY_ADV_DUPLEX_BOTH: - default: - data |= 0x0300; - break; + /* Setup the PHY into coma mode until the cable is + * plugged back in + */ + if (etdev->RegistryPhyComa == 1) + EnablePhyComa(etdev); + } } - /* Write back advertisement */ - MiWrite(etdev, PHY_1000_CONTROL, data); -} + if (bmsr_ints.bits.auto_neg_complete || + (etdev->AiForceDpx == 3 && bmsr_ints.bits.link_status)) { + if (bmsr.bits.auto_neg_complete || etdev->AiForceDpx == 3) { + ET1310_PhyLinkStatus(etdev, + &link_status, &autoneg_status, + &speed, &duplex, &mdi_mdix, + &masterslave, &polarity); -void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *etdev, - uint16_t duplex) -{ - uint16_t data; + etdev->linkspeed = speed; + etdev->duplex_mode = duplex; - /* Read the Autonegotiation Register (10/100) */ - MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); + etdev->PoMgmt.TransPhyComaModeOnBoot = 20; - /* Clear bits 7,8 */ - data &= ~0x0180; + if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { + /* + * NOTE - Is there a way to query this without + * TruePHY? + * && TRU_QueryCoreType(etdev->hTruePhy, 0)== EMI_TRUEPHY_A13O) { + */ + u16 Register18; - switch (duplex) { - case TRUEPHY_ADV_DUPLEX_NONE: - /* Duplex already cleared, do nothing */ - break; + MiRead(etdev, 0x12, &Register18); + MiWrite(etdev, 0x12, Register18 | 0x4); + MiWrite(etdev, 0x10, Register18 | 0x8402); + MiWrite(etdev, 0x11, Register18 | 511); + MiWrite(etdev, 0x12, Register18); + } - case TRUEPHY_ADV_DUPLEX_FULL: - /* Set Bit 8 */ - data |= 0x0100; - break; + ConfigFlowControl(etdev); - case TRUEPHY_ADV_DUPLEX_HALF: - /* Set Bit 7 */ - data |= 0x0080; - break; + if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS && + etdev->RegistryJumboPacket > 2048) + ET1310_PhyAndOrReg(etdev, 0x16, 0xcfff, + 0x2000); - case TRUEPHY_ADV_DUPLEX_BOTH: - default: - /* Set Bits 7,8 */ - data |= 0x0180; - break; + SetRxDmaTimer(etdev); + ConfigMACRegs2(etdev); + } } - - /* Write back advertisement */ - MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); } -void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev, - uint16_t duplex) -{ - uint16_t data; - - /* Read the Autonegotiation Register (10/100) */ - MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); - - /* Clear bits 5,6 */ - data &= ~0x0060; +/* + * The routines which follow provide low-level access to the PHY, and are used + * primarily by the routines above (although there are a few places elsewhere + * in the driver where this level of access is required). + */ - switch (duplex) { - case TRUEPHY_ADV_DUPLEX_NONE: - /* Duplex already cleared, do nothing */ - break; +static const u16 ConfigPhy[25][2] = { + /* Reg Value Register */ + /* Addr */ + {0x880B, 0x0926}, /* AfeIfCreg4B1000Msbs */ + {0x880C, 0x0926}, /* AfeIfCreg4B100Msbs */ + {0x880D, 0x0926}, /* AfeIfCreg4B10Msbs */ - case TRUEPHY_ADV_DUPLEX_FULL: - /* Set Bit 6 */ - data |= 0x0040; - break; + {0x880E, 0xB4D3}, /* AfeIfCreg4B1000Lsbs */ + {0x880F, 0xB4D3}, /* AfeIfCreg4B100Lsbs */ + {0x8810, 0xB4D3}, /* AfeIfCreg4B10Lsbs */ - case TRUEPHY_ADV_DUPLEX_HALF: - /* Set Bit 5 */ - data |= 0x0020; - break; + {0x8805, 0xB03E}, /* AfeIfCreg3B1000Msbs */ + {0x8806, 0xB03E}, /* AfeIfCreg3B100Msbs */ + {0x8807, 0xFF00}, /* AfeIfCreg3B10Msbs */ - case TRUEPHY_ADV_DUPLEX_BOTH: - default: - /* Set Bits 5,6 */ - data |= 0x0060; - break; - } + {0x8808, 0xE090}, /* AfeIfCreg3B1000Lsbs */ + {0x8809, 0xE110}, /* AfeIfCreg3B100Lsbs */ + {0x880A, 0x0000}, /* AfeIfCreg3B10Lsbs */ - /* Write back advertisement */ - MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); -} + {0x300D, 1}, /* DisableNorm */ -void ET1310_PhyLinkStatus(struct et131x_adapter *etdev, - uint8_t *link_status, - uint32_t *autoneg, - uint32_t *linkspeed, - uint32_t *duplex_mode, - uint32_t *mdi_mdix, - uint32_t *masterslave, uint32_t *polarity) -{ - uint16_t mistatus = 0; - uint16_t is1000BaseT = 0; - uint16_t vmi_phystatus = 0; - uint16_t control = 0; + {0x280C, 0x0180}, /* LinkHoldEnd */ - MiRead(etdev, PHY_STATUS, &mistatus); - MiRead(etdev, PHY_1000_STATUS, &is1000BaseT); - MiRead(etdev, PHY_PHY_STATUS, &vmi_phystatus); - MiRead(etdev, PHY_CONTROL, &control); + {0x1C21, 0x0002}, /* AlphaM */ - if (link_status) { - *link_status = - (unsigned char)((vmi_phystatus & 0x0040) ? 1 : 0); - } + {0x3821, 6}, /* FfeLkgTx0 */ + {0x381D, 1}, /* FfeLkg1g4 */ + {0x381E, 1}, /* FfeLkg1g5 */ + {0x381F, 1}, /* FfeLkg1g6 */ + {0x3820, 1}, /* FfeLkg1g7 */ - if (autoneg) { - *autoneg = - (control & 0x1000) ? ((vmi_phystatus & 0x0020) ? - TRUEPHY_ANEG_COMPLETE : - TRUEPHY_ANEG_NOT_COMPLETE) : - TRUEPHY_ANEG_DISABLED; - } + {0x8402, 0x01F0}, /* Btinact */ + {0x800E, 20}, /* LftrainTime */ + {0x800F, 24}, /* DvguardTime */ + {0x8010, 46}, /* IdlguardTime */ - if (linkspeed) - *linkspeed = (vmi_phystatus & 0x0300) >> 8; + {0, 0} - if (duplex_mode) - *duplex_mode = (vmi_phystatus & 0x0080) >> 7; +}; - if (mdi_mdix) - /* NOTE: Need to complete this */ - *mdi_mdix = 0; +/* condensed version of the phy initialization routine */ +void ET1310_PhyInit(struct et131x_adapter *etdev) +{ + u16 data, index; - if (masterslave) { - *masterslave = - (is1000BaseT & 0x4000) ? TRUEPHY_CFG_MASTER : - TRUEPHY_CFG_SLAVE; - } + if (etdev == NULL) + return; - if (polarity) { - *polarity = - (vmi_phystatus & 0x0400) ? TRUEPHY_POLARITY_INVERTED : - TRUEPHY_POLARITY_NORMAL; - } -} + /* get the identity (again ?) */ + MiRead(etdev, PHY_ID_1, &data); + MiRead(etdev, PHY_ID_2, &data); -void ET1310_PhyAndOrReg(struct et131x_adapter *etdev, - uint16_t regnum, uint16_t andMask, uint16_t orMask) -{ - uint16_t reg; + /* what does this do/achieve ? */ + MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */ + MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0006); - /* Read the requested register */ - MiRead(etdev, regnum, ®); + /* read modem register 0402, should I do something with the return + data ? */ + MiWrite(etdev, PHY_INDEX_REG, 0x0402); + MiRead(etdev, PHY_DATA_REG, &data); - /* Apply the AND mask */ - reg &= andMask; + /* what does this do/achieve ? */ + MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); - /* Apply the OR mask */ - reg |= orMask; + /* get the identity (again ?) */ + MiRead(etdev, PHY_ID_1, &data); + MiRead(etdev, PHY_ID_2, &data); - /* Write the value back to the register */ - MiWrite(etdev, regnum, reg); -} + /* what does this achieve ? */ + MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */ + MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0006); -void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, uint16_t action, - uint16_t regnum, uint16_t bitnum, uint8_t *value) -{ - uint16_t reg; - uint16_t mask = 0; + /* read modem register 0402, should I do something with + the return data? */ + MiWrite(etdev, PHY_INDEX_REG, 0x0402); + MiRead(etdev, PHY_DATA_REG, &data); - /* Create a mask to isolate the requested bit */ - mask = 0x0001 << bitnum; + MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); - /* Read the requested register */ - MiRead(etdev, regnum, ®); + /* what does this achieve (should return 0x1040) */ + MiRead(etdev, PHY_CONTROL, &data); + MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */ + MiWrite(etdev, PHY_CONTROL, 0x1840); - switch (action) { - case TRUEPHY_BIT_READ: - if (value != NULL) - *value = (reg & mask) >> bitnum; - break; + MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0007); - case TRUEPHY_BIT_SET: - reg |= mask; - MiWrite(etdev, regnum, reg); - break; + /* here the writing of the array starts.... */ + index = 0; + while (ConfigPhy[index][0] != 0x0000) { + /* write value */ + MiWrite(etdev, PHY_INDEX_REG, ConfigPhy[index][0]); + MiWrite(etdev, PHY_DATA_REG, ConfigPhy[index][1]); - case TRUEPHY_BIT_CLEAR: - reg &= ~mask; - MiWrite(etdev, regnum, reg); - break; + /* read it back */ + MiWrite(etdev, PHY_INDEX_REG, ConfigPhy[index][0]); + MiRead(etdev, PHY_DATA_REG, &data); - default: - break; + /* do a check on the value read back ? */ + index++; } + /* here the writing of the array ends... */ + + MiRead(etdev, PHY_CONTROL, &data); /* 0x1840 */ + MiRead(etdev, PHY_MPHY_CONTROL_REG, &data);/* should read 0007 */ + MiWrite(etdev, PHY_CONTROL, 0x1040); + MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); } + diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h index 6978b25c7e13..0ea12378fdaa 100644 --- a/drivers/staging/et131x/et1310_phy.h +++ b/drivers/staging/et131x/et1310_phy.h @@ -739,25 +739,15 @@ typedef union _MI_LCR2_t { /* Forward declaration of the private adapter structure */ struct et131x_adapter; -/* OS Specific Functions*/ -void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *adapter); -void TPAL_SetPhy10FullDuplex(struct et131x_adapter *adapter); -void TPAL_SetPhy10Force(struct et131x_adapter *pAdapter); -void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *adapter); -void TPAL_SetPhy100FullDuplex(struct et131x_adapter *adapter); -void TPAL_SetPhy100Force(struct et131x_adapter *pAdapter); -void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *adapter); -void TPAL_SetPhyAutoNeg(struct et131x_adapter *adapter); - /* Prototypes for ET1310_phy.c */ int et131x_xcvr_find(struct et131x_adapter *adapter); int et131x_setphy_normal(struct et131x_adapter *adapter); -int32_t PhyMiRead(struct et131x_adapter *adapter, - u8 xcvrAddr, u8 xcvrReg, u16 *value); /* static inline function does not work because et131x_adapter is not always * defined */ +int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, + u8 xcvrReg, u16 *value); #define MiRead(adapter, xcvrReg, value) \ PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value)) @@ -857,24 +847,8 @@ void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter); void ET1310_PhyInit(struct et131x_adapter *adapter); void ET1310_PhyReset(struct et131x_adapter *adapter); void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down); -void ET1310_PhyAutoNeg(struct et131x_adapter *adapter, bool enable); -void ET1310_PhyDuplexMode(struct et131x_adapter *adapter, u16 duplex); -void ET1310_PhySpeedSelect(struct et131x_adapter *adapter, u16 speed); void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter, u16 duplex); -void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *adapter, - u16 duplex); -void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *adapter, - u16 duplex); -void ET1310_PhyLinkStatus(struct et131x_adapter *adapter, - u8 *Link_status, - u32 *autoneg, - u32 *linkspeed, - u32 *duplex_mode, - u32 *mdi_mdix, - u32 *masterslave, u32 *polarity); -void ET1310_PhyAndOrReg(struct et131x_adapter *adapter, - u16 regnum, u16 andMask, u16 orMask); void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter, u16 action, u16 regnum, u16 bitnum, u8 *value); -- cgit v1.2.3 From 2a90822762cad4c0706a09a867bb54ede90537d8 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 6 Oct 2009 15:51:17 +0100 Subject: Staging: et131x: Clean up the phy code, especially dup stuff Fold in the TPAL stuff and remove the duplication Clean up other stuff where we do un-needed work or have verbose implementations Comment some of the functions as we go Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_phy.c | 622 +++++++++++++----------------------- drivers/staging/et131x/et1310_phy.h | 2 +- 2 files changed, 215 insertions(+), 409 deletions(-) (limited to 'drivers/staging/et131x/et1310_phy.h') diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index c1aedbb2469a..6ecad619f779 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -98,21 +98,21 @@ #include "et1310_mac.h" /* Prototypes for functions with local scope */ -static int et131x_xcvr_init(struct et131x_adapter *adapter); +static void et131x_xcvr_init(struct et131x_adapter *etdev); /** * PhyMiRead - Read from the PHY through the MII Interface on the MAC - * @adapter: pointer to our private adapter structure + * @etdev: pointer to our private adapter structure * @xcvrAddr: the address of the transciever * @xcvrReg: the register to read * @value: pointer to a 16-bit value in which the value will be stored * * Returns 0 on success, errno on failure (as defined in errno.h) */ -int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, +int PhyMiRead(struct et131x_adapter *etdev, u8 xcvrAddr, u8 xcvrReg, u16 *value) { - struct _MAC_t __iomem *mac = &adapter->regs->mac; + struct _MAC_t __iomem *mac = &etdev->regs->mac; int status = 0; u32 delay; u32 miiAddr; @@ -144,9 +144,9 @@ int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, /* If we hit the max delay, we could not read the register */ if (delay == 50) { - dev_warn(&adapter->pdev->dev, + dev_warn(&etdev->pdev->dev, "xcvrReg 0x%08x could not be read\n", xcvrReg); - dev_warn(&adapter->pdev->dev, "status is 0x%08x\n", + dev_warn(&etdev->pdev->dev, "status is 0x%08x\n", miiIndicator); status = -EIO; @@ -170,7 +170,7 @@ int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, /** * MiWrite - Write to a PHY register through the MII interface of the MAC - * @adapter: pointer to our private adapter structure + * @etdev: pointer to our private adapter structure * @xcvrReg: the register to read * @value: 16-bit value to write * @@ -178,11 +178,11 @@ int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, * * Return 0 on success, errno on failure (as defined in errno.h) */ -int MiWrite(struct et131x_adapter *adapter, u8 xcvrReg, u16 value) +int MiWrite(struct et131x_adapter *etdev, u8 xcvrReg, u16 value) { - struct _MAC_t __iomem *mac = &adapter->regs->mac; + struct _MAC_t __iomem *mac = &etdev->regs->mac; int status = 0; - u8 xcvrAddr = adapter->Stats.xcvr_addr; + u8 xcvrAddr = etdev->Stats.xcvr_addr; u32 delay; u32 miiAddr; u32 miiCmd; @@ -214,14 +214,14 @@ int MiWrite(struct et131x_adapter *adapter, u8 xcvrReg, u16 value) if (delay == 100) { u16 TempValue; - dev_warn(&adapter->pdev->dev, + dev_warn(&etdev->pdev->dev, "xcvrReg 0x%08x could not be written", xcvrReg); - dev_warn(&adapter->pdev->dev, "status is 0x%08x\n", + dev_warn(&etdev->pdev->dev, "status is 0x%08x\n", miiIndicator); - dev_warn(&adapter->pdev->dev, "command is 0x%08x\n", + dev_warn(&etdev->pdev->dev, "command is 0x%08x\n", readl(&mac->mii_mgmt_cmd)); - MiRead(adapter, xcvrReg, &TempValue); + MiRead(etdev, xcvrReg, &TempValue); status = -EIO; } @@ -239,13 +239,12 @@ int MiWrite(struct et131x_adapter *adapter, u8 xcvrReg, u16 value) /** * et131x_xcvr_find - Find the PHY ID - * @adapter: pointer to our private adapter structure + * @etdev: pointer to our private adapter structure * * Returns 0 on success, errno on failure (as defined in errno.h) */ -int et131x_xcvr_find(struct et131x_adapter *adapter) +int et131x_xcvr_find(struct et131x_adapter *etdev) { - int status = -ENODEV; u8 xcvr_addr; MI_IDR1_t idr1; MI_IDR2_t idr2; @@ -254,42 +253,22 @@ int et131x_xcvr_find(struct et131x_adapter *adapter) /* We need to get xcvr id and address we just get the first one */ for (xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++) { /* Read the ID from the PHY */ - PhyMiRead(adapter, xcvr_addr, + PhyMiRead(etdev, xcvr_addr, (u8) offsetof(MI_REGS_t, idr1), &idr1.value); - PhyMiRead(adapter, xcvr_addr, + PhyMiRead(etdev, xcvr_addr, (u8) offsetof(MI_REGS_t, idr2), &idr2.value); xcvr_id = (u32) ((idr1.value << 16) | idr2.value); - if ((idr1.value != 0) && (idr1.value != 0xffff)) { - adapter->Stats.xcvr_id = xcvr_id; - adapter->Stats.xcvr_addr = xcvr_addr; - - status = 0; - break; + if (idr1.value != 0 && idr1.value != 0xffff) { + etdev->Stats.xcvr_id = xcvr_id; + etdev->Stats.xcvr_addr = xcvr_addr; + return 0; } } - return status; -} - -/** - * et131x_setphy_normal - Set PHY for normal operation. - * @adapter: pointer to our private adapter structure - * - * Used by Power Management to force the PHY into 10 Base T half-duplex mode, - * when going to D3 in WOL mode. Also used during initialization to set the - * PHY for normal operation. - */ -int et131x_setphy_normal(struct et131x_adapter *adapter) -{ - int status; - - /* Make sure the PHY is powered up */ - ET1310_PhyPowerDown(adapter, 0); - status = et131x_xcvr_init(adapter); - return status; + return -ENODEV; } void ET1310_PhyReset(struct et131x_adapter *etdev) @@ -297,88 +276,105 @@ void ET1310_PhyReset(struct et131x_adapter *etdev) MiWrite(etdev, PHY_CONTROL, 0x8000); } +/** + * ET1310_PhyPowerDown - PHY power control + * @etdev: device to control + * @down: true for off/false for back on + * + * one hundred, ten, one thousand megs + * How would you like to have your LAN accessed + * Can't you see that this code processed + * Phy power, phy power.. + */ + void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down) { u16 data; MiRead(etdev, PHY_CONTROL, &data); - - if (down == false) { - /* Power UP */ - data &= ~0x0800; - MiWrite(etdev, PHY_CONTROL, data); - } else { - /* Power DOWN */ + data &= ~0x0800; /* Power UP */ + if (down) /* Power DOWN */ data |= 0x0800; - MiWrite(etdev, PHY_CONTROL, data); - } + MiWrite(etdev, PHY_CONTROL, data); } +/** + * ET130_PhyAutoNEg - autonegotiate control + * @etdev: device to control + * @enabe: autoneg on/off + * + * Set up the autonegotiation state according to whether we will be + * negotiating the state or forcing a speed. + */ + static void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable) { u16 data; MiRead(etdev, PHY_CONTROL, &data); - - if (enable == true) { - /* Autonegotiation ON */ - data |= 0x1000; - MiWrite(etdev, PHY_CONTROL, data); - } else { - /* Autonegotiation OFF */ - data &= ~0x1000; - MiWrite(etdev, PHY_CONTROL, data); - } + data &= ~0x1000; /* Autonegotiation OFF */ + if (enable) + data |= 0x1000; /* Autonegotiation ON */ + MiWrite(etdev, PHY_CONTROL, data); } +/** + * ET130_PhyDuplexMode - duplex control + * @etdev: device to control + * @duplex: duplex on/off + * + * Set up the duplex state on the PHY + */ + static void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, u16 duplex) { u16 data; MiRead(etdev, PHY_CONTROL, &data); - - if (duplex == TRUEPHY_DUPLEX_FULL) { - /* Set Full Duplex */ - data |= 0x100; - MiWrite(etdev, PHY_CONTROL, data); - } else { - /* Set Half Duplex */ - data &= ~0x100; - MiWrite(etdev, PHY_CONTROL, data); - } + data &= ~0x100; /* Set Half Duplex */ + if (duplex == TRUEPHY_DUPLEX_FULL) + data |= 0x100; /* Set Full Duplex */ + MiWrite(etdev, PHY_CONTROL, data); } +/** + * ET130_PhySpeedSelect - speed control + * @etdev: device to control + * @duplex: duplex on/off + * + * Set the speed of our PHY. + */ + static void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, u16 speed) { u16 data; + static const u16 bits[3]={0x0000, 0x2000, 0x0040}; /* Read the PHY control register */ MiRead(etdev, PHY_CONTROL, &data); - /* Clear all Speed settings (Bits 6, 13) */ data &= ~0x2040; - - /* Reset the speed bits based on user selection */ - switch (speed) { - case TRUEPHY_SPEED_10MBPS: - /* Bits already cleared above, do nothing */ - break; - - case TRUEPHY_SPEED_100MBPS: - /* 100M == Set bit 13 */ - data |= 0x2000; - break; - - case TRUEPHY_SPEED_1000MBPS: - default: - data |= 0x0040; - break; - } - /* Write back the new speed */ - MiWrite(etdev, PHY_CONTROL, data); + MiWrite(etdev, PHY_CONTROL, data | bits[speed]); } +/** + * ET1310_PhyLinkStatus - read link state + * @etdev: device to read + * @link_status: reported link state + * @autoneg: reported autonegotiation state (complete/incomplete/disabled) + * @linkspeed: returnedlink speed in use + * @duplex_mode: reported half/full duplex state + * @mdi_mdix: not yet working + * @masterslave: report whether we are master or slave + * @polarity: link polarity + * + * I can read your lan like a magazine + * I see if your up + * I know your link speed + * I see all the setting that you'd rather keep + */ + static void ET1310_PhyLinkStatus(struct et131x_adapter *etdev, u8 *link_status, u32 *autoneg, @@ -397,40 +393,20 @@ static void ET1310_PhyLinkStatus(struct et131x_adapter *etdev, MiRead(etdev, PHY_PHY_STATUS, &vmi_phystatus); MiRead(etdev, PHY_CONTROL, &control); - if (link_status) { - *link_status = - (unsigned char)((vmi_phystatus & 0x0040) ? 1 : 0); - } - - if (autoneg) { - *autoneg = - (control & 0x1000) ? ((vmi_phystatus & 0x0020) ? + *link_status = (vmi_phystatus & 0x0040) ? 1 : 0; + *autoneg = (control & 0x1000) ? ((vmi_phystatus & 0x0020) ? TRUEPHY_ANEG_COMPLETE : TRUEPHY_ANEG_NOT_COMPLETE) : TRUEPHY_ANEG_DISABLED; - } - - if (linkspeed) - *linkspeed = (vmi_phystatus & 0x0300) >> 8; - - if (duplex_mode) - *duplex_mode = (vmi_phystatus & 0x0080) >> 7; - - if (mdi_mdix) - /* NOTE: Need to complete this */ - *mdi_mdix = 0; - - if (masterslave) { - *masterslave = - (is1000BaseT & 0x4000) ? TRUEPHY_CFG_MASTER : - TRUEPHY_CFG_SLAVE; - } - - if (polarity) { - *polarity = - (vmi_phystatus & 0x0400) ? TRUEPHY_POLARITY_INVERTED : - TRUEPHY_POLARITY_NORMAL; - } + *linkspeed = (vmi_phystatus & 0x0300) >> 8; + *duplex_mode = (vmi_phystatus & 0x0080) >> 7; + /* NOTE: Need to complete this */ + *mdi_mdix = 0; + + *masterslave = (is1000BaseT & 0x4000) ? + TRUEPHY_CFG_MASTER : TRUEPHY_CFG_SLAVE; + *polarity = (vmi_phystatus & 0x0400) ? + TRUEPHY_POLARITY_INVERTED : TRUEPHY_POLARITY_NORMAL; } static void ET1310_PhyAndOrReg(struct et131x_adapter *etdev, @@ -438,46 +414,33 @@ static void ET1310_PhyAndOrReg(struct et131x_adapter *etdev, { u16 reg; - /* Read the requested register */ MiRead(etdev, regnum, ®); - - /* Apply the AND mask */ reg &= andMask; - - /* Apply the OR mask */ reg |= orMask; - - /* Write the value back to the register */ MiWrite(etdev, regnum, reg); } -/* Still used from _mac */ +/* Still used from _mac for BIT_READ */ void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, u16 action, u16 regnum, u16 bitnum, u8 *value) { u16 reg; - u16 mask = 0; - - /* Create a mask to isolate the requested bit */ - mask = 0x0001 << bitnum; + u16 mask = 0x0001 << bitnum; /* Read the requested register */ MiRead(etdev, regnum, ®); switch (action) { case TRUEPHY_BIT_READ: - if (value != NULL) - *value = (reg & mask) >> bitnum; + *value = (reg & mask) >> bitnum; break; case TRUEPHY_BIT_SET: - reg |= mask; - MiWrite(etdev, regnum, reg); + MiWrite(etdev, regnum, reg | mask); break; case TRUEPHY_BIT_CLEAR: - reg &= ~mask; - MiWrite(etdev, regnum, reg); + MiWrite(etdev, regnum, reg & ~mask); break; default: @@ -595,226 +558,38 @@ static void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev, MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); } - /** - * TPAL_SetPhy10HalfDuplex - Force the phy into 10 Base T Half Duplex mode. - * @etdev: pointer to the adapter structure - * - * Also sets the MAC so it is syncd up properly - */ -static void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* First we need to turn off all other advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Set our advertise values accordingly */ - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_HALF); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy10FullDuplex - Force the phy into 10 Base T Full Duplex mode. - * @etdev: pointer to the adapter structure - * - * Also sets the MAC so it is syncd up properly - */ -static void TPAL_SetPhy10FullDuplex(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* First we need to turn off all other advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Set our advertise values accordingly */ - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy10Force - Force Base-T FD mode WITHOUT using autonegotiation - * @etdev: pointer to the adapter structure - */ -static void TPAL_SetPhy10Force(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* Disable autoneg */ - ET1310_PhyAutoNeg(etdev, false); - - /* Disable all advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Force 10 Mbps */ - ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_10MBPS); - - /* Force Full duplex */ - ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy100HalfDuplex - Force 100 Base T Half Duplex mode. - * @etdev: pointer to the adapter structure - * - * Also sets the MAC so it is syncd up properly. - */ -static void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* first we need to turn off all other advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Set our advertise values accordingly */ - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_HALF); - - /* Set speed */ - ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy100FullDuplex - Force 100 Base T Full Duplex mode. - * @etdev: pointer to the adapter structure - * - * Also sets the MAC so it is syncd up properly - */ -static void TPAL_SetPhy100FullDuplex(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* First we need to turn off all other advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Set our advertise values accordingly */ - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy100Force - Force 100 BaseT FD mode WITHOUT using autonegotiation - * @etdev: pointer to the adapter structure - */ -static void TPAL_SetPhy100Force(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* Disable autoneg */ - ET1310_PhyAutoNeg(etdev, false); - - /* Disable all advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Force 100 Mbps */ - ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS); - - /* Force Full duplex */ - ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy1000FullDuplex - Force 1000 Base T Full Duplex mode - * @etdev: pointer to the adapter structure + * et131x_setphy_normal - Set PHY for normal operation. + * @etdev: pointer to our private adapter structure * - * Also sets the MAC so it is syncd up properly. - */ -static void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* first we need to turn off all other advertisement */ - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* set our advertise values accordingly */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); - - /* power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhyAutoNeg - Set phy to autonegotiation mode. - * @etdev: pointer to the adapter structure + * Used by Power Management to force the PHY into 10 Base T half-duplex mode, + * when going to D3 in WOL mode. Also used during initialization to set the + * PHY for normal operation. */ -static void TPAL_SetPhyAutoNeg(struct et131x_adapter *etdev) +void et131x_setphy_normal(struct et131x_adapter *etdev) { - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* Turn on advertisement of all capabilities */ - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_BOTH); - - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_BOTH); - - if (etdev->pdev->device != ET131X_PCI_DEVICE_ID_FAST) - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); - else - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Make sure auto-neg is ON (it is disabled in FORCE modes) */ - ET1310_PhyAutoNeg(etdev, true); - - /* Power up PHY */ + /* Make sure the PHY is powered up */ ET1310_PhyPowerDown(etdev, 0); + et131x_xcvr_init(etdev); } - /** * et131x_xcvr_init - Init the phy if we are setting it into force mode - * @adapter: pointer to our private adapter structure + * @etdev: pointer to our private adapter structure * - * Returns 0 on success, errno on failure (as defined in errno.h) */ -static int et131x_xcvr_init(struct et131x_adapter *adapter) +static void et131x_xcvr_init(struct et131x_adapter *etdev) { - int status = 0; MI_IMR_t imr; MI_ISR_t isr; MI_LCR2_t lcr2; /* Zero out the adapter structure variable representing BMSR */ - adapter->Bmsr.value = 0; - - MiRead(adapter, (u8) offsetof(MI_REGS_t, isr), &isr.value); + etdev->Bmsr.value = 0; - MiRead(adapter, (u8) offsetof(MI_REGS_t, imr), &imr.value); + MiRead(etdev, (u8) offsetof(MI_REGS_t, isr), &isr.value); + MiRead(etdev, (u8) offsetof(MI_REGS_t, imr), &imr.value); /* Set the link status interrupt only. Bad behavior when link status * and auto neg are set, we run into a nested interrupt problem @@ -823,7 +598,7 @@ static int et131x_xcvr_init(struct et131x_adapter *adapter) imr.bits.link_status = 0x1; imr.bits.autoneg_status = 0x1; - MiWrite(adapter, (u8) offsetof(MI_REGS_t, imr), imr.value); + MiWrite(etdev, (u8) offsetof(MI_REGS_t, imr), imr.value); /* Set the LED behavior such that LED 1 indicates speed (off = * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates @@ -833,95 +608,126 @@ static int et131x_xcvr_init(struct et131x_adapter *adapter) * vendors; The LED behavior is now determined by vendor data in the * EEPROM. However, the above description is the default. */ - if ((adapter->eepromData[1] & 0x4) == 0) { - MiRead(adapter, (u8) offsetof(MI_REGS_t, lcr2), + if ((etdev->eepromData[1] & 0x4) == 0) { + MiRead(etdev, (u8) offsetof(MI_REGS_t, lcr2), &lcr2.value); - if ((adapter->eepromData[1] & 0x8) == 0) + if ((etdev->eepromData[1] & 0x8) == 0) lcr2.bits.led_tx_rx = 0x3; else lcr2.bits.led_tx_rx = 0x4; lcr2.bits.led_link = 0xa; - MiWrite(adapter, (u8) offsetof(MI_REGS_t, lcr2), + MiWrite(etdev, (u8) offsetof(MI_REGS_t, lcr2), lcr2.value); } /* Determine if we need to go into a force mode and set it */ - if (adapter->AiForceSpeed == 0 && adapter->AiForceDpx == 0) { - if (adapter->RegistryFlowControl == TxOnly || - adapter->RegistryFlowControl == Both) - ET1310_PhyAccessMiBit(adapter, + if (etdev->AiForceSpeed == 0 && etdev->AiForceDpx == 0) { + if (etdev->RegistryFlowControl == TxOnly || + etdev->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 4, 11, NULL); else - ET1310_PhyAccessMiBit(adapter, + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 11, NULL); - if (adapter->RegistryFlowControl == Both) - ET1310_PhyAccessMiBit(adapter, + if (etdev->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 4, 10, NULL); else - ET1310_PhyAccessMiBit(adapter, + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 10, NULL); /* Set the phy to autonegotiation */ - ET1310_PhyAutoNeg(adapter, true); + ET1310_PhyAutoNeg(etdev, true); /* NOTE - Do we need this? */ - ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL); - return status; + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 0, 9, NULL); + return; + } + + ET1310_PhyAutoNeg(etdev, false); + + /* Set to the correct force mode. */ + if (etdev->AiForceDpx != 1) { + if (etdev->RegistryFlowControl == TxOnly || + etdev->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(etdev, + TRUEPHY_BIT_SET, 4, 11, NULL); + else + ET1310_PhyAccessMiBit(etdev, + TRUEPHY_BIT_CLEAR, 4, 11, NULL); + + if (etdev->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(etdev, + TRUEPHY_BIT_SET, 4, 10, NULL); + else + ET1310_PhyAccessMiBit(etdev, + TRUEPHY_BIT_CLEAR, 4, 10, NULL); } else { - ET1310_PhyAutoNeg(adapter, false); - - /* Set to the correct force mode. */ - if (adapter->AiForceDpx != 1) { - if (adapter->RegistryFlowControl == TxOnly || - adapter->RegistryFlowControl == Both) - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_SET, 4, 11, - NULL); - else - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 11, - NULL); - - if (adapter->RegistryFlowControl == Both) - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_SET, 4, 10, - NULL); - else - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 10, - NULL); + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 10, NULL); + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 11, NULL); + } + ET1310_PhyPowerDown(etdev, 1); + switch (etdev->AiForceSpeed) { + case 10: + /* First we need to turn off all other advertisement */ + ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + if (etdev->AiForceDpx == 1) { + /* Set our advertise values accordingly */ + ET1310_PhyAdvertise10BaseT(etdev, + TRUEPHY_ADV_DUPLEX_HALF); + } else if (etdev->AiForceDpx == 2) { + /* Set our advertise values accordingly */ + ET1310_PhyAdvertise10BaseT(etdev, + TRUEPHY_ADV_DUPLEX_FULL); } else { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 10, NULL); - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 11, NULL); + /* Disable autoneg */ + ET1310_PhyAutoNeg(etdev, false); + /* Disable rest of the advertisements */ + ET1310_PhyAdvertise10BaseT(etdev, + TRUEPHY_ADV_DUPLEX_NONE); + /* Force 10 Mbps */ + ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_10MBPS); + /* Force Full duplex */ + ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL); } - - switch (adapter->AiForceSpeed) { - case 10: - if (adapter->AiForceDpx == 1) - TPAL_SetPhy10HalfDuplex(adapter); - else if (adapter->AiForceDpx == 2) - TPAL_SetPhy10FullDuplex(adapter); - else - TPAL_SetPhy10Force(adapter); - break; - case 100: - if (adapter->AiForceDpx == 1) - TPAL_SetPhy100HalfDuplex(adapter); - else if (adapter->AiForceDpx == 2) - TPAL_SetPhy100FullDuplex(adapter); - else - TPAL_SetPhy100Force(adapter); - break; - case 1000: - TPAL_SetPhy1000FullDuplex(adapter); - break; + break; + case 100: + /* first we need to turn off all other advertisement */ + ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + if (etdev->AiForceDpx == 1) { + /* Set our advertise values accordingly */ + ET1310_PhyAdvertise100BaseT(etdev, + TRUEPHY_ADV_DUPLEX_HALF); + /* Set speed */ + ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS); + } else if (etdev->AiForceDpx == 2) { + /* Set our advertise values accordingly */ + ET1310_PhyAdvertise100BaseT(etdev, + TRUEPHY_ADV_DUPLEX_FULL); + } else { + /* Disable autoneg */ + ET1310_PhyAutoNeg(etdev, false); + /* Disable other advertisement */ + ET1310_PhyAdvertise100BaseT(etdev, + TRUEPHY_ADV_DUPLEX_NONE); + /* Force 100 Mbps */ + ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS); + /* Force Full duplex */ + ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL); } - - return status; + break; + case 1000: + /* first we need to turn off all other advertisement */ + ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + /* set our advertise values accordingly */ + ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); + break; } + ET1310_PhyPowerDown(etdev, 0); } void et131x_Mii_check(struct et131x_adapter *etdev, diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h index 0ea12378fdaa..758b9b251715 100644 --- a/drivers/staging/et131x/et1310_phy.h +++ b/drivers/staging/et131x/et1310_phy.h @@ -741,7 +741,7 @@ struct et131x_adapter; /* Prototypes for ET1310_phy.c */ int et131x_xcvr_find(struct et131x_adapter *adapter); -int et131x_setphy_normal(struct et131x_adapter *adapter); +void et131x_setphy_normal(struct et131x_adapter *adapter); /* static inline function does not work because et131x_adapter is not always * defined -- cgit v1.2.3