Ejemplo n.º 1
0
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)
{
	u16 mistatus = 0;
	u16 is1000BaseT = 0;
	u16 vmi_phystatus = 0;
	u16 control = 0;

	MiRead(etdev, PHY_STATUS, &mistatus);
	MiRead(etdev, PHY_1000_STATUS, &is1000BaseT);
	MiRead(etdev, PHY_PHY_STATUS, &vmi_phystatus);
	MiRead(etdev, PHY_CONTROL, &control);

	*link_status = (vmi_phystatus & 0x0040) ? 1 : 0;
	*autoneg = (control & 0x1000) ? ((vmi_phystatus & 0x0020) ?
					    TRUEPHY_ANEG_COMPLETE :
					    TRUEPHY_ANEG_NOT_COMPLETE) :
		    TRUEPHY_ANEG_DISABLED;
	*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;
}
Ejemplo n.º 2
0
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;

	MiRead(etdev, PHY_STATUS, &mistatus);
	MiRead(etdev, PHY_1000_STATUS, &is1000BaseT);
	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) ?
					    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)
		
		*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;
	}
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
/* 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, &reg);

	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;
	}
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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, &reg);

	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;
	}
}
Ejemplo n.º 7
0
/**
 * 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;
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
/**
 * MiWrite - Write to a PHY register through the MII interface of the MAC
 * @etdev: pointer to our private adapter structure
 * @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 *etdev, u8 xcvrReg, u16 value)
{
	struct mac_regs __iomem *mac = &etdev->regs->mac;
	int status = 0;
	u8 xcvrAddr = etdev->stats.xcvr_addr;
	u32 delay;
	u32 miiAddr;
	u32 miiCmd;
	u32 miiIndicator;

	/* Save a local copy of the registers we are dealing with so we can
	 * set them back
	 */
	miiAddr = readl(&mac->mii_mgmt_addr);
	miiCmd = readl(&mac->mii_mgmt_cmd);

	/* Stop the current operation */
	writel(0, &mac->mii_mgmt_cmd);

	/* Set up the register we need to write to on the correct PHY */
	writel(MII_ADDR(xcvrAddr, xcvrReg), &mac->mii_mgmt_addr);

	/* Add the value to write to the registers to the mac */
	writel(value, &mac->mii_mgmt_ctrl);
	delay = 0;

	do {
		udelay(50);
		delay++;
		miiIndicator = readl(&mac->mii_mgmt_indicator);
	} while ((miiIndicator & MGMT_BUSY) && delay < 100);

	/* If we hit the max delay, we could not write the register */
	if (delay == 100) {
		u16 TempValue;

		dev_warn(&etdev->pdev->dev,
		    "xcvrReg 0x%08x could not be written", xcvrReg);
		dev_warn(&etdev->pdev->dev, "status is  0x%08x\n",
			    miiIndicator);
		dev_warn(&etdev->pdev->dev, "command is  0x%08x\n",
			    readl(&mac->mii_mgmt_cmd));

		MiRead(etdev, xcvrReg, &TempValue);

		status = -EIO;
	}
	/* Stop the write operation */
	writel(0, &mac->mii_mgmt_cmd);

	/* set the registers we touched back to the state at which we entered
	 * this function
	 */
	writel(miiAddr, &mac->mii_mgmt_addr);
	writel(miiCmd, &mac->mii_mgmt_cmd);

	return status;
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
static void ET1310_PhyAndOrReg(struct et131x_adapter *etdev,
			u16 regnum, u16 andMask, u16 orMask)
{
	u16 reg;

	MiRead(etdev, regnum, &reg);
	reg &= andMask;
	reg |= orMask;
	MiWrite(etdev, regnum, reg);
}
Ejemplo n.º 13
0
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);
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
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]);
}
Ejemplo n.º 16
0
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);
	}
}
Ejemplo n.º 17
0
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);
	}
}
Ejemplo n.º 18
0
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);
	}
}
Ejemplo n.º 19
0
void ET1310_PhyAndOrReg(struct et131x_adapter *etdev,
			uint16_t regnum, uint16_t andMask, uint16_t orMask)
{
	uint16_t reg;

	
	MiRead(etdev, regnum, &reg);

	
	reg &= andMask;

	
	reg |= orMask;

	
	MiWrite(etdev, regnum, reg);
}
Ejemplo n.º 20
0
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, &reg);

	/* Apply the AND mask */
	reg &= andMask;

	/* Apply the OR mask */
	reg |= orMask;

	/* Write the value back to the register */
	MiWrite(etdev, regnum, reg);
}
Ejemplo n.º 21
0
/**
 * 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;
}
Ejemplo n.º 22
0
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);
}
Ejemplo n.º 23
0
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);
}
Ejemplo n.º 24
0
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);
		}
	}
}
Ejemplo n.º 25
0
/* 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);
}
Ejemplo n.º 26
0
int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value)
{
	struct _MAC_t __iomem *mac = &adapter->regs->mac;
	int status = 0;
	uint8_t xcvrAddr = adapter->Stats.xcvr_addr;
	uint32_t delay;
	MII_MGMT_ADDR_t miiAddr;
	MII_MGMT_CMD_t miiCmd;
	MII_MGMT_INDICATOR_t miiIndicator;

	
	miiAddr.value = readl(&mac->mii_mgmt_addr.value);
	miiCmd.value = readl(&mac->mii_mgmt_cmd.value);

	
	writel(0, &mac->mii_mgmt_cmd.value);

	
	{
		MII_MGMT_ADDR_t mii_mgmt_addr;

		mii_mgmt_addr.bits.phy_addr = xcvrAddr;
		mii_mgmt_addr.bits.reg_addr = xcvrReg;
		writel(mii_mgmt_addr.value, &mac->mii_mgmt_addr.value);
	}

	
	writel(value, &mac->mii_mgmt_ctrl.value);
	delay = 0;

	do {
		udelay(50);
		delay++;
		miiIndicator.value = readl(&mac->mii_mgmt_indicator.value);
	} while (miiIndicator.bits.busy && delay < 100);

	
	if (delay == 100) {
		uint16_t TempValue;

		dev_warn(&adapter->pdev->dev,
		    "xcvrReg 0x%08x could not be written", xcvrReg);
		dev_warn(&adapter->pdev->dev, "status is  0x%08x\n",
			    miiIndicator.value);
		dev_warn(&adapter->pdev->dev, "command is  0x%08x\n",
			    readl(&mac->mii_mgmt_cmd.value));

		MiRead(adapter, xcvrReg, &TempValue);

		status = -EIO;
	}

	
	writel(0, &mac->mii_mgmt_cmd.value);

	
	writel(miiAddr.value, &mac->mii_mgmt_addr.value);
	writel(miiCmd.value, &mac->mii_mgmt_cmd.value);

	return status;
}
Ejemplo n.º 27
0
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;
	}
}
Ejemplo n.º 28
0
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);
		}
	}
}
Ejemplo n.º 29
0
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);
}
Ejemplo n.º 30
0
/**
 * 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;
	}
}