Commit 57aed3b4 authored by Alan Cox's avatar Alan Cox Committed by Greg Kroah-Hartman
Browse files

Staging: et131x: Clean up MII control

parent 4ea30f84
Loading
Loading
Loading
Loading
+24 −75
Original line number Diff line number Diff line
@@ -1407,97 +1407,46 @@ typedef struct _RXMAC_t { /* Location: */
/*
 * structure for MII Management Command reg in mac address map.
 * located at address 0x5024
 * bit 1: scan cycle
 * bit 0: read cycle
 */
typedef union _MII_MGMT_CMD_t {
	u32 value;
	struct {
#ifdef _BIT_FIELDS_HTOL
		u32 reserved:30;	/* bits 2-31 */
		u32 scan_cycle:1;	/* bit 1 */
		u32 read_cycle:1;	/* bit 0 */
#else
		u32 read_cycle:1;	/* bit 0 */
		u32 scan_cycle:1;	/* bit 1 */
		u32 reserved:30;	/* bits 2-31 */
#endif
	} bits;
} MII_MGMT_CMD_t, *PMII_MGMT_CMD_t;

/*
 * structure for MII Management Address reg in mac address map.
 * located at address 0x5028
 * 31-13: reserved
 * 12-8: phy addr
 * 7-5: reserved
 * 4-0: register
 */
typedef union _MII_MGMT_ADDR_t {
	u32 value;
	struct {
#ifdef _BIT_FIELDS_HTOL
		u32 reserved2:19;	/* bit 13-31 */
		u32 phy_addr:5;	/* bits 8-12 */
		u32 reserved1:3;	/* bits 5-7 */
		u32 reg_addr:5;	/* bits 0-4 */
#else
		u32 reg_addr:5;	/* bits 0-4 */
		u32 reserved1:3;	/* bits 5-7 */
		u32 phy_addr:5;	/* bits 8-12 */
		u32 reserved2:19;	/* bit 13-31 */
#endif
	} bits;
} MII_MGMT_ADDR_t, *PMII_MGMT_ADDR_t;

#define MII_ADDR(phy,reg)	((phy) << 8 | (reg))

/*
 * structure for MII Management Control reg in mac address map.
 * located at address 0x502C
 * 31-16: reserved
 * 15-0: phy control
 */
typedef union _MII_MGMT_CTRL_t {
	u32 value;
	struct {
#ifdef _BIT_FIELDS_HTOL
		u32 reserved:16;	/* bits 16-31 */
		u32 phy_ctrl:16;	/* bits 0-15 */
#else
		u32 phy_ctrl:16;	/* bits 0-15 */
		u32 reserved:16;	/* bits 16-31 */
#endif
	} bits;
} MII_MGMT_CTRL_t, *PMII_MGMT_CTRL_t;

/*
 * structure for MII Management Status reg in mac address map.
 * located at address 0x5030
 * 31-16: reserved
 * 15-0: phy control
 */
typedef union _MII_MGMT_STAT_t {
	u32 value;
	struct {
#ifdef _BIT_FIELDS_HTOL
		u32 reserved:16;	/* bits 16-31 */
		u32 phy_stat:16;	/* bits 0-15 */
#else
		u32 phy_stat:16;	/* bits 0-15 */
		u32 reserved:16;	/* bits 16-31 */
#endif
	} bits;
} MII_MGMT_STAT_t, *PMII_MGMT_STAT_t;

/*
 * structure for MII Management Indicators reg in mac address map.
 * located at address 0x5034
 * 31-3: reserved
 * 2: not valid
 * 1: scanning
 * 0: busy
 */
typedef union _MII_MGMT_INDICATOR_t {
	u32 value;
	struct {
#ifdef _BIT_FIELDS_HTOL
		u32 reserved:29;	/* bits 3-31 */
		u32 not_valid:1;	/* bit 2 */
		u32 scanning:1;	/* bit 1 */
		u32 busy:1;	/* bit 0 */
#else
		u32 busy:1;	/* bit 0 */
		u32 scanning:1;	/* bit 1 */
		u32 not_valid:1;	/* bit 2 */
		u32 reserved:29;	/* bits 3-31 */
#endif
	} bits;
} MII_MGMT_INDICATOR_t, *PMII_MGMT_INDICATOR_t;

#define MGMT_BUSY	0x00000001	/* busy */
#define MGMT_WAIT	0x00000005	/* busy | not valid */

/*
 * structure for Interface Control reg in mac address map.
@@ -1634,11 +1583,11 @@ typedef struct _MAC_t { /* Location: */
	u32 rsv2;					/*  0x5018 */
	u32 mac_test;					/*  0x501C */
	u32 mii_mgmt_cfg;				/*  0x5020 */
	MII_MGMT_CMD_t mii_mgmt_cmd;			/*  0x5024 */
	MII_MGMT_ADDR_t mii_mgmt_addr;			/*  0x5028 */
	MII_MGMT_CTRL_t mii_mgmt_ctrl;			/*  0x502C */
	MII_MGMT_STAT_t mii_mgmt_stat;			/*  0x5030 */
	MII_MGMT_INDICATOR_t mii_mgmt_indicator;	/*  0x5034 */
	u32 mii_mgmt_cmd;				/*  0x5024 */
	u32 mii_mgmt_addr;				/*  0x5028 */
	u32 mii_mgmt_ctrl;				/*  0x502C */
	u32 mii_mgmt_stat;				/*  0x5030 */
	u32 mii_mgmt_indicator;				/*  0x5034 */
	MAC_IF_CTRL_t if_ctrl;				/*  0x5038 */
	MAC_IF_STAT_t if_stat;				/*  0x503C */
	MAC_STATION_ADDR1_t station_addr_1;		/*  0x5040 */
+32 −53
Original line number Diff line number Diff line
@@ -115,69 +115,55 @@ int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr,
	struct _MAC_t __iomem *mac = &adapter->regs->mac;
	int status = 0;
	uint32_t delay;
	MII_MGMT_ADDR_t miiAddr;
	MII_MGMT_CMD_t miiCmd;
	MII_MGMT_INDICATOR_t miiIndicator;
	u32 miiAddr;
	u32 miiCmd;
	u32 miiIndicator;

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

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

	/* Set up the register we need to read from on the correct PHY */
	{
		MII_MGMT_ADDR_t mii_mgmt_addr = { 0 };

		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(MII_ADDR(xcvrAddr, xcvrReg), &mac->mii_mgmt_addr);

	/* Kick the read cycle off */
	delay = 0;

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

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

	/* If we hit the max delay, we could not read the register */
	if (delay >= 50) {
	if (delay == 50) {
		dev_warn(&adapter->pdev->dev,
			    "xcvrReg 0x%08x could not be read\n", xcvrReg);
		dev_warn(&adapter->pdev->dev, "status is  0x%08x\n",
			    miiIndicator.value);
			    miiIndicator);

		status = -EIO;
	}

	/* If we hit here we were able to read the register and we need to
	 * return the value to the caller
	 */
	/* TODO: make this stuff a simple readw()?! */
	{
		MII_MGMT_STAT_t mii_mgmt_stat;

		mii_mgmt_stat.value = readl(&mac->mii_mgmt_stat.value);
		*value = (uint16_t) mii_mgmt_stat.bits.phy_stat;
	}
	 * return the value to the caller */
	*value = readl(&mac->mii_mgmt_stat) & 0xFFFF;

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

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

	return status;
}
@@ -196,37 +182,31 @@ int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value)
	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;
	u32 miiAddr;
	u32 miiCmd;
	u32 miiIndicator;

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

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

	/* Set up the register we need to write to on the correct PHY */
	{
		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(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.value);
	writel(value, &mac->mii_mgmt_ctrl);
	delay = 0;

	do {
		udelay(50);
		delay++;
		miiIndicator.value = readl(&mac->mii_mgmt_indicator.value);
	} while (miiIndicator.bits.busy && delay < 100);
		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) {
@@ -235,23 +215,22 @@ int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value)
		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);
			    miiIndicator);
		dev_warn(&adapter->pdev->dev, "command is  0x%08x\n",
			    readl(&mac->mii_mgmt_cmd.value));
			    readl(&mac->mii_mgmt_cmd));

		MiRead(adapter, xcvrReg, &TempValue);

		status = -EIO;
	}

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

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

	return status;
}