atl1c: Add support for Atheros AR8152 and AR8152

AR8151 is a Gigabit Ethernet device. AR8152 devices are
Fast Ethernet devices, there are two revisions, a 1.0
and a 2.0 revision.

This has been tested against these devices:

Driver	Model-name	vendor:device	Type
atl1c 	AR8131		1969:1063	Gigabit Ethernet
atl1c	AR8132		1969:1062	Fast Ethernet
atl1c	AR8151(v1.0)	1969:1073	Gigabit Ethernet
atl1c	AR8152(v1.1)	1969:2060	Fast Ethernet

This device has no hardware available yet so it goes untested,
but it should work:

atl1c	AR8152(v2.0)	1969:2062	Fast Ethernet

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c
index 3e69b94..f1389d6 100644
--- a/drivers/net/atl1c/atl1c_hw.c
+++ b/drivers/net/atl1c/atl1c_hw.c
@@ -70,17 +70,39 @@
 	u32 otp_ctrl_data;
 	u32 twsi_ctrl_data;
 	u8  eth_addr[ETH_ALEN];
+	u16 phy_data;
+	bool raise_vol = false;
 
 	/* init */
 	addr[0] = addr[1] = 0;
 	AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
 	if (atl1c_check_eeprom_exist(hw)) {
-		/* Enable OTP CLK */
-		if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
-			otp_ctrl_data |= OTP_CTRL_CLK_EN;
-			AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
-			AT_WRITE_FLUSH(hw);
-			msleep(1);
+		if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b) {
+			/* Enable OTP CLK */
+			if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
+				otp_ctrl_data |= OTP_CTRL_CLK_EN;
+				AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+				AT_WRITE_FLUSH(hw);
+				msleep(1);
+			}
+		}
+
+		if (hw->nic_type == athr_l2c_b ||
+		    hw->nic_type == athr_l2c_b2 ||
+		    hw->nic_type == athr_l1d) {
+			atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00);
+			if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+				goto out;
+			phy_data &= 0xFF7F;
+			atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+
+			atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
+			if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+				goto out;
+			phy_data |= 0x8;
+			atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+			udelay(20);
+			raise_vol = true;
 		}
 
 		AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
@@ -96,11 +118,31 @@
 			return -1;
 	}
 	/* Disable OTP_CLK */
-	if (otp_ctrl_data & OTP_CTRL_CLK_EN) {
-		otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
-		AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
-		AT_WRITE_FLUSH(hw);
-		msleep(1);
+	if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) {
+		if (otp_ctrl_data & OTP_CTRL_CLK_EN) {
+			otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
+			AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+			AT_WRITE_FLUSH(hw);
+			msleep(1);
+		}
+	}
+	if (raise_vol) {
+		if (hw->nic_type == athr_l2c_b ||
+		    hw->nic_type == athr_l2c_b2 ||
+		    hw->nic_type == athr_l1d) {
+			atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00);
+			if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+				goto out;
+			phy_data |= 0x80;
+			atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+
+			atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
+			if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+				goto out;
+			phy_data &= 0xFFF7;
+			atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+			udelay(20);
+		}
 	}
 
 	/* maybe MAC-address is from BIOS */
@@ -114,6 +156,7 @@
 		return 0;
 	}
 
+out:
 	return -1;
 }
 
@@ -307,7 +350,7 @@
 		mii_adv_data |= ADVERTISE_10HALF  | ADVERTISE_10FULL |
 				ADVERTISE_100HALF | ADVERTISE_100FULL;
 
-	if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M) {
+	if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M) {
 		if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half)
 			mii_giga_ctrl_data |= ADVERTISE_1000HALF;
 		if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full)
@@ -389,6 +432,7 @@
 {
 	struct atl1c_adapter *adapter = hw->adapter;
 	struct pci_dev *pdev = adapter->pdev;
+	u16 phy_data;
 	u32 phy_ctrl_data = GPHY_CTRL_DEFAULT;
 	u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN;
 	int err;
@@ -404,6 +448,21 @@
 	AT_WRITE_FLUSH(hw);
 	msleep(10);
 
+	if (hw->nic_type == athr_l2c_b) {
+		atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x0A);
+		atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data);
+		atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xDFFF);
+	}
+
+	if (hw->nic_type == athr_l2c_b ||
+	    hw->nic_type == athr_l2c_b2 ||
+	    hw->nic_type == athr_l1d) {
+		atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
+		atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data);
+		atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xFFF7);
+		msleep(20);
+	}
+
 	/*Enable PHY LinkChange Interrupt */
 	err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data);
 	if (err) {