diff options
author | xiong <xiong@qca.qualcomm.com> | 2013-01-19 13:15:06 +0800 |
---|---|---|
committer | Luis R. Rodriguez <mcgrof@do-not-panic.com> | 2013-01-24 07:56:06 -0800 |
commit | f6a28405f4366240ab04dca308a1f23b2c313551 (patch) | |
tree | a89300238b569b0c63a575410d91d48e0d84d618 | |
parent | fe7025d3b8685c6905531d88b6ff98712d393520 (diff) | |
download | alx-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.c | 41 | ||||
-rw-r--r-- | src/alx_hw.h | 6 | ||||
-rw-r--r-- | src/alx_main.c | 12 | ||||
-rw-r--r-- | src/alx_reg.h | 218 |
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 |