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; mask = 0x0001 << bitnum; 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; } }
/* 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 = 0x0001 << bitnum; /* Read the requested register */ MiRead(etdev, regnum, ®); switch (action) { case TRUEPHY_BIT_READ: *value = (reg & mask) >> bitnum; break; case TRUEPHY_BIT_SET: MiWrite(etdev, regnum, reg | mask); break; case TRUEPHY_BIT_CLEAR: MiWrite(etdev, regnum, reg & ~mask); break; default: break; } }
void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, uint16_t speed) { uint16_t data; /* 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); }
void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev, uint16_t duplex) { uint16_t data; MiRead(etdev, PHY_1000_CONTROL, &data); data &= ~0x0300; switch (duplex) { case TRUEPHY_ADV_DUPLEX_NONE: break; case TRUEPHY_ADV_DUPLEX_FULL: data |= 0x0200; break; case TRUEPHY_ADV_DUPLEX_HALF: data |= 0x0100; break; case TRUEPHY_ADV_DUPLEX_BOTH: default: data |= 0x0300; break; } MiWrite(etdev, PHY_1000_CONTROL, data); }
/** * et131x_ioctl_mii - The function which handles MII IOCTLs * @netdev: device on which the query is being made * @reqbuf: the request-specific data buffer * @cmd: the command request code * * Returns 0 on success, errno on failure (as defined in errno.h) */ int et131x_ioctl_mii(struct net_device *netdev, struct ifreq *reqbuf, int cmd) { int status = 0; struct et131x_adapter *etdev = netdev_priv(netdev); struct mii_ioctl_data *data = if_mii(reqbuf); switch (cmd) { case SIOCGMIIPHY: data->phy_id = etdev->Stats.xcvr_addr; break; case SIOCGMIIREG: if (!capable(CAP_NET_ADMIN)) status = -EPERM; else status = MiRead(etdev, data->reg_num, &data->val_out); break; case SIOCSMIIREG: if (!capable(CAP_NET_ADMIN)) status = -EPERM; else status = MiWrite(etdev, data->reg_num, data->val_in); break; default: status = -EOPNOTSUPP; } return status; }
void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, uint16_t speed) { uint16_t data; MiRead(etdev, PHY_CONTROL, &data); data &= ~0x2040; switch (speed) { case TRUEPHY_SPEED_10MBPS: break; case TRUEPHY_SPEED_100MBPS: data |= 0x2000; break; case TRUEPHY_SPEED_1000MBPS: default: data |= 0x0040; break; } MiWrite(etdev, PHY_CONTROL, data); }
void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable) { uint16_t data; MiRead(etdev, PHY_CONTROL, &data); if (enable == true) { data |= 0x1000; MiWrite(etdev, PHY_CONTROL, data); } else { data &= ~0x1000; MiWrite(etdev, PHY_CONTROL, data); } }
void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, uint16_t duplex) { uint16_t data; MiRead(etdev, PHY_CONTROL, &data); if (duplex == TRUEPHY_DUPLEX_FULL) { data |= 0x100; MiWrite(etdev, PHY_CONTROL, data); } else { data &= ~0x100; MiWrite(etdev, PHY_CONTROL, data); } }
void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down) { uint16_t data; MiRead(etdev, PHY_CONTROL, &data); if (down == false) { data &= ~0x0800; MiWrite(etdev, PHY_CONTROL, data); } else { data |= 0x0800; MiWrite(etdev, PHY_CONTROL, data); } }
void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev, u16 duplex) { u16 data; /* Read the PHY 1000 Base-T Control Register */ MiRead(etdev, PHY_1000_CONTROL, &data); /* Clear Bits 8,9 */ data &= ~0x0300; switch (duplex) { case TRUEPHY_ADV_DUPLEX_NONE: /* Duplex already cleared, do nothing */ break; case TRUEPHY_ADV_DUPLEX_FULL: /* Set Bit 9 */ data |= 0x0200; break; case TRUEPHY_ADV_DUPLEX_HALF: /* Set Bit 8 */ data |= 0x0100; break; case TRUEPHY_ADV_DUPLEX_BOTH: default: data |= 0x0300; break; } /* Write back advertisement */ MiWrite(etdev, PHY_1000_CONTROL, data); }
static void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable) { u16 data; MiRead(etdev, PHY_CONTROL, &data); data &= ~0x1000; /* Autonegotiation OFF */ if (enable) data |= 0x1000; /* Autonegotiation ON */ MiWrite(etdev, PHY_CONTROL, data); }
static void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, u16 duplex) { u16 data; MiRead(etdev, PHY_CONTROL, &data); data &= ~0x100; /* Set Half Duplex */ if (duplex == TRUEPHY_DUPLEX_FULL) data |= 0x100; /* Set Full Duplex */ MiWrite(etdev, PHY_CONTROL, data); }
static void ET1310_PhyAndOrReg(struct et131x_adapter *etdev, u16 regnum, u16 andMask, u16 orMask) { u16 reg; MiRead(etdev, regnum, ®); reg &= andMask; reg |= orMask; MiWrite(etdev, regnum, reg); }
void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down) { u16 data; MiRead(etdev, PHY_CONTROL, &data); data &= ~0x0800; /* Power UP */ if (down) /* Power DOWN */ data |= 0x0800; MiWrite(etdev, PHY_CONTROL, data); }
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; /* Write back the new speed */ MiWrite(etdev, PHY_CONTROL, data | bits[speed]); }
void ET1310_PhyAndOrReg(struct et131x_adapter *etdev, uint16_t regnum, uint16_t andMask, uint16_t orMask) { uint16_t reg; MiRead(etdev, regnum, ®); reg &= andMask; reg |= orMask; MiWrite(etdev, regnum, reg); }
void ET1310_PhyAndOrReg(struct et131x_adapter *etdev, uint16_t regnum, uint16_t andMask, uint16_t orMask) { uint16_t 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); }
/** * et131x_ioctl_mii - The function which handles MII IOCTLs * @netdev: device on which the query is being made * @reqbuf: the request-specific data buffer * @cmd: the command request code * * Returns 0 on success, errno on failure (as defined in errno.h) */ int et131x_ioctl_mii(struct net_device *netdev, struct ifreq *reqbuf, int cmd) { int status = 0; struct et131x_adapter *pAdapter = netdev_priv(netdev); struct mii_ioctl_data *data = if_mii(reqbuf); DBG_ENTER(et131x_dbginfo); switch (cmd) { case SIOCGMIIPHY: DBG_VERBOSE(et131x_dbginfo, "SIOCGMIIPHY\n"); data->phy_id = pAdapter->Stats.xcvr_addr; break; case SIOCGMIIREG: DBG_VERBOSE(et131x_dbginfo, "SIOCGMIIREG\n"); if (!capable(CAP_NET_ADMIN)) { status = -EPERM; } else { status = MiRead(pAdapter, data->reg_num, &data->val_out); } break; case SIOCSMIIREG: DBG_VERBOSE(et131x_dbginfo, "SIOCSMIIREG\n"); if (!capable(CAP_NET_ADMIN)) { status = -EPERM; } else { status = MiWrite(pAdapter, data->reg_num, data->val_in); } break; default: status = -EOPNOTSUPP; } DBG_LEAVE(et131x_dbginfo); return status; }
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); }
void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev, uint16_t duplex) { uint16_t data; MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); data &= ~0x0060; switch (duplex) { case TRUEPHY_ADV_DUPLEX_NONE: break; case TRUEPHY_ADV_DUPLEX_FULL: data |= 0x0040; break; case TRUEPHY_ADV_DUPLEX_HALF: data |= 0x0020; break; case TRUEPHY_ADV_DUPLEX_BOTH: default: data |= 0x0060; break; } MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); }
/* condensed version of the phy initialization routine */ void ET1310_PhyInit(struct et131x_adapter *etdev) { uint16_t data, index; 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 et131x_Mii_check(struct et131x_adapter *etdev, MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints) { 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; if (bmsr_ints.bits.link_status) { if (bmsr.bits.link_status) { etdev->PoMgmt.TransPhyComaModeOnBoot = 20; spin_lock_irqsave(&etdev->Lock, flags); etdev->MediaState = NETIF_STATUS_MEDIA_CONNECT; etdev->Flags &= ~fMP_ADAPTER_LINK_DETECTION; spin_unlock_irqrestore(&etdev->Lock, flags); if (etdev->RegistryPhyLoopbk == false) netif_carrier_on(etdev->netdev); } else { dev_warn(&etdev->pdev->dev, "Link down - cable problem ?\n"); if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { uint16_t Register18; MiRead(etdev, 0x12, &Register18); MiWrite(etdev, 0x12, Register18 | 0x4); MiWrite(etdev, 0x10, Register18 | 0x8402); MiWrite(etdev, 0x11, Register18 | 511); MiWrite(etdev, 0x12, Register18); } 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 (etdev->RegistryPhyLoopbk == false) netif_carrier_off(etdev->netdev); } etdev->linkspeed = 0; etdev->duplex_mode = 0; et131x_free_busy_send_packets(etdev); et131x_init_send(etdev); et131x_reset_recv(etdev); et131x_soft_reset(etdev); et131x_adapter_setup(etdev); if (etdev->RegistryPhyComa == 1) EnablePhyComa(etdev); } } 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); etdev->linkspeed = speed; etdev->duplex_mode = duplex; etdev->PoMgmt.TransPhyComaModeOnBoot = 20; if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { uint16_t Register18; MiRead(etdev, 0x12, &Register18); MiWrite(etdev, 0x12, Register18 | 0x4); MiWrite(etdev, 0x10, Register18 | 0x8402); MiWrite(etdev, 0x11, Register18 | 511); MiWrite(etdev, 0x12, Register18); } ConfigFlowControl(etdev); if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS && etdev->RegistryJumboPacket > 2048) ET1310_PhyAndOrReg(etdev, 0x16, 0xcfff, 0x2000); SetRxDmaTimer(etdev); ConfigMACRegs2(etdev); } } }
void et131x_Mii_check(struct et131x_adapter *etdev, MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints) { 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; if (bmsr_ints.bits.link_status) { if (bmsr.bits.link_status) { etdev->PoMgmt.TransPhyComaModeOnBoot = 20; /* Update our state variables and indicate the * connected state */ spin_lock_irqsave(&etdev->Lock, flags); etdev->MediaState = NETIF_STATUS_MEDIA_CONNECT; etdev->Flags &= ~fMP_ADAPTER_LINK_DETECTION; spin_unlock_irqrestore(&etdev->Lock, flags); /* Don't indicate state if we're in loopback mode */ if (etdev->RegistryPhyLoopbk == false) netif_carrier_on(etdev->netdev); } else { dev_warn(&etdev->pdev->dev, "Link down - cable problem ?\n"); 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; MiRead(etdev, 0x12, &Register18); MiWrite(etdev, 0x12, Register18 | 0x4); MiWrite(etdev, 0x10, Register18 | 0x8402); MiWrite(etdev, 0x11, Register18 | 511); MiWrite(etdev, 0x12, Register18); } /* 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); /* Only indicate state if we're in loopback * mode */ if (etdev->RegistryPhyLoopbk == false) netif_carrier_off(etdev->netdev); } etdev->linkspeed = 0; etdev->duplex_mode = 0; /* Free the packets being actively sent & stopped */ et131x_free_busy_send_packets(etdev); /* Re-initialize the send structures */ et131x_init_send(etdev); /* Reset the RFD list and re-start RU */ et131x_reset_recv(etdev); /* * 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); /* Setup ET1310 as per the documentation */ et131x_adapter_setup(etdev); /* Setup the PHY into coma mode until the cable is * plugged back in */ if (etdev->RegistryPhyComa == 1) EnablePhyComa(etdev); } } 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); etdev->linkspeed = speed; etdev->duplex_mode = duplex; etdev->PoMgmt.TransPhyComaModeOnBoot = 20; 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; MiRead(etdev, 0x12, &Register18); MiWrite(etdev, 0x12, Register18 | 0x4); MiWrite(etdev, 0x10, Register18 | 0x8402); MiWrite(etdev, 0x11, Register18 | 511); MiWrite(etdev, 0x12, Register18); } ConfigFlowControl(etdev); if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS && etdev->RegistryJumboPacket > 2048) ET1310_PhyAndOrReg(etdev, 0x16, 0xcfff, 0x2000); SetRxDmaTimer(etdev); ConfigMACRegs2(etdev); } } }
void ET1310_PhyInit(struct et131x_adapter *etdev) { uint16_t data, index; if (etdev == NULL) return; MiRead(etdev, PHY_ID_1, &data); MiRead(etdev, PHY_ID_2, &data); MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0006); MiWrite(etdev, PHY_INDEX_REG, 0x0402); MiRead(etdev, PHY_DATA_REG, &data); MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); MiRead(etdev, PHY_ID_1, &data); MiRead(etdev, PHY_ID_2, &data); MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0006); MiWrite(etdev, PHY_INDEX_REG, 0x0402); MiRead(etdev, PHY_DATA_REG, &data); MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); MiRead(etdev, PHY_CONTROL, &data); MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); MiWrite(etdev, PHY_CONTROL, 0x1840); MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0007); index = 0; while (ConfigPhy[index][0] != 0x0000) { MiWrite(etdev, PHY_INDEX_REG, ConfigPhy[index][0]); MiWrite(etdev, PHY_DATA_REG, ConfigPhy[index][1]); MiWrite(etdev, PHY_INDEX_REG, ConfigPhy[index][0]); MiRead(etdev, PHY_DATA_REG, &data); index++; } MiRead(etdev, PHY_CONTROL, &data); MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); MiWrite(etdev, PHY_CONTROL, 0x1040); MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); }
/** * 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; /* Zero out the adapter structure variable representing BMSR */ adapter->Bmsr.value = 0; MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, isr), &isr.value); MiRead(adapter, (uint8_t) 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 */ imr.bits.int_en = 0x1; imr.bits.link_status = 0x1; imr.bits.autoneg_status = 0x1; MiWrite(adapter, (uint8_t) 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 * 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); } /* 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); } /* Set the phy to autonegotiation */ ET1310_PhyAutoNeg(adapter, true); /* NOTE - Do we need this? */ ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL); return status; } 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); } } else { ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_CLEAR, 4, 10, NULL); ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_CLEAR, 4, 11, NULL); } 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; } return status; } }
static int et131x_xcvr_init(struct et131x_adapter *adapter) { int status = 0; MI_IMR_t imr; MI_ISR_t isr; MI_LCR2_t lcr2; adapter->Bmsr.value = 0; MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, isr), &isr.value); MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, imr), &imr.value); imr.bits.int_en = 0x1; imr.bits.link_status = 0x1; imr.bits.autoneg_status = 0x1; MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, imr), imr.value); 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 (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); } ET1310_PhyAutoNeg(adapter, true); ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL); return status; } else { ET1310_PhyAutoNeg(adapter, false); 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); } } else { ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_CLEAR, 4, 10, NULL); ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_CLEAR, 4, 11, NULL); } 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; } return status; } }
void ET1310_PhyReset(struct et131x_adapter *etdev) { MiWrite(etdev, PHY_CONTROL, 0x8000); }