aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxiong <xiong@qca.qualcomm.com>2013-01-19 13:15:06 +0800
committerLuis R. Rodriguez <mcgrof@do-not-panic.com>2013-01-24 07:56:06 -0800
commitf6a28405f4366240ab04dca308a1f23b2c313551 (patch)
treea89300238b569b0c63a575410d91d48e0d84d618
parentfe7025d3b8685c6905531d88b6ff98712d393520 (diff)
downloadalx-f6a28405f4366240ab04dca308a1f23b2c313551.tar.gz
alx: support version C0 FPGA
current C0 FPGA platform is ready, this patch adds new register difinition for C0. To run this driver on FPGA, just revised hw->is_fpga to 'true' in init_sw Signed-off-by: xiong <xiong@qca.qualcomm.com> Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
-rw-r--r--src/alx_hw.c41
-rw-r--r--src/alx_hw.h6
-rw-r--r--src/alx_main.c12
-rw-r--r--src/alx_reg.h218
4 files changed, 249 insertions, 28 deletions
diff --git a/src/alx_hw.c b/src/alx_hw.c
index 6f23d10..5922a65 100644
--- a/src/alx_hw.c
+++ b/src/alx_hw.c
@@ -302,6 +302,9 @@ void alx_reset_phy(struct alx_hw *hw, bool hib_en)
for (i = 0; i < ALX_PHY_CTRL_DSPRST_TO; i++)
udelay(10);
+ if (hw->is_fpga)
+ goto set_imr;
+
/* phy power saving & hib */
if (hib_en) {
alx_write_phy_dbg(hw, ALX_MIIDBG_LEGCYPS, ALX_LEGCYPS_DEF);
@@ -364,6 +367,7 @@ void alx_reset_phy(struct alx_hw *hw, bool hib_en)
phy_val | ALX_CLDCTRL5_BP_VD_HLFBIAS);
}
+set_imr:
/* set phy interrupt mask */
alx_write_phy_reg(hw, ALX_MII_IER,
ALX_IER_LINK_UP | ALX_IER_LINK_DOWN);
@@ -800,6 +804,35 @@ bool __alx_wait_mdio_idle(struct alx_hw *hw)
return i != ALX_MDIO_MAX_AC_TO;
}
+void __alx_stop_phy_polling(struct alx_hw *hw)
+{
+ if (!hw->is_fpga)
+ return;
+
+ ALX_MEM_W32(hw, ALX_MDIO, 0);
+ __alx_wait_mdio_idle(hw);
+}
+
+void __alx_start_phy_polling(struct alx_hw *hw, u16 clk_sel)
+{
+ u32 val;
+
+ if (!hw->is_fpga)
+ return;
+
+ val = ALX_MDIO_SPRES_PRMBL |
+ FIELDX(ALX_MDIO_CLK_SEL, clk_sel) |
+ FIELDX(ALX_MDIO_REG, 1) |
+ ALX_MDIO_START |
+ ALX_MDIO_OP_READ;
+ ALX_MEM_W32(hw, ALX_MDIO, val);
+ __alx_wait_mdio_idle(hw);
+ val |= ALX_MDIO_AUTO_POLLING;
+ val &= ~ALX_MDIO_START;
+ ALX_MEM_W32(hw, ALX_MDIO, val);
+ udelay(30);
+}
+
/* __alx_read_phy_core
* core function to read register in PHY via MDIO interface
* ext: extension register (see IEEE 802.3)
@@ -812,6 +845,8 @@ int __alx_read_phy_core(struct alx_hw *hw, bool ext, u8 dev,
u32 val, clk_sel;
int err;
+ __alx_stop_phy_polling(hw);
+
*phy_data = 0;
/* use slow clock when it's in hibernation status */
@@ -845,6 +880,8 @@ int __alx_read_phy_core(struct alx_hw *hw, bool ext, u8 dev,
err = 0;
}
+ __alx_start_phy_polling(hw, clk_sel);
+
return err;
}
@@ -860,6 +897,8 @@ int __alx_write_phy_core(struct alx_hw *hw, bool ext, u8 dev,
u32 val, clk_sel;
int err = 0;
+ __alx_stop_phy_polling(hw);
+
/* use slow clock when it's in hibernation status */
clk_sel = hw->link_up ?
ALX_MDIO_CLK_SEL_25MD128 : ALX_MDIO_CLK_SEL_25MD4;
@@ -886,6 +925,8 @@ int __alx_write_phy_core(struct alx_hw *hw, bool ext, u8 dev,
if (unlikely(!__alx_wait_mdio_idle(hw)))
err = ALX_ERR_MIIBUSY;
+ __alx_start_phy_polling(hw, clk_sel);
+
return err;
}
diff --git a/src/alx_hw.h b/src/alx_hw.h
index 2d16aff..2f0dcb8 100644
--- a/src/alx_hw.h
+++ b/src/alx_hw.h
@@ -524,6 +524,10 @@ struct alx_hw {
struct alx_hw_stats hw_stats;
u32 sleep_ctrl;
+ /* sram address for pattern wol */
+ u32 ptrn_ofs;
+ /* max patterns number */
+ u16 max_ptrns;
spinlock_t mdio_lock;
struct mdio_if_info mdio;
@@ -534,6 +538,8 @@ struct alx_hw {
bool lnk_patch;
/* PHY hibernation patch flag */
bool hib_patch;
+ /* FPGA or ASIC */
+ bool is_fpga;
};
#define ALX_DID(_hw) ((_hw)->device_id)
diff --git a/src/alx_main.c b/src/alx_main.c
index a8184a4..f3762d9 100644
--- a/src/alx_main.c
+++ b/src/alx_main.c
@@ -1012,7 +1012,7 @@ static int __devinit alx_identify_hw(struct alx_adapter *adpt)
case ALX_DEV_ID_AR8162:
case ALX_DEV_ID_AR8171:
case ALX_DEV_ID_AR8172:
- if (rev > ALX_REV_B0)
+ if (rev > ALX_REV_C0)
break;
err = 0;
ALX_CAP_SET(hw, L0S);
@@ -1021,7 +1021,14 @@ static int __devinit alx_identify_hw(struct alx_adapter *adpt)
ALX_CAP_SET(hw, RSS);
ALX_CAP_SET(hw, MSIX);
ALX_CAP_SET(hw, SWOI);
- hw->max_dma_chnl = rev == ALX_REV_B0 ? 4 : 2;
+ hw->max_dma_chnl = rev >= ALX_REV_B0 ? 4 : 2;
+ if (rev < ALX_REV_C0) {
+ hw->ptrn_ofs = 0x600;
+ hw->max_ptrns = 8;
+ } else {
+ hw->ptrn_ofs = 0x14000;
+ hw->max_ptrns = 16;
+ }
break;
}
@@ -1109,6 +1116,7 @@ static int __devinit alx_init_sw(struct alx_adapter *adpt)
ALX_MAC_CTRL_RXFC_EN |
ALX_MAC_CTRL_TXFC_EN |
FIELDX(ALX_MAC_CTRL_PRMBLEN, 7);
+ hw->is_fpga = false;
atomic_set(&adpt->irq_sem, 1);
ALX_FLAG_SET(adpt, HALT);
diff --git a/src/alx_reg.h b/src/alx_reg.h
index a91d716..58177f3 100644
--- a/src/alx_reg.h
+++ b/src/alx_reg.h
@@ -618,22 +618,60 @@
#define ALX_HRTBT_CTRL_PKTLEN_MASK 0xFFFUL
#define ALX_HRTBT_CTRL_PKTLEN_SHIFT 0
-/* for B0 */
-#define ALX_HRTBT_EXT_CTRL 0x1AD0
-#define ALX_HRTBT_EXT_CTRL_NS_EN BIT(12)
-#define ALX_HRTBT_EXT_CTRL_FRAG_LEN_MASK 0xFFUL
-#define ALX_HRTBT_EXT_CTRL_FRAG_LEN_SHIFT 4
-#define ALX_HRTBT_EXT_CTRL_IS_8023 BIT(3)
-#define ALX_HRTBT_EXT_CTRL_IS_IPV6 BIT(2)
-#define ALX_HRTBT_EXT_CTRL_WAKEUP_EN BIT(1)
-#define ALX_HRTBT_EXT_CTRL_ARP_EN BIT(0)
-
-#define ALX_HRTBT_REM_IPV4_ADDR 0x1AD4
-#define ALX_HRTBT_HOST_IPV4_ADDR 0x1478
-#define ALX_HRTBT_REM_IPV6_ADDR3 0x1AD8
-#define ALX_HRTBT_REM_IPV6_ADDR2 0x1ADC
-#define ALX_HRTBT_REM_IPV6_ADDR1 0x1AE0
-#define ALX_HRTBT_REM_IPV6_ADDR0 0x1AE4
+/* for B0+, bit[13..] for C0+ */
+#define ALX_HRTBT_EXT_CTRL 0x1AD0
+#define L1F_HRTBT_EXT_CTRL_PERIOD_HIGH_MASK 0x3FUL
+#define L1F_HRTBT_EXT_CTRL_PERIOD_HIGH_SHIFT 24
+#define L1F_HRTBT_EXT_CTRL_SWOI_STARTUP_PKT_EN BIT(23)
+#define L1F_HRTBT_EXT_CTRL_IOAC_2_FRAGMENTED BIT(22)
+#define L1F_HRTBT_EXT_CTRL_IOAC_1_FRAGMENTED BIT(21)
+#define L1F_HRTBT_EXT_CTRL_IOAC_1_KEEPALIVE_EN BIT(20)
+#define L1F_HRTBT_EXT_CTRL_IOAC_1_HAS_VLAN BIT(19)
+#define L1F_HRTBT_EXT_CTRL_IOAC_1_IS_8023 BIT(18)
+#define L1F_HRTBT_EXT_CTRL_IOAC_1_IS_IPV6 BIT(17)
+#define L1F_HRTBT_EXT_CTRL_IOAC_2_KEEPALIVE_EN BIT(16)
+#define L1F_HRTBT_EXT_CTRL_IOAC_2_HAS_VLAN BIT(15)
+#define L1F_HRTBT_EXT_CTRL_IOAC_2_IS_8023 BIT(14)
+#define L1F_HRTBT_EXT_CTRL_IOAC_2_IS_IPV6 BIT(13)
+#define ALX_HRTBT_EXT_CTRL_NS_EN BIT(12)
+#define ALX_HRTBT_EXT_CTRL_FRAG_LEN_MASK 0xFFUL
+#define ALX_HRTBT_EXT_CTRL_FRAG_LEN_SHIFT 4
+#define ALX_HRTBT_EXT_CTRL_IS_8023 BIT(3)
+#define ALX_HRTBT_EXT_CTRL_IS_IPV6 BIT(2)
+#define ALX_HRTBT_EXT_CTRL_WAKEUP_EN BIT(1)
+#define ALX_HRTBT_EXT_CTRL_ARP_EN BIT(0)
+
+#define ALX_HRTBT_REM_IPV4_ADDR 0x1AD4
+#define ALX_HRTBT_HOST_IPV4_ADDR 0x1478
+#define ALX_HRTBT_REM_IPV6_ADDR3 0x1AD8
+#define ALX_HRTBT_REM_IPV6_ADDR2 0x1ADC
+#define ALX_HRTBT_REM_IPV6_ADDR1 0x1AE0
+#define ALX_HRTBT_REM_IPV6_ADDR0 0x1AE4
+
+/* 1B8C ~ 1B94 for C0+ */
+#define ALX_SWOI_ACER_CTRL 0x1B8C
+#define ALX_SWOI_ORIG_ACK_NAK_EN BIT(20)
+#define ALX_SWOI_ORIG_ACK_NAK_PKT_LEN_MASK 0XFFUL
+#define ALX_SWOI_ORIG_ACK_NAK_PKT_LEN_SHIFT 12
+#define ALX_SWOI_ORIG_ACK_ADDR_MASK 0XFFFUL
+#define ALX_SWOI_ORIG_ACK_ADDR_SHIFT 0
+
+#define ALX_SWOI_IOAC_CTRL_2 0x1B90
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_FRAG_LEN_MASK 0xFFUL
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_FRAG_LEN_SHIFT 24
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_PKT_LEN_MASK 0xFFFUL
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_PKT_LEN_SHIFT 12
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_HDR_ADDR_MASK 0xFFFUL
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_HDR_ADDR_SHIFT 0
+
+#define ALX_SWOI_IOAC_CTRL_3 0x1B94
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_FRAG_LEN_MASK 0xFFUL
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_FRAG_LEN_SHIFT 24
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_PKT_LEN_MASK 0xFFFUL
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_PKT_LEN_SHIFT 12
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_HDR_ADDR_MASK 0xFFFUL
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_HDR_ADDR_SHIFT 0
+
/*SWOI_HOST_IPV6_ADDR reuse reg1a60-1a6c, 1a70-1a7c, 1aa0-1aac, 1ab0-1abc.*/
#define ALX_HRTBT_WAKEUP_PORT 0x1AE8
#define ALX_HRTBT_WAKEUP_PORT_SRC_MASK 0xFFFFUL
@@ -1518,16 +1556,144 @@
#define ALX_PMOFLD_SYNCV6_EN BIT(1)
#define ALX_PMOFLD_SYNCV4_EN BIT(0)
-#define ALX_RSS_KEY0 0x14B0
-#define ALX_RSS_KEY1 0x14B4
-#define ALX_RSS_KEY2 0x14B8
-#define ALX_RSS_KEY3 0x14BC
-#define ALX_RSS_KEY4 0x14C0
-#define ALX_RSS_KEY5 0x14C4
-#define ALX_RSS_KEY6 0x14C8
-#define ALX_RSS_KEY7 0x14CC
-#define ALX_RSS_KEY8 0x14D0
-#define ALX_RSS_KEY9 0x14D4
+/* reg 1830 ~ 186C for C0+, 16 bit map patterns and wake packet detection */
+#define ALX_WOL_CTRL2 0x1830
+#define ALX_WOL_CTRL2_DATA_STORE BIT(3)
+#define ALX_WOL_CTRL2_PTRN_EVT BIT(2)
+#define ALX_WOL_CTRL2_PME_PTRN_EN BIT(1)
+#define ALX_WOL_CTRL2_PTRN_EN BIT(0)
+
+#define ALX_WOL_CTRL3 0x1834
+#define ALX_WOL_CTRL3_PTRN_ADDR_MASK 0xFFFFFUL
+#define ALX_WOL_CTRL3_PTRN_ADDR_SHIFT 0
+
+#define ALX_WOL_CTRL4 0x1838
+#define ALX_WOL_CTRL4_PT15_MATCH BIT(31)
+#define ALX_WOL_CTRL4_PT14_MATCH BIT(30)
+#define ALX_WOL_CTRL4_PT13_MATCH BIT(29)
+#define ALX_WOL_CTRL4_PT12_MATCH BIT(28)
+#define ALX_WOL_CTRL4_PT11_MATCH BIT(27)
+#define ALX_WOL_CTRL4_PT10_MATCH BIT(26)
+#define ALX_WOL_CTRL4_PT9_MATCH BIT(25)
+#define ALX_WOL_CTRL4_PT8_MATCH BIT(24)
+#define ALX_WOL_CTRL4_PT7_MATCH BIT(23)
+#define ALX_WOL_CTRL4_PT6_MATCH BIT(22)
+#define ALX_WOL_CTRL4_PT5_MATCH BIT(21)
+#define ALX_WOL_CTRL4_PT4_MATCH BIT(20)
+#define ALX_WOL_CTRL4_PT3_MATCH BIT(19)
+#define ALX_WOL_CTRL4_PT2_MATCH BIT(18)
+#define ALX_WOL_CTRL4_PT1_MATCH BIT(17)
+#define ALX_WOL_CTRL4_PT0_MATCH BIT(16)
+#define ALX_WOL_CTRL4_PT15_EN BIT(15)
+#define ALX_WOL_CTRL4_PT14_EN BIT(14)
+#define ALX_WOL_CTRL4_PT13_EN BIT(13)
+#define ALX_WOL_CTRL4_PT12_EN BIT(12)
+#define ALX_WOL_CTRL4_PT11_EN BIT(11)
+#define ALX_WOL_CTRL4_PT10_EN BIT(10)
+#define ALX_WOL_CTRL4_PT9_EN BIT(9)
+#define ALX_WOL_CTRL4_PT8_EN BIT(8)
+#define ALX_WOL_CTRL4_PT7_EN BIT(7)
+#define ALX_WOL_CTRL4_PT6_EN BIT(6)
+#define ALX_WOL_CTRL4_PT5_EN BIT(5)
+#define ALX_WOL_CTRL4_PT4_EN BIT(4)
+#define ALX_WOL_CTRL4_PT3_EN BIT(3)
+#define ALX_WOL_CTRL4_PT2_EN BIT(2)
+#define ALX_WOL_CTRL4_PT1_EN BIT(1)
+#define ALX_WOL_CTRL4_PT0_EN BIT(0)
+
+#define ALX_WOL_CTRL5 0x183C
+#define ALX_WOL_CTRL5_PT3_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT3_LEN_SHIFT 24
+#define ALX_WOL_CTRL5_PT2_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT2_LEN_SHIFT 16
+#define ALX_WOL_CTRL5_PT1_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT1_LEN_SHIFT 8
+#define ALX_WOL_CTRL5_PT0_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT0_LEN_SHIFT 0
+
+#define ALX_WOL_CTRL6 0x1840
+#define ALX_WOL_CTRL5_PT7_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT7_LEN_SHIFT 24
+#define ALX_WOL_CTRL5_PT6_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT6_LEN_SHIFT 16
+#define ALX_WOL_CTRL5_PT5_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT5_LEN_SHIFT 8
+#define ALX_WOL_CTRL5_PT4_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT4_LEN_SHIFT 0
+
+#define ALX_WOL_CTRL7 0x1844
+#define ALX_WOL_CTRL5_PT11_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT11_LEN_SHIFT 24
+#define ALX_WOL_CTRL5_PT10_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT10_LEN_SHIFT 16
+#define ALX_WOL_CTRL5_PT9_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT9_LEN_SHIFT 8
+#define ALX_WOL_CTRL5_PT8_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT8_LEN_SHIFT 0
+
+#define ALX_WOL_CTRL8 0x1848
+#define ALX_WOL_CTRL5_PT15_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT15_LEN_SHIFT 24
+#define ALX_WOL_CTRL5_PT14_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT14_LEN_SHIFT 16
+#define ALX_WOL_CTRL5_PT13_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT13_LEN_SHIFT 8
+#define ALX_WOL_CTRL5_PT12_LEN_MASK 0xFFUL
+#define ALX_WOL_CTRL5_PT12_LEN_SHIFT 0
+
+#define ALX_ACER_FIXED_PTN0 0x1850
+#define ALX_ACER_FIXED_PTN0_MASK 0xFFFFFFFFUL
+#define ALX_ACER_FIXED_PTN0_SHIFT 0
+
+#define ALX_ACER_FIXED_PTN1 0x1854
+#define ALX_ACER_FIXED_PTN1_MASK 0xFFFFUL
+#define ALX_ACER_FIXED_PTN1_SHIFT 0
+
+#define ALX_ACER_RANDOM_NUM0 0x1858
+#define ALX_ACER_RANDOM_NUM0_MASK 0xFFFFFFFFUL
+#define ALX_ACER_RANDOM_NUM0_SHIFT 0
+
+#define ALX_ACER_RANDOM_NUM1 0x185C
+#define ALX_ACER_RANDOM_NUM1_MASK 0xFFFFFFFFUL
+#define ALX_ACER_RANDOM_NUM1_SHIFT 0
+
+#define ALX_ACER_RANDOM_NUM2 0x1860
+#define ALX_ACER_RANDOM_NUM2_MASK 0xFFFFFFFFUL
+#define ALX_ACER_RANDOM_NUM2_SHIFT 0
+
+#define ALX_ACER_RANDOM_NUM3 0x1864
+#define ALX_ACER_RANDOM_NUM3_MASK 0xFFFFFFFFUL
+#define ALX_ACER_RANDOM_NUM3_SHIFT 0
+
+#define ALX_ACER_MAGIC 0x1868
+#define ALX_ACER_MAGIC_EN BIT(31)
+#define ALX_ACER_MAGIC_PME_EN BIT(30)
+#define ALX_ACER_MAGIC_MATCH BIT(29)
+#define ALX_ACER_MAGIC_FF_CHECK BIT(10)
+#define ALX_ACER_MAGIC_RAN_LEN_MASK 0x1FUL
+#define ALX_ACER_MAGIC_RAN_LEN_SHIFT 5
+#define ALX_ACER_MAGIC_FIX_LEN_MASK 0x1FUL
+#define ALX_ACER_MAGIC_FIX_LEN_SHIFT 0
+
+#define ALX_ACER_TIMER 0x186C
+#define ALX_ACER_TIMER_EN BIT(31)
+#define ALX_ACER_TIMER_PME_EN BIT(30)
+#define ALX_ACER_TIMER_MATCH BIT(29)
+#define ALX_ACER_TIMER_THRES_MASK 0x1FFFFUL
+#define ALX_ACER_TIMER_THRES_SHIFT 0
+#define ALX_ACER_TIMER_THRES_DEF 1
+
+/* RSS definitions */
+#define ALX_RSS_KEY0 0x14B0
+#define ALX_RSS_KEY1 0x14B4
+#define ALX_RSS_KEY2 0x14B8
+#define ALX_RSS_KEY3 0x14BC
+#define ALX_RSS_KEY4 0x14C0
+#define ALX_RSS_KEY5 0x14C4
+#define ALX_RSS_KEY6 0x14C8
+#define ALX_RSS_KEY7 0x14CC
+#define ALX_RSS_KEY8 0x14D0
+#define ALX_RSS_KEY9 0x14D4
#define ALX_RSS_IDT_TBL0 0x1B00
#define ALX_RSS_IDT_TBL1 0x1B04