+++ /dev/null
-From 4d59bde6ad6120d81f8b8ac6ac0beda718f7fb21 Mon Sep 17 00:00:00 2001
-From: Luis R. Rodriguez <mcgrof@frijolero.org>
-Date: Tue, 28 Feb 2012 11:49:31 -0800
-Subject: [PATCH] net: add new QCA alx ethernet driver which supercedes atl1c
-
-This driver is intended to replace the atl1c driver and provide
-support for a two new chipsets. Qualcomm Atheros (QCA) is commiting
-to fixing all bugs found on this driver. Test results show this
-driver performs better than atl1c on all supported chipsets, closes
-the gap between TX and RX throughput (they now match) and has also
-been verified with ASPM enabled on all supported chipsets. This
-driver and patch also have addressed all sparse and checkpatch
-warnings.
-
-QCA is commiting on fixing all bugs upstream on this driver.
-This driver is also permissively licensed thereby enabling
-developers of other OSes to cherry pick this driver to port to
-their OS, such as FreeBSD.
-
-Both atl1c and alx driver support the following chipsets:
-
-1969:1063 - AR8131 Gigabit Ethernet
-1969:1062 - AR8132 Fast Ethernet (10/100 Mbit/s)
-1969:2062 - AR8152 v2.0 Fast Ethernet
-1969:2060 - AR8152 v1.1 Fast Ethernet
-1969:1073 - AR8151 v1.0 Gigabit Ethernet
-1969:1083 - AR8151 v2.0 Gigabit Ethernet
-
-But alx also supports these two new chipstes:
-
-1969:1091 - AR8161 Gigabit Ethernet
-1969:1090 - AR8162 Fast Ethernet
-
-We leave the atl1c driver in place for now but mark it as
-deprecated in favor for the alx. Linux distributions should
-consider using alx moving forward and any issues found with
-the alx driver will be proactively addressed and tracked by
-assigned by QCA engineers.
-
-For more detail including a shiny graph of throughput in comparison
-to atl1c see the new shiny alx driver home page:
-
-https://www.linuxfoundation.org/collaborate/workgroups/networking/alx
-
-Signed-off-by: Stevent Li <steventl@qca.qualcomm.com>
-Signed-off-by: Hao-Ran Liu (Joseph Liu) <hao-ran.liu@canonical.com>
-Signed-off-by: Cloud Ren <cjren@qca.qualcomm.com>
-Signed-off-by: Joe Perches <joe@perches.com>
-Signed-off-by: Luis R. Rodriguez <mcgrof@frijolero.org>
----
- MAINTAINERS | 11 +
- drivers/net/ethernet/atheros/Kconfig | 42 +-
- drivers/net/ethernet/atheros/Makefile | 1 +
- drivers/net/ethernet/atheros/alx/Makefile | 3 +
- drivers/net/ethernet/atheros/alx/alc_cb.c | 912 ++++++
- drivers/net/ethernet/atheros/alx/alc_hw.c | 1087 +++++++
- drivers/net/ethernet/atheros/alx/alc_hw.h | 1324 ++++++++
- drivers/net/ethernet/atheros/alx/alf_cb.c | 1187 +++++++
- drivers/net/ethernet/atheros/alx/alf_hw.c | 918 ++++++
- drivers/net/ethernet/atheros/alx/alf_hw.h | 2098 +++++++++++++
- drivers/net/ethernet/atheros/alx/alx.h | 670 ++++
- drivers/net/ethernet/atheros/alx/alx_ethtool.c | 519 ++++
- drivers/net/ethernet/atheros/alx/alx_hwcom.h | 187 ++
- drivers/net/ethernet/atheros/alx/alx_main.c | 3899 ++++++++++++++++++++++++
- drivers/net/ethernet/atheros/alx/alx_sw.h | 493 +++
- 15 files changed, 13350 insertions(+), 1 deletions(-)
- create mode 100644 drivers/net/ethernet/atheros/alx/Makefile
- create mode 100644 drivers/net/ethernet/atheros/alx/alc_cb.c
- create mode 100644 drivers/net/ethernet/atheros/alx/alc_hw.c
- create mode 100644 drivers/net/ethernet/atheros/alx/alc_hw.h
- create mode 100644 drivers/net/ethernet/atheros/alx/alf_cb.c
- create mode 100644 drivers/net/ethernet/atheros/alx/alf_hw.c
- create mode 100644 drivers/net/ethernet/atheros/alx/alf_hw.h
- create mode 100644 drivers/net/ethernet/atheros/alx/alx.h
- create mode 100644 drivers/net/ethernet/atheros/alx/alx_ethtool.c
- create mode 100644 drivers/net/ethernet/atheros/alx/alx_hwcom.h
- create mode 100644 drivers/net/ethernet/atheros/alx/alx_main.c
- create mode 100644 drivers/net/ethernet/atheros/alx/alx_sw.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -1329,6 +1329,17 @@ W: http://atl1.sourceforge.net
- S: Maintained
- F: drivers/net/ethernet/atheros/
-
-+ALX ETHERNET DRIVERS
-+M: Cloud Ren <cjren@qca.qualcomm.com>
-+M: Stevent Li <steventl@qca.qualcomm.com>
-+M: Wu Ken <kenw@qca.qualcomm.com>
-+M: David Liu <dwliu@qca.qualcomm.com>
-+L: netdev@vger.kernel.org
-+L: nic-devel@qualcomm.com
-+W: http://wireless.kernel.org/en/users/Drivers/ethernet/alx
-+S: Supported
-+F: drivers/net/ethernet/atheros/alx/
-+
- ATM
- M: Chas Williams <chas@cmf.nrl.navy.mil>
- L: linux-atm-general@lists.sourceforge.net (moderated for non-subscribers)
---- a/drivers/net/ethernet/atheros/Kconfig
-+++ b/drivers/net/ethernet/atheros/Kconfig
-@@ -56,15 +56,55 @@ config ATL1E
- will be called atl1e.
-
- config ATL1C
-- tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)"
-+ tristate "Atheros L1C Gigabit Ethernet support (DEPRECATED)"
- depends on PCI && EXPERIMENTAL
- select CRC32
- select NET_CORE
- select MII
- ---help---
- This driver supports the Atheros L1C gigabit ethernet adapter.
-+ This driver is deprecated in favor for the alx (CONFIG_ALX) driver.
-+ This driver supports the following chipsets:
-+
-+ 1969:1063 - AR8131 Gigabit Ethernet
-+ 1969:1062 - AR8132 Fast Ethernet (10/100 Mbit/s)
-+ 1969:2062 - AR8152 v2.0 Fast Ethernet
-+ 1969:2060 - AR8152 v1.1 Fast Ethernet
-+ 1969:1073 - AR8151 v1.0 Gigabit Ethernet
-+ 1969:1083 - AR8151 v2.0 Gigabit Ethernet
-
- To compile this driver as a module, choose M here. The module
- will be called atl1c.
-
-+config ALX
-+ tristate "Atheros ALX Gigabit Ethernet support"
-+ depends on PCI
-+ select CRC32
-+ select NET_CORE
-+ select MII
-+ ---help---
-+ This driver supports the Atheros L1C/L1D/L1F gigabit ethernet
-+ adapter. The alx driver is intended to replace completely the
-+ atl1c driver with proper support and commitment from Qualcomm
-+ Atheros (QCA). Both atl1c and alx supports the following chipsets:
-+
-+ 1969:1063 - AR8131 Gigabit Ethernet
-+ 1969:1062 - AR8132 Fast Ethernet (10/100 Mbit/s)
-+ 1969:2062 - AR8152 v2.0 Fast Ethernet
-+ 1969:2060 - AR8152 v1.1 Fast Ethernet
-+ 1969:1073 - AR8151 v1.0 Gigabit Ethernet
-+ 1969:1083 - AR8151 v2.0 Gigabit Ethernet
-+
-+ Only alx supports the following chipsets:
-+
-+ 1969:1091 - AR8161
-+ 1969:1090 - AR8162
-+
-+ For more information see:
-+
-+ https://www.linuxfoundation.org/collaborate/workgroups/networking/alx
-+
-+ To compile this driver as a module, choose M here. The module
-+ will be called alx.
-+
- endif # NET_VENDOR_ATHEROS
---- a/drivers/net/ethernet/atheros/Makefile
-+++ b/drivers/net/ethernet/atheros/Makefile
-@@ -6,3 +6,4 @@ obj-$(CONFIG_ATL1) += atlx/
- obj-$(CONFIG_ATL2) += atlx/
- obj-$(CONFIG_ATL1E) += atl1e/
- obj-$(CONFIG_ATL1C) += atl1c/
-+obj-$(CONFIG_ALX) += alx/
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/Makefile
-@@ -0,0 +1,3 @@
-+obj-$(CONFIG_ALX) += alx.o
-+alx-objs := alx_main.o alx_ethtool.o alc_cb.o alc_hw.o alf_cb.o alf_hw.o
-+ccflags-y += -D__CHECK_ENDIAN__
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alc_cb.c
-@@ -0,0 +1,912 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ */
-+
-+#include <linux/pci_regs.h>
-+#include <linux/mii.h>
-+
-+#include "alc_hw.h"
-+
-+
-+/* NIC */
-+static int alc_identify_nic(struct alx_hw *hw)
-+{
-+ return 0;
-+}
-+
-+
-+/* PHY */
-+static int alc_read_phy_reg(struct alx_hw *hw, u16 reg_addr, u16 *phy_data)
-+{
-+ unsigned long flags;
-+ int retval = 0;
-+
-+ spin_lock_irqsave(&hw->mdio_lock, flags);
-+
-+ if (l1c_read_phy(hw, false, ALX_MDIO_DEV_TYPE_NORM, false, reg_addr,
-+ phy_data)) {
-+ alx_hw_err(hw, "error when read phy reg\n");
-+ retval = -EINVAL;
-+ }
-+
-+ spin_unlock_irqrestore(&hw->mdio_lock, flags);
-+ return retval;
-+}
-+
-+
-+static int alc_write_phy_reg(struct alx_hw *hw, u16 reg_addr, u16 phy_data)
-+{
-+ unsigned long flags;
-+ int retval = 0;
-+
-+ spin_lock_irqsave(&hw->mdio_lock, flags);
-+
-+ if (l1c_write_phy(hw, false, ALX_MDIO_DEV_TYPE_NORM, false, reg_addr,
-+ phy_data)) {
-+ alx_hw_err(hw, "error when write phy reg\n");
-+ retval = -EINVAL;
-+ }
-+
-+ spin_unlock_irqrestore(&hw->mdio_lock, flags);
-+ return retval;
-+}
-+
-+
-+static int alc_init_phy(struct alx_hw *hw)
-+{
-+ u16 phy_id[2];
-+ int retval;
-+
-+ spin_lock_init(&hw->mdio_lock);
-+
-+ retval = alc_read_phy_reg(hw, MII_PHYSID1, &phy_id[0]);
-+ if (retval)
-+ return retval;
-+ retval = alc_read_phy_reg(hw, MII_PHYSID2, &phy_id[1]);
-+ if (retval)
-+ return retval;
-+
-+ memcpy(&hw->phy_id, phy_id, sizeof(hw->phy_id));
-+
-+ hw->autoneg_advertised = ALX_LINK_SPEED_1GB_FULL |
-+ ALX_LINK_SPEED_10_HALF |
-+ ALX_LINK_SPEED_10_FULL |
-+ ALX_LINK_SPEED_100_HALF |
-+ ALX_LINK_SPEED_100_FULL;
-+ return retval;
-+}
-+
-+
-+static int alc_reset_phy(struct alx_hw *hw)
-+{
-+ bool pws_en, az_en, ptp_en;
-+ int retval = 0;
-+
-+ pws_en = az_en = ptp_en = false;
-+ CLI_HW_FLAG(PWSAVE_EN);
-+ CLI_HW_FLAG(AZ_EN);
-+ CLI_HW_FLAG(PTP_EN);
-+
-+ if (CHK_HW_FLAG(PWSAVE_CAP)) {
-+ pws_en = true;
-+ SET_HW_FLAG(PWSAVE_EN);
-+ }
-+
-+ if (CHK_HW_FLAG(AZ_CAP)) {
-+ az_en = true;
-+ SET_HW_FLAG(AZ_EN);
-+ }
-+
-+ if (CHK_HW_FLAG(PTP_CAP)) {
-+ ptp_en = true;
-+ SET_HW_FLAG(PTP_EN);
-+ }
-+
-+ alx_hw_info(hw, "reset PHY, pws = %d, az = %d, ptp = %d\n",
-+ pws_en, az_en, ptp_en);
-+
-+ if (l1c_reset_phy(hw, pws_en, az_en, ptp_en)) {
-+ alx_hw_err(hw, "error when reset phy\n");
-+ retval = -EINVAL;
-+ }
-+
-+ return retval;
-+}
-+
-+
-+/* LINK */
-+static int alc_setup_phy_link(struct alx_hw *hw, u32 speed, bool autoneg,
-+ bool fc)
-+{
-+ u8 link_cap = 0;
-+ int retval = 0;
-+
-+ alx_hw_info(hw, "speed = 0x%x, autoneg = %d\n", speed, autoneg);
-+ if (speed & ALX_LINK_SPEED_1GB_FULL)
-+ link_cap |= LX_LC_1000F;
-+
-+ if (speed & ALX_LINK_SPEED_100_FULL)
-+ link_cap |= LX_LC_100F;
-+
-+ if (speed & ALX_LINK_SPEED_100_HALF)
-+ link_cap |= LX_LC_100H;
-+
-+ if (speed & ALX_LINK_SPEED_10_FULL)
-+ link_cap |= LX_LC_10F;
-+
-+ if (speed & ALX_LINK_SPEED_10_HALF)
-+ link_cap |= LX_LC_10H;
-+
-+ if (l1c_init_phy_spdfc(hw, autoneg, link_cap, fc)) {
-+ alx_hw_err(hw, "error when init phy speed and fc\n");
-+ retval = -EINVAL;
-+ }
-+
-+ return retval;
-+}
-+
-+
-+static int alc_setup_phy_link_speed(struct alx_hw *hw, u32 speed,
-+ bool autoneg, bool fc)
-+{
-+ /*
-+ * Clear autoneg_advertised and set new values based on input link
-+ * speed.
-+ */
-+ hw->autoneg_advertised = 0;
-+
-+ if (speed & ALX_LINK_SPEED_1GB_FULL)
-+ hw->autoneg_advertised |= ALX_LINK_SPEED_1GB_FULL;
-+
-+ if (speed & ALX_LINK_SPEED_100_FULL)
-+ hw->autoneg_advertised |= ALX_LINK_SPEED_100_FULL;
-+
-+ if (speed & ALX_LINK_SPEED_100_HALF)
-+ hw->autoneg_advertised |= ALX_LINK_SPEED_100_HALF;
-+
-+ if (speed & ALX_LINK_SPEED_10_FULL)
-+ hw->autoneg_advertised |= ALX_LINK_SPEED_10_FULL;
-+
-+ if (speed & ALX_LINK_SPEED_10_HALF)
-+ hw->autoneg_advertised |= ALX_LINK_SPEED_10_HALF;
-+
-+ return alc_setup_phy_link(hw, hw->autoneg_advertised,
-+ autoneg, fc);
-+}
-+
-+
-+static int alc_check_phy_link(struct alx_hw *hw, u32 *speed, bool *link_up)
-+{
-+ u16 bmsr, giga;
-+ int retval;
-+
-+ alc_read_phy_reg(hw, MII_BMSR, &bmsr);
-+ retval = alc_read_phy_reg(hw, MII_BMSR, &bmsr);
-+ if (retval)
-+ return retval;
-+
-+ if (!(bmsr & BMSR_LSTATUS)) {
-+ *link_up = false;
-+ *speed = ALX_LINK_SPEED_UNKNOWN;
-+ return 0;
-+ }
-+ *link_up = true;
-+
-+ /* Read PHY Specific Status Register (17) */
-+ retval = alc_read_phy_reg(hw, L1C_MII_GIGA_PSSR, &giga);
-+ if (retval)
-+ return retval;
-+
-+
-+ if (!(giga & L1C_GIGA_PSSR_SPD_DPLX_RESOLVED)) {
-+ alx_hw_err(hw, "error for speed duplex resolved\n");
-+ return -EINVAL;
-+ }
-+
-+ switch (giga & L1C_GIGA_PSSR_SPEED) {
-+ case L1C_GIGA_PSSR_1000MBS:
-+ if (giga & L1C_GIGA_PSSR_DPLX)
-+ *speed = ALX_LINK_SPEED_1GB_FULL;
-+ else
-+ alx_hw_err(hw, "1000M half is invalid\n");
-+ break;
-+ case L1C_GIGA_PSSR_100MBS:
-+ if (giga & L1C_GIGA_PSSR_DPLX)
-+ *speed = ALX_LINK_SPEED_100_FULL;
-+ else
-+ *speed = ALX_LINK_SPEED_100_HALF;
-+ break;
-+ case L1C_GIGA_PSSR_10MBS:
-+ if (giga & L1C_GIGA_PSSR_DPLX)
-+ *speed = ALX_LINK_SPEED_10_FULL;
-+ else
-+ *speed = ALX_LINK_SPEED_10_HALF;
-+ break;
-+ default:
-+ *speed = ALX_LINK_SPEED_UNKNOWN;
-+ retval = -EINVAL;
-+ break;
-+ }
-+
-+ return retval;
-+}
-+
-+
-+/*
-+ * 1. stop_mac
-+ * 2. reset mac & dma by reg1400(MASTER)
-+ * 3. control speed/duplex, hash-alg
-+ * 4. clock switch setting
-+ */
-+static int alc_reset_mac(struct alx_hw *hw)
-+{
-+ int retval = 0;
-+
-+ if (l1c_reset_mac(hw)) {
-+ alx_hw_err(hw, "error when reset mac\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alc_start_mac(struct alx_hw *hw)
-+{
-+ u16 en_ctrl = 0;
-+ int retval = 0;
-+
-+ /* set link speed param */
-+ switch (hw->link_speed) {
-+ case ALX_LINK_SPEED_1GB_FULL:
-+ en_ctrl |= LX_MACSPEED_1000;
-+ /* fall through */
-+ case ALX_LINK_SPEED_100_FULL:
-+ case ALX_LINK_SPEED_10_FULL:
-+ en_ctrl |= LX_MACDUPLEX_FULL;
-+ break;
-+ }
-+
-+ /* set fc param*/
-+ switch (hw->cur_fc_mode) {
-+ case alx_fc_full:
-+ en_ctrl |= LX_FC_RXEN; /* Flow Control RX Enable */
-+ en_ctrl |= LX_FC_TXEN; /* Flow Control TX Enable */
-+ break;
-+ case alx_fc_rx_pause:
-+ en_ctrl |= LX_FC_RXEN; /* Flow Control RX Enable */
-+ break;
-+ case alx_fc_tx_pause:
-+ en_ctrl |= LX_FC_TXEN; /* Flow Control TX Enable */
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (hw->fc_single_pause)
-+ en_ctrl |= LX_SINGLE_PAUSE;
-+
-+
-+ en_ctrl |= LX_FLT_DIRECT; /* RX Enable; and TX Always Enable */
-+ en_ctrl |= LX_FLT_BROADCAST; /* RX Broadcast Enable */
-+ en_ctrl |= LX_ADD_FCS;
-+
-+ if (CHK_HW_FLAG(VLANSTRIP_EN))
-+ en_ctrl |= LX_VLAN_STRIP;
-+
-+ if (CHK_HW_FLAG(PROMISC_EN))
-+ en_ctrl |= LX_FLT_PROMISC;
-+
-+ if (CHK_HW_FLAG(MULTIALL_EN))
-+ en_ctrl |= LX_FLT_MULTI_ALL;
-+
-+ if (CHK_HW_FLAG(LOOPBACK_EN))
-+ en_ctrl |= LX_LOOPBACK;
-+
-+ if (l1c_enable_mac(hw, true, en_ctrl)) {
-+ alx_hw_err(hw, "error when start mac\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+/*
-+ * 1. stop RXQ (reg15A0) and TXQ (reg1590)
-+ * 2. stop MAC (reg1480)
-+ */
-+static int alc_stop_mac(struct alx_hw *hw)
-+{
-+ int retval = 0;
-+
-+ if (l1c_enable_mac(hw, false, 0)) {
-+ alx_hw_err(hw, "error when stop mac\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alc_config_mac(struct alx_hw *hw, u16 rxbuf_sz, u16 rx_qnum,
-+ u16 rxring_sz, u16 tx_qnum, u16 txring_sz)
-+{
-+ u8 *addr;
-+
-+ u32 txmem_hi, txmem_lo[4];
-+
-+ u32 rxmem_hi, rfdmem_lo, rrdmem_lo;
-+
-+ u16 smb_timer, mtu_with_eth, int_mod;
-+ bool hash_legacy;
-+
-+ int i;
-+ int retval = 0;
-+
-+ addr = hw->mac_addr;
-+
-+ txmem_hi = ALX_DMA_ADDR_HI(hw->tpdma[0]);
-+ for (i = 0; i < tx_qnum; i++)
-+ txmem_lo[i] = ALX_DMA_ADDR_LO(hw->tpdma[i]);
-+
-+
-+ rxmem_hi = ALX_DMA_ADDR_HI(hw->rfdma[0]);
-+ rfdmem_lo = ALX_DMA_ADDR_LO(hw->rfdma[0]);
-+ rrdmem_lo = ALX_DMA_ADDR_LO(hw->rrdma[0]);
-+
-+
-+ smb_timer = (u16)hw->smb_timer;
-+ mtu_with_eth = hw->mtu + ALX_ETH_LENGTH_OF_HEADER;
-+ int_mod = hw->imt;
-+
-+ hash_legacy = true;
-+
-+ if (l1c_init_mac(hw, addr, txmem_hi, txmem_lo, tx_qnum, txring_sz,
-+ rxmem_hi, rfdmem_lo, rrdmem_lo, rxring_sz, rxbuf_sz,
-+ smb_timer, mtu_with_eth, int_mod, hash_legacy)) {
-+ alx_hw_err(hw, "error when config mac\n");
-+ retval = -EINVAL;
-+ }
-+
-+ return retval;
-+}
-+
-+
-+/**
-+ * alc_get_mac_addr
-+ * @hw: pointer to hardware structure
-+ **/
-+static int alc_get_mac_addr(struct alx_hw *hw, u8 *addr)
-+{
-+ int retval = 0;
-+
-+ if (l1c_get_perm_macaddr(hw, addr)) {
-+ alx_hw_err(hw, "error when get permanent mac address\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alc_reset_pcie(struct alx_hw *hw, bool l0s_en, bool l1_en)
-+{
-+ int retval = 0;
-+
-+ if (!CHK_HW_FLAG(L0S_CAP))
-+ l0s_en = false;
-+
-+ if (l0s_en)
-+ SET_HW_FLAG(L0S_EN);
-+ else
-+ CLI_HW_FLAG(L0S_EN);
-+
-+
-+ if (!CHK_HW_FLAG(L1_CAP))
-+ l1_en = false;
-+
-+ if (l1_en)
-+ SET_HW_FLAG(L1_EN);
-+ else
-+ CLI_HW_FLAG(L1_EN);
-+
-+ if (l1c_reset_pcie(hw, l0s_en, l1_en)) {
-+ alx_hw_err(hw, "error when reset pcie\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alc_config_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en)
-+{
-+ u8 link_stat;
-+ int retval = 0;
-+
-+ if (!CHK_HW_FLAG(L0S_CAP))
-+ l0s_en = false;
-+
-+ if (l0s_en)
-+ SET_HW_FLAG(L0S_EN);
-+ else
-+ CLI_HW_FLAG(L0S_EN);
-+
-+ if (!CHK_HW_FLAG(L1_CAP))
-+ l1_en = false;
-+
-+ if (l1_en)
-+ SET_HW_FLAG(L1_EN);
-+ else
-+ CLI_HW_FLAG(L1_EN);
-+
-+ link_stat = hw->link_up ? LX_LC_ALL : 0;
-+ if (l1c_enable_aspm(hw, l0s_en, l1_en, link_stat)) {
-+ alx_hw_err(hw, "error when enable aspm\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alc_config_wol(struct alx_hw *hw, u32 wufc)
-+{
-+ u32 wol = 0;
-+
-+ /* turn on magic packet event */
-+ if (wufc & ALX_WOL_MAGIC) {
-+ wol |= L1C_WOL0_MAGIC_EN | L1C_WOL0_PME_MAGIC_EN;
-+ if (hw->mac_type == alx_mac_l2cb_v1 &&
-+ hw->pci_revid == ALX_REV_ID_AR8152_V1_1) {
-+ wol |= L1C_WOL0_PATTERN_EN | L1C_WOL0_PME_PATTERN_EN;
-+ }
-+ /* magic packet maybe Broadcast&multicast&Unicast frame
-+ * move to l1c_powersaving
-+ */
-+ }
-+
-+ /* turn on link up event */
-+ if (wufc & ALX_WOL_PHY) {
-+ wol |= L1C_WOL0_LINK_EN | L1C_WOL0_PME_LINK;
-+ /* only link up can wake up */
-+ alc_write_phy_reg(hw, L1C_MII_IER, L1C_IER_LINK_UP);
-+ }
-+
-+ alx_mem_w32(hw, L1C_WOL0, wol);
-+ return 0;
-+}
-+
-+
-+static int alc_config_mac_ctrl(struct alx_hw *hw)
-+{
-+ u32 mac;
-+
-+ alx_mem_r32(hw, L1C_MAC_CTRL, &mac);
-+
-+ /* enable/disable VLAN tag insert,strip */
-+ if (CHK_HW_FLAG(VLANSTRIP_EN))
-+ mac |= L1C_MAC_CTRL_VLANSTRIP;
-+ else
-+ mac &= ~L1C_MAC_CTRL_VLANSTRIP;
-+
-+ if (CHK_HW_FLAG(PROMISC_EN))
-+ mac |= L1C_MAC_CTRL_PROMISC_EN;
-+ else
-+ mac &= ~L1C_MAC_CTRL_PROMISC_EN;
-+
-+ if (CHK_HW_FLAG(MULTIALL_EN))
-+ mac |= L1C_MAC_CTRL_MULTIALL_EN;
-+ else
-+ mac &= ~L1C_MAC_CTRL_MULTIALL_EN;
-+
-+ if (CHK_HW_FLAG(LOOPBACK_EN))
-+ mac |= L1C_MAC_CTRL_LPBACK_EN;
-+ else
-+ mac &= ~L1C_MAC_CTRL_LPBACK_EN;
-+
-+ alx_mem_w32(hw, L1C_MAC_CTRL, mac);
-+ return 0;
-+}
-+
-+
-+static int alc_config_pow_save(struct alx_hw *hw, u32 speed, bool wol_en,
-+ bool tx_en, bool rx_en, bool pws_en)
-+{
-+ u8 wire_spd = LX_LC_10H;
-+ int retval = 0;
-+
-+ switch (speed) {
-+ case ALX_LINK_SPEED_UNKNOWN:
-+ case ALX_LINK_SPEED_10_HALF:
-+ wire_spd = LX_LC_10H;
-+ break;
-+ case ALX_LINK_SPEED_10_FULL:
-+ wire_spd = LX_LC_10F;
-+ break;
-+ case ALX_LINK_SPEED_100_HALF:
-+ wire_spd = LX_LC_100H;
-+ break;
-+ case ALX_LINK_SPEED_100_FULL:
-+ wire_spd = LX_LC_100F;
-+ break;
-+ case ALX_LINK_SPEED_1GB_FULL:
-+ wire_spd = LX_LC_1000F;
-+ break;
-+ }
-+
-+ if (l1c_powersaving(hw, wire_spd, wol_en, tx_en, rx_en, pws_en)) {
-+ alx_hw_err(hw, "error when set power saving\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+/* RAR, Multicast, VLAN */
-+static int alc_set_mac_addr(struct alx_hw *hw, u8 *addr)
-+{
-+ u32 sta;
-+
-+ /*
-+ * for example: 00-0B-6A-F6-00-DC
-+ * 0<-->6AF600DC, 1<-->000B.
-+ */
-+
-+ /* low dword */
-+ sta = (((u32)addr[2]) << 24) | (((u32)addr[3]) << 16) |
-+ (((u32)addr[4]) << 8) | (((u32)addr[5])) ;
-+ alx_mem_w32(hw, L1C_STAD0, sta);
-+
-+ /* hight dword */
-+ sta = (((u32)addr[0]) << 8) | (((u32)addr[1])) ;
-+ alx_mem_w32(hw, L1C_STAD1, sta);
-+ return 0;
-+}
-+
-+
-+static int alc_set_mc_addr(struct alx_hw *hw, u8 *addr)
-+{
-+ u32 crc32, bit, reg, mta;
-+
-+ /*
-+ * set hash value for a multicast address hash calcu processing.
-+ * 1. calcu 32bit CRC for multicast address
-+ * 2. reverse crc with MSB to LSB
-+ */
-+ crc32 = ALX_ETH_CRC(addr, ALX_ETH_LENGTH_OF_ADDRESS);
-+
-+ /*
-+ * The HASH Table is a register array of 2 32-bit registers.
-+ * It is treated like an array of 64 bits. We want to set
-+ * bit BitArray[hash_value]. So we figure out what register
-+ * the bit is in, read it, OR in the new bit, then write
-+ * back the new value. The register is determined by the
-+ * upper 7 bits of the hash value and the bit within that
-+ * register are determined by the lower 5 bits of the value.
-+ */
-+ reg = (crc32 >> 31) & 0x1;
-+ bit = (crc32 >> 26) & 0x1F;
-+
-+ alx_mem_r32(hw, L1C_HASH_TBL0 + (reg<<2), &mta);
-+ mta |= (0x1 << bit);
-+ alx_mem_w32(hw, L1C_HASH_TBL0 + (reg<<2), mta);
-+ return 0;
-+}
-+
-+
-+static int alc_clear_mc_addr(struct alx_hw *hw)
-+{
-+ alx_mem_w32(hw, L1C_HASH_TBL0, 0);
-+ alx_mem_w32(hw, L1C_HASH_TBL1, 0);
-+ return 0;
-+}
-+
-+
-+/* RTX */
-+static int alc_config_tx(struct alx_hw *hw)
-+{
-+ return 0;
-+}
-+
-+
-+/* INTR */
-+static int alc_ack_phy_intr(struct alx_hw *hw)
-+{
-+ u16 isr;
-+ return alc_read_phy_reg(hw, L1C_MII_ISR, &isr);
-+}
-+
-+
-+static int alc_enable_legacy_intr(struct alx_hw *hw)
-+{
-+ alx_mem_w32(hw, L1C_ISR, ~((u32) L1C_ISR_DIS));
-+ alx_mem_w32(hw, L1C_IMR, hw->intr_mask);
-+ return 0;
-+}
-+
-+
-+static int alc_disable_legacy_intr(struct alx_hw *hw)
-+{
-+ alx_mem_w32(hw, L1C_ISR, L1C_ISR_DIS);
-+ alx_mem_w32(hw, L1C_IMR, 0);
-+ alx_mem_flush(hw);
-+ return 0;
-+}
-+
-+
-+/*
-+ * NV Ram
-+ */
-+static int alc_check_nvram(struct alx_hw *hw, bool *exist)
-+{
-+ *exist = false;
-+ return 0;
-+}
-+
-+
-+static int alc_read_nvram(struct alx_hw *hw, u16 offset, u32 *data)
-+{
-+ int i;
-+ u32 ectrl1, ectrl2, edata;
-+ int retval = 0;
-+
-+ if (offset & 0x3)
-+ return retval; /* address do not align */
-+
-+ alx_mem_r32(hw, L1C_EFUSE_CTRL2, &ectrl2);
-+ if (!(ectrl2 & L1C_EFUSE_CTRL2_CLK_EN))
-+ alx_mem_w32(hw, L1C_EFUSE_CTRL2, ectrl2|L1C_EFUSE_CTRL2_CLK_EN);
-+
-+ alx_mem_w32(hw, L1C_EFUSE_DATA, 0);
-+ ectrl1 = FIELDL(L1C_EFUSE_CTRL_ADDR, offset);
-+ alx_mem_w32(hw, L1C_EFUSE_CTRL, ectrl1);
-+
-+ for (i = 0; i < 10; i++) {
-+ udelay(100);
-+ alx_mem_r32(hw, L1C_EFUSE_CTRL, &ectrl1);
-+ if (ectrl1 & L1C_EFUSE_CTRL_FLAG)
-+ break;
-+ }
-+ if (ectrl1 & L1C_EFUSE_CTRL_FLAG) {
-+ alx_mem_r32(hw, L1C_EFUSE_CTRL, &ectrl1);
-+ alx_mem_r32(hw, L1C_EFUSE_DATA, &edata);
-+ *data = LX_SWAP_DW((ectrl1 << 16) | (edata >> 16));
-+ return retval;
-+ }
-+
-+ if (!(ectrl2 & L1C_EFUSE_CTRL2_CLK_EN))
-+ alx_mem_w32(hw, L1C_EFUSE_CTRL2, ectrl2);
-+
-+ return retval;
-+}
-+
-+
-+static int alc_write_nvram(struct alx_hw *hw, u16 offset, u32 data)
-+{
-+ return 0;
-+}
-+
-+
-+/* fc */
-+static int alc_get_fc_mode(struct alx_hw *hw, enum alx_fc_mode *mode)
-+{
-+ u16 bmsr, giga;
-+ int i;
-+ int retval = 0;
-+
-+ for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) {
-+ alc_read_phy_reg(hw, MII_BMSR, &bmsr);
-+ alc_read_phy_reg(hw, MII_BMSR, &bmsr);
-+ if (bmsr & BMSR_LSTATUS) {
-+ /* Read phy Specific Status Register (17) */
-+ retval = alc_read_phy_reg(hw, L1C_MII_GIGA_PSSR, &giga);
-+ if (retval)
-+ return retval;
-+
-+ if (!(giga & L1C_GIGA_PSSR_SPD_DPLX_RESOLVED)) {
-+ alx_hw_err(hw,
-+ "error for speed duplex resolved\n");
-+ return -EINVAL;
-+ }
-+
-+ if ((giga & L1C_GIGA_PSSR_FC_TXEN) &&
-+ (giga & L1C_GIGA_PSSR_FC_RXEN)) {
-+ *mode = alx_fc_full;
-+ } else if (giga & L1C_GIGA_PSSR_FC_TXEN) {
-+ *mode = alx_fc_tx_pause;
-+ } else if (giga & L1C_GIGA_PSSR_FC_RXEN) {
-+ *mode = alx_fc_rx_pause;
-+ } else {
-+ *mode = alx_fc_none;
-+ }
-+ break;
-+ }
-+ mdelay(100);
-+ }
-+
-+ if (i == ALX_MAX_SETUP_LNK_CYCLE) {
-+ alx_hw_err(hw, "error when get flow control mode\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alc_config_fc(struct alx_hw *hw)
-+{
-+ u32 mac;
-+ int retval = 0;
-+
-+ if (hw->disable_fc_autoneg) {
-+ hw->fc_was_autonegged = false;
-+ hw->cur_fc_mode = hw->req_fc_mode;
-+ } else {
-+ hw->fc_was_autonegged = true;
-+ retval = alc_get_fc_mode(hw, &hw->cur_fc_mode);
-+ if (retval)
-+ return retval;
-+ }
-+
-+ alx_mem_r32(hw, L1C_MAC_CTRL, &mac);
-+
-+ switch (hw->cur_fc_mode) {
-+ case alx_fc_none: /* 0 */
-+ mac &= ~(L1C_MAC_CTRL_RXFC_EN | L1C_MAC_CTRL_TXFC_EN);
-+ break;
-+ case alx_fc_rx_pause: /* 1 */
-+ mac &= ~L1C_MAC_CTRL_TXFC_EN;
-+ mac |= L1C_MAC_CTRL_RXFC_EN;
-+ break;
-+ case alx_fc_tx_pause: /* 2 */
-+ mac |= L1C_MAC_CTRL_TXFC_EN;
-+ mac &= ~L1C_MAC_CTRL_RXFC_EN;
-+ break;
-+ case alx_fc_full: /* 3 */
-+ case alx_fc_default: /* 4 */
-+ mac |= (L1C_MAC_CTRL_TXFC_EN | L1C_MAC_CTRL_RXFC_EN);
-+ break;
-+ default:
-+ alx_hw_err(hw, "flow control param set incorrectly\n");
-+ return -EINVAL;
-+ }
-+
-+ alx_mem_w32(hw, L1C_MAC_CTRL, mac);
-+ return retval;
-+}
-+
-+
-+/* ethtool */
-+static int alc_get_ethtool_regs(struct alx_hw *hw, void *buff)
-+{
-+ int i;
-+ u32 *val = buff;
-+ static const int reg[] = {
-+ /* 0 */
-+ L1C_LNK_CAP, L1C_PMCTRL, L1C_HALFD, L1C_SLD, L1C_MASTER,
-+ L1C_MANU_TIMER, L1C_IRQ_MODU_TIMER, L1C_PHY_CTRL, L1C_LNK_CTRL,
-+ L1C_MAC_STS,
-+
-+ /* 10 */
-+ L1C_MDIO, L1C_SERDES, L1C_MAC_CTRL, L1C_GAP, L1C_STAD0,
-+ L1C_STAD1, L1C_HASH_TBL0, L1C_HASH_TBL1, L1C_RXQ0, L1C_RXQ1,
-+
-+ /* 20 */
-+ L1C_RXQ2, L1C_RXQ3, L1C_TXQ0, L1C_TXQ1, L1C_TXQ2, L1C_MTU,
-+ L1C_WOL0, L1C_WOL1, L1C_WOL2,
-+ };
-+
-+ for (i = 0; i < ARRAY_SIZE(reg); i++)
-+ alx_mem_r32(hw, reg[i], &val[i]);
-+ return 0;
-+}
-+
-+
-+/******************************************************************************/
-+static int alc_get_hw_capabilities(struct alx_hw *hw)
-+{
-+ /*
-+ * because there is some hareware error on some platforms, just disable
-+ * this feature when link connected.
-+ */
-+ CLI_HW_FLAG(L0S_CAP);
-+ CLI_HW_FLAG(L1_CAP);
-+
-+ if ((hw->mac_type == alx_mac_l1c) ||
-+ (hw->mac_type == alx_mac_l1d_v1) ||
-+ (hw->mac_type == alx_mac_l1d_v2))
-+ SET_HW_FLAG(GIGA_CAP);
-+
-+ SET_HW_FLAG(PWSAVE_CAP);
-+ return 0;
-+}
-+
-+
-+/* alc_set_hw_info */
-+static int alc_set_hw_infos(struct alx_hw *hw)
-+{
-+ hw->rxstat_reg = 0x1700;
-+ hw->rxstat_sz = 0x60;
-+ hw->txstat_reg = 0x1760;
-+ hw->txstat_sz = 0x68;
-+
-+ hw->rx_prod_reg[0] = L1C_RFD_PIDX;
-+ hw->rx_cons_reg[0] = L1C_RFD_CIDX;
-+
-+ hw->tx_prod_reg[0] = L1C_TPD_PRI0_PIDX;
-+ hw->tx_cons_reg[0] = L1C_TPD_PRI0_CIDX;
-+ hw->tx_prod_reg[1] = L1C_TPD_PRI1_PIDX;
-+ hw->tx_cons_reg[1] = L1C_TPD_PRI1_CIDX;
-+
-+ hw->hwreg_sz = 0x80;
-+ hw->eeprom_sz = 0;
-+
-+ return 0;
-+}
-+
-+
-+/**
-+ * alc_init_hw_callbacks - Inits func ptrs and MAC type
-+ * @hw: pointer to hardware structure
-+ **/
-+int alc_init_hw_callbacks(struct alx_hw *hw)
-+{
-+ /* NIC */
-+ hw->cbs.identify_nic = &alc_identify_nic;
-+ /* MAC*/
-+ hw->cbs.reset_mac = &alc_reset_mac;
-+ hw->cbs.start_mac = &alc_start_mac;
-+ hw->cbs.stop_mac = &alc_stop_mac;
-+ hw->cbs.config_mac = &alc_config_mac;
-+ hw->cbs.get_mac_addr = &alc_get_mac_addr;
-+ hw->cbs.set_mac_addr = &alc_set_mac_addr;
-+ hw->cbs.set_mc_addr = &alc_set_mc_addr;
-+ hw->cbs.clear_mc_addr = &alc_clear_mc_addr;
-+
-+ /* PHY */
-+ hw->cbs.init_phy = &alc_init_phy;
-+ hw->cbs.reset_phy = &alc_reset_phy;
-+ hw->cbs.read_phy_reg = &alc_read_phy_reg;
-+ hw->cbs.write_phy_reg = &alc_write_phy_reg;
-+ hw->cbs.check_phy_link = &alc_check_phy_link;
-+ hw->cbs.setup_phy_link = &alc_setup_phy_link;
-+ hw->cbs.setup_phy_link_speed = &alc_setup_phy_link_speed;
-+
-+ /* Interrupt */
-+ hw->cbs.ack_phy_intr = &alc_ack_phy_intr;
-+ hw->cbs.enable_legacy_intr = &alc_enable_legacy_intr;
-+ hw->cbs.disable_legacy_intr = &alc_disable_legacy_intr;
-+
-+ /* Configure */
-+ hw->cbs.config_tx = &alc_config_tx;
-+ hw->cbs.config_fc = &alc_config_fc;
-+ hw->cbs.config_aspm = &alc_config_aspm;
-+ hw->cbs.config_wol = &alc_config_wol;
-+ hw->cbs.config_mac_ctrl = &alc_config_mac_ctrl;
-+ hw->cbs.config_pow_save = &alc_config_pow_save;
-+ hw->cbs.reset_pcie = &alc_reset_pcie;
-+
-+ /* NVRam */
-+ hw->cbs.check_nvram = &alc_check_nvram;
-+ hw->cbs.read_nvram = &alc_read_nvram;
-+ hw->cbs.write_nvram = &alc_write_nvram;
-+
-+ /* Others */
-+ hw->cbs.get_ethtool_regs = alc_get_ethtool_regs;
-+
-+ /* get hw capabilitites to HW->flags */
-+ alc_get_hw_capabilities(hw);
-+ alc_set_hw_infos(hw);
-+
-+ alx_hw_info(hw, "HW Flags = 0x%x\n", hw->flags);
-+ return 0;
-+}
-+
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alc_hw.c
-@@ -0,0 +1,1087 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/pci_regs.h>
-+#include <linux/mii.h>
-+
-+#include "alc_hw.h"
-+
-+
-+
-+/*
-+ * get permanent mac address
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1c_get_perm_macaddr(struct alx_hw *hw, u8 *addr)
-+{
-+ u32 val, otp_ctrl, otp_flag, mac0, mac1;
-+ u16 i;
-+ u16 phy_val;
-+
-+ /* get it from register first */
-+ alx_mem_r32(hw, L1C_STAD0, &mac0);
-+ alx_mem_r32(hw, L1C_STAD1, &mac1);
-+
-+ *(u32 *)(addr + 2) = LX_SWAP_DW(mac0);
-+ *(u16 *)addr = (u16)LX_SWAP_W((u16)mac1);
-+
-+ if (macaddr_valid(addr))
-+ return 0;
-+
-+ alx_mem_r32(hw, L1C_TWSI_DBG, &val);
-+ alx_mem_r32(hw, L1C_EFUSE_CTRL2, &otp_ctrl);
-+ alx_mem_r32(hw, L1C_MASTER, &otp_flag);
-+
-+ if ((val & L1C_TWSI_DBG_DEV_EXIST) != 0 ||
-+ (otp_flag & L1C_MASTER_OTP_FLG) != 0) {
-+ /* nov-memory exist, do software-autoload */
-+ /* enable OTP_CLK for L1C */
-+ if (hw->pci_devid == L1C_DEV_ID ||
-+ hw->pci_devid == L2C_DEV_ID) {
-+ if ((otp_ctrl & L1C_EFUSE_CTRL2_CLK_EN) != 0) {
-+ alx_mem_w32(hw, L1C_EFUSE_CTRL2,
-+ otp_ctrl | L1C_EFUSE_CTRL2_CLK_EN);
-+ udelay(5);
-+ }
-+ }
-+ /* raise voltage temporally for L2CB/L1D */
-+ if (hw->pci_devid == L2CB_DEV_ID ||
-+ hw->pci_devid == L2CB2_DEV_ID) {
-+ /* clear bit[7] of debugport 00 */
-+ l1c_read_phydbg(hw, true, L1C_MIIDBG_ANACTRL,
-+ &phy_val);
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_ANACTRL,
-+ phy_val & ~L1C_ANACTRL_HB_EN);
-+ /* set bit[3] of debugport 3B */
-+ l1c_read_phydbg(hw, true, L1C_MIIDBG_VOLT_CTRL,
-+ &phy_val);
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_VOLT_CTRL,
-+ phy_val | L1C_VOLT_CTRL_SWLOWEST);
-+ udelay(20);
-+ }
-+ /* do load */
-+ alx_mem_r32(hw, L1C_SLD, &val);
-+ alx_mem_w32(hw, L1C_SLD, val | L1C_SLD_START);
-+ for (i = 0; i < L1C_SLD_MAX_TO; i++) {
-+ mdelay(1);
-+ alx_mem_r32(hw, L1C_SLD, &val);
-+ if ((val & L1C_SLD_START) == 0)
-+ break;
-+ }
-+ /* disable OTP_CLK for L1C */
-+ if (hw->pci_devid == L1C_DEV_ID ||
-+ hw->pci_devid == L2C_DEV_ID) {
-+ alx_mem_w32(hw, L1C_EFUSE_CTRL2,
-+ otp_ctrl & ~L1C_EFUSE_CTRL2_CLK_EN);
-+ udelay(5);
-+ }
-+ /* low voltage */
-+ if (hw->pci_devid == L2CB_DEV_ID ||
-+ hw->pci_devid == L2CB2_DEV_ID) {
-+ /* set bit[7] of debugport 00 */
-+ l1c_read_phydbg(hw, true, L1C_MIIDBG_ANACTRL,
-+ &phy_val);
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_ANACTRL,
-+ phy_val | L1C_ANACTRL_HB_EN);
-+ /* clear bit[3] of debugport 3B */
-+ l1c_read_phydbg(hw, true, L1C_MIIDBG_VOLT_CTRL,
-+ &phy_val);
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_VOLT_CTRL,
-+ phy_val & ~L1C_VOLT_CTRL_SWLOWEST);
-+ udelay(20);
-+ }
-+ if (i == L1C_SLD_MAX_TO)
-+ goto out;
-+ } else {
-+ if (hw->pci_devid == L1C_DEV_ID ||
-+ hw->pci_devid == L2C_DEV_ID) {
-+ alx_mem_w32(hw, L1C_EFUSE_CTRL2,
-+ otp_ctrl & ~L1C_EFUSE_CTRL2_CLK_EN);
-+ udelay(5);
-+ }
-+ }
-+
-+ alx_mem_r32(hw, L1C_STAD0, &mac0);
-+ alx_mem_r32(hw, L1C_STAD1, &mac1);
-+
-+ *(u32 *)(addr + 2) = LX_SWAP_DW(mac0);
-+ *(u16 *)addr = (u16)LX_SWAP_W((u16)mac1);
-+
-+ if (macaddr_valid(addr))
-+ return 0;
-+
-+out:
-+ return LX_ERR_ALOAD;
-+}
-+
-+/*
-+ * reset mac & dma
-+ * return
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1c_reset_mac(struct alx_hw *hw)
-+{
-+ u32 val, mrst_val;
-+ u16 ret;
-+ u16 i;
-+
-+ /* disable all interrupts, RXQ/TXQ */
-+ alx_mem_w32(hw, L1C_IMR, 0);
-+ alx_mem_w32(hw, L1C_ISR, L1C_ISR_DIS);
-+
-+ ret = l1c_enable_mac(hw, false, 0);
-+ if (ret != 0)
-+ return ret;
-+ /* reset whole mac safely. OOB is meaningful for L1D only */
-+ alx_mem_r32(hw, L1C_MASTER, &mrst_val);
-+ mrst_val |= L1C_MASTER_OOB_DIS;
-+ alx_mem_w32(hw, L1C_MASTER, mrst_val | L1C_MASTER_DMA_MAC_RST);
-+
-+ /* make sure it's idle */
-+ for (i = 0; i < L1C_DMA_MAC_RST_TO; i++) {
-+ alx_mem_r32(hw, L1C_MASTER, &val);
-+ if ((val & L1C_MASTER_DMA_MAC_RST) == 0)
-+ break;
-+ udelay(20);
-+ }
-+ if (i == L1C_DMA_MAC_RST_TO)
-+ return LX_ERR_RSTMAC;
-+ /* keep the old value */
-+ alx_mem_w32(hw, L1C_MASTER, mrst_val & ~L1C_MASTER_DMA_MAC_RST);
-+
-+ /* driver control speed/duplex, hash-alg */
-+ alx_mem_r32(hw, L1C_MAC_CTRL, &val);
-+ alx_mem_w32(hw, L1C_MAC_CTRL, val | L1C_MAC_CTRL_WOLSPED_SWEN);
-+
-+ /* clk switch setting */
-+ alx_mem_r32(hw, L1C_SERDES, &val);
-+ switch (hw->pci_devid) {
-+ case L2CB_DEV_ID:
-+ alx_mem_w32(hw, L1C_SERDES, val & ~L1C_SERDES_PHYCLK_SLWDWN);
-+ break;
-+ case L2CB2_DEV_ID:
-+ case L1D2_DEV_ID:
-+ alx_mem_w32(hw, L1C_SERDES,
-+ val | L1C_SERDES_PHYCLK_SLWDWN |
-+ L1C_SERDES_MACCLK_SLWDWN);
-+ break;
-+ default:
-+ /* the defalut value of default product is OFF */;
-+ }
-+
-+ return 0;
-+}
-+
-+/* reset phy
-+ * return
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1c_reset_phy(struct alx_hw *hw, bool pws_en, bool az_en, bool ptp_en)
-+{
-+ u32 val;
-+ u16 i, phy_val;
-+
-+ ptp_en = ptp_en;
-+
-+ /* reset PHY core */
-+ alx_mem_r32(hw, L1C_PHY_CTRL, &val);
-+ val &= ~(L1C_PHY_CTRL_DSPRST_OUT | L1C_PHY_CTRL_IDDQ |
-+ L1C_PHY_CTRL_GATE_25M | L1C_PHY_CTRL_POWER_DOWN |
-+ L1C_PHY_CTRL_CLS);
-+ val |= L1C_PHY_CTRL_RST_ANALOG;
-+
-+ if (pws_en)
-+ val |= (L1C_PHY_CTRL_HIB_PULSE | L1C_PHY_CTRL_HIB_EN);
-+ else
-+ val &= ~(L1C_PHY_CTRL_HIB_PULSE | L1C_PHY_CTRL_HIB_EN);
-+
-+ alx_mem_w32(hw, L1C_PHY_CTRL, val);
-+ udelay(10); /* 5us is enough */
-+ alx_mem_w32(hw, L1C_PHY_CTRL, val | L1C_PHY_CTRL_DSPRST_OUT);
-+
-+ /* delay 800us */
-+ for (i = 0; i < L1C_PHY_CTRL_DSPRST_TO; i++)
-+ udelay(10);
-+
-+ /* switch clock */
-+ if (hw->pci_devid == L2CB_DEV_ID) {
-+ l1c_read_phydbg(hw, true, L1C_MIIDBG_CFGLPSPD, &phy_val);
-+ /* clear bit13 */
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_CFGLPSPD,
-+ phy_val & ~L1C_CFGLPSPD_RSTCNT_CLK125SW);
-+ }
-+
-+ /* fix tx-half-amp issue */
-+ if (hw->pci_devid == L2CB_DEV_ID || hw->pci_devid == L2CB2_DEV_ID) {
-+ l1c_read_phydbg(hw, true, L1C_MIIDBG_CABLE1TH_DET, &phy_val);
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_CABLE1TH_DET,
-+ phy_val | L1C_CABLE1TH_DET_EN); /* set bit15 */
-+ }
-+
-+ if (pws_en) {
-+ /* clear bit[3] of debugport 3B to 0,
-+ * lower voltage to save power */
-+ if (hw->pci_devid == L2CB_DEV_ID ||
-+ hw->pci_devid == L2CB2_DEV_ID) {
-+ l1c_read_phydbg(hw, true, L1C_MIIDBG_VOLT_CTRL,
-+ &phy_val);
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_VOLT_CTRL,
-+ phy_val & ~L1C_VOLT_CTRL_SWLOWEST);
-+ }
-+ /* power saving config */
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_LEGCYPS,
-+ (hw->pci_devid == L1D_DEV_ID ||
-+ hw->pci_devid == L1D2_DEV_ID) ?
-+ L1D_LEGCYPS_DEF : L1C_LEGCYPS_DEF);
-+ /* hib */
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_SYSMODCTRL,
-+ L1C_SYSMODCTRL_IECHOADJ_DEF);
-+ } else {
-+ /*dis powersaving */
-+ l1c_read_phydbg(hw, true, L1C_MIIDBG_LEGCYPS, &phy_val);
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_LEGCYPS,
-+ phy_val & ~L1C_LEGCYPS_EN);
-+ /* disable hibernate */
-+ l1c_read_phydbg(hw, true, L1C_MIIDBG_HIBNEG, &phy_val);
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_HIBNEG,
-+ phy_val & ~L1C_HIBNEG_PSHIB_EN);
-+ }
-+
-+ /* az is only for l2cbv2 / l1dv1 /l1dv2 */
-+ if (hw->pci_devid == L1D_DEV_ID ||
-+ hw->pci_devid == L1D2_DEV_ID ||
-+ hw->pci_devid == L2CB2_DEV_ID) {
-+ if (az_en) {
-+ switch (hw->pci_devid) {
-+ case L2CB2_DEV_ID:
-+ alx_mem_w32(hw, L1C_LPI_DECISN_TIMER,
-+ L1C_LPI_DESISN_TIMER_L2CB);
-+ /* az enable 100M */
-+ l1c_write_phy(hw, true, L1C_MIIEXT_ANEG, true,
-+ L1C_MIIEXT_LOCAL_EEEADV,
-+ L1C_LOCAL_EEEADV_100BT);
-+ /* az long wake threshold */
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_AZCTRL5,
-+ L1C_AZCTRL5_WAKE_LTH_L2CB);
-+ /* az short wake threshold */
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_AZCTRL4,
-+ L1C_AZCTRL4_WAKE_STH_L2CB);
-+
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_CLDCTRL3,
-+ L1C_CLDCTRL3_L2CB);
-+
-+ /* bit7 set to 0, otherwise ping fail */
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_CLDCTRL7,
-+ L1C_CLDCTRL7_L2CB);
-+
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_AZCTRL2,
-+ L1C_AZCTRL2_L2CB);
-+ break;
-+
-+ case L1D_DEV_ID:
-+ l1c_write_phydbg(hw, true,
-+ L1C_MIIDBG_AZ_ANADECT, L1C_AZ_ANADECT_DEF);
-+ phy_val = hw->long_cable ? L1C_CLDCTRL3_L1D :
-+ (L1C_CLDCTRL3_L1D &
-+ ~(L1C_CLDCTRL3_BP_CABLE1TH_DET_GT |
-+ L1C_CLDCTRL3_AZ_DISAMP));
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_CLDCTRL3, phy_val);
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_AZCTRL,
-+ L1C_AZCTRL_L1D);
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_AZCTRL2,
-+ L1C_AZCTRL2_L2CB);
-+ break;
-+
-+ case L1D2_DEV_ID:
-+ l1c_write_phydbg(hw, true,
-+ L1C_MIIDBG_AZ_ANADECT,
-+ L1C_AZ_ANADECT_DEF);
-+ phy_val = hw->long_cable ? L1C_CLDCTRL3_L1D :
-+ (L1C_CLDCTRL3_L1D &
-+ ~L1C_CLDCTRL3_BP_CABLE1TH_DET_GT);
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_CLDCTRL3, phy_val);
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_AZCTRL,
-+ L1C_AZCTRL_L1D);
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_AZCTRL2,
-+ L1C_AZCTRL2_L1D2);
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_AZCTRL6,
-+ L1C_AZCTRL6_L1D2);
-+ break;
-+ }
-+ } else {
-+ alx_mem_r32(hw, L1C_LPI_CTRL, &val);
-+ alx_mem_w32(hw, L1C_LPI_CTRL, val & ~L1C_LPI_CTRL_EN);
-+ l1c_write_phy(hw, true, L1C_MIIEXT_ANEG, true,
-+ L1C_MIIEXT_LOCAL_EEEADV, 0);
-+ l1c_write_phy(hw, true, L1C_MIIEXT_PCS, true,
-+ L1C_MIIEXT_CLDCTRL3, L1C_CLDCTRL3_L2CB);
-+ }
-+ }
-+
-+ /* other debug port need to set */
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_ANACTRL, L1C_ANACTRL_DEF);
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_SRDSYSMOD, L1C_SRDSYSMOD_DEF);
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_TST10BTCFG, L1C_TST10BTCFG_DEF);
-+ /* L1c, L2c, L1d, L2cb link fail inhibit
-+ timer issue of L1c UNH-IOL test fail, set bit7*/
-+ l1c_write_phydbg(hw, true, L1C_MIIDBG_TST100BTCFG,
-+ L1C_TST100BTCFG_DEF | L1C_TST100BTCFG_LITCH_EN);
-+
-+ /* set phy interrupt mask */
-+ l1c_write_phy(hw, false, 0, true,
-+ L1C_MII_IER, L1C_IER_LINK_UP | L1C_IER_LINK_DOWN);
-+
-+ return 0;
-+}
-+
-+
-+/* reset pcie
-+ * just reset pcie relative registers (pci command, clk, aspm...)
-+ * return
-+ * 0:success
-+ * non-0:fail
-+ */
-+u16 l1c_reset_pcie(struct alx_hw *hw, bool l0s_en, bool l1_en)
-+{
-+ u32 val;
-+ u16 val16;
-+ u16 ret;
-+
-+ /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */
-+ alx_cfg_r16(hw, PCI_COMMAND, &val16);
-+ if ((val16 & (PCI_COMMAND_IO |
-+ PCI_COMMAND_MEMORY |
-+ PCI_COMMAND_MASTER)) == 0 ||
-+ (val16 & PCI_COMMAND_INTX_DISABLE) != 0) {
-+ val16 = (u16)((val16 | (PCI_COMMAND_IO |
-+ PCI_COMMAND_MEMORY |
-+ PCI_COMMAND_MASTER))
-+ & ~PCI_COMMAND_INTX_DISABLE);
-+ alx_cfg_w16(hw, PCI_COMMAND, val16);
-+ }
-+
-+ /* Clear any PowerSaving Settings */
-+ alx_cfg_w16(hw, L1C_PM_CSR, 0);
-+
-+ /* close write attr for some registes */
-+ alx_mem_r32(hw, L1C_LTSSM_CTRL, &val);
-+ alx_mem_w32(hw, L1C_LTSSM_CTRL, val & ~L1C_LTSSM_WRO_EN);
-+
-+ /* mask some pcie error bits */
-+ alx_mem_r32(hw, L1C_UE_SVRT, &val);
-+ val &= ~(L1C_UE_SVRT_DLPROTERR | L1C_UE_SVRT_FCPROTERR);
-+ alx_mem_w32(hw, L1C_UE_SVRT, val);
-+
-+ /* pclk */
-+ alx_mem_r32(hw, L1C_MASTER, &val);
-+ val &= ~L1C_MASTER_PCLKSEL_SRDS;
-+ alx_mem_w32(hw, L1C_MASTER, val);
-+
-+ /* Set 1000 bit 2, only used for L1c/L2c , WOL usage */
-+ if (hw->pci_devid == L1C_DEV_ID || hw->pci_devid == L2C_DEV_ID) {
-+ alx_mem_r32(hw, L1C_PPHY_MISC1, &val);
-+ alx_mem_w32(hw, L1C_PPHY_MISC1, val | L1C_PPHY_MISC1_RCVDET);
-+ } else { /* other device should set bit 5 of reg1400 for WOL */
-+ if ((val & L1C_MASTER_WAKEN_25M) == 0)
-+ alx_mem_w32(hw, L1C_MASTER, val | L1C_MASTER_WAKEN_25M);
-+ }
-+ /* l2cb 1.0*/
-+ if (hw->pci_devid == L2CB_DEV_ID && hw->pci_revid == L2CB_V10) {
-+ alx_mem_r32(hw, L1C_PPHY_MISC2, &val);
-+ FIELD_SETL(val, L1C_PPHY_MISC2_L0S_TH,
-+ L1C_PPHY_MISC2_L0S_TH_L2CB1);
-+ FIELD_SETL(val, L1C_PPHY_MISC2_CDR_BW,
-+ L1C_PPHY_MISC2_CDR_BW_L2CB1);
-+ alx_mem_w32(hw, L1C_PPHY_MISC2, val);
-+ /* extend L1 sync timer, this will use more power,
-+ * only for L2cb v1.0*/
-+ if (!hw->aps_en) {
-+ alx_mem_r32(hw, L1C_LNK_CTRL, &val);
-+ alx_mem_w32(hw, L1C_LNK_CTRL,
-+ val | L1C_LNK_CTRL_EXTSYNC);
-+ }
-+ }
-+
-+ /* l2cbv1.x & l1dv1.x */
-+ if (hw->pci_devid == L2CB_DEV_ID || hw->pci_devid == L1D_DEV_ID) {
-+ alx_mem_r32(hw, L1C_PMCTRL, &val);
-+ alx_mem_w32(hw, L1C_PMCTRL, val | L1C_PMCTRL_L0S_BUFSRX_EN);
-+ /* clear vendor message for L1d & L2cb */
-+ alx_mem_r32(hw, L1C_DMA_DBG, &val);
-+ alx_mem_w32(hw, L1C_DMA_DBG, val & ~L1C_DMA_DBG_VENDOR_MSG);
-+ }
-+
-+ /* hi-tx-perf */
-+ if (hw->hi_txperf) {
-+ alx_mem_r32(hw, L1C_PPHY_MISC1, &val);
-+ FIELD_SETL(val, L1C_PPHY_MISC1_NFTS,
-+ L1C_PPHY_MISC1_NFTS_HIPERF);
-+ alx_mem_w32(hw, L1C_PPHY_MISC1, val);
-+ }
-+ /* l0s, l1 setting */
-+ ret = l1c_enable_aspm(hw, l0s_en, l1_en, 0);
-+
-+ udelay(10);
-+
-+ return ret;
-+}
-+
-+
-+/* disable/enable MAC/RXQ/TXQ
-+ * en
-+ * true:enable
-+ * false:disable
-+ * return
-+ * 0:success
-+ * non-0-fail
-+ */
-+u16 l1c_enable_mac(struct alx_hw *hw, bool en, u16 en_ctrl)
-+{
-+ u32 rxq, txq, mac, val;
-+ u16 i;
-+
-+ alx_mem_r32(hw, L1C_RXQ0, &rxq);
-+ alx_mem_r32(hw, L1C_TXQ0, &txq);
-+ alx_mem_r32(hw, L1C_MAC_CTRL, &mac);
-+
-+ if (en) { /* enable */
-+ alx_mem_w32(hw, L1C_RXQ0, rxq | L1C_RXQ0_EN);
-+ alx_mem_w32(hw, L1C_TXQ0, txq | L1C_TXQ0_EN);
-+ if ((en_ctrl & LX_MACSPEED_1000) != 0) {
-+ FIELD_SETL(mac, L1C_MAC_CTRL_SPEED,
-+ L1C_MAC_CTRL_SPEED_1000);
-+ } else {
-+ FIELD_SETL(mac, L1C_MAC_CTRL_SPEED,
-+ L1C_MAC_CTRL_SPEED_10_100);
-+ }
-+
-+ test_set_or_clear(mac, en_ctrl, LX_MACDUPLEX_FULL,
-+ L1C_MAC_CTRL_FULLD);
-+
-+ /* rx filter */
-+ test_set_or_clear(mac, en_ctrl, LX_FLT_PROMISC,
-+ L1C_MAC_CTRL_PROMISC_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_FLT_MULTI_ALL,
-+ L1C_MAC_CTRL_MULTIALL_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_FLT_BROADCAST,
-+ L1C_MAC_CTRL_BRD_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_FLT_DIRECT,
-+ L1C_MAC_CTRL_RX_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_FC_TXEN,
-+ L1C_MAC_CTRL_TXFC_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_FC_RXEN,
-+ L1C_MAC_CTRL_RXFC_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_VLAN_STRIP,
-+ L1C_MAC_CTRL_VLANSTRIP);
-+ test_set_or_clear(mac, en_ctrl, LX_LOOPBACK,
-+ L1C_MAC_CTRL_LPBACK_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_SINGLE_PAUSE,
-+ L1C_MAC_CTRL_SPAUSE_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_ADD_FCS,
-+ (L1C_MAC_CTRL_PCRCE | L1C_MAC_CTRL_CRCE));
-+
-+ alx_mem_w32(hw, L1C_MAC_CTRL, mac | L1C_MAC_CTRL_TX_EN);
-+ } else { /* disable mac */
-+ alx_mem_w32(hw, L1C_RXQ0, rxq & ~L1C_RXQ0_EN);
-+ alx_mem_w32(hw, L1C_TXQ0, txq & ~L1C_TXQ0_EN);
-+
-+ /* waiting for rxq/txq be idle */
-+ for (i = 0; i < L1C_DMA_MAC_RST_TO; i++) {/* wait atmost 1ms */
-+ alx_mem_r32(hw, L1C_MAC_STS, &val);
-+ if ((val & (L1C_MAC_STS_TXQ_BUSY |
-+ L1C_MAC_STS_RXQ_BUSY)) == 0) {
-+ break;
-+ }
-+ udelay(20);
-+ }
-+ if (L1C_DMA_MAC_RST_TO == i)
-+ return LX_ERR_RSTMAC;
-+ /* stop mac tx/rx */
-+ alx_mem_w32(hw, L1C_MAC_CTRL,
-+ mac & ~(L1C_MAC_CTRL_RX_EN | L1C_MAC_CTRL_TX_EN));
-+
-+ for (i = 0; i < L1C_DMA_MAC_RST_TO; i++) {
-+ alx_mem_r32(hw, L1C_MAC_STS, &val);
-+ if ((val & L1C_MAC_STS_IDLE) == 0)
-+ break;
-+ udelay(10);
-+ }
-+ if (L1C_DMA_MAC_RST_TO == i)
-+ return LX_ERR_RSTMAC;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+/* enable/disable aspm support
-+ * that will change settings for phy/mac/pcie
-+ */
-+u16 l1c_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en, u8 lnk_stat)
-+{
-+ u32 pmctrl;
-+ bool linkon;
-+
-+ linkon = (lnk_stat == LX_LC_10H || lnk_stat == LX_LC_10F ||
-+ lnk_stat == LX_LC_100H || lnk_stat == LX_LC_100F ||
-+ lnk_stat == LX_LC_1000F) ? true : false;
-+
-+ alx_mem_r32(hw, L1C_PMCTRL, &pmctrl);
-+ pmctrl &= ~(L1C_PMCTRL_L0S_EN |
-+ L1C_PMCTRL_L1_EN |
-+ L1C_PMCTRL_ASPM_FCEN);
-+ FIELD_SETL(pmctrl, L1C_PMCTRL_LCKDET_TIMER,
-+ L1C_PMCTRL_LCKDET_TIMER_DEF);
-+
-+ /* l1 timer */
-+ if (hw->pci_devid == L2CB2_DEV_ID || hw->pci_devid == L1D2_DEV_ID) {
-+ pmctrl &= ~L1D_PMCTRL_TXL1_AFTER_L0S;
-+ FIELD_SETL(pmctrl, L1D_PMCTRL_L1_TIMER,
-+ (lnk_stat == LX_LC_100H ||
-+ lnk_stat == LX_LC_100F ||
-+ lnk_stat == LX_LC_1000F) ?
-+ L1D_PMCTRL_L1_TIMER_16US : 1);
-+ } else {
-+ FIELD_SETL(pmctrl, L1C_PMCTRL_L1_TIMER,
-+ (lnk_stat == LX_LC_100H ||
-+ lnk_stat == LX_LC_100F ||
-+ lnk_stat == LX_LC_1000F) ?
-+ ((hw->pci_devid == L2CB_DEV_ID) ?
-+ L1C_PMCTRL_L1_TIMER_L2CB1 : L1C_PMCTRL_L1_TIMER_DEF
-+ ) : 1);
-+ }
-+ if (l0s_en) { /* on/off l0s only if bios/system enable l0s */
-+ pmctrl |= (L1C_PMCTRL_L0S_EN | L1C_PMCTRL_ASPM_FCEN);
-+ }
-+ if (l1_en) { /* on/off l1 only if bios/system enable l1 */
-+ pmctrl |= (L1C_PMCTRL_L1_EN | L1C_PMCTRL_ASPM_FCEN);
-+ }
-+
-+ if (hw->pci_devid == L2CB_DEV_ID || hw->pci_devid == L1D_DEV_ID ||
-+ hw->pci_devid == L2CB2_DEV_ID || hw->pci_devid == L1D2_DEV_ID) {
-+ /* If the pm_request_l1 time exceeds the value of this timer,
-+ it will enter L0s instead of L1 for this ASPM request.*/
-+ FIELD_SETL(pmctrl, L1C_PMCTRL_L1REQ_TO,
-+ L1C_PMCTRL_L1REG_TO_DEF);
-+
-+ pmctrl |= L1C_PMCTRL_RCVR_WT_1US | /* wait 1us not 2ms */
-+ L1C_PMCTRL_L1_SRDSRX_PWD | /* pwd serdes */
-+ L1C_PMCTRL_L1_CLKSW_EN;
-+ pmctrl &= ~(L1C_PMCTRL_L1_SRDS_EN |
-+ L1C_PMCTRL_L1_SRDSPLL_EN|
-+ L1C_PMCTRL_L1_BUFSRX_EN |
-+ L1C_PMCTRL_SADLY_EN |
-+ L1C_PMCTRL_HOTRST_WTEN);
-+ /* disable l0s if linkdown or l2cbv1.x */
-+ if (!linkon ||
-+ (!hw->aps_en && hw->pci_devid == L2CB_DEV_ID)) {
-+ pmctrl &= ~L1C_PMCTRL_L0S_EN;
-+ }
-+ } else { /* l1c */
-+ FIELD_SETL(pmctrl, L1C_PMCTRL_L1_TIMER, 0);
-+ if (linkon) {
-+ pmctrl |= L1C_PMCTRL_L1_SRDS_EN |
-+ L1C_PMCTRL_L1_SRDSPLL_EN |
-+ L1C_PMCTRL_L1_BUFSRX_EN;
-+ pmctrl &= ~(L1C_PMCTRL_L1_SRDSRX_PWD|
-+ L1C_PMCTRL_L1_CLKSW_EN |
-+ L1C_PMCTRL_L0S_EN |
-+ L1C_PMCTRL_L1_EN);
-+ } else {
-+ pmctrl |= L1C_PMCTRL_L1_CLKSW_EN;
-+ pmctrl &= ~(L1C_PMCTRL_L1_SRDS_EN |
-+ L1C_PMCTRL_L1_SRDSPLL_EN|
-+ L1C_PMCTRL_L1_BUFSRX_EN |
-+ L1C_PMCTRL_L0S_EN);
-+ }
-+ }
-+
-+ alx_mem_w32(hw, L1C_PMCTRL, pmctrl);
-+
-+ return 0;
-+}
-+
-+
-+/* initialize phy for speed / flow control
-+ * lnk_cap
-+ * if autoNeg, is link capability to tell the peer
-+ * if force mode, is forced speed/duplex
-+ */
-+u16 l1c_init_phy_spdfc(struct alx_hw *hw, bool auto_neg,
-+ u8 lnk_cap, bool fc_en)
-+{
-+ u16 adv, giga, cr;
-+ u32 val;
-+ u16 ret;
-+
-+ /* clear flag */
-+ l1c_write_phy(hw, false, 0, false, L1C_MII_DBG_ADDR, 0);
-+ alx_mem_r32(hw, L1C_DRV, &val);
-+ FIELD_SETL(val, LX_DRV_PHY, 0);
-+
-+ if (auto_neg) {
-+ adv = L1C_ADVERTISE_DEFAULT_CAP & ~L1C_ADVERTISE_SPEED_MASK;
-+ giga = L1C_GIGA_CR_1000T_DEFAULT_CAP &
-+ ~L1C_GIGA_CR_1000T_SPEED_MASK;
-+ val |= LX_DRV_PHY_AUTO;
-+ if (!fc_en)
-+ adv &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
-+ else
-+ val |= LX_DRV_PHY_FC;
-+ if ((LX_LC_10H & lnk_cap) != 0) {
-+ adv |= ADVERTISE_10HALF;
-+ val |= LX_DRV_PHY_10;
-+ }
-+ if ((LX_LC_10F & lnk_cap) != 0) {
-+ adv |= ADVERTISE_10HALF |
-+ ADVERTISE_10FULL;
-+ val |= LX_DRV_PHY_10 | LX_DRV_PHY_DUPLEX;
-+ }
-+ if ((LX_LC_100H & lnk_cap) != 0) {
-+ adv |= ADVERTISE_100HALF;
-+ val |= LX_DRV_PHY_100;
-+ }
-+ if ((LX_LC_100F & lnk_cap) != 0) {
-+ adv |= ADVERTISE_100HALF |
-+ ADVERTISE_100FULL;
-+ val |= LX_DRV_PHY_100 | LX_DRV_PHY_DUPLEX;
-+ }
-+ if ((LX_LC_1000F & lnk_cap) != 0) {
-+ giga |= L1C_GIGA_CR_1000T_FD_CAPS;
-+ val |= LX_DRV_PHY_1000 | LX_DRV_PHY_DUPLEX;
-+ }
-+
-+ ret = l1c_write_phy(hw, false, 0, false, MII_ADVERTISE, adv);
-+ ret = l1c_write_phy(hw, false, 0, false, MII_CTRL1000, giga);
-+
-+ cr = BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART;
-+ ret = l1c_write_phy(hw, false, 0, false, MII_BMCR, cr);
-+ } else { /* force mode */
-+ cr = BMCR_RESET;
-+ switch (lnk_cap) {
-+ case LX_LC_10H:
-+ val |= LX_DRV_PHY_10;
-+ break;
-+ case LX_LC_10F:
-+ cr |= BMCR_FULLDPLX;
-+ val |= LX_DRV_PHY_10 | LX_DRV_PHY_DUPLEX;
-+ break;
-+ case LX_LC_100H:
-+ cr |= BMCR_SPEED100;
-+ val |= LX_DRV_PHY_100;
-+ break;
-+ case LX_LC_100F:
-+ cr |= BMCR_SPEED100 | BMCR_FULLDPLX;
-+ val |= LX_DRV_PHY_100 | LX_DRV_PHY_DUPLEX;
-+ break;
-+ default:
-+ return LX_ERR_PARM;
-+ }
-+ ret = l1c_write_phy(hw, false, 0, false, MII_BMCR, cr);
-+ }
-+
-+ if (!ret) {
-+ l1c_write_phy(hw, false, 0, false, L1C_MII_DBG_ADDR,
-+ LX_PHY_INITED);
-+ }
-+ alx_mem_w32(hw, L1C_DRV, val);
-+
-+ return ret;
-+}
-+
-+
-+/* do power saving setting befor enter suspend mode
-+ * NOTE:
-+ * 1. phy link must be established before calling this function
-+ * 2. wol option (pattern,magic,link,etc.) is configed before call it.
-+ */
-+u16 l1c_powersaving(struct alx_hw *hw, u8 wire_spd, bool wol_en,
-+ bool mac_txen, bool mac_rxen, bool pws_en)
-+{
-+ u32 master_ctrl, mac_ctrl, phy_ctrl;
-+ u16 pm_ctrl, ret = 0;
-+
-+ master_ctrl = 0;
-+ mac_ctrl = 0;
-+ phy_ctrl = 0;
-+
-+ pws_en = pws_en;
-+
-+ alx_mem_r32(hw, L1C_MASTER, &master_ctrl);
-+ master_ctrl &= ~L1C_MASTER_PCLKSEL_SRDS;
-+
-+ alx_mem_r32(hw, L1C_MAC_CTRL, &mac_ctrl);
-+ /* 10/100 half */
-+ FIELD_SETL(mac_ctrl, L1C_MAC_CTRL_SPEED, L1C_MAC_CTRL_SPEED_10_100);
-+ mac_ctrl &= ~(L1C_MAC_CTRL_FULLD |
-+ L1C_MAC_CTRL_RX_EN |
-+ L1C_MAC_CTRL_TX_EN);
-+
-+ alx_mem_r32(hw, L1C_PHY_CTRL, &phy_ctrl);
-+ phy_ctrl &= ~(L1C_PHY_CTRL_DSPRST_OUT | L1C_PHY_CTRL_CLS);
-+ /* if (pws_en) */
-+ phy_ctrl |= (L1C_PHY_CTRL_RST_ANALOG | L1C_PHY_CTRL_HIB_PULSE |
-+ L1C_PHY_CTRL_HIB_EN);
-+
-+ if (wol_en) { /* enable rx packet or tx packet */
-+ if (mac_rxen)
-+ mac_ctrl |= (L1C_MAC_CTRL_RX_EN | L1C_MAC_CTRL_BRD_EN);
-+ if (mac_txen)
-+ mac_ctrl |= L1C_MAC_CTRL_TX_EN;
-+ if (LX_LC_1000F == wire_spd) {
-+ FIELD_SETL(mac_ctrl, L1C_MAC_CTRL_SPEED,
-+ L1C_MAC_CTRL_SPEED_1000);
-+ }
-+ if (LX_LC_10F == wire_spd || LX_LC_100F == wire_spd ||
-+ LX_LC_100F == wire_spd) {
-+ mac_ctrl |= L1C_MAC_CTRL_FULLD;
-+ }
-+ phy_ctrl |= L1C_PHY_CTRL_DSPRST_OUT;
-+ ret = l1c_write_phy(hw, false, 0, false,
-+ L1C_MII_IER, L1C_IER_LINK_UP);
-+ } else {
-+ master_ctrl |= L1C_MASTER_PCLKSEL_SRDS;
-+ ret = l1c_write_phy(hw, false, 0, false, L1C_MII_IER, 0);
-+ phy_ctrl |= (L1C_PHY_CTRL_IDDQ | L1C_PHY_CTRL_POWER_DOWN);
-+ }
-+ alx_mem_w32(hw, L1C_MASTER, master_ctrl);
-+ alx_mem_w32(hw, L1C_MAC_CTRL, mac_ctrl);
-+ alx_mem_w32(hw, L1C_PHY_CTRL, phy_ctrl);
-+
-+ /* set PME_EN ?? */
-+ if (wol_en) {
-+ alx_cfg_r16(hw, L1C_PM_CSR, &pm_ctrl);
-+ pm_ctrl |= L1C_PM_CSR_PME_EN;
-+ alx_cfg_w16(hw, L1C_PM_CSR, pm_ctrl);
-+ }
-+
-+ return ret;
-+}
-+
-+
-+/* read phy register */
-+u16 l1c_read_phy(struct alx_hw *hw, bool ext, u8 dev, bool fast,
-+ u16 reg, u16 *data)
-+{
-+ u32 val;
-+ u16 clk_sel, i, ret = 0;
-+
-+ *data = 0;
-+ clk_sel = fast ?
-+ (u16)L1C_MDIO_CLK_SEL_25MD4 : (u16)L1C_MDIO_CLK_SEL_25MD128;
-+
-+ if (ext) {
-+ val = FIELDL(L1C_MDIO_EXTN_DEVAD, dev) |
-+ FIELDL(L1C_MDIO_EXTN_REG, reg);
-+ alx_mem_w32(hw, L1C_MDIO_EXTN, val);
-+
-+ val = L1C_MDIO_SPRES_PRMBL |
-+ FIELDL(L1C_MDIO_CLK_SEL, clk_sel) |
-+ L1C_MDIO_START |
-+ L1C_MDIO_MODE_EXT |
-+ L1C_MDIO_OP_READ;
-+ } else {
-+ val = L1C_MDIO_SPRES_PRMBL |
-+ FIELDL(L1C_MDIO_CLK_SEL, clk_sel) |
-+ FIELDL(L1C_MDIO_REG, reg) |
-+ L1C_MDIO_START |
-+ L1C_MDIO_OP_READ;
-+ }
-+
-+ alx_mem_w32(hw, L1C_MDIO, val);
-+
-+ for (i = 0; i < L1C_MDIO_MAX_AC_TO; i++) {
-+ alx_mem_r32(hw, L1C_MDIO, &val);
-+ if ((val & L1C_MDIO_BUSY) == 0) {
-+ *data = (u16)FIELD_GETX(val, L1C_MDIO_DATA);
-+ break;
-+ }
-+ udelay(10);
-+ }
-+ if (L1C_MDIO_MAX_AC_TO == i)
-+ ret = LX_ERR_MIIBUSY;
-+
-+ return ret;
-+}
-+
-+/* write phy register */
-+u16 l1c_write_phy(struct alx_hw *hw, bool ext, u8 dev, bool fast,
-+ u16 reg, u16 data)
-+{
-+ u32 val;
-+ u16 clk_sel, i, ret = 0;
-+
-+ clk_sel = fast ?
-+ (u16)L1C_MDIO_CLK_SEL_25MD4 : (u16)L1C_MDIO_CLK_SEL_25MD128;
-+
-+ if (ext) {
-+ val = FIELDL(L1C_MDIO_EXTN_DEVAD, dev) |
-+ FIELDL(L1C_MDIO_EXTN_REG, reg);
-+ alx_mem_w32(hw, L1C_MDIO_EXTN, val);
-+
-+ val = L1C_MDIO_SPRES_PRMBL |
-+ FIELDL(L1C_MDIO_CLK_SEL, clk_sel) |
-+ FIELDL(L1C_MDIO_DATA, data) |
-+ L1C_MDIO_START |
-+ L1C_MDIO_MODE_EXT;
-+ } else {
-+ val = L1C_MDIO_SPRES_PRMBL |
-+ FIELDL(L1C_MDIO_CLK_SEL, clk_sel) |
-+ FIELDL(L1C_MDIO_REG, reg) |
-+ FIELDL(L1C_MDIO_DATA, data) |
-+ L1C_MDIO_START;
-+ }
-+
-+ alx_mem_w32(hw, L1C_MDIO, val);
-+
-+ for (i = 0; i < L1C_MDIO_MAX_AC_TO; i++) {
-+ alx_mem_r32(hw, L1C_MDIO, &val);
-+ if ((val & L1C_MDIO_BUSY) == 0)
-+ break;
-+ udelay(10);
-+ }
-+
-+ if (L1C_MDIO_MAX_AC_TO == i)
-+ ret = LX_ERR_MIIBUSY;
-+
-+ return ret;
-+}
-+
-+u16 l1c_read_phydbg(struct alx_hw *hw, bool fast, u16 reg, u16 *data)
-+{
-+ u16 ret;
-+
-+ ret = l1c_write_phy(hw, false, 0, fast, L1C_MII_DBG_ADDR, reg);
-+ ret = l1c_read_phy(hw, false, 0, fast, L1C_MII_DBG_DATA, data);
-+
-+ return ret;
-+}
-+
-+u16 l1c_write_phydbg(struct alx_hw *hw, bool fast, u16 reg, u16 data)
-+{
-+ u16 ret;
-+
-+ ret = l1c_write_phy(hw, false, 0, fast, L1C_MII_DBG_ADDR, reg);
-+ ret = l1c_write_phy(hw, false, 0, fast, L1C_MII_DBG_DATA, data);
-+
-+ return ret;
-+}
-+
-+
-+/*
-+ * initialize mac basically
-+ * most of hi-feature no init
-+ * MAC/PHY should be reset before call this function
-+ * smb_timer : million-second
-+ * int_mod : micro-second
-+ * disable RSS as default
-+ */
-+u16 l1c_init_mac(struct alx_hw *hw, u8 *addr, u32 txmem_hi,
-+ u32 *tx_mem_lo, u8 tx_qnum, u16 txring_sz,
-+ u32 rxmem_hi, u32 rfdmem_lo, u32 rrdmem_lo,
-+ u16 rxring_sz, u16 rxbuf_sz, u16 smb_timer,
-+ u16 mtu, u16 int_mod, bool hash_legacy)
-+{
-+ u32 val;
-+ u16 val16;
-+ u8 dmar_len;
-+
-+ /* set mac-address */
-+ val = *(u32 *)(addr + 2);
-+ alx_mem_w32(hw, L1C_STAD0, LX_SWAP_DW(val));
-+ val = *(u16 *)addr ;
-+ alx_mem_w32(hw, L1C_STAD1, LX_SWAP_W((u16)val));
-+
-+ /* clear multicast hash table, algrithm */
-+ alx_mem_w32(hw, L1C_HASH_TBL0, 0);
-+ alx_mem_w32(hw, L1C_HASH_TBL1, 0);
-+ alx_mem_r32(hw, L1C_MAC_CTRL, &val);
-+ if (hash_legacy)
-+ val |= L1C_MAC_CTRL_MHASH_ALG_HI5B;
-+ else
-+ val &= ~L1C_MAC_CTRL_MHASH_ALG_HI5B;
-+ alx_mem_w32(hw, L1C_MAC_CTRL, val);
-+
-+ /* clear any wol setting/status */
-+ alx_mem_r32(hw, L1C_WOL0, &val);
-+ alx_mem_w32(hw, L1C_WOL0, 0);
-+
-+ /* clk gating */
-+ alx_mem_w32(hw, L1C_CLK_GATE, (hw->pci_devid == L1D_DEV_ID) ? 0 :
-+ (L1C_CLK_GATE_DMAR | L1C_CLK_GATE_DMAW |
-+ L1C_CLK_GATE_TXQ | L1C_CLK_GATE_RXQ |
-+ L1C_CLK_GATE_TXMAC));
-+
-+ /* descriptor ring base memory */
-+ alx_mem_w32(hw, L1C_TX_BASE_ADDR_HI, txmem_hi);
-+ alx_mem_w32(hw, L1C_TPD_RING_SZ, txring_sz);
-+ switch (tx_qnum) {
-+ case 2:
-+ alx_mem_w32(hw, L1C_TPD_PRI1_ADDR_LO, tx_mem_lo[1]);
-+ /* fall through */
-+ case 1:
-+ alx_mem_w32(hw, L1C_TPD_PRI0_ADDR_LO, tx_mem_lo[0]);
-+ break;
-+ default:
-+ return LX_ERR_PARM;
-+ }
-+ alx_mem_w32(hw, L1C_RX_BASE_ADDR_HI, rxmem_hi);
-+ alx_mem_w32(hw, L1C_RFD_ADDR_LO, rfdmem_lo);
-+ alx_mem_w32(hw, L1C_RRD_ADDR_LO, rrdmem_lo);
-+ alx_mem_w32(hw, L1C_RFD_BUF_SZ, rxbuf_sz);
-+ alx_mem_w32(hw, L1C_RRD_RING_SZ, rxring_sz);
-+ alx_mem_w32(hw, L1C_RFD_RING_SZ, rxring_sz);
-+ alx_mem_w32(hw, L1C_SMB_TIMER, smb_timer * 500UL);
-+
-+ if (hw->pci_devid == L2CB_DEV_ID) {
-+ /* revise SRAM configuration */
-+ alx_mem_w32(hw, L1C_SRAM5, L1C_SRAM_RXF_LEN_L2CB1);
-+ alx_mem_w32(hw, L1C_SRAM7, L1C_SRAM_TXF_LEN_L2CB1);
-+ alx_mem_w32(hw, L1C_SRAM4, L1C_SRAM_RXF_HT_L2CB1);
-+ alx_mem_w32(hw, L1C_SRAM0, L1C_SRAM_RFD_HT_L2CB1);
-+ alx_mem_w32(hw, L1C_SRAM6, L1C_SRAM_TXF_HT_L2CB1);
-+ alx_mem_w32(hw, L1C_SRAM2, L1C_SRAM_TRD_HT_L2CB1);
-+ alx_mem_w32(hw, L1C_TXQ2, 0); /* TX watermark, goto L1 state.*/
-+ alx_mem_w32(hw, L1C_RXQ3, 0); /* RXD threshold. */
-+ }
-+ alx_mem_w32(hw, L1C_SRAM9, L1C_SRAM_LOAD_PTR);
-+
-+ /* int moduration */
-+ alx_mem_r32(hw, L1C_MASTER, &val);
-+ val |= L1C_MASTER_IRQMOD2_EN | L1C_MASTER_IRQMOD1_EN |
-+ L1C_MASTER_SYSALVTIMER_EN; /* sysalive */
-+ alx_mem_w32(hw, L1C_MASTER, val);
-+ /* set Interrupt Moderator Timer (max interrupt per sec)
-+ * we use seperate time for rx/tx */
-+ alx_mem_w32(hw, L1C_IRQ_MODU_TIMER,
-+ FIELDL(L1C_IRQ_MODU_TIMER1, int_mod) |
-+ FIELDL(L1C_IRQ_MODU_TIMER2, int_mod >> 1));
-+
-+ /* tpd threshold to trig int */
-+ alx_mem_w32(hw, L1C_TINT_TPD_THRSHLD, (u32)txring_sz / 3);
-+ alx_mem_w32(hw, L1C_TINT_TIMER, int_mod * 2);
-+ /* re-send int */
-+ alx_mem_w32(hw, L1C_INT_RETRIG, L1C_INT_RETRIG_TO);
-+
-+ /* mtu */
-+ alx_mem_w32(hw, L1C_MTU, (u32)(mtu + 4 + 4)); /* crc + vlan */
-+
-+ /* txq */
-+ if ((mtu + 8) < L1C_TXQ1_JUMBO_TSO_TH)
-+ val = (u32)(mtu + 8 + 7); /* 7 for QWORD align */
-+ else
-+ val = L1C_TXQ1_JUMBO_TSO_TH;
-+ alx_mem_w32(hw, L1C_TXQ1, val >> 3);
-+
-+ alx_mem_r32(hw, L1C_DEV_CTRL, &val);
-+ dmar_len = (u8)FIELD_GETX(val, L1C_DEV_CTRL_MAXRRS);
-+ /* if BIOS had changed the default dma read max length,
-+ * restore it to default value */
-+ if (dmar_len < L1C_DEV_CTRL_MAXRRS_MIN) {
-+ FIELD_SETL(val, L1C_DEV_CTRL_MAXRRS, L1C_DEV_CTRL_MAXRRS_MIN);
-+ alx_mem_w32(hw, L1C_DEV_CTRL, val);
-+ dmar_len = L1C_DEV_CTRL_MAXRRS_MIN;
-+ }
-+ val = FIELDL(L1C_TXQ0_TPD_BURSTPREF, L1C_TXQ0_TPD_BURSTPREF_DEF) |
-+ L1C_TXQ0_MODE_ENHANCE |
-+ L1C_TXQ0_LSO_8023_EN |
-+ L1C_TXQ0_SUPT_IPOPT |
-+ FIELDL(L1C_TXQ0_TXF_BURST_PREF,
-+ (hw->pci_devid == L2CB_DEV_ID ||
-+ hw->pci_devid == L2CB2_DEV_ID) ?
-+ L1C_TXQ0_TXF_BURST_PREF_L2CB :
-+ L1C_TXQ0_TXF_BURST_PREF_DEF);
-+ alx_mem_w32(hw, L1C_TXQ0, val);
-+
-+ /* fc */
-+ alx_mem_r32(hw, L1C_SRAM5, &val);
-+ val = FIELD_GETX(val, L1C_SRAM_RXF_LEN) << 3; /* bytes */
-+ if (val > L1C_SRAM_RXF_LEN_8K) {
-+ val16 = L1C_MTU_STD_ALGN;
-+ val = (val - (2 * L1C_MTU_STD_ALGN + L1C_MTU_MIN));
-+ } else {
-+ val16 = L1C_MTU_STD_ALGN;
-+ val = (val - L1C_MTU_STD_ALGN);
-+ }
-+ alx_mem_w32(hw, L1C_RXQ2,
-+ FIELDL(L1C_RXQ2_RXF_XOFF_THRESH, val16 >> 3) |
-+ FIELDL(L1C_RXQ2_RXF_XON_THRESH, val >> 3));
-+ /* rxq */
-+ val = FIELDL(L1C_RXQ0_NUM_RFD_PREF, L1C_RXQ0_NUM_RFD_PREF_DEF) |
-+ L1C_RXQ0_IPV6_PARSE_EN;
-+ if (mtu > L1C_MTU_JUMBO_TH)
-+ val |= L1C_RXQ0_CUT_THRU_EN;
-+ if ((hw->pci_devid & 1) != 0) {
-+ FIELD_SETL(val, L1C_RXQ0_ASPM_THRESH,
-+ (hw->pci_devid == L1D2_DEV_ID) ?
-+ L1C_RXQ0_ASPM_THRESH_NO :
-+ L1C_RXQ0_ASPM_THRESH_100M);
-+ }
-+ alx_mem_w32(hw, L1C_RXQ0, val);
-+
-+ /* rfd producer index */
-+ alx_mem_w32(hw, L1C_RFD_PIDX, (u32)rxring_sz - 1);
-+
-+ /* DMA */
-+ val = FIELDL(L1C_DMA_RORDER_MODE, L1C_DMA_RORDER_MODE_OUT) |
-+ L1C_DMA_RREQ_PRI_DATA |
-+ FIELDL(L1C_DMA_RREQ_BLEN, dmar_len) |
-+ FIELDL(L1C_DMA_WDLY_CNT, L1C_DMA_WDLY_CNT_DEF) |
-+ FIELDL(L1C_DMA_RDLY_CNT, L1C_DMA_RDLY_CNT_DEF) ;
-+ alx_mem_w32(hw, L1C_DMA, val);
-+
-+ return 0;
-+}
-+
-+
-+u16 l1c_get_phy_config(struct alx_hw *hw)
-+{
-+ u32 val;
-+ u16 phy_val;
-+
-+ alx_mem_r32(hw, L1C_PHY_CTRL, &val);
-+ if ((val & L1C_PHY_CTRL_DSPRST_OUT) == 0) { /* phy in rst */
-+ return LX_DRV_PHY_UNKNOWN;
-+ }
-+
-+ alx_mem_r32(hw, L1C_DRV, &val);
-+ val = FIELD_GETX(val, LX_DRV_PHY);
-+ if (LX_DRV_PHY_UNKNOWN == val)
-+ return LX_DRV_PHY_UNKNOWN;
-+
-+ l1c_read_phy(hw, false, 0, false, L1C_MII_DBG_ADDR, &phy_val);
-+
-+ if (LX_PHY_INITED == phy_val)
-+ return (u16) val;
-+
-+ return LX_DRV_PHY_UNKNOWN;
-+}
-+
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alc_hw.h
-@@ -0,0 +1,1324 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef L1C_HW_H_
-+#define L1C_HW_H_
-+
-+/*********************************************************************
-+ * some reqs for l1x_sw.h
-+ *
-+ * 1. some basic type must be defined if there are not defined by
-+ * your compiler:
-+ * u8, u16, u32, bool
-+ *
-+ * 2. PETHCONTEXT difinition should be in l1x_sw.h and it must contain
-+ * pci_devid & pci_venid & pci_revid
-+ *
-+ *********************************************************************/
-+
-+#include "alx_hwcom.h"
-+
-+/******************************************************************************/
-+
-+#define L1C_DEV_ID 0x1063
-+#define L2C_DEV_ID 0x1062
-+#define L2CB_DEV_ID 0x2060
-+#define L2CB2_DEV_ID 0x2062
-+#define L1D_DEV_ID 0x1073
-+#define L1D2_DEV_ID 0x1083
-+
-+#define L2CB_V10 0xC0
-+#define L2CB_V11 0xC1
-+#define L2CB_V20 0xC0
-+#define L2CB_V21 0xC1
-+
-+#define L1C_PM_CSR 0x0044 /* 16bit */
-+#define L1C_PM_CSR_PME_STAT BIT(15)
-+#define L1C_PM_CSR_DSCAL_MASK ASHFT13(3U)
-+#define L1C_PM_CSR_DSCAL_SHIFT 13
-+#define L1C_PM_CSR_DSEL_MASK ASHFT9(0xFU)
-+#define L1C_PM_CSR_DSEL_SHIFT 9
-+#define L1C_PM_CSR_PME_EN BIT(8)
-+#define L1C_PM_CSR_PWST_MASK ASHFT0(3U)
-+#define L1C_PM_CSR_PWST_SHIFT 0
-+
-+#define L1C_PM_DATA 0x0047 /* 8bit */
-+
-+#define L1C_DEV_CAP 0x005C
-+#define L1C_DEV_CAP_SPLSL_MASK ASHFT26(3UL)
-+#define L1C_DEV_CAP_SPLSL_SHIFT 26
-+#define L1C_DEV_CAP_SPLV_MASK ASHFT18(0xFFUL)
-+#define L1C_DEV_CAP_SPLV_SHIFT 18
-+#define L1C_DEV_CAP_RBER BIT(15)
-+#define L1C_DEV_CAP_PIPRS BIT(14)
-+#define L1C_DEV_CAP_AIPRS BIT(13)
-+#define L1C_DEV_CAP_ABPRS BIT(12)
-+#define L1C_DEV_CAP_L1ACLAT_MASK ASHFT9(7UL)
-+#define L1C_DEV_CAP_L1ACLAT_SHIFT 9
-+#define L1C_DEV_CAP_L0SACLAT_MASK ASHFT6(7UL)
-+#define L1C_DEV_CAP_L0SACLAT_SHIFT 6
-+#define L1C_DEV_CAP_EXTAG BIT(5)
-+#define L1C_DEV_CAP_PHANTOM BIT(4)
-+#define L1C_DEV_CAP_MPL_MASK ASHFT0(7UL)
-+#define L1C_DEV_CAP_MPL_SHIFT 0
-+#define L1C_DEV_CAP_MPL_128 1
-+#define L1C_DEV_CAP_MPL_256 2
-+#define L1C_DEV_CAP_MPL_512 3
-+#define L1C_DEV_CAP_MPL_1024 4
-+#define L1C_DEV_CAP_MPL_2048 5
-+#define L1C_DEV_CAP_MPL_4096 6
-+
-+#define L1C_DEV_CTRL 0x0060 /* 16bit */
-+#define L1C_DEV_CTRL_MAXRRS_MASK ASHFT12(7U)
-+#define L1C_DEV_CTRL_MAXRRS_SHIFT 12
-+#define L1C_DEV_CTRL_MAXRRS_MIN 2
-+#define L1C_DEV_CTRL_NOSNP_EN BIT(11)
-+#define L1C_DEV_CTRL_AUXPWR_EN BIT(10)
-+#define L1C_DEV_CTRL_PHANTOM_EN BIT(9)
-+#define L1C_DEV_CTRL_EXTAG_EN BIT(8)
-+#define L1C_DEV_CTRL_MPL_MASK ASHFT5(7U)
-+#define L1C_DEV_CTRL_MPL_SHIFT 5
-+#define L1C_DEV_CTRL_RELORD_EN BIT(4)
-+#define L1C_DEV_CTRL_URR_EN BIT(3)
-+#define L1C_DEV_CTRL_FERR_EN BIT(2)
-+#define L1C_DEV_CTRL_NFERR_EN BIT(1)
-+#define L1C_DEV_CTRL_CERR_EN BIT(0)
-+
-+#define L1C_DEV_STAT 0x0062 /* 16bit */
-+#define L1C_DEV_STAT_XS_PEND BIT(5)
-+#define L1C_DEV_STAT_AUXPWR BIT(4)
-+#define L1C_DEV_STAT_UR BIT(3)
-+#define L1C_DEV_STAT_FERR BIT(2)
-+#define L1C_DEV_STAT_NFERR BIT(1)
-+#define L1C_DEV_STAT_CERR BIT(0)
-+
-+#define L1C_LNK_CAP 0x0064
-+#define L1C_LNK_CAP_PRTNUM_MASK ASHFT24(0xFFUL)
-+#define L1C_LNK_CAP_PRTNUM_SHIFT 24
-+#define L1C_LNK_CAP_CLK_PM BIT(18)
-+#define L1C_LNK_CAP_L1EXTLAT_MASK ASHFT15(7UL)
-+#define L1C_LNK_CAP_L1EXTLAT_SHIFT 15
-+#define L1C_LNK_CAP_L0SEXTLAT_MASK ASHFT12(7UL)
-+#define L1C_LNK_CAP_L0SEXTLAT_SHIFT 12
-+#define L1C_LNK_CAP_ASPM_SUP_MASK ASHFT10(3UL)
-+#define L1C_LNK_CAP_ASPM_SUP_SHIFT 10
-+#define L1C_LNK_CAP_ASPM_SUP_L0S 1
-+#define L1C_LNK_CAP_ASPM_SUP_L0SL1 3
-+#define L1C_LNK_CAP_MAX_LWH_MASK ASHFT4(0x3FUL)
-+#define L1C_LNK_CAP_MAX_LWH_SHIFT 4
-+#define L1C_LNK_CAP_MAX_LSPD_MASH ASHFT0(0xFUL)
-+#define L1C_LNK_CAP_MAX_LSPD_SHIFT 0
-+
-+#define L1C_LNK_CTRL 0x0068 /* 16bit */
-+#define L1C_LNK_CTRL_CLK_PM_EN BIT(8)
-+#define L1C_LNK_CTRL_EXTSYNC BIT(7)
-+#define L1C_LNK_CTRL_CMNCLK_CFG BIT(6)
-+#define L1C_LNK_CTRL_RCB_128B BIT(3) /* 0:64b,1:128b */
-+#define L1C_LNK_CTRL_ASPM_MASK ASHFT0(3U)
-+#define L1C_LNK_CTRL_ASPM_SHIFT 0
-+#define L1C_LNK_CTRL_ASPM_DIS 0
-+#define L1C_LNK_CTRL_ASPM_ENL0S 1
-+#define L1C_LNK_CTRL_ASPM_ENL1 2
-+#define L1C_LNK_CTRL_ASPM_ENL0SL1 3
-+
-+#define L1C_LNK_STAT 0x006A /* 16bit */
-+#define L1C_LNK_STAT_SCLKCFG BIT(12)
-+#define L1C_LNK_STAT_LNKTRAIN BIT(11)
-+#define L1C_LNK_STAT_TRNERR BIT(10)
-+#define L1C_LNK_STAT_LNKSPD_MASK ASHFT0(0xFU)
-+#define L1C_LNK_STAT_LNKSPD_SHIFT 0
-+#define L1C_LNK_STAT_NEGLW_MASK ASHFT4(0x3FU)
-+#define L1C_LNK_STAT_NEGLW_SHIFT 4
-+
-+#define L1C_UE_SVRT 0x010C
-+#define L1C_UE_SVRT_UR BIT(20)
-+#define L1C_UE_SVRT_ECRCERR BIT(19)
-+#define L1C_UE_SVRT_MTLP BIT(18)
-+#define L1C_UE_SVRT_RCVOVFL BIT(17)
-+#define L1C_UE_SVRT_UNEXPCPL BIT(16)
-+#define L1C_UE_SVRT_CPLABRT BIT(15)
-+#define L1C_UE_SVRT_CPLTO BIT(14)
-+#define L1C_UE_SVRT_FCPROTERR BIT(13)
-+#define L1C_UE_SVRT_PTLP BIT(12)
-+#define L1C_UE_SVRT_DLPROTERR BIT(4)
-+#define L1C_UE_SVRT_TRNERR BIT(0)
-+
-+#define L1C_SLD 0x0218 /* efuse load */
-+#define L1C_SLD_FREQ_MASK ASHFT24(3UL)
-+#define L1C_SLD_FREQ_SHIFT 24
-+#define L1C_SLD_FREQ_100K 0
-+#define L1C_SLD_FREQ_200K 1
-+#define L1C_SLD_FREQ_300K 2
-+#define L1C_SLD_FREQ_400K 3
-+#define L1C_SLD_EXIST BIT(23)
-+#define L1C_SLD_SLVADDR_MASK ASHFT16(0x7FUL)
-+#define L1C_SLD_SLVADDR_SHIFT 16
-+#define L1C_SLD_IDLE BIT(13)
-+#define L1C_SLD_STAT BIT(12) /* 0:finish,1:in progress */
-+#define L1C_SLD_START BIT(11)
-+#define L1C_SLD_STARTADDR_MASK ASHFT0(0xFFUL)
-+#define L1C_SLD_STARTADDR_SHIFT 0
-+#define L1C_SLD_MAX_TO 100
-+
-+#define L1C_PPHY_MISC1 0x1000
-+#define L1C_PPHY_MISC1_RCVDET BIT(2)
-+#define L1C_PPHY_MISC1_NFTS_MASK ASHFT16(0xFFUL)
-+#define L1C_PPHY_MISC1_NFTS_SHIFT 16
-+#define L1C_PPHY_MISC1_NFTS_HIPERF 0xA0 /* ???? */
-+
-+#define L1C_PPHY_MISC2 0x1004
-+#define L1C_PPHY_MISC2_L0S_TH_MASK ASHFT18(0x3UL)
-+#define L1C_PPHY_MISC2_L0S_TH_SHIFT 18
-+#define L1C_PPHY_MISC2_L0S_TH_L2CB1 3
-+#define L1C_PPHY_MISC2_CDR_BW_MASK ASHFT16(0x3UL)
-+#define L1C_PPHY_MISC2_CDR_BW_SHIFT 16
-+#define L1C_PPHY_MISC2_CDR_BW_L2CB1 3
-+
-+#define L1C_PDLL_TRNS1 0x1104
-+#define L1C_PDLL_TRNS1_D3PLLOFF_EN BIT(11)
-+#define L1C_PDLL_TRNS1_REGCLK_SEL_NORM BIT(10)
-+#define L1C_PDLL_TRNS1_REPLY_TO_MASK ASHFT0(0x3FFUL)
-+#define L1C_PDLL_TRNS1_REPLY_TO_SHIFT 0
-+
-+#define L1C_TWSI_DBG 0x1108
-+#define L1C_TWSI_DBG_DEV_EXIST BIT(29)
-+
-+#define L1C_DMA_DBG 0x1114
-+#define L1C_DMA_DBG_VENDOR_MSG BIT(0)
-+
-+#define L1C_TLEXTN_STATS 0x1204 /* diff with l1f */
-+#define L1C_TLEXTN_STATS_DEVNO_MASK ASHFT16(0x1FUL)
-+#define L1C_TLEXTN_STATS_DEVNO_SHIFT 16
-+#define L1C_TLEXTN_STATS_BUSNO_MASK ASHFT8(0xFFUL)
-+#define L1C_TLEXTN_STATS_BUSNO_SHIFT 8
-+
-+#define L1C_EFUSE_CTRL 0x12C0
-+#define L1C_EFUSE_CTRL_FLAG BIT(31) /* 0:read,1:write */
-+#define L1C_EUFSE_CTRL_ACK BIT(30)
-+#define L1C_EFUSE_CTRL_ADDR_MASK ASHFT16(0x3FFUL)
-+#define L1C_EFUSE_CTRL_ADDR_SHIFT 16
-+
-+#define L1C_EFUSE_DATA 0x12C4
-+
-+#define EFUSE_OP_MAX_AC_TIMER 100 /* 1ms */
-+
-+#define L1C_EFUSE_CTRL2 0x12F0
-+#define L1C_EFUSE_CTRL2_CLK_EN BIT(1)
-+
-+#define L1C_PMCTRL 0x12F8
-+#define L1C_PMCTRL_HOTRST_WTEN BIT(31)
-+#define L1C_PMCTRL_ASPM_FCEN BIT(30) /* L0s/L1 dis by MAC based on
-+ * thrghput(setting in 15A0) */
-+#define L1C_PMCTRL_SADLY_EN BIT(29)
-+#define L1C_PMCTRL_L0S_BUFSRX_EN BIT(28)
-+#define L1C_PMCTRL_LCKDET_TIMER_MASK ASHFT24(0xFUL)
-+#define L1C_PMCTRL_LCKDET_TIMER_SHIFT 24
-+#define L1C_PMCTRL_LCKDET_TIMER_DEF 0xC
-+#define L1C_PMCTRL_L1REQ_TO_MASK ASHFT20(0xFUL)
-+#define L1C_PMCTRL_L1REQ_TO_SHIFT 20 /* pm_request_l1 time > @
-+ * ->L0s not L1 */
-+#define L1C_PMCTRL_L1REG_TO_DEF 0xC
-+#define L1D_PMCTRL_TXL1_AFTER_L0S BIT(19) /* l1dv2.0+ */
-+#define L1D_PMCTRL_L1_TIMER_MASK ASHFT16(7UL)
-+#define L1D_PMCTRL_L1_TIMER_SHIFT 16
-+#define L1D_PMCTRL_L1_TIMER_DIS 0
-+#define L1D_PMCTRL_L1_TIMER_2US 1
-+#define L1D_PMCTRL_L1_TIMER_4US 2
-+#define L1D_PMCTRL_L1_TIMER_8US 3
-+#define L1D_PMCTRL_L1_TIMER_16US 4
-+#define L1D_PMCTRL_L1_TIMER_24US 5
-+#define L1D_PMCTRL_L1_TIMER_32US 6
-+#define L1D_PMCTRL_L1_TIMER_63US 7
-+#define L1C_PMCTRL_L1_TIMER_MASK ASHFT16(0xFUL)
-+#define L1C_PMCTRL_L1_TIMER_SHIFT 16
-+#define L1C_PMCTRL_L1_TIMER_L2CB1 7
-+#define L1C_PMCTRL_L1_TIMER_DEF 0xF
-+#define L1C_PMCTRL_RCVR_WT_1US BIT(15) /* 1:1us, 0:2ms */
-+#define L1C_PMCTRL_PWM_VER_11 BIT(14) /* 0:1.0a,1:1.1 */
-+#define L1C_PMCTRL_L1_CLKSW_EN BIT(13) /* en pcie clk sw in L1 */
-+#define L1C_PMCTRL_L0S_EN BIT(12)
-+#define L1D_PMCTRL_RXL1_AFTER_L0S BIT(11) /* l1dv2.0+ */
-+#define L1D_PMCTRL_L0S_TIMER_MASK ASHFT8(7UL)
-+#define L1D_PMCTRL_L0S_TIMER_SHIFT 8
-+#define L1C_PMCTRL_L0S_TIMER_MASK ASHFT8(0xFUL)
-+#define L1C_PMCTRL_L0S_TIMER_SHIFT 8
-+#define L1C_PMCTRL_L1_BUFSRX_EN BIT(7)
-+#define L1C_PMCTRL_L1_SRDSRX_PWD BIT(6) /* power down serdes rx */
-+#define L1C_PMCTRL_L1_SRDSPLL_EN BIT(5)
-+#define L1C_PMCTRL_L1_SRDS_EN BIT(4)
-+#define L1C_PMCTRL_L1_EN BIT(3)
-+#define L1C_PMCTRL_CLKREQ_EN BIT(2)
-+#define L1C_PMCTRL_RBER_EN BIT(1)
-+#define L1C_PMCTRL_SPRSDWER_EN BIT(0)
-+
-+#define L1C_LTSSM_CTRL 0x12FC
-+#define L1C_LTSSM_WRO_EN BIT(12)
-+#define L1C_LTSSM_TXTLP_BYPASS BIT(7)
-+
-+#define L1C_MASTER 0x1400
-+#define L1C_MASTER_OTP_FLG BIT(31)
-+#define L1C_MASTER_DEV_NUM_MASK ASHFT24(0x7FUL)
-+#define L1C_MASTER_DEV_NUM_SHIFT 24
-+#define L1C_MASTER_REV_NUM_MASK ASHFT16(0xFFUL)
-+#define L1C_MASTER_REV_NUM_SHIFT 16
-+#define L1C_MASTER_RDCLR_INT BIT(14)
-+#define L1C_MASTER_CLKSW_L2EV1 BIT(13) /* 0:l2ev2.0,1:l2ev1.0 */
-+#define L1C_MASTER_PCLKSEL_SRDS BIT(12) /* 1:alwys sel pclk from
-+ * serdes, not sw to 25M */
-+#define L1C_MASTER_IRQMOD2_EN BIT(11) /* IRQ MODURATION FOR RX */
-+#define L1C_MASTER_IRQMOD1_EN BIT(10) /* MODURATION FOR TX/RX */
-+#define L1C_MASTER_MANU_INT BIT(9) /* SOFT MANUAL INT */
-+#define L1C_MASTER_MANUTIMER_EN BIT(8)
-+#define L1C_MASTER_SYSALVTIMER_EN BIT(7) /* SYS ALIVE TIMER EN */
-+#define L1C_MASTER_OOB_DIS BIT(6) /* OUT OF BOX DIS */
-+#define L1C_MASTER_WAKEN_25M BIT(5) /* WAKE WO. PCIE CLK */
-+#define L1C_MASTER_BERT_START BIT(4)
-+#define L1C_MASTER_PCIE_TSTMOD_MASK ASHFT2(3UL)
-+#define L1C_MASTER_PCIE_TSTMOD_SHIFT 2
-+#define L1C_MASTER_PCIE_RST BIT(1)
-+#define L1C_MASTER_DMA_MAC_RST BIT(0) /* RST MAC & DMA */
-+#define L1C_DMA_MAC_RST_TO 50
-+
-+#define L1C_MANU_TIMER 0x1404
-+
-+#define L1C_IRQ_MODU_TIMER 0x1408
-+#define L1C_IRQ_MODU_TIMER2_MASK ASHFT16(0xFFFFUL)
-+#define L1C_IRQ_MODU_TIMER2_SHIFT 16 /* ONLY FOR RX */
-+#define L1C_IRQ_MODU_TIMER1_MASK ASHFT0(0xFFFFUL)
-+#define L1C_IRQ_MODU_TIMER1_SHIFT 0
-+
-+#define L1C_PHY_CTRL 0x140C
-+#define L1C_PHY_CTRL_ADDR_MASK ASHFT19(0x1FUL)
-+#define L1C_PHY_CTRL_ADDR_SHIFT 19
-+#define L1C_PHY_CTRL_BP_VLTGSW BIT(18)
-+#define L1C_PHY_CTRL_100AB_EN BIT(17)
-+#define L1C_PHY_CTRL_10AB_EN BIT(16)
-+#define L1C_PHY_CTRL_PLL_BYPASS BIT(15)
-+#define L1C_PHY_CTRL_POWER_DOWN BIT(14) /* affect MAC & PHY,
-+ * go to low power sts */
-+#define L1C_PHY_CTRL_PLL_ON BIT(13) /* 1:PLL ALWAYS ON
-+ * 0:CAN SWITCH IN LPW */
-+#define L1C_PHY_CTRL_RST_ANALOG BIT(12)
-+#define L1C_PHY_CTRL_HIB_PULSE BIT(11)
-+#define L1C_PHY_CTRL_HIB_EN BIT(10)
-+#define L1C_PHY_CTRL_GIGA_DIS BIT(9)
-+#define L1C_PHY_CTRL_IDDQ_DIS BIT(8) /* POWER ON RST */
-+#define L1C_PHY_CTRL_IDDQ BIT(7) /* WHILE REBOOT, BIT8(1)
-+ * EFFECTS BIT7 */
-+#define L1C_PHY_CTRL_LPW_EXIT BIT(6)
-+#define L1C_PHY_CTRL_GATE_25M BIT(5)
-+#define L1C_PHY_CTRL_RVRS_ANEG BIT(4)
-+#define L1C_PHY_CTRL_ANEG_NOW BIT(3)
-+#define L1C_PHY_CTRL_LED_MODE BIT(2)
-+#define L1C_PHY_CTRL_RTL_MODE BIT(1)
-+#define L1C_PHY_CTRL_DSPRST_OUT BIT(0) /* OUT OF DSP RST STATE */
-+#define L1C_PHY_CTRL_DSPRST_TO 80
-+#define L1C_PHY_CTRL_CLS (\
-+ L1C_PHY_CTRL_LED_MODE |\
-+ L1C_PHY_CTRL_100AB_EN |\
-+ L1C_PHY_CTRL_PLL_ON)
-+
-+
-+#define L1C_MAC_STS 0x1410
-+#define L1C_MAC_STS_SFORCE_MASK ASHFT14(0xFUL)
-+#define L1C_MAC_STS_SFORCE_SHIFT 14
-+#define L1C_MAC_STS_CALIB_DONE BIT13
-+#define L1C_MAC_STS_CALIB_RES_MASK ASHFT8(0x1FUL)
-+#define L1C_MAC_STS_CALIB_RES_SHIFT 8
-+#define L1C_MAC_STS_CALIBERR_MASK ASHFT4(0xFUL)
-+#define L1C_MAC_STS_CALIBERR_SHIFT 4
-+#define L1C_MAC_STS_TXQ_BUSY BIT(3)
-+#define L1C_MAC_STS_RXQ_BUSY BIT(2)
-+#define L1C_MAC_STS_TXMAC_BUSY BIT(1)
-+#define L1C_MAC_STS_RXMAC_BUSY BIT(0)
-+#define L1C_MAC_STS_IDLE (\
-+ L1C_MAC_STS_TXQ_BUSY |\
-+ L1C_MAC_STS_RXQ_BUSY |\
-+ L1C_MAC_STS_TXMAC_BUSY |\
-+ L1C_MAC_STS_RXMAC_BUSY)
-+
-+#define L1C_MDIO 0x1414
-+#define L1C_MDIO_MODE_EXT BIT(30) /* 0:normal,1:ext */
-+#define L1C_MDIO_POST_READ BIT(29)
-+#define L1C_MDIO_AUTO_POLLING BIT(28)
-+#define L1C_MDIO_BUSY BIT(27)
-+#define L1C_MDIO_CLK_SEL_MASK ASHFT24(7UL)
-+#define L1C_MDIO_CLK_SEL_SHIFT 24
-+#define L1C_MDIO_CLK_SEL_25MD4 0 /* 25M DIV 4 */
-+#define L1C_MDIO_CLK_SEL_25MD6 2
-+#define L1C_MDIO_CLK_SEL_25MD8 3
-+#define L1C_MDIO_CLK_SEL_25MD10 4
-+#define L1C_MDIO_CLK_SEL_25MD32 5
-+#define L1C_MDIO_CLK_SEL_25MD64 6
-+#define L1C_MDIO_CLK_SEL_25MD128 7
-+#define L1C_MDIO_START BIT(23)
-+#define L1C_MDIO_SPRES_PRMBL BIT(22)
-+#define L1C_MDIO_OP_READ BIT(21) /* 1:read,0:write */
-+#define L1C_MDIO_REG_MASK ASHFT16(0x1FUL)
-+#define L1C_MDIO_REG_SHIFT 16
-+#define L1C_MDIO_DATA_MASK ASHFT0(0xFFFFUL)
-+#define L1C_MDIO_DATA_SHIFT 0
-+#define L1C_MDIO_MAX_AC_TO 120
-+
-+#define L1C_MDIO_EXTN 0x1448
-+#define L1C_MDIO_EXTN_PORTAD_MASK ASHFT21(0x1FUL)
-+#define L1C_MDIO_EXTN_PORTAD_SHIFT 21
-+#define L1C_MDIO_EXTN_DEVAD_MASK ASHFT16(0x1FUL)
-+#define L1C_MDIO_EXTN_DEVAD_SHIFT 16
-+#define L1C_MDIO_EXTN_REG_MASK ASHFT0(0xFFFFUL)
-+#define L1C_MDIO_EXTN_REG_SHIFT 0
-+
-+#define L1C_PHY_STS 0x1418
-+#define L1C_PHY_STS_LPW BIT(31)
-+#define L1C_PHY_STS_LPI BIT(30)
-+#define L1C_PHY_STS_PWON_STRIP_MASK ASHFT16(0xFFFUL)
-+#define L1C_PHY_STS_PWON_STRIP_SHIFT 16
-+
-+#define L1C_PHY_STS_DUPLEX BIT(3)
-+#define L1C_PHY_STS_LINKUP BIT(2)
-+#define L1C_PHY_STS_SPEED_MASK ASHFT0(3UL)
-+#define L1C_PHY_STS_SPEED_SHIFT 0
-+#define L1C_PHY_STS_SPEED_SHIFT 0
-+#define L1C_PHY_STS_SPEED_1000M 2
-+#define L1C_PHY_STS_SPEED_100M 1
-+#define L1C_PHY_STS_SPEED_10M 0
-+
-+#define L1C_BIST0 0x141C
-+#define L1C_BIST0_COL_MASK ASHFT24(0x3FUL)
-+#define L1C_BIST0_COL_SHIFT 24
-+#define L1C_BIST0_ROW_MASK ASHFT12(0xFFFUL)
-+#define L1C_BIST0_ROW_SHIFT 12
-+#define L1C_BIST0_STEP_MASK ASHFT8(0xFUL)
-+#define L1C_BIST0_STEP_SHIFT 8
-+#define L1C_BIST0_PATTERN_MASK ASHFT4(7UL)
-+#define L1C_BIST0_PATTERN_SHIFT 4
-+#define L1C_BIST0_CRIT BIT(3)
-+#define L1C_BIST0_FIXED BIT(2)
-+#define L1C_BIST0_FAIL BIT(1)
-+#define L1C_BIST0_START BIT(0)
-+
-+#define L1C_BIST1 0x1420
-+#define L1C_BIST1_COL_MASK ASHFT24(0x3FUL)
-+#define L1C_BIST1_COL_SHIFT 24
-+#define L1C_BIST1_ROW_MASK ASHFT12(0xFFFUL)
-+#define L1C_BIST1_ROW_SHIFT 12
-+#define L1C_BIST1_STEP_MASK ASHFT8(0xFUL)
-+#define L1C_BIST1_STEP_SHIFT 8
-+#define L1C_BIST1_PATTERN_MASK ASHFT4(7UL)
-+#define L1C_BIST1_PATTERN_SHIFT 4
-+#define L1C_BIST1_CRIT BIT(3)
-+#define L1C_BIST1_FIXED BIT(2)
-+#define L1C_BIST1_FAIL BIT(1)
-+#define L1C_BIST1_START BIT(0)
-+
-+#define L1C_SERDES 0x1424
-+#define L1C_SERDES_PHYCLK_SLWDWN BIT(18)
-+#define L1C_SERDES_MACCLK_SLWDWN BIT(17)
-+#define L1C_SERDES_SELFB_PLL_MASK ASHFT14(3UL)
-+#define L1C_SERDES_SELFB_PLL_SHIFT 14
-+#define L1C_SERDES_PHYCLK_SEL_GTX BIT(13) /* 1:gtx_clk, 0:25M */
-+#define L1C_SERDES_PCIECLK_SEL_SRDS BIT(12) /* 1:serdes,0:25M */
-+#define L1C_SERDES_BUFS_RX_EN BIT(11)
-+#define L1C_SERDES_PD_RX BIT(10)
-+#define L1C_SERDES_PLL_EN BIT(9)
-+#define L1C_SERDES_EN BIT(8)
-+#define L1C_SERDES_SELFB_PLL_SEL_CSR BIT(6) /* 0:state-machine,1:csr */
-+#define L1C_SERDES_SELFB_PLL_CSR_MASK ASHFT4(3UL)
-+#define L1C_SERDES_SELFB_PLL_CSR_SHIFT 4
-+#define L1C_SERDES_SELFB_PLL_CSR_4 3 /* 4-12% OV-CLK */
-+#define L1C_SERDES_SELFB_PLL_CSR_0 2 /* 0-4% OV-CLK */
-+#define L1C_SERDES_SELFB_PLL_CSR_12 1 /* 12-18% OV-CLK */
-+#define L1C_SERDES_SELFB_PLL_CSR_18 0 /* 18-25% OV-CLK */
-+#define L1C_SERDES_VCO_SLOW BIT(3)
-+#define L1C_SERDES_VCO_FAST BIT(2)
-+#define L1C_SERDES_LOCKDCT_EN BIT(1)
-+#define L1C_SERDES_LOCKDCTED BIT(0)
-+
-+#define L1C_LED_CTRL 0x1428
-+#define L1C_LED_CTRL_PATMAP2_MASK ASHFT8(3UL)
-+#define L1C_LED_CTRL_PATMAP2_SHIFT 8
-+#define L1C_LED_CTRL_PATMAP1_MASK ASHFT6(3UL)
-+#define L1C_LED_CTRL_PATMAP1_SHIFT 6
-+#define L1C_LED_CTRL_PATMAP0_MASK ASHFT4(3UL)
-+#define L1C_LED_CTRL_PATMAP0_SHIFT 4
-+#define L1C_LED_CTRL_D3_MODE_MASK ASHFT2(3UL)
-+#define L1C_LED_CTRL_D3_MODE_SHIFT 2
-+#define L1C_LED_CTRL_D3_MODE_NORMAL 0
-+#define L1C_LED_CTRL_D3_MODE_WOL_DIS 1
-+#define L1C_LED_CTRL_D3_MODE_WOL_ANY 2
-+#define L1C_LED_CTRL_D3_MODE_WOL_EN 3
-+#define L1C_LED_CTRL_DUTY_CYCL_MASK ASHFT0(3UL)
-+#define L1C_LED_CTRL_DUTY_CYCL_SHIFT 0
-+#define L1C_LED_CTRL_DUTY_CYCL_50 0 /* 50% */
-+#define L1C_LED_CTRL_DUTY_CYCL_125 1 /* 12.5% */
-+#define L1C_LED_CTRL_DUTY_CYCL_25 2 /* 25% */
-+#define L1C_LED_CTRL_DUTY_CYCL_75 3 /* 75% */
-+
-+#define L1C_LED_PATN 0x142C
-+#define L1C_LED_PATN1_MASK ASHFT16(0xFFFFUL)
-+#define L1C_LED_PATN1_SHIFT 16
-+#define L1C_LED_PATN0_MASK ASHFT0(0xFFFFUL)
-+#define L1C_LED_PATN0_SHIFT 0
-+
-+#define L1C_LED_PATN2 0x1430
-+#define L1C_LED_PATN2_MASK ASHFT0(0xFFFFUL)
-+#define L1C_LED_PATN2_SHIFT 0
-+
-+#define L1C_SYSALV 0x1434
-+#define L1C_SYSALV_FLAG BIT(0)
-+
-+#define L1C_PCIERR_INST 0x1438
-+#define L1C_PCIERR_INST_TX_RATE_MASK ASHFT4(0xFUL)
-+#define L1C_PCIERR_INST_TX_RATE_SHIFT 4
-+#define L1C_PCIERR_INST_RX_RATE_MASK ASHFT0(0xFUL)
-+#define L1C_PCIERR_INST_RX_RATE_SHIFT 0
-+
-+#define L1C_LPI_DECISN_TIMER 0x143C
-+#define L1C_LPI_DESISN_TIMER_L2CB 0x7D00
-+
-+#define L1C_LPI_CTRL 0x1440
-+#define L1C_LPI_CTRL_CHK_DA BIT(31)
-+#define L1C_LPI_CTRL_ENH_TO_MASK ASHFT12(0x1FFFUL)
-+#define L1C_LPI_CTRL_ENH_TO_SHIFT 12
-+#define L1C_LPI_CTRL_ENH_TH_MASK ASHFT6(0x1FUL)
-+#define L1C_LPI_CTRL_ENH_TH_SHIFT 6
-+#define L1C_LPI_CTRL_ENH_EN BIT(5)
-+#define L1C_LPI_CTRL_CHK_RX BIT(4)
-+#define L1C_LPI_CTRL_CHK_STATE BIT(3)
-+#define L1C_LPI_CTRL_GMII BIT(2)
-+#define L1C_LPI_CTRL_TO_PHY BIT(1)
-+#define L1C_LPI_CTRL_EN BIT(0)
-+
-+#define L1C_LPI_WAIT 0x1444
-+#define L1C_LPI_WAIT_TIMER_MASK ASHFT0(0xFFFFUL)
-+#define L1C_LPI_WAIT_TIMER_SHIFT 0
-+
-+#define L1C_MAC_CTRL 0x1480
-+#define L1C_MAC_CTRL_WOLSPED_SWEN BIT(30) /* 0:phy,1:sw */
-+#define L1C_MAC_CTRL_MHASH_ALG_HI5B BIT(29) /* 1:legacy, 0:marvl(low5b)*/
-+#define L1C_MAC_CTRL_SPAUSE_EN BIT(28)
-+#define L1C_MAC_CTRL_DBG_EN BIT(27)
-+#define L1C_MAC_CTRL_BRD_EN BIT(26)
-+#define L1C_MAC_CTRL_MULTIALL_EN BIT(25)
-+#define L1C_MAC_CTRL_RX_XSUM_EN BIT(24)
-+#define L1C_MAC_CTRL_THUGE BIT(23)
-+#define L1C_MAC_CTRL_MBOF BIT(22)
-+#define L1C_MAC_CTRL_SPEED_MASK ASHFT20(3UL)
-+#define L1C_MAC_CTRL_SPEED_SHIFT 20
-+#define L1C_MAC_CTRL_SPEED_10_100 1
-+#define L1C_MAC_CTRL_SPEED_1000 2
-+#define L1C_MAC_CTRL_SIMR BIT(19)
-+#define L1C_MAC_CTRL_SSTCT BIT(17)
-+#define L1C_MAC_CTRL_TPAUSE BIT(16)
-+#define L1C_MAC_CTRL_PROMISC_EN BIT(15)
-+#define L1C_MAC_CTRL_VLANSTRIP BIT(14)
-+#define L1C_MAC_CTRL_PRMBLEN_MASK ASHFT10(0xFUL)
-+#define L1C_MAC_CTRL_PRMBLEN_SHIFT 10
-+#define L1C_MAC_CTRL_RHUGE_EN BIT(9)
-+#define L1C_MAC_CTRL_FLCHK BIT(8)
-+#define L1C_MAC_CTRL_PCRCE BIT(7)
-+#define L1C_MAC_CTRL_CRCE BIT(6)
-+#define L1C_MAC_CTRL_FULLD BIT(5)
-+#define L1C_MAC_CTRL_LPBACK_EN BIT(4)
-+#define L1C_MAC_CTRL_RXFC_EN BIT(3)
-+#define L1C_MAC_CTRL_TXFC_EN BIT(2)
-+#define L1C_MAC_CTRL_RX_EN BIT(1)
-+#define L1C_MAC_CTRL_TX_EN BIT(0)
-+
-+#define L1C_GAP 0x1484
-+#define L1C_GAP_IPGR2_MASK ASHFT24(0x7FUL)
-+#define L1C_GAP_IPGR2_SHIFT 24
-+#define L1C_GAP_IPGR1_MASK ASHFT16(0x7FUL)
-+#define L1C_GAP_IPGR1_SHIFT 16
-+#define L1C_GAP_MIN_IFG_MASK ASHFT8(0xFFUL)
-+#define L1C_GAP_MIN_IFG_SHIFT 8
-+#define L1C_GAP_IPGT_MASK ASHFT0(0x7FUL)
-+#define L1C_GAP_IPGT_SHIFT 0
-+
-+#define L1C_STAD0 0x1488
-+#define L1C_STAD1 0x148C
-+
-+#define L1C_HASH_TBL0 0x1490
-+#define L1C_HASH_TBL1 0x1494
-+
-+#define L1C_HALFD 0x1498
-+#define L1C_HALFD_JAM_IPG_MASK ASHFT24(0xFUL)
-+#define L1C_HALFD_JAM_IPG_SHIFT 24
-+#define L1C_HALFD_ABEBT_MASK ASHFT20(0xFUL)
-+#define L1C_HALFD_ABEBT_SHIFT 20
-+#define L1C_HALFD_ABEBE BIT(19)
-+#define L1C_HALFD_BPNB BIT(18)
-+#define L1C_HALFD_NOBO BIT(17)
-+#define L1C_HALFD_EDXSDFR BIT(16)
-+#define L1C_HALFD_RETRY_MASK ASHFT12(0xFUL)
-+#define L1C_HALFD_RETRY_SHIFT 12
-+#define L1C_HALFD_LCOL_MASK ASHFT0(0x3FFUL)
-+#define L1C_HALFD_LCOL_SHIFT 0
-+
-+#define L1C_MTU 0x149C
-+#define L1C_MTU_JUMBO_TH 1514
-+#define L1C_MTU_STD_ALGN 1536
-+#define L1C_MTU_MIN 64
-+
-+#define L1C_WOL0 0x14A0
-+#define L1C_WOL0_PT7_MATCH BIT(31)
-+#define L1C_WOL0_PT6_MATCH BIT(30)
-+#define L1C_WOL0_PT5_MATCH BIT(29)
-+#define L1C_WOL0_PT4_MATCH BIT(28)
-+#define L1C_WOL0_PT3_MATCH BIT(27)
-+#define L1C_WOL0_PT2_MATCH BIT(26)
-+#define L1C_WOL0_PT1_MATCH BIT(25)
-+#define L1C_WOL0_PT0_MATCH BIT(24)
-+#define L1C_WOL0_PT7_EN BIT(23)
-+#define L1C_WOL0_PT6_EN BIT(22)
-+#define L1C_WOL0_PT5_EN BIT(21)
-+#define L1C_WOL0_PT4_EN BIT(20)
-+#define L1C_WOL0_PT3_EN BIT(19)
-+#define L1C_WOL0_PT2_EN BIT(18)
-+#define L1C_WOL0_PT1_EN BIT(17)
-+#define L1C_WOL0_PT0_EN BIT(16)
-+#define L1C_WOL0_IPV4_SYNC_EVT BIT(14)
-+#define L1C_WOL0_IPV6_SYNC_EVT BIT(13)
-+#define L1C_WOL0_LINK_EVT BIT(10)
-+#define L1C_WOL0_MAGIC_EVT BIT(9)
-+#define L1C_WOL0_PATTERN_EVT BIT(8)
-+#define L1D_WOL0_OOB_EN BIT(6)
-+#define L1C_WOL0_PME_LINK BIT(5)
-+#define L1C_WOL0_LINK_EN BIT(4)
-+#define L1C_WOL0_PME_MAGIC_EN BIT(3)
-+#define L1C_WOL0_MAGIC_EN BIT(2)
-+#define L1C_WOL0_PME_PATTERN_EN BIT(1)
-+#define L1C_WOL0_PATTERN_EN BIT(0)
-+
-+#define L1C_WOL1 0x14A4
-+#define L1C_WOL1_PT3_LEN_MASK ASHFT24(0xFFUL)
-+#define L1C_WOL1_PT3_LEN_SHIFT 24
-+#define L1C_WOL1_PT2_LEN_MASK ASHFT16(0xFFUL)
-+#define L1C_WOL1_PT2_LEN_SHIFT 16
-+#define L1C_WOL1_PT1_LEN_MASK ASHFT8(0xFFUL)
-+#define L1C_WOL1_PT1_LEN_SHIFT 8
-+#define L1C_WOL1_PT0_LEN_MASK ASHFT0(0xFFUL)
-+#define L1C_WOL1_PT0_LEN_SHIFT 0
-+
-+#define L1C_WOL2 0x14A8
-+#define L1C_WOL2_PT7_LEN_MASK ASHFT24(0xFFUL)
-+#define L1C_WOL2_PT7_LEN_SHIFT 24
-+#define L1C_WOL2_PT6_LEN_MASK ASHFT16(0xFFUL)
-+#define L1C_WOL2_PT6_LEN_SHIFT 16
-+#define L1C_WOL2_PT5_LEN_MASK ASHFT8(0xFFUL)
-+#define L1C_WOL2_PT5_LEN_SHIFT 8
-+#define L1C_WOL2_PT4_LEN_MASK ASHFT0(0xFFUL)
-+#define L1C_WOL2_PT4_LEN_SHIFT 0
-+
-+#define L1C_SRAM0 0x1500
-+#define L1C_SRAM_RFD_TAIL_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1C_SRAM_RFD_TAIL_ADDR_SHIFT 16
-+#define L1C_SRAM_RFD_HEAD_ADDR_MASK ASHFT0(0xFFFUL)
-+#define L1C_SRAM_RFD_HEAD_ADDR_SHIFT 0
-+#define L1C_SRAM_RFD_HT_L2CB1 0x02bf02a0L
-+
-+#define L1C_SRAM1 0x1510
-+#define L1C_SRAM_RFD_LEN_MASK ASHFT0(0xFFFUL) /* 8BYTES UNIT */
-+#define L1C_SRAM_RFD_LEN_SHIFT 0
-+
-+#define L1C_SRAM2 0x1518
-+#define L1C_SRAM_TRD_TAIL_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1C_SRAM_TRD_TAIL_ADDR_SHIFT 16
-+#define L1C_SRMA_TRD_HEAD_ADDR_MASK ASHFT0(0xFFFUL)
-+#define L1C_SRAM_TRD_HEAD_ADDR_SHIFT 0
-+#define L1C_SRAM_TRD_HT_L2CB1 0x03df03c0L
-+
-+#define L1C_SRAM3 0x151C
-+#define L1C_SRAM_TRD_LEN_MASK ASHFT0(0xFFFUL) /* 8BYTES UNIT */
-+#define L1C_SRAM_TRD_LEN_SHIFT 0
-+
-+#define L1C_SRAM4 0x1520
-+#define L1C_SRAM_RXF_TAIL_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1C_SRAM_RXF_TAIL_ADDR_SHIFT 16
-+#define L1C_SRAM_RXF_HEAD_ADDR_MASK ASHFT0(0xFFFUL)
-+#define L1C_SRAM_RXF_HEAD_ADDR_SHIFT 0
-+#define L1C_SRAM_RXF_HT_L2CB1 0x029f0000L
-+
-+#define L1C_SRAM5 0x1524
-+#define L1C_SRAM_RXF_LEN_MASK ASHFT0(0xFFFUL) /* 8BYTES UNIT */
-+#define L1C_SRAM_RXF_LEN_SHIFT 0
-+#define L1C_SRAM_RXF_LEN_8K (8*1024)
-+#define L1C_SRAM_RXF_LEN_L2CB1 0x02a0L
-+
-+#define L1C_SRAM6 0x1528
-+#define L1C_SRAM_TXF_TAIL_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1C_SRAM_TXF_TAIL_ADDR_SHIFT 16
-+#define L1C_SRAM_TXF_HEAD_ADDR_MASK ASHFT0(0xFFFUL)
-+#define L1C_SRAM_TXF_HEAD_ADDR_SHIFT 0
-+#define L1C_SRAM_TXF_HT_L2CB1 0x03bf02c0L
-+
-+#define L1C_SRAM7 0x152C
-+#define L1C_SRAM_TXF_LEN_MASK ASHFT0(0xFFFUL) /* 8BYTES UNIT */
-+#define L1C_SRAM_TXF_LEN_SHIFT 0
-+#define L1C_SRAM_TXF_LEN_L2CB1 0x0100L
-+
-+#define L1C_SRAM8 0x1530
-+#define L1C_SRAM_PATTERN_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1C_SRAM_PATTERN_ADDR_SHIFT 16
-+#define L1C_SRAM_TSO_ADDR_MASK ASHFT0(0xFFFUL)
-+#define L1C_SRAM_TSO_ADDR_SHIFT 0
-+
-+#define L1C_SRAM9 0x1534
-+#define L1C_SRAM_LOAD_PTR BIT(0)
-+
-+#define L1C_RX_BASE_ADDR_HI 0x1540
-+
-+#define L1C_TX_BASE_ADDR_HI 0x1544
-+
-+#define L1C_RFD_ADDR_LO 0x1550
-+#define L1C_RFD_RING_SZ 0x1560
-+#define L1C_RFD_BUF_SZ 0x1564
-+#define L1C_RFD_BUF_SZ_MASK ASHFT0(0xFFFFUL)
-+#define L1C_RFD_BUF_SZ_SHIFT 0
-+
-+#define L1C_RRD_ADDR_LO 0x1568
-+#define L1C_RRD_RING_SZ 0x1578
-+#define L1C_RRD_RING_SZ_MASK ASHFT0(0xFFFUL)
-+#define L1C_RRD_RING_SZ_SHIFT 0
-+
-+#define L1C_TPD_PRI1_ADDR_LO 0x157C
-+#define L1C_TPD_PRI0_ADDR_LO 0x1580 /* LOWEST PRORITY */
-+
-+#define L1C_TPD_PRI1_PIDX 0x15F0 /* 16BIT */
-+#define L1C_TPD_PRI0_PIDX 0x15F2 /* 16BIT */
-+
-+#define L1C_TPD_PRI1_CIDX 0x15F4 /* 16BIT */
-+#define L1C_TPD_PRI0_CIDX 0x15F6 /* 16BIT */
-+
-+#define L1C_TPD_RING_SZ 0x1584
-+#define L1C_TPD_RING_SZ_MASK ASHFT0(0xFFFFUL)
-+#define L1C_TPD_RING_SZ_SHIFT 0
-+
-+#define L1C_TXQ0 0x1590
-+#define L1C_TXQ0_TXF_BURST_PREF_MASK ASHFT16(0xFFFFUL)
-+#define L1C_TXQ0_TXF_BURST_PREF_SHIFT 16
-+#define L1C_TXQ0_TXF_BURST_PREF_DEF 0x200
-+#define L1C_TXQ0_TXF_BURST_PREF_L2CB 0x40
-+#define L1D_TXQ0_PEDING_CLR BIT(8)
-+#define L1C_TXQ0_LSO_8023_EN BIT(7)
-+#define L1C_TXQ0_MODE_ENHANCE BIT(6)
-+#define L1C_TXQ0_EN BIT(5)
-+#define L1C_TXQ0_SUPT_IPOPT BIT(4)
-+#define L1C_TXQ0_TPD_BURSTPREF_MASK ASHFT0(0xFUL)
-+#define L1C_TXQ0_TPD_BURSTPREF_SHIFT 0
-+#define L1C_TXQ0_TPD_BURSTPREF_DEF 5
-+
-+#define L1C_TXQ1 0x1594
-+#define L1C_TXQ1_JUMBO_TSOTHR_MASK ASHFT0(0x7FFUL) /* 8BYTES UNIT */
-+#define L1C_TXQ1_JUMBO_TSOTHR_SHIFT 0
-+#define L1C_TXQ1_JUMBO_TSO_TH (7*1024) /* byte */
-+
-+#define L1C_TXQ2 0x1598 /* ENTER L1 CONTROL */
-+#define L1C_TXQ2_BURST_EN BIT(31)
-+#define L1C_TXQ2_BURST_HI_WM_MASK ASHFT16(0xFFFUL)
-+#define L1C_TXQ2_BURST_HI_WM_SHIFT 16
-+#define L1C_TXQ2_BURST_LO_WM_MASK ASHFT0(0xFFFUL)
-+#define L1C_TXQ2_BURST_LO_WM_SHIFT 0
-+
-+#define L1C_RFD_PIDX 0x15E0
-+#define L1C_RFD_PIDX_MASK ASHFT0(0xFFFUL)
-+#define L1C_RFD_PIDX_SHIFT 0
-+
-+#define L1C_RFD_CIDX 0x15F8
-+#define L1C_RFD_CIDX_MASK ASHFT0(0xFFFUL)
-+#define L1C_RFD_CIDX_SHIFT 0
-+
-+#define L1C_RXQ0 0x15A0
-+#define L1C_RXQ0_EN BIT(31)
-+#define L1C_RXQ0_CUT_THRU_EN BIT(30)
-+#define L1C_RXQ0_RSS_HASH_EN BIT(29)
-+#define L1C_RXQ0_NON_IP_QTBL BIT(28) /* 0:q0,1:table */
-+#define L1C_RXQ0_RSS_MODE_MASK ASHFT26(3UL)
-+#define L1C_RXQ0_RSS_MODE_SHIFT 26
-+#define L1C_RXQ0_RSS_MODE_DIS 0
-+#define L1C_RXQ0_RSS_MODE_SQSI 1
-+#define L1C_RXQ0_RSS_MODE_MQSI 2
-+#define L1C_RXQ0_RSS_MODE_MQMI 3
-+#define L1C_RXQ0_NUM_RFD_PREF_MASK ASHFT20(0x3FUL)
-+#define L1C_RXQ0_NUM_RFD_PREF_SHIFT 20
-+#define L1C_RXQ0_NUM_RFD_PREF_DEF 8
-+#define L1C_RXQ0_RSS_HSTYP_IPV6_TCP_EN BIT(19)
-+#define L1C_RXQ0_RSS_HSTYP_IPV6_EN BIT(18)
-+#define L1C_RXQ0_RSS_HSTYP_IPV4_TCP_EN BIT(17)
-+#define L1C_RXQ0_RSS_HSTYP_IPV4_EN BIT(16)
-+#define L1C_RXQ0_RSS_HSTYP_ALL (\
-+ L1C_RXQ0_RSS_HSTYP_IPV6_TCP_EN |\
-+ L1C_RXQ0_RSS_HSTYP_IPV4_TCP_EN |\
-+ L1C_RXQ0_RSS_HSTYP_IPV6_EN |\
-+ L1C_RXQ0_RSS_HSTYP_IPV4_EN)
-+#define L1C_RXQ0_IDT_TBL_SIZE_MASK ASHFT8(0xFFUL)
-+#define L1C_RXQ0_IDT_TBL_SIZE_SHIFT 8
-+#define L1C_RXQ0_IDT_TBL_SIZE_DEF 0x80
-+#define L1C_RXQ0_IPV6_PARSE_EN BIT(7)
-+#define L1C_RXQ0_ASPM_THRESH_MASK ASHFT0(3UL)
-+#define L1C_RXQ0_ASPM_THRESH_SHIFT 0
-+#define L1C_RXQ0_ASPM_THRESH_NO 0
-+#define L1C_RXQ0_ASPM_THRESH_1M 1
-+#define L1C_RXQ0_ASPM_THRESH_10M 2
-+#define L1C_RXQ0_ASPM_THRESH_100M 3
-+
-+#define L1C_RXQ1 0x15A4
-+#define L1C_RXQ1_RFD_PREF_DOWN_MASK ASHFT6(0x3FUL)
-+#define L1C_RXQ1_RFD_PREF_DOWN_SHIFT 6
-+#define L1C_RXQ1_RFD_PREF_UP_MASK ASHFT0(0x3FUL)
-+#define L1C_RXQ1_RFD_PREF_UP_SHIFT 0
-+
-+#define L1C_RXQ2 0x15A8
-+/* XOFF: USED SRAM LOWER THAN IT, THEN NOTIFY THE PEER TO SEND AGAIN */
-+#define L1C_RXQ2_RXF_XOFF_THRESH_MASK ASHFT16(0xFFFUL)
-+#define L1C_RXQ2_RXF_XOFF_THRESH_SHIFT 16
-+#define L1C_RXQ2_RXF_XON_THRESH_MASK ASHFT0(0xFFFUL)
-+#define L1C_RXQ2_RXF_XON_THRESH_SHIFT 0
-+
-+#define L1C_RXQ3 0x15AC
-+#define L1C_RXQ3_RXD_TIMER_MASK ASHFT16(0xFFFFUL)
-+#define L1C_RXQ3_RXD_TIMER_SHIFT 16
-+#define L1C_RXQ3_RXD_THRESH_MASK ASHFT0(0xFFFUL) /* 8BYTES UNIT */
-+#define L1C_RXQ3_RXD_THRESH_SHIFT 0
-+
-+#define L1C_DMA 0x15C0
-+#define L1C_DMA_WPEND_CLR BIT(30)
-+#define L1C_DMA_RPEND_CLR BIT(29)
-+#define L1C_DMA_WDLY_CNT_MASK ASHFT16(0xFUL)
-+#define L1C_DMA_WDLY_CNT_SHIFT 16
-+#define L1C_DMA_WDLY_CNT_DEF 4
-+#define L1C_DMA_RDLY_CNT_MASK ASHFT11(0x1FUL)
-+#define L1C_DMA_RDLY_CNT_SHIFT 11
-+#define L1C_DMA_RDLY_CNT_DEF 15
-+#define L1C_DMA_RREQ_PRI_DATA BIT(10) /* 0:tpd, 1:data */
-+#define L1C_DMA_WREQ_BLEN_MASK ASHFT7(7UL)
-+#define L1C_DMA_WREQ_BLEN_SHIFT 7
-+#define L1C_DMA_RREQ_BLEN_MASK ASHFT4(7UL)
-+#define L1C_DMA_RREQ_BLEN_SHIFT 4
-+#define L1C_DMA_RCB_LEN128 BIT(3) /* 0:64bytes,1:128bytes */
-+#define L1C_DMA_RORDER_MODE_MASK ASHFT0(7UL)
-+#define L1C_DMA_RORDER_MODE_SHIFT 0
-+#define L1C_DMA_RORDER_MODE_OUT 4
-+#define L1C_DMA_RORDER_MODE_ENHANCE 2
-+#define L1C_DMA_RORDER_MODE_IN 1
-+
-+#define L1C_SMB_TIMER 0x15C4
-+
-+#define L1C_TINT_TPD_THRSHLD 0x15C8
-+
-+#define L1C_TINT_TIMER 0x15CC
-+
-+#define L1C_ISR 0x1600
-+#define L1C_ISR_DIS BIT(31)
-+#define L1C_ISR_PCIE_LNKDOWN BIT(26)
-+#define L1C_ISR_PCIE_CERR BIT(25)
-+#define L1C_ISR_PCIE_NFERR BIT(24)
-+#define L1C_ISR_PCIE_FERR BIT(23)
-+#define L1C_ISR_PCIE_UR BIT(22)
-+#define L1C_ISR_MAC_TX BIT(21)
-+#define L1C_ISR_MAC_RX BIT(20)
-+#define L1C_ISR_RX_Q0 BIT(16)
-+#define L1C_ISR_TX_Q0 BIT(15)
-+#define L1C_ISR_TXQ_TO BIT(14)
-+#define L1C_ISR_PHY_LPW BIT(13)
-+#define L1C_ISR_PHY BIT(12)
-+#define L1C_ISR_TX_CREDIT BIT(11)
-+#define L1C_ISR_DMAW BIT(10)
-+#define L1C_ISR_DMAR BIT(9)
-+#define L1C_ISR_TXF_UR BIT(8)
-+#define L1C_ISR_RFD_UR BIT(4)
-+#define L1C_ISR_RXF_OV BIT(3)
-+#define L1C_ISR_MANU BIT(2)
-+#define L1C_ISR_TIMER BIT(1)
-+#define L1C_ISR_SMB BIT(0)
-+
-+#define L1C_IMR 0x1604
-+
-+#define L1C_INT_RETRIG 0x1608 /* re-send deassrt/assert
-+ * if sw no reflect */
-+#define L1C_INT_RETRIG_TO 20000 /* 40 ms */
-+
-+/* WOL mask register only for L1Dv2.0 and later chips */
-+#define L1D_PATTERN_MASK 0x1620 /* 128bytes, sleep state */
-+#define L1D_PATTERN_MASK_LEN 128 /* 128bytes, 32DWORDs */
-+
-+
-+#define L1C_BTROM_CFG 0x1800 /* pwon rst */
-+
-+#define L1C_DRV 0x1804 /* pwon rst */
-+/* bit definition is in lx_hwcomm.h */
-+
-+#define L1C_DRV_ERR1 0x1808 /* perst */
-+#define L1C_DRV_ERR1_GEN BIT(31) /* geneneral err */
-+#define L1C_DRV_ERR1_NOR BIT(30) /* rrd.nor */
-+#define L1C_DRV_ERR1_TRUNC BIT(29)
-+#define L1C_DRV_ERR1_RES BIT(28)
-+#define L1C_DRV_ERR1_INTFATAL BIT(27)
-+#define L1C_DRV_ERR1_TXQPEND BIT(26)
-+#define L1C_DRV_ERR1_DMAW BIT(25)
-+#define L1C_DRV_ERR1_DMAR BIT(24)
-+#define L1C_DRV_ERR1_PCIELNKDWN BIT(23)
-+#define L1C_DRV_ERR1_PKTSIZE BIT(22)
-+#define L1C_DRV_ERR1_FIFOFUL BIT(21)
-+#define L1C_DRV_ERR1_RFDUR BIT(20)
-+#define L1C_DRV_ERR1_RRDSI BIT(19)
-+#define L1C_DRV_ERR1_UPDATE BIT(18)
-+
-+#define L1C_DRV_ERR2 0x180C /* perst */
-+
-+#define L1C_CLK_GATE 0x1814
-+#define L1C_CLK_GATE_RXMAC BIT(5)
-+#define L1C_CLK_GATE_TXMAC BIT(4)
-+#define L1C_CLK_GATE_RXQ BIT(3)
-+#define L1C_CLK_GATE_TXQ BIT(2)
-+#define L1C_CLK_GATE_DMAR BIT(1)
-+#define L1C_CLK_GATE_DMAW BIT(0)
-+#define L1C_CLK_GATE_ALL (\
-+ L1C_CLK_GATE_RXMAC |\
-+ L1C_CLK_GATE_TXMAC |\
-+ L1C_CLK_GATE_RXQ |\
-+ L1C_CLK_GATE_TXQ |\
-+ L1C_CLK_GATE_DMAR |\
-+ L1C_CLK_GATE_DMAW)
-+
-+#define L1C_DBG_ADDR 0x1900 /* DWORD reg */
-+#define L1C_DBG_DATA 0x1904 /* DWORD reg */
-+
-+/***************************** IO mapping registers ***************************/
-+#define L1C_IO_ADDR 0x00 /* DWORD reg */
-+#define L1C_IO_DATA 0x04 /* DWORD reg */
-+#define L1C_IO_MASTER 0x08 /* DWORD same as reg0x1400 */
-+#define L1C_IO_MAC_CTRL 0x0C /* DWORD same as reg0x1480*/
-+#define L1C_IO_ISR 0x10 /* DWORD same as reg0x1600 */
-+#define L1C_IO_IMR 0x14 /* DWORD same as reg0x1604 */
-+#define L1C_IO_TPD_PRI1_PIDX 0x18 /* WORD same as reg0x15F0 */
-+#define L1C_IO_TPD_PRI0_PIDX 0x1A /* WORD same as reg0x15F2 */
-+#define L1C_IO_TPD_PRI1_CIDX 0x1C /* WORD same as reg0x15F4 */
-+#define L1C_IO_TPD_PRI0_CIDX 0x1E /* WORD same as reg0x15F6 */
-+#define L1C_IO_RFD_PIDX 0x20 /* WORD same as reg0x15E0 */
-+#define L1C_IO_RFD_CIDX 0x30 /* WORD same as reg0x15F8 */
-+#define L1C_IO_MDIO 0x38 /* WORD same as reg0x1414 */
-+#define L1C_IO_PHY_CTRL 0x3C /* DWORD same as reg0x140C */
-+
-+
-+
-+/********************* PHY regs definition ***************************/
-+
-+/* Autoneg Advertisement Register (0x4) */
-+#define L1C_ADVERTISE_SPEED_MASK 0x01E0
-+#define L1C_ADVERTISE_DEFAULT_CAP 0x0DE0 /* diff with L1C */
-+
-+/* 1000BASE-T Control Register (0x9) */
-+#define L1C_GIGA_CR_1000T_HD_CAPS 0x0100
-+#define L1C_GIGA_CR_1000T_FD_CAPS 0x0200
-+#define L1C_GIGA_CR_1000T_REPEATER_DTE 0x0400
-+#define L1C_GIGA_CR_1000T_MS_VALUE 0x0800
-+#define L1C_GIGA_CR_1000T_MS_ENABLE 0x1000
-+#define L1C_GIGA_CR_1000T_TEST_MODE_NORMAL 0x0000
-+#define L1C_GIGA_CR_1000T_TEST_MODE_1 0x2000
-+#define L1C_GIGA_CR_1000T_TEST_MODE_2 0x4000
-+#define L1C_GIGA_CR_1000T_TEST_MODE_3 0x6000
-+#define L1C_GIGA_CR_1000T_TEST_MODE_4 0x8000
-+#define L1C_GIGA_CR_1000T_SPEED_MASK 0x0300
-+#define L1C_GIGA_CR_1000T_DEFAULT_CAP 0x0300
-+
-+/* 1000BASE-T Status Register */
-+#define L1C_MII_GIGA_SR 0x0A
-+
-+/* PHY Specific Status Register */
-+#define L1C_MII_GIGA_PSSR 0x11
-+#define L1C_GIGA_PSSR_FC_RXEN 0x0004
-+#define L1C_GIGA_PSSR_FC_TXEN 0x0008
-+#define L1C_GIGA_PSSR_SPD_DPLX_RESOLVED 0x0800
-+#define L1C_GIGA_PSSR_DPLX 0x2000
-+#define L1C_GIGA_PSSR_SPEED 0xC000
-+#define L1C_GIGA_PSSR_10MBS 0x0000
-+#define L1C_GIGA_PSSR_100MBS 0x4000
-+#define L1C_GIGA_PSSR_1000MBS 0x8000
-+
-+/* PHY Interrupt Enable Register */
-+#define L1C_MII_IER 0x12
-+#define L1C_IER_LINK_UP 0x0400
-+#define L1C_IER_LINK_DOWN 0x0800
-+
-+/* PHY Interrupt Status Register */
-+#define L1C_MII_ISR 0x13
-+#define L1C_ISR_LINK_UP 0x0400
-+#define L1C_ISR_LINK_DOWN 0x0800
-+
-+/* Cable-Detect-Test Control Register */
-+#define L1C_MII_CDTC 0x16
-+#define L1C_CDTC_EN 1 /* sc */
-+#define L1C_CDTC_PAIR_MASK ASHFT8(3U)
-+#define L1C_CDTC_PAIR_SHIFT 8
-+
-+
-+/* Cable-Detect-Test Status Register */
-+#define L1C_MII_CDTS 0x1C
-+#define L1C_CDTS_STATUS_MASK ASHFT8(3U)
-+#define L1C_CDTS_STATUS_SHIFT 8
-+#define L1C_CDTS_STATUS_NORMAL 0
-+#define L1C_CDTS_STATUS_SHORT 1
-+#define L1C_CDTS_STATUS_OPEN 2
-+#define L1C_CDTS_STATUS_INVALID 3
-+
-+#define L1C_MII_DBG_ADDR 0x1D
-+#define L1C_MII_DBG_DATA 0x1E
-+
-+/***************************** debug port *************************************/
-+
-+#define L1C_MIIDBG_ANACTRL 0x00
-+#define L1C_ANACTRL_CLK125M_DELAY_EN BIT(15)
-+#define L1C_ANACTRL_VCO_FAST BIT(14)
-+#define L1C_ANACTRL_VCO_SLOW BIT(13)
-+#define L1C_ANACTRL_AFE_MODE_EN BIT(12)
-+#define L1C_ANACTRL_LCKDET_PHY BIT(11)
-+#define L1C_ANACTRL_LCKDET_EN BIT(10)
-+#define L1C_ANACTRL_OEN_125M BIT(9)
-+#define L1C_ANACTRL_HBIAS_EN BIT(8)
-+#define L1C_ANACTRL_HB_EN BIT(7)
-+#define L1C_ANACTRL_SEL_HSP BIT(6)
-+#define L1C_ANACTRL_CLASSA_EN BIT(5)
-+#define L1C_ANACTRL_MANUSWON_SWR_MASK ASHFT2(3U)
-+#define L1C_ANACTRL_MANUSWON_SWR_SHIFT 2
-+#define L1C_ANACTRL_MANUSWON_SWR_2V 0
-+#define L1C_ANACTRL_MANUSWON_SWR_1P9V 1
-+#define L1C_ANACTRL_MANUSWON_SWR_1P8V 2
-+#define L1C_ANACTRL_MANUSWON_SWR_1P7V 3
-+#define L1C_ANACTRL_MANUSWON_BW3_4M BIT(1)
-+#define L1C_ANACTRL_RESTART_CAL BIT(0)
-+#define L1C_ANACTRL_DEF 0x02EF
-+
-+
-+#define L1C_MIIDBG_SYSMODCTRL 0x04
-+#define L1C_SYSMODCTRL_IECHOADJ_PFMH_PHY BIT(15)
-+#define L1C_SYSMODCTRL_IECHOADJ_BIASGEN BIT(14)
-+#define L1C_SYSMODCTRL_IECHOADJ_PFML_PHY BIT(13)
-+#define L1C_SYSMODCTRL_IECHOADJ_PS_MASK ASHFT10(3U)
-+#define L1C_SYSMODCTRL_IECHOADJ_PS_SHIFT 10
-+#define L1C_SYSMODCTRL_IECHOADJ_PS_40 3
-+#define L1C_SYSMODCTRL_IECHOADJ_PS_20 2
-+#define L1C_SYSMODCTRL_IECHOADJ_PS_0 1
-+#define L1C_SYSMODCTRL_IECHOADJ_10BT_100MV BIT(6) /* 1:100mv, 0:200mv */
-+#define L1C_SYSMODCTRL_IECHOADJ_HLFAP_MASK ASHFT4(3U)
-+#define L1C_SYSMODCTRL_IECHOADJ_HLFAP_SHIFT 4
-+#define L1C_SYSMODCTRL_IECHOADJ_VDFULBW BIT(3)
-+#define L1C_SYSMODCTRL_IECHOADJ_VDBIASHLF BIT(2)
-+#define L1C_SYSMODCTRL_IECHOADJ_VDAMPHLF BIT(1)
-+#define L1C_SYSMODCTRL_IECHOADJ_VDLANSW BIT(0)
-+#define L1C_SYSMODCTRL_IECHOADJ_DEF 0x88BB /* ???? */
-+
-+
-+
-+#define L1D_MIIDBG_SYSMODCTRL 0x04 /* l1d & l2cb */
-+#define L1D_SYSMODCTRL_IECHOADJ_CUR_ADD BIT(15)
-+#define L1D_SYSMODCTRL_IECHOADJ_CUR_MASK ASHFT12(7U)
-+#define L1D_SYSMODCTRL_IECHOADJ_CUR_SHIFT 12
-+#define L1D_SYSMODCTRL_IECHOADJ_VOL_MASK ASHFT8(0xFU)
-+#define L1D_SYSMODCTRL_IECHOADJ_VOL_SHIFT 8
-+#define L1D_SYSMODCTRL_IECHOADJ_VOL_17ALL 3
-+#define L1D_SYSMODCTRL_IECHOADJ_VOL_100M15 1
-+#define L1D_SYSMODCTRL_IECHOADJ_VOL_10M17 0
-+#define L1D_SYSMODCTRL_IECHOADJ_BIAS1_MASK ASHFT4(0xFU)
-+#define L1D_SYSMODCTRL_IECHOADJ_BIAS1_SHIFT 4
-+#define L1D_SYSMODCTRL_IECHOADJ_BIAS2_MASK ASHFT0(0xFU)
-+#define L1D_SYSMODCTRL_IECHOADJ_BIAS2_SHIFT 0
-+#define L1D_SYSMODCTRL_IECHOADJ_DEF 0x4FBB
-+
-+
-+#define L1C_MIIDBG_SRDSYSMOD 0x05
-+#define L1C_SRDSYSMOD_LCKDET_EN BIT(13)
-+#define L1C_SRDSYSMOD_PLL_EN BIT(11)
-+#define L1C_SRDSYSMOD_SEL_HSP BIT(10)
-+#define L1C_SRDSYSMOD_HLFTXDR BIT(9)
-+#define L1C_SRDSYSMOD_TXCLK_DELAY_EN BIT(8)
-+#define L1C_SRDSYSMOD_TXELECIDLE BIT(7)
-+#define L1C_SRDSYSMOD_DEEMP_EN BIT(6)
-+#define L1C_SRDSYSMOD_MS_PAD BIT(2)
-+#define L1C_SRDSYSMOD_CDR_ADC_VLTG BIT(1)
-+#define L1C_SRDSYSMOD_CDR_DAC_1MA BIT(0)
-+#define L1C_SRDSYSMOD_DEF 0x2C46
-+
-+#define L1C_MIIDBG_CFGLPSPD 0x0A
-+#define L1C_CFGLPSPD_RSTCNT_MASK ASHFT(3U)
-+#define L1C_CFGLPSPD_RSTCNT_SHIFT 14
-+#define L1C_CFGLPSPD_RSTCNT_CLK125SW BIT(13)
-+
-+#define L1C_MIIDBG_HIBNEG 0x0B
-+#define L1C_HIBNEG_PSHIB_EN BIT(15)
-+#define L1C_HIBNEG_WAKE_BOTH BIT(14)
-+#define L1C_HIBNEG_ONOFF_ANACHG_SUDEN BIT(13)
-+#define L1C_HIBNEG_HIB_PULSE BIT(12)
-+#define L1C_HIBNEG_GATE_25M_EN BIT(11)
-+#define L1C_HIBNEG_RST_80U BIT(10)
-+#define L1C_HIBNEG_RST_TIMER_MASK ASHFT8(3U)
-+#define L1C_HIBNEG_RST_TIMER_SHIFT 8
-+#define L1C_HIBNEG_GTX_CLK_DELAY_MASK ASHFT5(3U)
-+#define L1C_HIBNEG_GTX_CLK_DELAY_SHIFT 5
-+#define L1C_HIBNEG_BYPSS_BRKTIMER BIT(4)
-+#define L1C_HIBNEG_DEF 0xBC40
-+
-+#define L1C_MIIDBG_TST10BTCFG 0x12
-+#define L1C_TST10BTCFG_INTV_TIMER_MASK ASHFT14(3U)
-+#define L1C_TST10BTCFG_INTV_TIMER_SHIFT 14
-+#define L1C_TST10BTCFG_TRIGER_TIMER_MASK ASHFT12(3U)
-+#define L1C_TST10BTCFG_TRIGER_TIMER_SHIFT 12
-+#define L1C_TST10BTCFG_DIV_MAN_MLT3_EN BIT(11)
-+#define L1C_TST10BTCFG_OFF_DAC_IDLE BIT(10)
-+#define L1C_TST10BTCFG_LPBK_DEEP BIT(2) /* 1:deep,0:shallow */
-+#define L1C_TST10BTCFG_DEF 0x4C04
-+
-+#define L1C_MIIDBG_AZ_ANADECT 0x15
-+#define L1C_AZ_ANADECT_10BTRX_TH BIT(15)
-+#define L1C_AZ_ANADECT_BOTH_01CHNL BIT(14)
-+#define L1C_AZ_ANADECT_INTV_MASK ASHFT8(0x3FU)
-+#define L1C_AZ_ANADECT_INTV_SHIFT 8
-+#define L1C_AZ_ANADECT_THRESH_MASK ASHFT4(0xFU)
-+#define L1C_AZ_ANADECT_THRESH_SHIFT 4
-+#define L1C_AZ_ANADECT_CHNL_MASK ASHFT0(0xFU)
-+#define L1C_AZ_ANADECT_CHNL_SHIFT 0
-+#define L1C_AZ_ANADECT_DEF 0x3220
-+#define L1C_AZ_ANADECT_LONG 0xb210
-+
-+#define L1D_MIIDBG_MSE16DB 0x18
-+#define L1D_MSE16DB_UP 0x05EA
-+#define L1D_MSE16DB_DOWN 0x02EA
-+
-+
-+#define L1C_MIIDBG_LEGCYPS 0x29
-+#define L1C_LEGCYPS_EN BIT(15)
-+#define L1C_LEGCYPS_DAC_AMP1000_MASK ASHFT12(7U)
-+#define L1C_LEGCYPS_DAC_AMP1000_SHIFT 12
-+#define L1C_LEGCYPS_DAC_AMP100_MASK ASHFT9(7U)
-+#define L1C_LEGCYPS_DAC_AMP100_SHIFT 9
-+#define L1C_LEGCYPS_DAC_AMP10_MASK ASHFT6(7U)
-+#define L1C_LEGCYPS_DAC_AMP10_SHIFT 6
-+#define L1C_LEGCYPS_UNPLUG_TIMER_MASK ASHFT3(7U)
-+#define L1C_LEGCYPS_UNPLUG_TIMER_SHIFT 3
-+#define L1C_LEGCYPS_UNPLUG_DECT_EN BIT(2)
-+#define L1C_LEGCYPS_ECNC_PS_EN BIT(0)
-+#define L1D_LEGCYPS_DEF 0x129D
-+#define L1C_LEGCYPS_DEF 0x36DD
-+
-+#define L1C_MIIDBG_TST100BTCFG 0x36
-+#define L1C_TST100BTCFG_NORMAL_BW_EN BIT(15)
-+#define L1C_TST100BTCFG_BADLNK_BYPASS BIT(14)
-+#define L1C_TST100BTCFG_SHORTCABL_TH_MASK ASHFT8(0x3FU)
-+#define L1C_TST100BTCFG_SHORTCABL_TH_SHIFT 8
-+#define L1C_TST100BTCFG_LITCH_EN BIT(7)
-+#define L1C_TST100BTCFG_VLT_SW BIT(6)
-+#define L1C_TST100BTCFG_LONGCABL_TH_MASK ASHFT0(0x3FU)
-+#define L1C_TST100BTCFG_LONGCABL_TH_SHIFT 0
-+#define L1C_TST100BTCFG_DEF 0xE12C
-+
-+#define L1C_MIIDBG_VOLT_CTRL 0x3B
-+#define L1C_VOLT_CTRL_CABLE1TH_MASK ASHFT7(0x1FFU)
-+#define L1C_VOLT_CTRL_CABLE1TH_SHIFT 7
-+#define L1C_VOLT_CTRL_AMPCTRL_MASK ASHFT5(3U)
-+#define L1C_VOLT_CTRL_AMPCTRL_SHIFT 5
-+#define L1C_VOLT_CTRL_SW_BYPASS BIT(4)
-+#define L1C_VOLT_CTRL_SWLOWEST BIT(3)
-+#define L1C_VOLT_CTRL_DACAMP10_MASK ASHFT0(7U)
-+#define L1C_VOLT_CTRL_DACAMP10_SHIFT 0
-+
-+#define L1C_MIIDBG_CABLE1TH_DET 0x3E
-+#define L1C_CABLE1TH_DET_EN BIT(15)
-+
-+/***************************** extension **************************************/
-+
-+/******* dev 3 *********/
-+#define L1C_MIIEXT_PCS 3
-+
-+#define L1C_MIIEXT_CLDCTRL3 0x8003
-+#define L1C_CLDCTRL3_BP_CABLE1TH_DET_GT BIT(15)
-+#define L1C_CLDCTRL3_AZ_DISAMP BIT(12)
-+#define L1C_CLDCTRL3_L2CB 0x4D19
-+#define L1C_CLDCTRL3_L1D 0xDD19
-+
-+#define L1C_MIIEXT_CLDCTRL6 0x8006
-+#define L1C_CLDCTRL6_CAB_LEN_MASK ASHFT0(0x1FFU)
-+#define L1C_CLDCTRL6_CAB_LEN_SHIFT 0
-+#define L1C_CLDCTRL6_CAB_LEN_SHORT 0x50
-+
-+#define L1C_MIIEXT_CLDCTRL7 0x8007
-+#define L1C_CLDCTRL7_VDHLF_BIAS_TH_MASK ASHFT9(0x7FU)
-+#define L1C_CLDCTRL7_VDHLF_BIAS_TH_SHIFT 9
-+#define L1C_CLDCTRL7_AFE_AZ_MASK ASHFT4(0x1FU)
-+#define L1C_CLDCTRL7_AFE_AZ_SHIFT 4
-+#define L1C_CLDCTRL7_SIDE_PEAK_TH_MASK ASHFT0(0xFU)
-+#define L1C_CLDCTRL7_SIDE_PEAK_TH_SHIFT 0
-+#define L1C_CLDCTRL7_DEF 0x6BF6 /* ???? */
-+#define L1C_CLDCTRL7_FPGA_DEF 0x0005
-+#define L1C_CLDCTRL7_L2CB 0x0175
-+
-+#define L1C_MIIEXT_AZCTRL 0x8008
-+#define L1C_AZCTRL_SHORT_TH_MASK ASHFT8(0xFFU)
-+#define L1C_AZCTRL_SHORT_TH_SHIFT 8
-+#define L1C_AZCTRL_LONG_TH_MASK ASHFT0(0xFFU)
-+#define L1C_AZCTRL_LONG_TH_SHIFT 0
-+#define L1C_AZCTRL_DEF 0x1629
-+#define L1C_AZCTRL_FPGA_DEF 0x101D
-+#define L1C_AZCTRL_L1D 0x2034
-+
-+#define L1C_MIIEXT_AZCTRL2 0x8009
-+#define L1C_AZCTRL2_WAKETRNING_MASK ASHFT8(0xFFU)
-+#define L1C_AZCTRL2_WAKETRNING_SHIFT 8
-+#define L1C_AZCTRL2_QUIET_TIMER_MASH ASHFT6(3U)
-+#define L1C_AZCTRL2_QUIET_TIMER_SHIFT 6
-+#define L1C_AZCTRL2_PHAS_JMP2 BIT(4)
-+#define L1C_AZCTRL2_CLKTRCV_125MD16 BIT(3)
-+#define L1C_AZCTRL2_GATE1000_EN BIT(2)
-+#define L1C_AZCTRL2_AVRG_FREQ BIT(1)
-+#define L1C_AZCTRL2_PHAS_JMP4 BIT(0)
-+#define L1C_AZCTRL2_DEF 0x32C0
-+#define L1C_AZCTRL2_FPGA_DEF 0x40C8
-+#define L1C_AZCTRL2_L2CB 0xE003
-+#define L1C_AZCTRL2_L1D2 0x18C0
-+
-+
-+#define L1C_MIIEXT_AZCTRL4 0x800B
-+#define L1C_AZCTRL4_WAKE_STH_L2CB 0x0094
-+
-+#define L1C_MIIEXT_AZCTRL5 0x800C
-+#define L1C_AZCTRL5_WAKE_LTH_L2CB 0x00EB
-+
-+#define L1C_MIIEXT_AZCTRL6 0x800D
-+#define L1C_AZCTRL6_L1D2 0x003F
-+
-+
-+
-+/********* dev 7 **********/
-+#define L1C_MIIEXT_ANEG 7
-+
-+#define L1C_MIIEXT_LOCAL_EEEADV 0x3C
-+#define L1C_LOCAL_EEEADV_1000BT BIT(2)
-+#define L1C_LOCAL_EEEADV_100BT BIT(1)
-+
-+#define L1C_MIIEXT_REMOTE_EEEADV 0x3D
-+#define L1C_REMOTE_EEEADV_1000BT BIT(2)
-+#define L1C_REMOTE_EEEADV_100BT BIT(1)
-+
-+#define L1C_MIIEXT_EEE_ANEG 0x8000
-+#define L1C_EEE_ANEG_1000M BIT(2)
-+#define L1C_EEE_ANEG_100M BIT(1)
-+
-+
-+
-+
-+/******************************************************************************/
-+
-+/* functions */
-+
-+/* get permanent mac address from
-+ * return
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1c_get_perm_macaddr(struct alx_hw *hw, u8 *addr);
-+
-+
-+/* reset mac & dma
-+ * return
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1c_reset_mac(struct alx_hw *hw);
-+
-+/* reset phy
-+ * return
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1c_reset_phy(struct alx_hw *hw, bool pws_en, bool az_en, bool ptp_en);
-+
-+
-+/* reset pcie
-+ * just reset pcie relative registers (pci command, clk, aspm...)
-+ * return
-+ * 0:success
-+ * non-0:fail
-+ */
-+u16 l1c_reset_pcie(struct alx_hw *hw, bool l0s_en, bool l1_en);
-+
-+
-+/* disable/enable MAC/RXQ/TXQ
-+ * en
-+ * true:enable
-+ * false:disable
-+ * return
-+ * 0:success
-+ * non-0-fail
-+ */
-+u16 l1c_enable_mac(struct alx_hw *hw, bool en, u16 en_ctrl);
-+
-+/* enable/disable aspm support
-+ * that will change settings for phy/mac/pcie
-+ */
-+u16 l1c_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en, u8 lnk_stat);
-+
-+
-+/* initialize phy for speed / flow control
-+ * lnk_cap
-+ * if autoNeg, is link capability to tell the peer
-+ * if force mode, is forced speed/duplex
-+ */
-+u16 l1c_init_phy_spdfc(struct alx_hw *hw, bool auto_neg,
-+ u8 lnk_cap, bool fc_en);
-+
-+/* do post setting on phy if link up/down event occur
-+ */
-+u16 l1c_post_phy_link(struct alx_hw *hw, bool linkon, u8 wire_spd);
-+
-+
-+/* do power saving setting befor enter suspend mode
-+ * NOTE:
-+ * 1. phy link must be established before calling this function
-+ * 2. wol option (pattern,magic,link,etc.) is configed before call it.
-+ */
-+u16 l1c_powersaving(struct alx_hw *hw, u8 wire_spd, bool wol_en,
-+ bool mac_txen, bool mac_rxen, bool pws_en);
-+
-+
-+/* read phy register */
-+u16 l1c_read_phy(struct alx_hw *hw, bool ext, u8 dev, bool fast, u16 reg,
-+ u16 *data);
-+
-+/* write phy register */
-+u16 l1c_write_phy(struct alx_hw *hw, bool ext, u8 dev, bool fast, u16 reg,
-+ u16 data);
-+
-+/* phy debug port */
-+u16 l1c_read_phydbg(struct alx_hw *hw, bool fast, u16 reg, u16 *data);
-+u16 l1c_write_phydbg(struct alx_hw *hw, bool fast, u16 reg, u16 data);
-+
-+/* check the configuration of the PHY */
-+u16 l1c_get_phy_config(struct alx_hw *hw);
-+
-+/*
-+ * initialize mac basically
-+ * most of hi-feature no init
-+ * MAC/PHY should be reset before call this function
-+ */
-+u16 l1c_init_mac(struct alx_hw *hw, u8 *addr, u32 txmem_hi,
-+ u32 *tx_mem_lo, u8 tx_qnum, u16 txring_sz,
-+ u32 rxmem_hi, u32 rfdmem_lo, u32 rrdmem_lo,
-+ u16 rxring_sz, u16 rxbuf_sz, u16 smb_timer,
-+ u16 mtu, u16 int_mod, bool hash_legacy);
-+
-+
-+
-+#endif/*L1C_HW_H_*/
-+
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alf_cb.c
-@@ -0,0 +1,1187 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+#include <linux/pci_regs.h>
-+#include <linux/mii.h>
-+
-+#include "alf_hw.h"
-+
-+
-+#define ALF_REV_ID_AR8161_B0 0x10
-+
-+/* definition for MSIX */
-+#define ALF_MSIX_ENTRY_BASE 0x2000
-+#define ALF_MSIX_ENTRY_SIZE 16
-+#define ALF_MSIX_MSG_LOADDR_OFF 0
-+#define ALF_MSIX_MSG_HIADDR_OFF 4
-+#define ALF_MSIX_MSG_DATA_OFF 8
-+#define ALF_MSIX_MSG_CTRL_OFF 12
-+
-+#define ALF_MSIX_INDEX_RXQ0 0
-+#define ALF_MSIX_INDEX_RXQ1 1
-+#define ALF_MSIX_INDEX_RXQ2 2
-+#define ALF_MSIX_INDEX_RXQ3 3
-+#define ALF_MSIX_INDEX_RXQ4 4
-+#define ALF_MSIX_INDEX_RXQ5 5
-+#define ALF_MSIX_INDEX_RXQ6 6
-+#define ALF_MSIX_INDEX_RXQ7 7
-+#define ALF_MSIX_INDEX_TXQ0 8
-+#define ALF_MSIX_INDEX_TXQ1 9
-+#define ALF_MSIX_INDEX_TXQ2 10
-+#define ALF_MSIX_INDEX_TXQ3 11
-+#define ALF_MSIX_INDEX_TIMER 12
-+#define ALF_MSIX_INDEX_ALERT 13
-+#define ALF_MSIX_INDEX_SMB 14
-+#define ALF_MSIX_INDEX_PHY 15
-+
-+
-+#define ALF_SRAM_BASE L1F_SRAM0
-+#define ALF_SRAM(_i, _type) \
-+ (ALF_SRAM_BASE + ((_i) * sizeof(_type)))
-+
-+#define ALF_MIB_BASE L1F_MIB_BASE
-+#define ALF_MIB(_i, _type) \
-+ (ALF_MIB_BASE + ((_i) * sizeof(_type)))
-+
-+/* definition for RSS */
-+#define ALF_RSS_KEY_BASE L1F_RSS_KEY0
-+#define ALF_RSS_IDT_BASE L1F_RSS_IDT_TBL0
-+#define ALF_RSS_KEY(_i, _type) \
-+ (ALF_RSS_KEY_BASE + ((_i) * sizeof(_type)))
-+#define ALF_RSS_TBL(_i, _type) \
-+ (L1F_RSS_IDT_TBL0 + ((_i) * sizeof(_type)))
-+
-+
-+/* NIC */
-+static int alf_identify_nic(struct alx_hw *hw)
-+{
-+ u32 drv;
-+
-+ if (hw->pci_revid < ALX_REV_ID_AR8161_V2_0)
-+ return 0;
-+
-+ /* check from V2_0(b0) to ... */
-+ switch (hw->pci_revid) {
-+ default:
-+ alx_mem_r32(hw, L1F_DRV, &drv);
-+ if (drv & LX_DRV_DISABLE)
-+ return -EINVAL;
-+ break;
-+ }
-+ return 0;
-+}
-+
-+
-+/* PHY */
-+static int alf_read_phy_reg(struct alx_hw *hw, u16 reg_addr, u16 *phy_data)
-+{
-+ unsigned long flags;
-+ int retval = 0;
-+
-+ spin_lock_irqsave(&hw->mdio_lock, flags);
-+
-+ if (l1f_read_phy(hw, false, ALX_MDIO_DEV_TYPE_NORM, false, reg_addr,
-+ phy_data)) {
-+ alx_hw_err(hw, "error when read phy reg\n");
-+ retval = -EINVAL;
-+ }
-+
-+ spin_unlock_irqrestore(&hw->mdio_lock, flags);
-+ return retval;
-+}
-+
-+
-+static int alf_write_phy_reg(struct alx_hw *hw, u16 reg_addr, u16 phy_data)
-+{
-+ unsigned long flags;
-+ int retval = 0;
-+
-+ spin_lock_irqsave(&hw->mdio_lock, flags);
-+
-+ if (l1f_write_phy(hw, false, ALX_MDIO_DEV_TYPE_NORM, false, reg_addr,
-+ phy_data)) {
-+ alx_hw_err(hw, "error when write phy reg\n");
-+ retval = -EINVAL;
-+ }
-+
-+ spin_unlock_irqrestore(&hw->mdio_lock, flags);
-+ return retval;
-+}
-+
-+
-+static int alf_init_phy(struct alx_hw *hw)
-+{
-+ u16 phy_id[2];
-+ int retval;
-+
-+ spin_lock_init(&hw->mdio_lock);
-+
-+ retval = alf_read_phy_reg(hw, MII_PHYSID1, &phy_id[0]);
-+ if (retval)
-+ return retval;
-+ retval = alf_read_phy_reg(hw, MII_PHYSID2, &phy_id[1]);
-+ if (retval)
-+ return retval;
-+ memcpy(&hw->phy_id, phy_id, sizeof(hw->phy_id));
-+
-+ hw->autoneg_advertised = ALX_LINK_SPEED_1GB_FULL |
-+ ALX_LINK_SPEED_10_HALF |
-+ ALX_LINK_SPEED_10_FULL |
-+ ALX_LINK_SPEED_100_HALF |
-+ ALX_LINK_SPEED_100_FULL;
-+ return retval;
-+}
-+
-+
-+static int alf_reset_phy(struct alx_hw *hw)
-+{
-+ int retval = 0;
-+ bool pws_en, az_en, ptp_en;
-+
-+ pws_en = az_en = ptp_en = false;
-+ CLI_HW_FLAG(PWSAVE_EN);
-+ CLI_HW_FLAG(AZ_EN);
-+ CLI_HW_FLAG(PTP_EN);
-+
-+ if (CHK_HW_FLAG(PWSAVE_CAP)) {
-+ pws_en = true;
-+ SET_HW_FLAG(PWSAVE_EN);
-+ }
-+
-+ if (CHK_HW_FLAG(AZ_CAP)) {
-+ az_en = true;
-+ SET_HW_FLAG(AZ_EN);
-+ }
-+
-+ if (CHK_HW_FLAG(PTP_CAP)) {
-+ ptp_en = true;
-+ SET_HW_FLAG(PTP_EN);
-+ }
-+
-+ alx_hw_info(hw, "reset PHY, pws = %d, az = %d, ptp = %d\n",
-+ pws_en, az_en, ptp_en);
-+ if (l1f_reset_phy(hw, pws_en, az_en, ptp_en)) {
-+ alx_hw_err(hw, "error when reset phy\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+/* LINK */
-+static int alf_setup_phy_link(struct alx_hw *hw, u32 speed, bool autoneg,
-+ bool fc)
-+{
-+ u8 link_cap = 0;
-+ int retval = 0;
-+
-+ alx_hw_info(hw, "speed = 0x%x, autoneg = %d\n", speed, autoneg);
-+ if (speed & ALX_LINK_SPEED_1GB_FULL)
-+ link_cap |= LX_LC_1000F;
-+
-+ if (speed & ALX_LINK_SPEED_100_FULL)
-+ link_cap |= LX_LC_100F;
-+
-+ if (speed & ALX_LINK_SPEED_100_HALF)
-+ link_cap |= LX_LC_100H;
-+
-+ if (speed & ALX_LINK_SPEED_10_FULL)
-+ link_cap |= LX_LC_10F;
-+
-+ if (speed & ALX_LINK_SPEED_10_HALF)
-+ link_cap |= LX_LC_10H;
-+
-+ if (l1f_init_phy_spdfc(hw, autoneg, link_cap, fc)) {
-+ alx_hw_err(hw, "error when init phy speed and fc\n");
-+ retval = -EINVAL;
-+ }
-+
-+ return retval;
-+}
-+
-+
-+static int alf_setup_phy_link_speed(struct alx_hw *hw, u32 speed,
-+ bool autoneg, bool fc)
-+{
-+ /*
-+ * Clear autoneg_advertised and set new values based on input link
-+ * speed.
-+ */
-+ hw->autoneg_advertised = 0;
-+
-+ if (speed & ALX_LINK_SPEED_1GB_FULL)
-+ hw->autoneg_advertised |= ALX_LINK_SPEED_1GB_FULL;
-+
-+ if (speed & ALX_LINK_SPEED_100_FULL)
-+ hw->autoneg_advertised |= ALX_LINK_SPEED_100_FULL;
-+
-+ if (speed & ALX_LINK_SPEED_100_HALF)
-+ hw->autoneg_advertised |= ALX_LINK_SPEED_100_HALF;
-+
-+ if (speed & ALX_LINK_SPEED_10_FULL)
-+ hw->autoneg_advertised |= ALX_LINK_SPEED_10_FULL;
-+
-+ if (speed & ALX_LINK_SPEED_10_HALF)
-+ hw->autoneg_advertised |= ALX_LINK_SPEED_10_HALF;
-+
-+ return alf_setup_phy_link(hw, hw->autoneg_advertised,
-+ autoneg, fc);
-+}
-+
-+
-+static int alf_check_phy_link(struct alx_hw *hw, u32 *speed, bool *link_up)
-+{
-+ u16 bmsr, giga;
-+ int retval;
-+
-+ alf_read_phy_reg(hw, MII_BMSR, &bmsr);
-+ retval = alf_read_phy_reg(hw, MII_BMSR, &bmsr);
-+ if (retval)
-+ return retval;
-+
-+ if (!(bmsr & BMSR_LSTATUS)) {
-+ *link_up = false;
-+ *speed = ALX_LINK_SPEED_UNKNOWN;
-+ return 0;
-+ }
-+ *link_up = true;
-+
-+ /* Read PHY Specific Status Register (17) */
-+ retval = alf_read_phy_reg(hw, L1F_MII_GIGA_PSSR, &giga);
-+ if (retval)
-+ return retval;
-+
-+
-+ if (!(giga & L1F_GIGA_PSSR_SPD_DPLX_RESOLVED)) {
-+ alx_hw_err(hw, "error for speed duplex resolved\n");
-+ return -EINVAL;
-+ }
-+
-+ switch (giga & L1F_GIGA_PSSR_SPEED) {
-+ case L1F_GIGA_PSSR_1000MBS:
-+ if (giga & L1F_GIGA_PSSR_DPLX)
-+ *speed = ALX_LINK_SPEED_1GB_FULL;
-+ else
-+ alx_hw_err(hw, "1000M half is invalid");
-+ break;
-+ case L1F_GIGA_PSSR_100MBS:
-+ if (giga & L1F_GIGA_PSSR_DPLX)
-+ *speed = ALX_LINK_SPEED_100_FULL;
-+ else
-+ *speed = ALX_LINK_SPEED_100_HALF;
-+ break;
-+ case L1F_GIGA_PSSR_10MBS:
-+ if (giga & L1F_GIGA_PSSR_DPLX)
-+ *speed = ALX_LINK_SPEED_10_FULL;
-+ else
-+ *speed = ALX_LINK_SPEED_10_HALF;
-+ break;
-+ default:
-+ *speed = ALX_LINK_SPEED_UNKNOWN;
-+ retval = -EINVAL;
-+ break;
-+ }
-+ return retval;
-+}
-+
-+
-+/*
-+ * 1. stop_mac
-+ * 2. reset mac & dma by reg1400(MASTER)
-+ * 3. control speed/duplex, hash-alg
-+ * 4. clock switch setting
-+ */
-+static int alf_reset_mac(struct alx_hw *hw)
-+{
-+ int retval = 0;
-+
-+ if (l1f_reset_mac(hw)) {
-+ alx_hw_err(hw, "error when reset mac\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alf_start_mac(struct alx_hw *hw)
-+{
-+ u16 en_ctrl = 0;
-+ int retval = 0;
-+
-+ /* set link speed param */
-+ switch (hw->link_speed) {
-+ case ALX_LINK_SPEED_1GB_FULL:
-+ en_ctrl |= LX_MACSPEED_1000;
-+ /* fall through */
-+ case ALX_LINK_SPEED_100_FULL:
-+ case ALX_LINK_SPEED_10_FULL:
-+ en_ctrl |= LX_MACDUPLEX_FULL;
-+ break;
-+ }
-+
-+ /* set fc param*/
-+ switch (hw->cur_fc_mode) {
-+ case alx_fc_full:
-+ en_ctrl |= LX_FC_RXEN; /* Flow Control RX Enable */
-+ en_ctrl |= LX_FC_TXEN; /* Flow Control TX Enable */
-+ break;
-+ case alx_fc_rx_pause:
-+ en_ctrl |= LX_FC_RXEN; /* Flow Control RX Enable */
-+ break;
-+ case alx_fc_tx_pause:
-+ en_ctrl |= LX_FC_TXEN; /* Flow Control TX Enable */
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (hw->fc_single_pause)
-+ en_ctrl |= LX_SINGLE_PAUSE;
-+
-+ en_ctrl |= LX_FLT_DIRECT; /* RX Enable; and TX Always Enable */
-+ en_ctrl |= LX_FLT_BROADCAST; /* RX Broadcast Enable */
-+ en_ctrl |= LX_ADD_FCS;
-+
-+ if (CHK_HW_FLAG(VLANSTRIP_EN))
-+ en_ctrl |= LX_VLAN_STRIP;
-+
-+ if (CHK_HW_FLAG(PROMISC_EN))
-+ en_ctrl |= LX_FLT_PROMISC;
-+
-+ if (CHK_HW_FLAG(MULTIALL_EN))
-+ en_ctrl |= LX_FLT_MULTI_ALL;
-+
-+ if (CHK_HW_FLAG(LOOPBACK_EN))
-+ en_ctrl |= LX_LOOPBACK;
-+
-+ if (l1f_enable_mac(hw, true, en_ctrl)) {
-+ alx_hw_err(hw, "error when start mac\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+/*
-+ * 1. stop RXQ (reg15A0) and TXQ (reg1590)
-+ * 2. stop MAC (reg1480)
-+ */
-+static int alf_stop_mac(struct alx_hw *hw)
-+{
-+ int retval = 0;
-+
-+ if (l1f_enable_mac(hw, false, 0)) {
-+ alx_hw_err(hw, "error when stop mac\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alf_config_mac(struct alx_hw *hw, u16 rxbuf_sz, u16 rx_qnum,
-+ u16 rxring_sz, u16 tx_qnum, u16 txring_sz)
-+{
-+ u8 *addr;
-+ u32 txmem_hi, txmem_lo[4];
-+ u32 rxmem_hi, rfdmem_lo, rrdmem_lo;
-+ u16 smb_timer, mtu_with_eth, int_mod;
-+ bool hash_legacy;
-+ int i;
-+ int retval = 0;
-+
-+ addr = hw->mac_addr;
-+
-+ txmem_hi = ALX_DMA_ADDR_HI(hw->tpdma[0]);
-+ for (i = 0; i < tx_qnum; i++)
-+ txmem_lo[i] = ALX_DMA_ADDR_LO(hw->tpdma[i]);
-+
-+
-+ rxmem_hi = ALX_DMA_ADDR_HI(hw->rfdma[0]);
-+ rfdmem_lo = ALX_DMA_ADDR_LO(hw->rfdma[0]);
-+ rrdmem_lo = ALX_DMA_ADDR_LO(hw->rrdma[0]);
-+
-+ smb_timer = (u16)hw->smb_timer;
-+ mtu_with_eth = hw->mtu + ALX_ETH_LENGTH_OF_HEADER;
-+ int_mod = hw->imt;
-+
-+ hash_legacy = true;
-+
-+ if (l1f_init_mac(hw, addr, txmem_hi, txmem_lo, tx_qnum, txring_sz,
-+ rxmem_hi, rfdmem_lo, rrdmem_lo, rxring_sz, rxbuf_sz,
-+ smb_timer, mtu_with_eth, int_mod, hash_legacy)) {
-+ alx_hw_err(hw, "error when config mac\n");
-+ retval = -EINVAL;
-+ }
-+
-+ return retval;
-+}
-+
-+
-+/**
-+ * alf_get_mac_addr
-+ * @hw: pointer to hardware structure
-+ **/
-+static int alf_get_mac_addr(struct alx_hw *hw, u8 *addr)
-+{
-+ int retval = 0;
-+
-+ if (l1f_get_perm_macaddr(hw, addr)) {
-+ alx_hw_err(hw, "error when get permanent mac address\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alf_reset_pcie(struct alx_hw *hw, bool l0s_en, bool l1_en)
-+{
-+ int retval = 0;
-+
-+ if (!CHK_HW_FLAG(L0S_CAP))
-+ l0s_en = false;
-+
-+ if (l0s_en)
-+ SET_HW_FLAG(L0S_EN);
-+ else
-+ CLI_HW_FLAG(L0S_EN);
-+
-+
-+ if (!CHK_HW_FLAG(L1_CAP))
-+ l1_en = false;
-+
-+ if (l1_en)
-+ SET_HW_FLAG(L1_EN);
-+ else
-+ CLI_HW_FLAG(L1_EN);
-+
-+ if (l1f_reset_pcie(hw, l0s_en, l1_en)) {
-+ alx_hw_err(hw, "error when reset pcie\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alf_config_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en)
-+{
-+ int retval = 0;
-+
-+ if (!CHK_HW_FLAG(L0S_CAP))
-+ l0s_en = false;
-+
-+ if (l0s_en)
-+ SET_HW_FLAG(L0S_EN);
-+ else
-+ CLI_HW_FLAG(L0S_EN);
-+
-+ if (!CHK_HW_FLAG(L1_CAP))
-+ l1_en = false;
-+
-+ if (l1_en)
-+ SET_HW_FLAG(L1_EN);
-+ else
-+ CLI_HW_FLAG(L1_EN);
-+
-+ if (l1f_enable_aspm(hw, l0s_en, l1_en, 0)) {
-+ alx_hw_err(hw, "error when enable aspm\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alf_config_wol(struct alx_hw *hw, u32 wufc)
-+{
-+ u32 wol;
-+ int retval = 0;
-+
-+ wol = 0;
-+ /* turn on magic packet event */
-+ if (wufc & ALX_WOL_MAGIC) {
-+ wol |= L1F_WOL0_MAGIC_EN | L1F_WOL0_PME_MAGIC_EN;
-+ /* magic packet maybe Broadcast&multicast&Unicast frame */
-+ /* mac |= MAC_CTRL_BC_EN; */
-+ }
-+
-+ /* turn on link up event */
-+ if (wufc & ALX_WOL_PHY) {
-+ wol |= L1F_WOL0_LINK_EN | L1F_WOL0_PME_LINK;
-+ /* only link up can wake up */
-+ retval = alf_write_phy_reg(hw, L1F_MII_IER, L1F_IER_LINK_UP);
-+ }
-+ alx_mem_w32(hw, L1F_WOL0, wol);
-+ return retval;
-+}
-+
-+
-+static int alf_config_mac_ctrl(struct alx_hw *hw)
-+{
-+ u32 mac;
-+
-+ alx_mem_r32(hw, L1F_MAC_CTRL, &mac);
-+
-+ /* enable/disable VLAN tag insert,strip */
-+ if (CHK_HW_FLAG(VLANSTRIP_EN))
-+ mac |= L1F_MAC_CTRL_VLANSTRIP;
-+ else
-+ mac &= ~L1F_MAC_CTRL_VLANSTRIP;
-+
-+ if (CHK_HW_FLAG(PROMISC_EN))
-+ mac |= L1F_MAC_CTRL_PROMISC_EN;
-+ else
-+ mac &= ~L1F_MAC_CTRL_PROMISC_EN;
-+
-+ if (CHK_HW_FLAG(MULTIALL_EN))
-+ mac |= L1F_MAC_CTRL_MULTIALL_EN;
-+ else
-+ mac &= ~L1F_MAC_CTRL_MULTIALL_EN;
-+
-+ if (CHK_HW_FLAG(LOOPBACK_EN))
-+ mac |= L1F_MAC_CTRL_LPBACK_EN;
-+ else
-+ mac &= ~L1F_MAC_CTRL_LPBACK_EN;
-+
-+ alx_mem_w32(hw, L1F_MAC_CTRL, mac);
-+ return 0;
-+}
-+
-+
-+static int alf_config_pow_save(struct alx_hw *hw, u32 speed, bool wol_en,
-+ bool tx_en, bool rx_en, bool pws_en)
-+{
-+ u8 wire_spd = LX_LC_10H;
-+ int retval = 0;
-+
-+ switch (speed) {
-+ case ALX_LINK_SPEED_UNKNOWN:
-+ case ALX_LINK_SPEED_10_HALF:
-+ wire_spd = LX_LC_10H;
-+ break;
-+ case ALX_LINK_SPEED_10_FULL:
-+ wire_spd = LX_LC_10F;
-+ break;
-+ case ALX_LINK_SPEED_100_HALF:
-+ wire_spd = LX_LC_100H;
-+ break;
-+ case ALX_LINK_SPEED_100_FULL:
-+ wire_spd = LX_LC_100F;
-+ break;
-+ case ALX_LINK_SPEED_1GB_FULL:
-+ wire_spd = LX_LC_1000F;
-+ break;
-+ }
-+
-+ if (l1f_powersaving(hw, wire_spd, wol_en, tx_en, rx_en, pws_en)) {
-+ alx_hw_err(hw, "error when set power saving\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+/* RAR, Multicast, VLAN */
-+static int alf_set_mac_addr(struct alx_hw *hw, u8 *addr)
-+{
-+ u32 sta;
-+
-+ /*
-+ * for example: 00-0B-6A-F6-00-DC
-+ * 0<-->6AF600DC, 1<-->000B.
-+ */
-+
-+ /* low dword */
-+ sta = (((u32)addr[2]) << 24) | (((u32)addr[3]) << 16) |
-+ (((u32)addr[4]) << 8) | (((u32)addr[5])) ;
-+ alx_mem_w32(hw, L1F_STAD0, sta);
-+
-+ /* hight dword */
-+ sta = (((u32)addr[0]) << 8) | (((u32)addr[1])) ;
-+ alx_mem_w32(hw, L1F_STAD1, sta);
-+ return 0;
-+}
-+
-+
-+static int alf_set_mc_addr(struct alx_hw *hw, u8 *addr)
-+{
-+ u32 crc32, bit, reg, mta;
-+
-+ /*
-+ * set hash value for a multicast address hash calcu processing.
-+ * 1. calcu 32bit CRC for multicast address
-+ * 2. reverse crc with MSB to LSB
-+ */
-+ crc32 = ALX_ETH_CRC(addr, ALX_ETH_LENGTH_OF_ADDRESS);
-+
-+ /*
-+ * The HASH Table is a register array of 2 32-bit registers.
-+ * It is treated like an array of 64 bits. We want to set
-+ * bit BitArray[hash_value]. So we figure out what register
-+ * the bit is in, read it, OR in the new bit, then write
-+ * back the new value. The register is determined by the
-+ * upper 7 bits of the hash value and the bit within that
-+ * register are determined by the lower 5 bits of the value.
-+ */
-+ reg = (crc32 >> 31) & 0x1;
-+ bit = (crc32 >> 26) & 0x1F;
-+
-+ alx_mem_r32(hw, L1F_HASH_TBL0 + (reg<<2), &mta);
-+ mta |= (0x1 << bit);
-+ alx_mem_w32(hw, L1F_HASH_TBL0 + (reg<<2), mta);
-+ return 0;
-+}
-+
-+
-+static int alf_clear_mc_addr(struct alx_hw *hw)
-+{
-+ alx_mem_w32(hw, L1F_HASH_TBL0, 0);
-+ alx_mem_w32(hw, L1F_HASH_TBL1, 0);
-+ return 0;
-+}
-+
-+
-+/* RTX, IRQ */
-+static int alf_config_tx(struct alx_hw *hw)
-+{
-+ u32 wrr;
-+
-+ alx_mem_r32(hw, L1F_WRR, &wrr);
-+ switch (hw->wrr_mode) {
-+ case alx_wrr_mode_none:
-+ FIELD_SETL(wrr, L1F_WRR_PRI, L1F_WRR_PRI_RESTRICT_NONE);
-+ break;
-+ case alx_wrr_mode_high:
-+ FIELD_SETL(wrr, L1F_WRR_PRI, L1F_WRR_PRI_RESTRICT_HI);
-+ break;
-+ case alx_wrr_mode_high2:
-+ FIELD_SETL(wrr, L1F_WRR_PRI, L1F_WRR_PRI_RESTRICT_HI2);
-+ break;
-+ case alx_wrr_mode_all:
-+ FIELD_SETL(wrr, L1F_WRR_PRI, L1F_WRR_PRI_RESTRICT_ALL);
-+ break;
-+ }
-+ FIELD_SETL(wrr, L1F_WRR_PRI0, hw->wrr_prio0);
-+ FIELD_SETL(wrr, L1F_WRR_PRI1, hw->wrr_prio1);
-+ FIELD_SETL(wrr, L1F_WRR_PRI2, hw->wrr_prio2);
-+ FIELD_SETL(wrr, L1F_WRR_PRI3, hw->wrr_prio3);
-+ alx_mem_w32(hw, L1F_WRR, wrr);
-+ return 0;
-+}
-+
-+
-+static int alf_config_msix(struct alx_hw *hw, u16 num_intrs,
-+ bool msix_en, bool msi_en)
-+{
-+ u32 map[2];
-+ u32 type;
-+ int msix_idx;
-+
-+ if (!msix_en)
-+ goto configure_legacy;
-+
-+ memset(map, 0, sizeof(map));
-+ for (msix_idx = 0; msix_idx < num_intrs; msix_idx++) {
-+ switch (msix_idx) {
-+ case ALF_MSIX_INDEX_RXQ0:
-+ FIELD_SETL(map[0], L1F_MSI_MAP_TBL1_RXQ0,
-+ ALF_MSIX_INDEX_RXQ0);
-+ break;
-+ case ALF_MSIX_INDEX_RXQ1:
-+ FIELD_SETL(map[0], L1F_MSI_MAP_TBL1_RXQ1,
-+ ALF_MSIX_INDEX_RXQ1);
-+ break;
-+ case ALF_MSIX_INDEX_RXQ2:
-+ FIELD_SETL(map[0], L1F_MSI_MAP_TBL1_RXQ2,
-+ ALF_MSIX_INDEX_RXQ2);
-+ break;
-+ case ALF_MSIX_INDEX_RXQ3:
-+ FIELD_SETL(map[0], L1F_MSI_MAP_TBL1_RXQ3,
-+ ALF_MSIX_INDEX_RXQ3);
-+ break;
-+ case ALF_MSIX_INDEX_RXQ4:
-+ FIELD_SETL(map[1], L1F_MSI_MAP_TBL2_RXQ4,
-+ ALF_MSIX_INDEX_RXQ4);
-+ break;
-+ case ALF_MSIX_INDEX_RXQ5:
-+ FIELD_SETL(map[1], L1F_MSI_MAP_TBL2_RXQ5,
-+ ALF_MSIX_INDEX_RXQ5);
-+ break;
-+ case ALF_MSIX_INDEX_RXQ6:
-+ FIELD_SETL(map[1], L1F_MSI_MAP_TBL2_RXQ6,
-+ ALF_MSIX_INDEX_RXQ6);
-+ break;
-+ case ALF_MSIX_INDEX_RXQ7:
-+ FIELD_SETL(map[1], L1F_MSI_MAP_TBL2_RXQ7,
-+ ALF_MSIX_INDEX_RXQ7);
-+ break;
-+ case ALF_MSIX_INDEX_TXQ0:
-+ FIELD_SETL(map[0], L1F_MSI_MAP_TBL1_TXQ0,
-+ ALF_MSIX_INDEX_TXQ0);
-+ break;
-+ case ALF_MSIX_INDEX_TXQ1:
-+ FIELD_SETL(map[0], L1F_MSI_MAP_TBL1_TXQ1,
-+ ALF_MSIX_INDEX_TXQ1);
-+ break;
-+ case ALF_MSIX_INDEX_TXQ2:
-+ FIELD_SETL(map[1], L1F_MSI_MAP_TBL2_TXQ2,
-+ ALF_MSIX_INDEX_TXQ2);
-+ break;
-+ case ALF_MSIX_INDEX_TXQ3:
-+ FIELD_SETL(map[1], L1F_MSI_MAP_TBL2_TXQ3,
-+ ALF_MSIX_INDEX_TXQ3);
-+ break;
-+ case ALF_MSIX_INDEX_TIMER:
-+ FIELD_SETL(map[0], L1F_MSI_MAP_TBL1_TIMER,
-+ ALF_MSIX_INDEX_TIMER);
-+ break;
-+ case ALF_MSIX_INDEX_ALERT:
-+ FIELD_SETL(map[0], L1F_MSI_MAP_TBL1_ALERT,
-+ ALF_MSIX_INDEX_ALERT);
-+ break;
-+ case ALF_MSIX_INDEX_SMB:
-+ FIELD_SETL(map[1], L1F_MSI_MAP_TBL2_SMB,
-+ ALF_MSIX_INDEX_SMB);
-+ break;
-+ case ALF_MSIX_INDEX_PHY:
-+ FIELD_SETL(map[1], L1F_MSI_MAP_TBL2_PHY,
-+ ALF_MSIX_INDEX_PHY);
-+ break;
-+ default:
-+ break;
-+
-+ }
-+
-+ }
-+
-+ alx_mem_w32(hw, L1F_MSI_MAP_TBL1, map[0]);
-+ alx_mem_w32(hw, L1F_MSI_MAP_TBL2, map[1]);
-+
-+ /* 0 to alert, 1 to timer */
-+ type = (L1F_MSI_ID_MAP_DMAW |
-+ L1F_MSI_ID_MAP_DMAR |
-+ L1F_MSI_ID_MAP_PCIELNKDW |
-+ L1F_MSI_ID_MAP_PCIECERR |
-+ L1F_MSI_ID_MAP_PCIENFERR |
-+ L1F_MSI_ID_MAP_PCIEFERR |
-+ L1F_MSI_ID_MAP_PCIEUR);
-+
-+ alx_mem_w32(hw, L1F_MSI_ID_MAP, type);
-+ return 0;
-+
-+configure_legacy:
-+ alx_mem_w32(hw, L1F_MSI_MAP_TBL1, 0x0);
-+ alx_mem_w32(hw, L1F_MSI_MAP_TBL2, 0x0);
-+ alx_mem_w32(hw, L1F_MSI_ID_MAP, 0x0);
-+ if (msi_en) {
-+ u32 msi;
-+ alx_mem_r32(hw, 0x1920, &msi);
-+ msi |= 0x10000;
-+ alx_mem_w32(hw, 0x1920, msi);
-+ }
-+ return 0;
-+}
-+
-+
-+/*
-+ * Interrupt
-+ */
-+static int alf_ack_phy_intr(struct alx_hw *hw)
-+{
-+ u16 isr;
-+ return alf_read_phy_reg(hw, L1F_MII_ISR, &isr);
-+}
-+
-+
-+static int alf_enable_legacy_intr(struct alx_hw *hw)
-+{
-+ u16 cmd;
-+
-+ alx_cfg_r16(hw, PCI_COMMAND, &cmd);
-+ cmd &= ~PCI_COMMAND_INTX_DISABLE;
-+ alx_cfg_w16(hw, PCI_COMMAND, cmd);
-+
-+ alx_mem_w32(hw, L1F_ISR, ~((u32) L1F_ISR_DIS));
-+ alx_mem_w32(hw, L1F_IMR, hw->intr_mask);
-+ return 0;
-+}
-+
-+
-+static int alf_disable_legacy_intr(struct alx_hw *hw)
-+{
-+ alx_mem_w32(hw, L1F_ISR, L1F_ISR_DIS);
-+ alx_mem_w32(hw, L1F_IMR, 0);
-+ alx_mem_flush(hw);
-+ return 0;
-+}
-+
-+
-+static int alf_enable_msix_intr(struct alx_hw *hw, u8 entry_idx)
-+{
-+ u32 ctrl_reg;
-+
-+ ctrl_reg = ALF_MSIX_ENTRY_BASE + (entry_idx * ALF_MSIX_ENTRY_SIZE) +
-+ ALF_MSIX_MSG_CTRL_OFF;
-+
-+ alx_mem_w32(hw, ctrl_reg, 0x0);
-+ alx_mem_flush(hw);
-+ return 0;
-+}
-+
-+
-+static int alf_disable_msix_intr(struct alx_hw *hw, u8 entry_idx)
-+{
-+ u32 ctrl_reg;
-+
-+ ctrl_reg = ALF_MSIX_ENTRY_BASE + (entry_idx * ALF_MSIX_ENTRY_SIZE) +
-+ ALF_MSIX_MSG_CTRL_OFF;
-+
-+ alx_mem_w32(hw, ctrl_reg, 0x1);
-+ alx_mem_flush(hw);
-+ return 0;
-+}
-+
-+
-+/* RSS */
-+static int alf_config_rss(struct alx_hw *hw, bool rss_en)
-+{
-+ int key_len_by_u8 = sizeof(hw->rss_key);
-+ int idt_len_by_u32 = sizeof(hw->rss_idt) / sizeof(u32);
-+ u32 rxq0;
-+ int i;
-+
-+ /* Fill out hash function keys */
-+ for (i = 0; i < key_len_by_u8; i++) {
-+ alx_mem_w8(hw, ALF_RSS_KEY(i, u8),
-+ hw->rss_key[key_len_by_u8 - i - 1]);
-+ }
-+
-+ /* Fill out redirection table */
-+ for (i = 0; i < idt_len_by_u32; i++)
-+ alx_mem_w32(hw, ALF_RSS_TBL(i, u32), hw->rss_idt[i]);
-+
-+ alx_mem_w32(hw, L1F_RSS_BASE_CPU_NUM, hw->rss_base_cpu);
-+
-+ alx_mem_r32(hw, L1F_RXQ0, &rxq0);
-+ if (hw->rss_hstype & ALX_RSS_HSTYP_IPV4_EN)
-+ rxq0 |= L1F_RXQ0_RSS_HSTYP_IPV4_EN;
-+ else
-+ rxq0 &= ~L1F_RXQ0_RSS_HSTYP_IPV4_EN;
-+
-+ if (hw->rss_hstype & ALX_RSS_HSTYP_TCP4_EN)
-+ rxq0 |= L1F_RXQ0_RSS_HSTYP_IPV4_TCP_EN;
-+ else
-+ rxq0 &= ~L1F_RXQ0_RSS_HSTYP_IPV4_TCP_EN;
-+
-+ if (hw->rss_hstype & ALX_RSS_HSTYP_IPV6_EN)
-+ rxq0 |= L1F_RXQ0_RSS_HSTYP_IPV6_EN;
-+ else
-+ rxq0 &= ~L1F_RXQ0_RSS_HSTYP_IPV6_EN;
-+
-+ if (hw->rss_hstype & ALX_RSS_HSTYP_TCP6_EN)
-+ rxq0 |= L1F_RXQ0_RSS_HSTYP_IPV6_TCP_EN;
-+ else
-+ rxq0 &= ~L1F_RXQ0_RSS_HSTYP_IPV6_TCP_EN;
-+
-+ FIELD_SETL(rxq0, L1F_RXQ0_RSS_MODE, hw->rss_mode);
-+ FIELD_SETL(rxq0, L1F_RXQ0_IDT_TBL_SIZE, hw->rss_idt_size);
-+
-+ if (rss_en)
-+ rxq0 |= L1F_RXQ0_RSS_HASH_EN;
-+ else
-+ rxq0 &= ~L1F_RXQ0_RSS_HASH_EN;
-+
-+ alx_mem_w32(hw, L1F_RXQ0, rxq0);
-+ return 0;
-+}
-+
-+
-+/* fc */
-+static int alf_get_fc_mode(struct alx_hw *hw, enum alx_fc_mode *mode)
-+{
-+ u16 bmsr, giga;
-+ int i;
-+ int retval = 0;
-+
-+ for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) {
-+ alf_read_phy_reg(hw, MII_BMSR, &bmsr);
-+ alf_read_phy_reg(hw, MII_BMSR, &bmsr);
-+ if (bmsr & BMSR_LSTATUS) {
-+ /* Read phy Specific Status Register (17) */
-+ retval = alf_read_phy_reg(hw, L1F_MII_GIGA_PSSR, &giga);
-+ if (retval)
-+ return retval;
-+
-+ if (!(giga & L1F_GIGA_PSSR_SPD_DPLX_RESOLVED)) {
-+ alx_hw_err(hw,
-+ "error for speed duplex resolved\n");
-+ return -EINVAL;
-+ }
-+
-+ if ((giga & L1F_GIGA_PSSR_FC_TXEN) &&
-+ (giga & L1F_GIGA_PSSR_FC_RXEN)) {
-+ *mode = alx_fc_full;
-+ } else if (giga & L1F_GIGA_PSSR_FC_TXEN) {
-+ *mode = alx_fc_tx_pause;
-+ } else if (giga & L1F_GIGA_PSSR_FC_RXEN) {
-+ *mode = alx_fc_rx_pause;
-+ } else {
-+ *mode = alx_fc_none;
-+ }
-+ break;
-+ }
-+ mdelay(100);
-+ }
-+
-+ if (i == ALX_MAX_SETUP_LNK_CYCLE) {
-+ alx_hw_err(hw, "error when get flow control mode\n");
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+
-+static int alf_config_fc(struct alx_hw *hw)
-+{
-+ u32 mac;
-+ int retval = 0;
-+
-+ if (hw->disable_fc_autoneg) {
-+ hw->fc_was_autonegged = false;
-+ hw->cur_fc_mode = hw->req_fc_mode;
-+ } else {
-+ hw->fc_was_autonegged = true;
-+ retval = alf_get_fc_mode(hw, &hw->cur_fc_mode);
-+ if (retval)
-+ return retval;
-+ }
-+
-+ alx_mem_r32(hw, L1F_MAC_CTRL, &mac);
-+
-+ switch (hw->cur_fc_mode) {
-+ case alx_fc_none: /* 0 */
-+ mac &= ~(L1F_MAC_CTRL_RXFC_EN | L1F_MAC_CTRL_TXFC_EN);
-+ break;
-+ case alx_fc_rx_pause: /* 1 */
-+ mac &= ~L1F_MAC_CTRL_TXFC_EN;
-+ mac |= L1F_MAC_CTRL_RXFC_EN;
-+ break;
-+ case alx_fc_tx_pause: /* 2 */
-+ mac |= L1F_MAC_CTRL_TXFC_EN;
-+ mac &= ~L1F_MAC_CTRL_RXFC_EN;
-+ break;
-+ case alx_fc_full: /* 3 */
-+ case alx_fc_default: /* 4 */
-+ mac |= (L1F_MAC_CTRL_TXFC_EN | L1F_MAC_CTRL_RXFC_EN);
-+ break;
-+ default:
-+ alx_hw_err(hw, "flow control param set incorrectly\n");
-+ return -EINVAL;
-+ break;
-+ }
-+
-+ alx_mem_w32(hw, L1F_MAC_CTRL, mac);
-+
-+ return retval;
-+}
-+
-+
-+/*
-+ * NVRam
-+ */
-+static int alf_check_nvram(struct alx_hw *hw, bool *exist)
-+{
-+ *exist = false;
-+ return 0;
-+}
-+
-+
-+/* ethtool */
-+static int alf_get_ethtool_regs(struct alx_hw *hw, void *buff)
-+{
-+ int i;
-+ u32 *val = buff;
-+ static const u32 reg[] = {
-+ /* 0 */
-+ L1F_DEV_CAP, L1F_DEV_CTRL, L1F_LNK_CAP, L1F_LNK_CTRL,
-+ L1F_UE_SVRT, L1F_EFLD, L1F_SLD, L1F_PPHY_MISC1,
-+ L1F_PPHY_MISC2, L1F_PDLL_TRNS1,
-+
-+ /* 10 */
-+ L1F_TLEXTN_STATS, L1F_EFUSE_CTRL, L1F_EFUSE_DATA, L1F_SPI_OP1,
-+ L1F_SPI_OP2, L1F_SPI_OP3, L1F_EF_CTRL, L1F_EF_ADDR,
-+ L1F_EF_DATA, L1F_SPI_ID,
-+
-+ /* 20 */
-+ L1F_SPI_CFG_START, L1F_PMCTRL, L1F_LTSSM_CTRL, L1F_MASTER,
-+ L1F_MANU_TIMER, L1F_IRQ_MODU_TIMER, L1F_PHY_CTRL, L1F_MAC_STS,
-+ L1F_MDIO, L1F_MDIO_EXTN,
-+
-+ /* 30 */
-+ L1F_PHY_STS, L1F_BIST0, L1F_BIST1, L1F_SERDES,
-+ L1F_LED_CTRL, L1F_LED_PATN, L1F_LED_PATN2, L1F_SYSALV,
-+ L1F_PCIERR_INST, L1F_LPI_DECISN_TIMER,
-+
-+ /* 40 */
-+ L1F_LPI_CTRL, L1F_LPI_WAIT, L1F_HRTBT_VLAN, L1F_HRTBT_CTRL,
-+ L1F_RXPARSE, L1F_MAC_CTRL, L1F_GAP, L1F_STAD1,
-+ L1F_LED_CTRL, L1F_HASH_TBL0,
-+
-+ /* 50 */
-+ L1F_HASH_TBL1, L1F_HALFD, L1F_DMA, L1F_WOL0,
-+ L1F_WOL1, L1F_WOL2, L1F_WRR, L1F_HQTPD,
-+ L1F_CPUMAP1, L1F_CPUMAP2,
-+
-+ /* 60 */
-+ L1F_MISC, L1F_RX_BASE_ADDR_HI, L1F_RFD_ADDR_LO, L1F_RFD_RING_SZ,
-+ L1F_RFD_BUF_SZ, L1F_RRD_ADDR_LO, L1F_RRD_RING_SZ,
-+ L1F_RFD_PIDX, L1F_RFD_CIDX, L1F_RXQ0,
-+
-+ /* 70 */
-+ L1F_RXQ1, L1F_RXQ2, L1F_RXQ3, L1F_TX_BASE_ADDR_HI,
-+ L1F_TPD_PRI0_ADDR_LO, L1F_TPD_PRI1_ADDR_LO,
-+ L1F_TPD_PRI2_ADDR_LO, L1F_TPD_PRI3_ADDR_LO,
-+ L1F_TPD_PRI0_PIDX, L1F_TPD_PRI1_PIDX,
-+
-+ /* 80 */
-+ L1F_TPD_PRI2_PIDX, L1F_TPD_PRI3_PIDX, L1F_TPD_PRI0_CIDX,
-+ L1F_TPD_PRI1_CIDX, L1F_TPD_PRI2_CIDX, L1F_TPD_PRI3_CIDX,
-+ L1F_TPD_RING_SZ, L1F_TXQ0, L1F_TXQ1, L1F_TXQ2,
-+
-+ /* 90 */
-+ L1F_MSI_MAP_TBL1, L1F_MSI_MAP_TBL2, L1F_MSI_ID_MAP,
-+ L1F_MSIX_MASK, L1F_MSIX_PENDING,
-+ };
-+
-+ for (i = 0; i < ARRAY_SIZE(reg); i++)
-+ alx_mem_r32(hw, reg[i], &val[i]);
-+
-+ /* SRAM */
-+ for (i = 0; i < 16; i++)
-+ alx_mem_r32(hw, ALF_SRAM(i, u32), &val[100 + i]);
-+
-+ /* RSS */
-+ for (i = 0; i < 10; i++)
-+ alx_mem_r32(hw, ALF_RSS_KEY(i, u32), &val[120 + i]);
-+ for (i = 0; i < 32; i++)
-+ alx_mem_r32(hw, ALF_RSS_TBL(i, u32), &val[130 + i]);
-+ alx_mem_r32(hw, L1F_RSS_HASH_VAL, &val[162]);
-+ alx_mem_r32(hw, L1F_RSS_HASH_FLAG, &val[163]);
-+ alx_mem_r32(hw, L1F_RSS_BASE_CPU_NUM, &val[164]);
-+
-+ /* MIB */
-+ for (i = 0; i < 48; i++)
-+ alx_mem_r32(hw, ALF_MIB(i, u32), &val[170 + i]);
-+ return 0;
-+}
-+
-+
-+/******************************************************************************/
-+static int alf_set_hw_capabilities(struct alx_hw *hw)
-+{
-+ SET_HW_FLAG(L0S_CAP);
-+ SET_HW_FLAG(L1_CAP);
-+
-+ if (hw->mac_type == alx_mac_l1f)
-+ SET_HW_FLAG(GIGA_CAP);
-+
-+ /* set flags of alx_phy_info */
-+ SET_HW_FLAG(PWSAVE_CAP);
-+ return 0;
-+}
-+
-+
-+/* alc_set_hw_info */
-+static int alf_set_hw_infos(struct alx_hw *hw)
-+{
-+ hw->rxstat_reg = L1F_MIB_RX_OK;
-+ hw->rxstat_sz = 0x60;
-+ hw->txstat_reg = L1F_MIB_TX_OK;
-+ hw->txstat_sz = 0x68;
-+
-+ hw->rx_prod_reg[0] = L1F_RFD_PIDX;
-+ hw->rx_cons_reg[0] = L1F_RFD_CIDX;
-+
-+ hw->tx_prod_reg[0] = L1F_TPD_PRI0_PIDX;
-+ hw->tx_cons_reg[0] = L1F_TPD_PRI0_CIDX;
-+ hw->tx_prod_reg[1] = L1F_TPD_PRI1_PIDX;
-+ hw->tx_cons_reg[1] = L1F_TPD_PRI1_CIDX;
-+ hw->tx_prod_reg[2] = L1F_TPD_PRI2_PIDX;
-+ hw->tx_cons_reg[2] = L1F_TPD_PRI2_CIDX;
-+ hw->tx_prod_reg[3] = L1F_TPD_PRI3_PIDX;
-+ hw->tx_cons_reg[3] = L1F_TPD_PRI3_CIDX;
-+
-+ hw->hwreg_sz = 0x200;
-+ hw->eeprom_sz = 0;
-+
-+ return 0;
-+}
-+
-+
-+/*
-+ * alf_init_hw_callbacks
-+ */
-+int alf_init_hw_callbacks(struct alx_hw *hw)
-+{
-+ /* NIC */
-+ hw->cbs.identify_nic = &alf_identify_nic;
-+ /* MAC */
-+ hw->cbs.reset_mac = &alf_reset_mac;
-+ hw->cbs.start_mac = &alf_start_mac;
-+ hw->cbs.stop_mac = &alf_stop_mac;
-+ hw->cbs.config_mac = &alf_config_mac;
-+ hw->cbs.get_mac_addr = &alf_get_mac_addr;
-+ hw->cbs.set_mac_addr = &alf_set_mac_addr;
-+ hw->cbs.set_mc_addr = &alf_set_mc_addr;
-+ hw->cbs.clear_mc_addr = &alf_clear_mc_addr;
-+
-+ /* PHY */
-+ hw->cbs.init_phy = &alf_init_phy;
-+ hw->cbs.reset_phy = &alf_reset_phy;
-+ hw->cbs.read_phy_reg = &alf_read_phy_reg;
-+ hw->cbs.write_phy_reg = &alf_write_phy_reg;
-+ hw->cbs.check_phy_link = &alf_check_phy_link;
-+ hw->cbs.setup_phy_link = &alf_setup_phy_link;
-+ hw->cbs.setup_phy_link_speed = &alf_setup_phy_link_speed;
-+
-+ /* Interrupt */
-+ hw->cbs.ack_phy_intr = &alf_ack_phy_intr;
-+ hw->cbs.enable_legacy_intr = &alf_enable_legacy_intr;
-+ hw->cbs.disable_legacy_intr = &alf_disable_legacy_intr;
-+ hw->cbs.enable_msix_intr = &alf_enable_msix_intr;
-+ hw->cbs.disable_msix_intr = &alf_disable_msix_intr;
-+
-+ /* Configure */
-+ hw->cbs.config_tx = &alf_config_tx;
-+ hw->cbs.config_fc = &alf_config_fc;
-+ hw->cbs.config_rss = &alf_config_rss;
-+ hw->cbs.config_msix = &alf_config_msix;
-+ hw->cbs.config_wol = &alf_config_wol;
-+ hw->cbs.config_aspm = &alf_config_aspm;
-+ hw->cbs.config_mac_ctrl = &alf_config_mac_ctrl;
-+ hw->cbs.config_pow_save = &alf_config_pow_save;
-+ hw->cbs.reset_pcie = &alf_reset_pcie;
-+
-+ /* NVRam */
-+ hw->cbs.check_nvram = &alf_check_nvram;
-+
-+ /* Others */
-+ hw->cbs.get_ethtool_regs = alf_get_ethtool_regs;
-+
-+ alf_set_hw_capabilities(hw);
-+ alf_set_hw_infos(hw);
-+
-+ alx_hw_info(hw, "HW Flags = 0x%x\n", hw->flags);
-+ return 0;
-+}
-+
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alf_hw.c
-@@ -0,0 +1,918 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/pci_regs.h>
-+#include <linux/mii.h>
-+
-+#include "alf_hw.h"
-+
-+
-+/* get permanent mac address from
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1f_get_perm_macaddr(struct alx_hw *hw, u8 *addr)
-+{
-+ u32 val, mac0, mac1;
-+ u16 flag, i;
-+
-+#define INTN_LOADED 0x1
-+#define EXTN_LOADED 0x2
-+
-+ flag = 0;
-+ val = 0;
-+
-+read_mcadr:
-+
-+ /* get it from register first */
-+ alx_mem_r32(hw, L1F_STAD0, &mac0);
-+ alx_mem_r32(hw, L1F_STAD1, &mac1);
-+
-+ *(u32 *)(addr + 2) = LX_SWAP_DW(mac0);
-+ *(u16 *)addr = (u16)LX_SWAP_W((u16)mac1);
-+
-+ if (macaddr_valid(addr))
-+ return 0;
-+
-+ if ((flag & INTN_LOADED) == 0) {
-+ /* load from efuse ? */
-+ for (i = 0; i < L1F_SLD_MAX_TO; i++) {
-+ alx_mem_r32(hw, L1F_SLD, &val);
-+ if ((val & (L1F_SLD_STAT | L1F_SLD_START)) == 0)
-+ break;
-+ mdelay(1);
-+ }
-+ if (i == L1F_SLD_MAX_TO)
-+ goto out;
-+ alx_mem_w32(hw, L1F_SLD, val | L1F_SLD_START);
-+ for (i = 0; i < L1F_SLD_MAX_TO; i++) {
-+ mdelay(1);
-+ alx_mem_r32(hw, L1F_SLD, &val);
-+ if ((val & L1F_SLD_START) == 0)
-+ break;
-+ }
-+ if (i == L1F_SLD_MAX_TO)
-+ goto out;
-+ flag |= INTN_LOADED;
-+ goto read_mcadr;
-+ }
-+
-+ if ((flag & EXTN_LOADED) == 0) {
-+ alx_mem_r32(hw, L1F_EFLD, &val);
-+ if ((val & (L1F_EFLD_F_EXIST | L1F_EFLD_E_EXIST)) != 0) {
-+ /* load from eeprom/flash ? */
-+ for (i = 0; i < L1F_SLD_MAX_TO; i++) {
-+ alx_mem_r32(hw, L1F_EFLD, &val);
-+ if ((val & (L1F_EFLD_STAT |
-+ L1F_EFLD_START)) == 0) {
-+ break;
-+ }
-+ mdelay(1);
-+ }
-+ if (i == L1F_SLD_MAX_TO)
-+ goto out;
-+ alx_mem_w32(hw, L1F_EFLD, val | L1F_EFLD_START);
-+ for (i = 0; i < L1F_SLD_MAX_TO; i++) {
-+ mdelay(1);
-+ alx_mem_r32(hw, L1F_EFLD, &val);
-+ if ((val & L1F_EFLD_START) == 0)
-+ break;
-+ }
-+ if (i == L1F_SLD_MAX_TO)
-+ goto out;
-+ flag |= EXTN_LOADED;
-+ goto read_mcadr;
-+ }
-+ }
-+
-+out:
-+ return LX_ERR_ALOAD;
-+}
-+
-+
-+/* reset mac & dma
-+ * return
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1f_reset_mac(struct alx_hw *hw)
-+{
-+ u32 val, pmctrl = 0;
-+ u16 ret;
-+ u16 i;
-+ u8 rev = (u8)(FIELD_GETX(hw->pci_revid, L1F_PCI_REVID));
-+
-+ /* disable all interrupts, RXQ/TXQ */
-+ alx_mem_w32(hw, L1F_MSIX_MASK, BIT_ALL); /* ???? msi-x */
-+ alx_mem_w32(hw, L1F_IMR, 0);
-+ alx_mem_w32(hw, L1F_ISR, L1F_ISR_DIS);
-+
-+ ret = l1f_enable_mac(hw, false, 0);
-+ if (ret != 0)
-+ return ret;
-+
-+ /* mac reset workaroud */
-+ alx_mem_w32(hw, L1F_RFD_PIDX, 1);
-+
-+ /* dis l0s/l1 before mac reset */
-+ if ((rev == L1F_REV_A0 || rev == L1F_REV_A1) &&
-+ (hw->pci_revid & L1F_PCI_REVID_WTH_CR) != 0) {
-+ alx_mem_r32(hw, L1F_PMCTRL, &pmctrl);
-+ if ((pmctrl & (L1F_PMCTRL_L1_EN | L1F_PMCTRL_L0S_EN)) != 0) {
-+ alx_mem_w32(hw, L1F_PMCTRL,
-+ pmctrl & ~(L1F_PMCTRL_L1_EN |
-+ L1F_PMCTRL_L0S_EN));
-+ }
-+ }
-+
-+ /* reset whole mac safely */
-+ alx_mem_r32(hw, L1F_MASTER, &val);
-+ alx_mem_w32(hw, L1F_MASTER,
-+ val | L1F_MASTER_DMA_MAC_RST | L1F_MASTER_OOB_DIS);
-+
-+ /* make sure it's real idle */
-+ udelay(10);
-+ for (i = 0; i < L1F_DMA_MAC_RST_TO; i++) {
-+ alx_mem_r32(hw, L1F_RFD_PIDX, &val);
-+ if (val == 0)
-+ break;
-+ udelay(10);
-+ }
-+ for (; i < L1F_DMA_MAC_RST_TO; i++) {
-+ alx_mem_r32(hw, L1F_MASTER, &val);
-+ if ((val & L1F_MASTER_DMA_MAC_RST) == 0)
-+ break;
-+ udelay(10);
-+ }
-+ if (i == L1F_DMA_MAC_RST_TO)
-+ return LX_ERR_RSTMAC;
-+ udelay(10);
-+
-+ if ((rev == L1F_REV_A0 || rev == L1F_REV_A1) &&
-+ (hw->pci_revid & L1F_PCI_REVID_WTH_CR) != 0) {
-+ /* set L1F_MASTER_PCLKSEL_SRDS (affect by soft-rst, PERST) */
-+ alx_mem_w32(hw, L1F_MASTER, val | L1F_MASTER_PCLKSEL_SRDS);
-+ /* resoter l0s / l1 */
-+ if ((pmctrl & (L1F_PMCTRL_L1_EN | L1F_PMCTRL_L0S_EN)) != 0)
-+ alx_mem_w32(hw, L1F_PMCTRL, pmctrl);
-+ }
-+
-+ /* clear Internal OSC settings, switching OSC by hw itself,
-+ * disable isoloate for A0 */
-+ alx_mem_r32(hw, L1F_MISC3, &val);
-+ alx_mem_w32(hw, L1F_MISC3,
-+ (val & ~L1F_MISC3_25M_BY_SW) | L1F_MISC3_25M_NOTO_INTNL);
-+ alx_mem_r32(hw, L1F_MISC, &val);
-+ val &= ~L1F_MISC_INTNLOSC_OPEN;
-+ if (rev == L1F_REV_A0 || rev == L1F_REV_A1)
-+ val &= ~L1F_MISC_ISO_EN;
-+ alx_mem_w32(hw, L1F_MISC, val);
-+ udelay(20);
-+
-+ /* driver control speed/duplex, hash-alg */
-+ alx_mem_r32(hw, L1F_MAC_CTRL, &val);
-+ alx_mem_w32(hw, L1F_MAC_CTRL, val | L1F_MAC_CTRL_WOLSPED_SWEN);
-+
-+ /* clk sw */
-+ alx_mem_r32(hw, L1F_SERDES, &val);
-+ alx_mem_w32(hw, L1F_SERDES,
-+ val | L1F_SERDES_MACCLK_SLWDWN | L1F_SERDES_PHYCLK_SLWDWN);
-+
-+ return 0;
-+}
-+
-+/* reset phy
-+ * return
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1f_reset_phy(struct alx_hw *hw, bool pws_en, bool az_en, bool ptp_en)
-+{
-+ u32 val;
-+ u16 i, phy_val;
-+
-+ az_en = az_en;
-+ ptp_en = ptp_en;
-+
-+ /* reset PHY core */
-+ alx_mem_r32(hw, L1F_PHY_CTRL, &val);
-+ val &= ~(L1F_PHY_CTRL_DSPRST_OUT | L1F_PHY_CTRL_IDDQ |
-+ L1F_PHY_CTRL_GATE_25M | L1F_PHY_CTRL_POWER_DOWN |
-+ L1F_PHY_CTRL_CLS);
-+ val |= L1F_PHY_CTRL_RST_ANALOG;
-+
-+ if (pws_en)
-+ val |= (L1F_PHY_CTRL_HIB_PULSE | L1F_PHY_CTRL_HIB_EN);
-+ else
-+ val &= ~(L1F_PHY_CTRL_HIB_PULSE | L1F_PHY_CTRL_HIB_EN);
-+ alx_mem_w32(hw, L1F_PHY_CTRL, val);
-+ udelay(10); /* 5us is enough */
-+ alx_mem_w32(hw, L1F_PHY_CTRL, val | L1F_PHY_CTRL_DSPRST_OUT);
-+
-+ for (i = 0; i < L1F_PHY_CTRL_DSPRST_TO; i++) { /* delay 800us */
-+ udelay(10);
-+ }
-+
-+ /* ???? phy power saving */
-+
-+ l1f_write_phydbg(hw, true,
-+ L1F_MIIDBG_TST10BTCFG, L1F_TST10BTCFG_DEF);
-+ l1f_write_phydbg(hw, true, L1F_MIIDBG_SRDSYSMOD, L1F_SRDSYSMOD_DEF);
-+ l1f_write_phydbg(hw, true,
-+ L1F_MIIDBG_TST100BTCFG, L1F_TST100BTCFG_DEF);
-+ l1f_write_phydbg(hw, true, L1F_MIIDBG_ANACTRL, L1F_ANACTRL_DEF);
-+ l1f_read_phydbg(hw, true, L1F_MIIDBG_GREENCFG2, &phy_val);
-+ l1f_write_phydbg(hw, true, L1F_MIIDBG_GREENCFG2,
-+ phy_val & ~L1F_GREENCFG2_GATE_DFSE_EN);
-+ /* rtl8139c, 120m */
-+ l1f_write_phy(hw, true, L1F_MIIEXT_ANEG, true,
-+ L1F_MIIEXT_NLP78, L1F_MIIEXT_NLP78_120M_DEF);
-+
-+ /* set phy interrupt mask */
-+ l1f_write_phy(hw, false, 0, true,
-+ L1F_MII_IER, L1F_IER_LINK_UP | L1F_IER_LINK_DOWN);
-+
-+
-+ /* TODO *****???? */
-+ return 0;
-+}
-+
-+
-+/* reset pcie
-+ * just reset pcie relative registers (pci command, clk, aspm...)
-+ * return
-+ * 0:success
-+ * non-0:fail
-+ */
-+u16 l1f_reset_pcie(struct alx_hw *hw, bool l0s_en, bool l1_en)
-+{
-+ u32 val;
-+ u16 val16;
-+ u16 ret;
-+ u8 rev = (u8)(FIELD_GETX(hw->pci_revid, L1F_PCI_REVID));
-+
-+ /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */
-+ alx_cfg_r16(hw, PCI_COMMAND, &val16);
-+ if ((val16 & (PCI_COMMAND_IO |
-+ PCI_COMMAND_MEMORY |
-+ PCI_COMMAND_MASTER)) == 0 ||
-+ (val16 & PCI_COMMAND_INTX_DISABLE) != 0) {
-+ val16 = (u16)((val16 | (PCI_COMMAND_IO |
-+ PCI_COMMAND_MEMORY |
-+ PCI_COMMAND_MASTER))
-+ & ~PCI_COMMAND_INTX_DISABLE);
-+ alx_cfg_w16(hw, PCI_COMMAND, val16);
-+ }
-+
-+ /* Clear any PowerSaving Settings */
-+ alx_cfg_w16(hw, L1F_PM_CSR, 0);
-+
-+ /* deflt val of PDLL D3PLLOFF */
-+ alx_mem_r32(hw, L1F_PDLL_TRNS1, &val);
-+ alx_mem_w32(hw, L1F_PDLL_TRNS1, val & ~L1F_PDLL_TRNS1_D3PLLOFF_EN);
-+
-+ /* mask some pcie error bits */
-+ alx_mem_r32(hw, L1F_UE_SVRT, &val);
-+ val &= ~(L1F_UE_SVRT_DLPROTERR | L1F_UE_SVRT_FCPROTERR);
-+ alx_mem_w32(hw, L1F_UE_SVRT, val);
-+
-+ /* wol 25M & pclk */
-+ alx_mem_r32(hw, L1F_MASTER, &val);
-+ if ((rev == L1F_REV_A0 || rev == L1F_REV_A1) &&
-+ (hw->pci_revid & L1F_PCI_REVID_WTH_CR) != 0) {
-+ if ((val & L1F_MASTER_WAKEN_25M) == 0 ||
-+ (val & L1F_MASTER_PCLKSEL_SRDS) == 0) {
-+ alx_mem_w32(hw, L1F_MASTER,
-+ val | L1F_MASTER_PCLKSEL_SRDS |
-+ L1F_MASTER_WAKEN_25M);
-+ }
-+ } else {
-+ if ((val & L1F_MASTER_WAKEN_25M) == 0 ||
-+ (val & L1F_MASTER_PCLKSEL_SRDS) != 0) {
-+ alx_mem_w32(hw, L1F_MASTER,
-+ (val & ~L1F_MASTER_PCLKSEL_SRDS) |
-+ L1F_MASTER_WAKEN_25M);
-+ }
-+ }
-+
-+ /* l0s, l1 setting */
-+ ret = l1f_enable_aspm(hw, l0s_en, l1_en, 0);
-+
-+ udelay(10);
-+
-+ return ret;
-+}
-+
-+
-+/* disable/enable MAC/RXQ/TXQ
-+ * en
-+ * true:enable
-+ * false:disable
-+ * return
-+ * 0:success
-+ * non-0-fail
-+ */
-+u16 l1f_enable_mac(struct alx_hw *hw, bool en, u16 en_ctrl)
-+{
-+ u32 rxq, txq, mac, val;
-+ u16 i;
-+
-+ alx_mem_r32(hw, L1F_RXQ0, &rxq);
-+ alx_mem_r32(hw, L1F_TXQ0, &txq);
-+ alx_mem_r32(hw, L1F_MAC_CTRL, &mac);
-+
-+ if (en) { /* enable */
-+ alx_mem_w32(hw, L1F_RXQ0, rxq | L1F_RXQ0_EN);
-+ alx_mem_w32(hw, L1F_TXQ0, txq | L1F_TXQ0_EN);
-+ if ((en_ctrl & LX_MACSPEED_1000) != 0) {
-+ FIELD_SETL(mac, L1F_MAC_CTRL_SPEED,
-+ L1F_MAC_CTRL_SPEED_1000);
-+ } else {
-+ FIELD_SETL(mac, L1F_MAC_CTRL_SPEED,
-+ L1F_MAC_CTRL_SPEED_10_100);
-+ }
-+
-+ test_set_or_clear(mac, en_ctrl, LX_MACDUPLEX_FULL,
-+ L1F_MAC_CTRL_FULLD);
-+ /* rx filter */
-+ test_set_or_clear(mac, en_ctrl, LX_FLT_PROMISC,
-+ L1F_MAC_CTRL_PROMISC_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_FLT_MULTI_ALL,
-+ L1F_MAC_CTRL_MULTIALL_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_FLT_BROADCAST,
-+ L1F_MAC_CTRL_BRD_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_FLT_DIRECT,
-+ L1F_MAC_CTRL_RX_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_FC_TXEN,
-+ L1F_MAC_CTRL_TXFC_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_FC_RXEN,
-+ L1F_MAC_CTRL_RXFC_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_VLAN_STRIP,
-+ L1F_MAC_CTRL_VLANSTRIP);
-+ test_set_or_clear(mac, en_ctrl, LX_LOOPBACK,
-+ L1F_MAC_CTRL_LPBACK_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_SINGLE_PAUSE,
-+ L1F_MAC_CTRL_SPAUSE_EN);
-+ test_set_or_clear(mac, en_ctrl, LX_ADD_FCS,
-+ (L1F_MAC_CTRL_PCRCE | L1F_MAC_CTRL_CRCE));
-+
-+ alx_mem_w32(hw, L1F_MAC_CTRL, mac | L1F_MAC_CTRL_TX_EN);
-+ } else { /* disable mac */
-+ alx_mem_w32(hw, L1F_RXQ0, rxq & ~L1F_RXQ0_EN);
-+ alx_mem_w32(hw, L1F_TXQ0, txq & ~L1F_TXQ0_EN);
-+
-+ /* waiting for rxq/txq be idle */
-+ udelay(40);
-+
-+ /* stop mac tx/rx */
-+ alx_mem_w32(hw, L1F_MAC_CTRL,
-+ mac & ~(L1F_MAC_CTRL_RX_EN | L1F_MAC_CTRL_TX_EN));
-+
-+ for (i = 0; i < L1F_DMA_MAC_RST_TO; i++) {
-+ alx_mem_r32(hw, L1F_MAC_STS, &val);
-+ if ((val & L1F_MAC_STS_IDLE) == 0)
-+ break;
-+ udelay(10);
-+ }
-+ if (L1F_DMA_MAC_RST_TO == i)
-+ return LX_ERR_RSTMAC;
-+ }
-+
-+ return 0;
-+}
-+
-+/* enable/disable aspm support
-+ * that will change settings for phy/mac/pcie
-+ */
-+u16 l1f_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en, u8 lnk_stat)
-+{
-+ u32 pmctrl;
-+ u8 rev = (u8)(FIELD_GETX(hw->pci_revid, L1F_PCI_REVID));
-+
-+ lnk_stat = lnk_stat;
-+
-+
-+ alx_mem_r32(hw, L1F_PMCTRL, &pmctrl);
-+
-+ /* ????default */
-+ FIELD_SETL(pmctrl, L1F_PMCTRL_LCKDET_TIMER,
-+ L1F_PMCTRL_LCKDET_TIMER_DEF);
-+ pmctrl |= L1F_PMCTRL_RCVR_WT_1US | /* wait 1us */
-+ L1F_PMCTRL_L1_CLKSW_EN | /* pcie clk sw */
-+ L1F_PMCTRL_L1_SRDSRX_PWD ; /* pwd serdes ????default */
-+ /* ????default */
-+ FIELD_SETL(pmctrl, L1F_PMCTRL_L1REQ_TO, L1F_PMCTRL_L1REG_TO_DEF);
-+ FIELD_SETL(pmctrl, L1F_PMCTRL_L1_TIMER, L1F_PMCTRL_L1_TIMER_16US);
-+ pmctrl &= ~(L1F_PMCTRL_L1_SRDS_EN |
-+ L1F_PMCTRL_L1_SRDSPLL_EN |
-+ L1F_PMCTRL_L1_BUFSRX_EN |
-+ L1F_PMCTRL_SADLY_EN | /* ???default */
-+ L1F_PMCTRL_HOTRST_WTEN|
-+ L1F_PMCTRL_L0S_EN |
-+ L1F_PMCTRL_L1_EN |
-+ L1F_PMCTRL_ASPM_FCEN |
-+ L1F_PMCTRL_TXL1_AFTER_L0S |
-+ L1F_PMCTRL_RXL1_AFTER_L0S
-+ );
-+ if ((rev == L1F_REV_A0 || rev == L1F_REV_A1) &&
-+ (hw->pci_revid & L1F_PCI_REVID_WTH_CR) != 0) {
-+ pmctrl |= L1F_PMCTRL_L1_SRDS_EN | L1F_PMCTRL_L1_SRDSPLL_EN;
-+ }
-+
-+ /* on/off l0s only if bios/system enable l0s */
-+ if (/* sysl0s_en && */ l0s_en)
-+ pmctrl |= (L1F_PMCTRL_L0S_EN | L1F_PMCTRL_ASPM_FCEN);
-+ /* on/off l1 only if bios/system enable l1 */
-+ if (/* sysl1_en && */ l1_en)
-+ pmctrl |= (L1F_PMCTRL_L1_EN | L1F_PMCTRL_ASPM_FCEN);
-+
-+ alx_mem_w32(hw, L1F_PMCTRL, pmctrl);
-+
-+ return 0;
-+}
-+
-+
-+/* initialize phy for speed / flow control
-+ * lnk_cap
-+ * if autoNeg, is link capability to tell the peer
-+ * if force mode, is forced speed/duplex
-+ */
-+u16 l1f_init_phy_spdfc(struct alx_hw *hw, bool auto_neg,
-+ u8 lnk_cap, bool fc_en)
-+{
-+ u16 adv, giga, cr;
-+ u32 val;
-+ u16 ret;
-+
-+ /* clear flag */
-+ l1f_write_phy(hw, false, 0, false, L1F_MII_DBG_ADDR, 0);
-+ alx_mem_r32(hw, L1F_DRV, &val);
-+ FIELD_SETL(val, LX_DRV_PHY, 0);
-+
-+ if (auto_neg) {
-+ adv = L1F_ADVERTISE_DEFAULT_CAP & ~L1F_ADVERTISE_SPEED_MASK;
-+ giga = L1F_GIGA_CR_1000T_DEFAULT_CAP &
-+ ~L1F_GIGA_CR_1000T_SPEED_MASK;
-+ val |= LX_DRV_PHY_AUTO;
-+ if (!fc_en)
-+ adv &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
-+ else
-+ val |= LX_DRV_PHY_FC;
-+ if ((LX_LC_10H & lnk_cap) != 0) {
-+ adv |= ADVERTISE_10HALF;
-+ val |= LX_DRV_PHY_10;
-+ }
-+ if ((LX_LC_10F & lnk_cap) != 0) {
-+ adv |= ADVERTISE_10HALF |
-+ ADVERTISE_10FULL;
-+ val |= LX_DRV_PHY_10 | LX_DRV_PHY_DUPLEX;
-+ }
-+ if ((LX_LC_100H & lnk_cap) != 0) {
-+ adv |= ADVERTISE_100HALF;
-+ val |= LX_DRV_PHY_100;
-+ }
-+ if ((LX_LC_100F & lnk_cap) != 0) {
-+ adv |= ADVERTISE_100HALF |
-+ ADVERTISE_100FULL;
-+ val |= LX_DRV_PHY_100 | LX_DRV_PHY_DUPLEX;
-+ }
-+ if ((LX_LC_1000F & lnk_cap) != 0) {
-+ giga |= L1F_GIGA_CR_1000T_FD_CAPS;
-+ val |= LX_DRV_PHY_1000 | LX_DRV_PHY_DUPLEX;
-+ }
-+
-+ ret = l1f_write_phy(hw, false, 0, false, MII_ADVERTISE, adv);
-+ ret = l1f_write_phy(hw, false, 0, false, MII_CTRL1000, giga);
-+
-+ cr = BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART;
-+ ret = l1f_write_phy(hw, false, 0, false, MII_BMCR, cr);
-+ } else { /* force mode */
-+ cr = BMCR_RESET;
-+ switch (lnk_cap) {
-+ case LX_LC_10H:
-+ val |= LX_DRV_PHY_10;
-+ break;
-+ case LX_LC_10F:
-+ cr |= BMCR_FULLDPLX;
-+ val |= LX_DRV_PHY_10 | LX_DRV_PHY_DUPLEX;
-+ break;
-+ case LX_LC_100H:
-+ cr |= BMCR_SPEED100;
-+ val |= LX_DRV_PHY_100;
-+ break;
-+ case LX_LC_100F:
-+ cr |= BMCR_SPEED100 | BMCR_FULLDPLX;
-+ val |= LX_DRV_PHY_100 | LX_DRV_PHY_DUPLEX;
-+ break;
-+ default:
-+ return LX_ERR_PARM;
-+ }
-+ ret = l1f_write_phy(hw, false, 0, false, MII_BMCR, cr);
-+ }
-+
-+ if (!ret) {
-+ l1f_write_phy(hw, false, 0, false,
-+ L1F_MII_DBG_ADDR, LX_PHY_INITED);
-+ }
-+ alx_mem_w32(hw, L1F_DRV, val);
-+
-+ return ret;
-+}
-+
-+
-+/* do power saving setting befor enter suspend mode
-+ * NOTE:
-+ * 1. phy link must be established before calling this function
-+ * 2. wol option (pattern,magic,link,etc.) is configed before call it.
-+ */
-+u16 l1f_powersaving(struct alx_hw *hw,
-+ u8 wire_spd,
-+ bool wol_en,
-+ bool mactx_en,
-+ bool macrx_en,
-+ bool pws_en)
-+{
-+ u32 master_ctrl, mac_ctrl, phy_ctrl, val;
-+ u16 pm_ctrl, ret = 0;
-+
-+ master_ctrl = 0;
-+ mac_ctrl = 0;
-+ phy_ctrl = 0;
-+
-+ pws_en = pws_en;
-+
-+ alx_mem_r32(hw, L1F_MASTER, &master_ctrl);
-+ master_ctrl &= ~L1F_MASTER_PCLKSEL_SRDS;
-+
-+ alx_mem_r32(hw, L1F_MAC_CTRL, &mac_ctrl);
-+ /* 10/100 half */
-+ FIELD_SETL(mac_ctrl, L1F_MAC_CTRL_SPEED, L1F_MAC_CTRL_SPEED_10_100);
-+ mac_ctrl &= ~(L1F_MAC_CTRL_FULLD |
-+ L1F_MAC_CTRL_RX_EN |
-+ L1F_MAC_CTRL_TX_EN);
-+
-+ alx_mem_r32(hw, L1F_PHY_CTRL, &phy_ctrl);
-+ phy_ctrl &= ~(L1F_PHY_CTRL_DSPRST_OUT | L1F_PHY_CTRL_CLS);
-+ /* if (pws_en) { */
-+ phy_ctrl |= (L1F_PHY_CTRL_RST_ANALOG | L1F_PHY_CTRL_HIB_PULSE |
-+ L1F_PHY_CTRL_HIB_EN);
-+
-+ if (wol_en) { /* enable rx packet or tx packet */
-+ if (macrx_en)
-+ mac_ctrl |= (L1F_MAC_CTRL_RX_EN | L1F_MAC_CTRL_BRD_EN);
-+ if (mactx_en)
-+ mac_ctrl |= L1F_MAC_CTRL_TX_EN;
-+ if (LX_LC_1000F == wire_spd) {
-+ FIELD_SETL(mac_ctrl, L1F_MAC_CTRL_SPEED,
-+ L1F_MAC_CTRL_SPEED_1000);
-+ }
-+ if (LX_LC_10F == wire_spd ||
-+ LX_LC_100F == wire_spd ||
-+ LX_LC_100F == wire_spd) {
-+ mac_ctrl |= L1F_MAC_CTRL_FULLD;
-+ }
-+ phy_ctrl |= L1F_PHY_CTRL_DSPRST_OUT;
-+ ret = l1f_write_phy(hw, false, 0, false, L1F_MII_IER,
-+ L1F_IER_LINK_UP);
-+ } else {
-+ ret = l1f_write_phy(hw, false, 0, false, L1F_MII_IER, 0);
-+ phy_ctrl |= (L1F_PHY_CTRL_IDDQ | L1F_PHY_CTRL_POWER_DOWN);
-+ }
-+ alx_mem_w32(hw, L1F_MASTER, master_ctrl);
-+ alx_mem_w32(hw, L1F_MAC_CTRL, mac_ctrl);
-+ alx_mem_w32(hw, L1F_PHY_CTRL, phy_ctrl);
-+
-+ /* set val of PDLL D3PLLOFF */
-+ alx_mem_r32(hw, L1F_PDLL_TRNS1, &val);
-+ alx_mem_w32(hw, L1F_PDLL_TRNS1, val | L1F_PDLL_TRNS1_D3PLLOFF_EN);
-+
-+ /* set PME_EN */
-+ if (wol_en) {
-+ alx_cfg_r16(hw, L1F_PM_CSR, &pm_ctrl);
-+ pm_ctrl |= L1F_PM_CSR_PME_EN;
-+ alx_cfg_w16(hw, L1F_PM_CSR, pm_ctrl);
-+ }
-+
-+ return ret;
-+}
-+
-+
-+/* read phy register */
-+u16 l1f_read_phy(struct alx_hw *hw, bool ext, u8 dev, bool fast,
-+ u16 reg, u16 *data)
-+{
-+ u32 val;
-+ u16 clk_sel, i, ret = 0;
-+
-+ *data = 0;
-+ clk_sel = fast ?
-+ (u16)L1F_MDIO_CLK_SEL_25MD4 : (u16)L1F_MDIO_CLK_SEL_25MD128;
-+
-+ if (ext) {
-+ val = FIELDL(L1F_MDIO_EXTN_DEVAD, dev) |
-+ FIELDL(L1F_MDIO_EXTN_REG, reg);
-+ alx_mem_w32(hw, L1F_MDIO_EXTN, val);
-+
-+ val = L1F_MDIO_SPRES_PRMBL |
-+ FIELDL(L1F_MDIO_CLK_SEL, clk_sel) |
-+ L1F_MDIO_START |
-+ L1F_MDIO_MODE_EXT |
-+ L1F_MDIO_OP_READ;
-+ } else {
-+ val = L1F_MDIO_SPRES_PRMBL |
-+ FIELDL(L1F_MDIO_CLK_SEL, clk_sel) |
-+ FIELDL(L1F_MDIO_REG, reg) |
-+ L1F_MDIO_START |
-+ L1F_MDIO_OP_READ;
-+ }
-+
-+ alx_mem_w32(hw, L1F_MDIO, val);
-+
-+ for (i = 0; i < L1F_MDIO_MAX_AC_TO; i++) {
-+ alx_mem_r32(hw, L1F_MDIO, &val);
-+ if ((val & L1F_MDIO_BUSY) == 0) {
-+ *data = (u16)FIELD_GETX(val, L1F_MDIO_DATA);
-+ break;
-+ }
-+ udelay(10);
-+ }
-+
-+ if (L1F_MDIO_MAX_AC_TO == i)
-+ ret = LX_ERR_MIIBUSY;
-+
-+ return ret;
-+}
-+
-+/* write phy register */
-+u16 l1f_write_phy(struct alx_hw *hw, bool ext, u8 dev, bool fast,
-+ u16 reg, u16 data)
-+{
-+ u32 val;
-+ u16 clk_sel, i, ret = 0;
-+
-+ clk_sel = fast ?
-+ (u16)L1F_MDIO_CLK_SEL_25MD4 : (u16)L1F_MDIO_CLK_SEL_25MD128;
-+
-+ if (ext) {
-+ val = FIELDL(L1F_MDIO_EXTN_DEVAD, dev) |
-+ FIELDL(L1F_MDIO_EXTN_REG, reg);
-+ alx_mem_w32(hw, L1F_MDIO_EXTN, val);
-+
-+ val = L1F_MDIO_SPRES_PRMBL |
-+ FIELDL(L1F_MDIO_CLK_SEL, clk_sel) |
-+ FIELDL(L1F_MDIO_DATA, data) |
-+ L1F_MDIO_START |
-+ L1F_MDIO_MODE_EXT;
-+ } else {
-+ val = L1F_MDIO_SPRES_PRMBL |
-+ FIELDL(L1F_MDIO_CLK_SEL, clk_sel) |
-+ FIELDL(L1F_MDIO_REG, reg) |
-+ FIELDL(L1F_MDIO_DATA, data) |
-+ L1F_MDIO_START;
-+ }
-+
-+ alx_mem_w32(hw, L1F_MDIO, val);
-+
-+ for (i = 0; i < L1F_MDIO_MAX_AC_TO; i++) {
-+ alx_mem_r32(hw, L1F_MDIO, &val);
-+ if ((val & L1F_MDIO_BUSY) == 0)
-+ break;
-+ udelay(10);
-+ }
-+
-+ if (L1F_MDIO_MAX_AC_TO == i)
-+ ret = LX_ERR_MIIBUSY;
-+
-+ return ret;
-+}
-+
-+u16 l1f_read_phydbg(struct alx_hw *hw, bool fast, u16 reg, u16 *data)
-+{
-+ u16 ret;
-+
-+ ret = l1f_write_phy(hw, false, 0, fast, L1F_MII_DBG_ADDR, reg);
-+ ret = l1f_read_phy(hw, false, 0, fast, L1F_MII_DBG_DATA, data);
-+
-+ return ret;
-+}
-+
-+u16 l1f_write_phydbg(struct alx_hw *hw, bool fast, u16 reg, u16 data)
-+{
-+ u16 ret;
-+
-+ ret = l1f_write_phy(hw, false, 0, fast, L1F_MII_DBG_ADDR, reg);
-+ ret = l1f_write_phy(hw, false, 0, fast, L1F_MII_DBG_DATA, data);
-+
-+ return ret;
-+}
-+
-+/*
-+ * initialize mac basically
-+ * most of hi-feature no init
-+ * MAC/PHY should be reset before call this function
-+ * smb_timer : million-second
-+ * int_mod : micro-second
-+ * disable RSS as default
-+ */
-+u16 l1f_init_mac(struct alx_hw *hw, u8 *addr, u32 txmem_hi,
-+ u32 *tx_mem_lo, u8 tx_qnum, u16 txring_sz,
-+ u32 rxmem_hi, u32 rfdmem_lo, u32 rrdmem_lo,
-+ u16 rxring_sz, u16 rxbuf_sz, u16 smb_timer,
-+ u16 mtu, u16 int_mod, bool hash_legacy)
-+{
-+ u32 val;
-+ u16 val16, devid;
-+ u8 dmar_len;
-+
-+ alx_cfg_r16(hw, PCI_DEVICE_ID, &devid);
-+
-+ /* set mac-address */
-+ val = *(u32 *)(addr + 2);
-+ alx_mem_w32(hw, L1F_STAD0, LX_SWAP_DW(val));
-+ val = *(u16 *)addr ;
-+ alx_mem_w32(hw, L1F_STAD1, LX_SWAP_W((u16)val));
-+
-+ /* clear multicast hash table, algrithm */
-+ alx_mem_w32(hw, L1F_HASH_TBL0, 0);
-+ alx_mem_w32(hw, L1F_HASH_TBL1, 0);
-+ alx_mem_r32(hw, L1F_MAC_CTRL, &val);
-+ if (hash_legacy)
-+ val |= L1F_MAC_CTRL_MHASH_ALG_HI5B;
-+ else
-+ val &= ~L1F_MAC_CTRL_MHASH_ALG_HI5B;
-+ alx_mem_w32(hw, L1F_MAC_CTRL, val);
-+
-+ /* clear any wol setting/status */
-+ alx_mem_r32(hw, L1F_WOL0, &val);
-+ alx_mem_w32(hw, L1F_WOL0, 0);
-+
-+ /* clk gating */
-+ alx_mem_w32(hw, L1F_CLK_GATE,
-+ (FIELD_GETX(hw->pci_revid, L1F_PCI_REVID) == L1F_REV_B0) ?
-+ L1F_CLK_GATE_ALL_B0 : L1F_CLK_GATE_ALL_A0);
-+
-+ /* idle timeout to switch clk_125M */
-+ if (FIELD_GETX(hw->pci_revid, L1F_PCI_REVID) == L1F_REV_B0) {
-+ alx_mem_w32(hw, L1F_IDLE_DECISN_TIMER,
-+ L1F_IDLE_DECISN_TIMER_DEF);
-+ }
-+
-+ /* descriptor ring base memory */
-+ alx_mem_w32(hw, L1F_TX_BASE_ADDR_HI, txmem_hi);
-+ alx_mem_w32(hw, L1F_TPD_RING_SZ, txring_sz);
-+ switch (tx_qnum) {
-+ case 4:
-+ alx_mem_w32(hw, L1F_TPD_PRI3_ADDR_LO, tx_mem_lo[3]);
-+ /* fall through */
-+ case 3:
-+ alx_mem_w32(hw, L1F_TPD_PRI2_ADDR_LO, tx_mem_lo[2]);
-+ /* fall through */
-+ case 2:
-+ alx_mem_w32(hw, L1F_TPD_PRI1_ADDR_LO, tx_mem_lo[1]);
-+ /* fall through */
-+ case 1:
-+ alx_mem_w32(hw, L1F_TPD_PRI0_ADDR_LO, tx_mem_lo[0]);
-+ break;
-+ default:
-+ return LX_ERR_PARM;
-+ }
-+ alx_mem_w32(hw, L1F_RX_BASE_ADDR_HI, rxmem_hi);
-+ alx_mem_w32(hw, L1F_RFD_ADDR_LO, rfdmem_lo);
-+ alx_mem_w32(hw, L1F_RRD_ADDR_LO, rrdmem_lo);
-+ alx_mem_w32(hw, L1F_RFD_BUF_SZ, rxbuf_sz);
-+ alx_mem_w32(hw, L1F_RRD_RING_SZ, rxring_sz);
-+ alx_mem_w32(hw, L1F_RFD_RING_SZ, rxring_sz);
-+ alx_mem_w32(hw, L1F_SMB_TIMER, smb_timer * 500UL);
-+ alx_mem_w32(hw, L1F_SRAM9, L1F_SRAM_LOAD_PTR);
-+
-+ /* int moduration */
-+ alx_mem_r32(hw, L1F_MASTER, &val);
-+/* val = (val & ~L1F_MASTER_IRQMOD2_EN) | */
-+ val = val | L1F_MASTER_IRQMOD2_EN |
-+ L1F_MASTER_IRQMOD1_EN |
-+ L1F_MASTER_SYSALVTIMER_EN; /* sysalive */
-+ alx_mem_w32(hw, L1F_MASTER, val);
-+ alx_mem_w32(hw, L1F_IRQ_MODU_TIMER,
-+ FIELDL(L1F_IRQ_MODU_TIMER1, int_mod >> 1));
-+
-+ /* tpd threshold to trig int */
-+ alx_mem_w32(hw, L1F_TINT_TPD_THRSHLD, (u32)txring_sz / 3);
-+ alx_mem_w32(hw, L1F_TINT_TIMER, int_mod);
-+ /* re-send int */
-+ alx_mem_w32(hw, L1F_INT_RETRIG, L1F_INT_RETRIG_TO);
-+
-+ /* mtu */
-+ alx_mem_w32(hw, L1F_MTU, (u32)(mtu + 4 + 4)); /* crc + vlan */
-+ if (mtu > L1F_MTU_JUMBO_TH) {
-+ alx_mem_r32(hw, L1F_MAC_CTRL, &val);
-+ alx_mem_w32(hw, L1F_MAC_CTRL, val & ~L1F_MAC_CTRL_FAST_PAUSE);
-+ }
-+
-+ /* txq */
-+ if ((mtu + 8) < L1F_TXQ1_JUMBO_TSO_TH)
-+ val = (u32)(mtu + 8 + 7) >> 3; /* 7 for QWORD align */
-+ else
-+ val = L1F_TXQ1_JUMBO_TSO_TH >> 3;
-+ alx_mem_w32(hw, L1F_TXQ1, val | L1F_TXQ1_ERRLGPKT_DROP_EN);
-+ alx_mem_r32(hw, L1F_DEV_CTRL, &val);
-+ dmar_len = (u8)FIELD_GETX(val, L1F_DEV_CTRL_MAXRRS);
-+ /* if BIOS had changed the default dma read max length,
-+ * restore it to default value */
-+ if (dmar_len < L1F_DEV_CTRL_MAXRRS_MIN) {
-+ FIELD_SETL(val, L1F_DEV_CTRL_MAXRRS, L1F_DEV_CTRL_MAXRRS_MIN);
-+ alx_mem_w32(hw, L1F_DEV_CTRL, val);
-+ }
-+ val = FIELDL(L1F_TXQ0_TPD_BURSTPREF, L1F_TXQ_TPD_BURSTPREF_DEF) |
-+ L1F_TXQ0_MODE_ENHANCE |
-+ L1F_TXQ0_LSO_8023_EN |
-+ L1F_TXQ0_SUPT_IPOPT |
-+ FIELDL(L1F_TXQ0_TXF_BURST_PREF, L1F_TXQ_TXF_BURST_PREF_DEF);
-+ alx_mem_w32(hw, L1F_TXQ0, val);
-+ val = FIELDL(L1F_HQTPD_Q1_NUMPREF, L1F_TXQ_TPD_BURSTPREF_DEF) |
-+ FIELDL(L1F_HQTPD_Q2_NUMPREF, L1F_TXQ_TPD_BURSTPREF_DEF) |
-+ FIELDL(L1F_HQTPD_Q3_NUMPREF, L1F_TXQ_TPD_BURSTPREF_DEF) |
-+ L1F_HQTPD_BURST_EN;
-+ alx_mem_w32(hw, L1F_HQTPD, val);
-+
-+ /* rxq */
-+ alx_mem_r32(hw, L1F_SRAM5, &val);
-+ val = FIELD_GETX(val, L1F_SRAM_RXF_LEN) << 3; /* bytes */
-+ if (val > L1F_SRAM_RXF_LEN_8K) {
-+ val16 = L1F_MTU_STD_ALGN >> 3;
-+ val = (val - (2 * L1F_MTU_STD_ALGN + L1F_MTU_MIN)) >> 3;
-+ } else {
-+ val16 = L1F_MTU_STD_ALGN >> 3;
-+ val = (val - L1F_MTU_STD_ALGN) >> 3;
-+ }
-+ alx_mem_w32(hw, L1F_RXQ2,
-+ FIELDL(L1F_RXQ2_RXF_XOFF_THRESH, val16) |
-+ FIELDL(L1F_RXQ2_RXF_XON_THRESH, val));
-+ val = FIELDL(L1F_RXQ0_NUM_RFD_PREF, L1F_RXQ0_NUM_RFD_PREF_DEF) |
-+ FIELDL(L1F_RXQ0_RSS_MODE, L1F_RXQ0_RSS_MODE_DIS) |
-+ FIELDL(L1F_RXQ0_IDT_TBL_SIZE, L1F_RXQ0_IDT_TBL_SIZE_DEF) |
-+ L1F_RXQ0_RSS_HSTYP_ALL |
-+ L1F_RXQ0_RSS_HASH_EN |
-+ L1F_RXQ0_IPV6_PARSE_EN;
-+ if (mtu > L1F_MTU_JUMBO_TH)
-+ val |= L1F_RXQ0_CUT_THRU_EN;
-+ if ((devid & 1) != 0) {
-+ FIELD_SETL(val, L1F_RXQ0_ASPM_THRESH,
-+ L1F_RXQ0_ASPM_THRESH_100M);
-+ }
-+ alx_mem_w32(hw, L1F_RXQ0, val);
-+
-+ /* rfd producer index */
-+ alx_mem_w32(hw, L1F_RFD_PIDX, (u32)rxring_sz - 1);
-+
-+ /* DMA */
-+ alx_mem_r32(hw, L1F_DMA, &val);
-+ val = FIELDL(L1F_DMA_RORDER_MODE, L1F_DMA_RORDER_MODE_OUT) |
-+ L1F_DMA_RREQ_PRI_DATA |
-+ FIELDL(L1F_DMA_RREQ_BLEN, dmar_len) |
-+ FIELDL(L1F_DMA_WDLY_CNT, L1F_DMA_WDLY_CNT_DEF) |
-+ FIELDL(L1F_DMA_RDLY_CNT, L1F_DMA_RDLY_CNT_DEF) |
-+ FIELDL(L1F_DMA_RCHNL_SEL, hw->dma_chnl - 1);
-+ alx_mem_w32(hw, L1F_DMA, val);
-+
-+ return 0;
-+}
-+
-+
-+u16 l1f_get_phy_config(struct alx_hw *hw)
-+{
-+ u32 val;
-+ u16 phy_val;
-+
-+ alx_mem_r32(hw, L1F_PHY_CTRL, &val);
-+
-+ /* phy in rst */
-+ if ((val & L1F_PHY_CTRL_DSPRST_OUT) == 0)
-+ return LX_DRV_PHY_UNKNOWN;
-+
-+ alx_mem_r32(hw, L1F_DRV, &val);
-+ val = FIELD_GETX(val, LX_DRV_PHY);
-+
-+ if (LX_DRV_PHY_UNKNOWN == val)
-+ return LX_DRV_PHY_UNKNOWN;
-+
-+ l1f_read_phy(hw, false, 0, false, L1F_MII_DBG_ADDR, &phy_val);
-+
-+ if (LX_PHY_INITED == phy_val)
-+ return (u16) val;
-+
-+ return LX_DRV_PHY_UNKNOWN;
-+}
-+
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alf_hw.h
-@@ -0,0 +1,2098 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef L1F_HW_H_
-+#define L1F_HW_H_
-+
-+/*********************************************************************
-+ * some reqs for l1f_sw.h
-+ *
-+ * 1. some basic type must be defined if there are not defined by
-+ * your compiler:
-+ * u8, u16, u32, bool
-+ *
-+ * 2. PETHCONTEXT difinition should be in l1x_sw.h and it must contain
-+ * pci_devid & pci_venid
-+ *
-+ *********************************************************************/
-+
-+#include "alx_hwcom.h"
-+
-+/******************************************************************************/
-+#define L1F_DEV_ID 0x1091
-+#define L2F_DEV_ID 0x1090
-+
-+
-+#define L1F_PCI_REVID_WTH_CR BIT(1)
-+#define L1F_PCI_REVID_WTH_XD BIT(0)
-+#define L1F_PCI_REVID_MASK ASHFT3(0x1FU)
-+#define L1F_PCI_REVID_SHIFT 3
-+#define L1F_REV_A0 0
-+#define L1F_REV_A1 1
-+#define L1F_REV_B0 2
-+
-+#define L1F_PM_CSR 0x0044 /* 16bit */
-+#define L1F_PM_CSR_PME_STAT BIT(15)
-+#define L1F_PM_CSR_DSCAL_MASK ASHFT13(3U)
-+#define L1F_PM_CSR_DSCAL_SHIFT 13
-+#define L1F_PM_CSR_DSEL_MASK ASHFT9(0xFU)
-+#define L1F_PM_CSR_DSEL_SHIFT 9
-+#define L1F_PM_CSR_PME_EN BIT(8)
-+#define L1F_PM_CSR_PWST_MASK ASHFT0(3U)
-+#define L1F_PM_CSR_PWST_SHIFT 0
-+
-+#define L1F_PM_DATA 0x0047 /* 8bit */
-+
-+
-+#define L1F_DEV_CAP 0x005C
-+#define L1F_DEV_CAP_SPLSL_MASK ASHFT26(3UL)
-+#define L1F_DEV_CAP_SPLSL_SHIFT 26
-+#define L1F_DEV_CAP_SPLV_MASK ASHFT18(0xFFUL)
-+#define L1F_DEV_CAP_SPLV_SHIFT 18
-+#define L1F_DEV_CAP_RBER BIT(15)
-+#define L1F_DEV_CAP_PIPRS BIT(14)
-+#define L1F_DEV_CAP_AIPRS BIT(13)
-+#define L1F_DEV_CAP_ABPRS BIT(12)
-+#define L1F_DEV_CAP_L1ACLAT_MASK ASHFT9(7UL)
-+#define L1F_DEV_CAP_L1ACLAT_SHIFT 9
-+#define L1F_DEV_CAP_L0SACLAT_MASK ASHFT6(7UL)
-+#define L1F_DEV_CAP_L0SACLAT_SHIFT 6
-+#define L1F_DEV_CAP_EXTAG BIT(5)
-+#define L1F_DEV_CAP_PHANTOM BIT(4)
-+#define L1F_DEV_CAP_MPL_MASK ASHFT0(7UL)
-+#define L1F_DEV_CAP_MPL_SHIFT 0
-+#define L1F_DEV_CAP_MPL_128 1
-+#define L1F_DEV_CAP_MPL_256 2
-+#define L1F_DEV_CAP_MPL_512 3
-+#define L1F_DEV_CAP_MPL_1024 4
-+#define L1F_DEV_CAP_MPL_2048 5
-+#define L1F_DEV_CAP_MPL_4096 6
-+
-+#define L1F_DEV_CTRL 0x0060 /* 16bit */
-+#define L1F_DEV_CTRL_MAXRRS_MASK ASHFT12(7U)
-+#define L1F_DEV_CTRL_MAXRRS_SHIFT 12
-+#define L1F_DEV_CTRL_MAXRRS_MIN 2
-+#define L1F_DEV_CTRL_NOSNP_EN BIT(11)
-+#define L1F_DEV_CTRL_AUXPWR_EN BIT(10)
-+#define L1F_DEV_CTRL_PHANTOM_EN BIT(9)
-+#define L1F_DEV_CTRL_EXTAG_EN BIT(8)
-+#define L1F_DEV_CTRL_MPL_MASK ASHFT5(7U)
-+#define L1F_DEV_CTRL_MPL_SHIFT 5
-+#define L1F_DEV_CTRL_RELORD_EN BIT(4)
-+#define L1F_DEV_CTRL_URR_EN BIT(3)
-+#define L1F_DEV_CTRL_FERR_EN BIT(2)
-+#define L1F_DEV_CTRL_NFERR_EN BIT(1)
-+#define L1F_DEV_CTRL_CERR_EN BIT(0)
-+
-+
-+#define L1F_DEV_STAT 0x0062 /* 16bit */
-+#define L1F_DEV_STAT_XS_PEND BIT(5)
-+#define L1F_DEV_STAT_AUXPWR BIT(4)
-+#define L1F_DEV_STAT_UR BIT(3)
-+#define L1F_DEV_STAT_FERR BIT(2)
-+#define L1F_DEV_STAT_NFERR BIT(1)
-+#define L1F_DEV_STAT_CERR BIT(0)
-+
-+#define L1F_LNK_CAP 0x0064
-+#define L1F_LNK_CAP_PRTNUM_MASK ASHFT24(0xFFUL)
-+#define L1F_LNK_CAP_PRTNUM_SHIFT 24
-+#define L1F_LNK_CAP_CLK_PM BIT(18)
-+#define L1F_LNK_CAP_L1EXTLAT_MASK ASHFT15(7UL)
-+#define L1F_LNK_CAP_L1EXTLAT_SHIFT 15
-+#define L1F_LNK_CAP_L0SEXTLAT_MASK ASHFT12(7UL)
-+#define L1F_LNK_CAP_L0SEXTLAT_SHIFT 12
-+#define L1F_LNK_CAP_ASPM_SUP_MASK ASHFT10(3UL)
-+#define L1F_LNK_CAP_ASPM_SUP_SHIFT 10
-+#define L1F_LNK_CAP_ASPM_SUP_L0S 1
-+#define L1F_LNK_CAP_ASPM_SUP_L0SL1 3
-+#define L1F_LNK_CAP_MAX_LWH_MASK ASHFT4(0x3FUL)
-+#define L1F_LNK_CAP_MAX_LWH_SHIFT 4
-+#define L1F_LNK_CAP_MAX_LSPD_MASH ASHFT0(0xFUL)
-+#define L1F_LNK_CAP_MAX_LSPD_SHIFT 0
-+
-+#define L1F_LNK_CTRL 0x0068 /* 16bit */
-+#define L1F_LNK_CTRL_CLK_PM_EN BIT(8)
-+#define L1F_LNK_CTRL_EXTSYNC BIT(7)
-+#define L1F_LNK_CTRL_CMNCLK_CFG BIT(6)
-+#define L1F_LNK_CTRL_RCB_128B BIT(3) /* 0:64b,1:128b */
-+#define L1F_LNK_CTRL_ASPM_MASK ASHFT0(3U)
-+#define L1F_LNK_CTRL_ASPM_SHIFT 0
-+#define L1F_LNK_CTRL_ASPM_DIS 0
-+#define L1F_LNK_CTRL_ASPM_ENL0S 1
-+#define L1F_LNK_CTRL_ASPM_ENL1 2
-+#define L1F_LNK_CTRL_ASPM_ENL0SL1 3
-+
-+#define L1F_LNK_STAT 0x006A /* 16bit */
-+#define L1F_LNK_STAT_SCLKCFG BIT(12)
-+#define L1F_LNK_STAT_LNKTRAIN BIT(11)
-+#define L1F_LNK_STAT_TRNERR BIT(10)
-+#define L1F_LNK_STAT_LNKSPD_MASK ASHFT0(0xFU)
-+#define L1F_LNK_STAT_LNKSPD_SHIFT 0
-+#define L1F_LNK_STAT_NEGLW_MASK ASHFT4(0x3FU)
-+#define L1F_LNK_STAT_NEGLW_SHIFT 4
-+
-+#define L1F_MSIX_MASK 0x0090
-+#define L1F_MSIX_PENDING 0x0094
-+
-+#define L1F_UE_SVRT 0x010C
-+#define L1F_UE_SVRT_UR BIT(20)
-+#define L1F_UE_SVRT_ECRCERR BIT(19)
-+#define L1F_UE_SVRT_MTLP BIT(18)
-+#define L1F_UE_SVRT_RCVOVFL BIT(17)
-+#define L1F_UE_SVRT_UNEXPCPL BIT(16)
-+#define L1F_UE_SVRT_CPLABRT BIT(15)
-+#define L1F_UE_SVRT_CPLTO BIT(14)
-+#define L1F_UE_SVRT_FCPROTERR BIT(13)
-+#define L1F_UE_SVRT_PTLP BIT(12)
-+#define L1F_UE_SVRT_DLPROTERR BIT(4)
-+#define L1F_UE_SVRT_TRNERR BIT(0)
-+
-+#define L1F_EFLD 0x0204 /* eeprom/flash load */
-+#define L1F_EFLD_F_ENDADDR_MASK ASHFT16(0x3FFUL)
-+#define L1F_EFLD_F_ENDADDR_SHIFT 16
-+#define L1F_EFLD_F_EXIST BIT(10)
-+#define L1F_EFLD_E_EXIST BIT(9)
-+#define L1F_EFLD_EXIST BIT(8)
-+#define L1F_EFLD_STAT BIT(5) /* 0:finish,1:in progress */
-+#define L1F_EFLD_IDLE BIT(4)
-+#define L1F_EFLD_START BIT(0)
-+
-+#define L1F_SLD 0x0218 /* efuse load */
-+#define L1F_SLD_FREQ_MASK ASHFT24(3UL)
-+#define L1F_SLD_FREQ_SHIFT 24
-+#define L1F_SLD_FREQ_100K 0
-+#define L1F_SLD_FREQ_200K 1
-+#define L1F_SLD_FREQ_300K 2
-+#define L1F_SLD_FREQ_400K 3
-+#define L1F_SLD_EXIST BIT(23)
-+#define L1F_SLD_SLVADDR_MASK ASHFT16(0x7FUL)
-+#define L1F_SLD_SLVADDR_SHIFT 16
-+#define L1F_SLD_IDLE BIT(13)
-+#define L1F_SLD_STAT BIT(12) /* 0:finish,1:in progress */
-+#define L1F_SLD_START BIT(11)
-+#define L1F_SLD_STARTADDR_MASK ASHFT0(0xFFUL)
-+#define L1F_SLD_STARTADDR_SHIFT 0
-+#define L1F_SLD_MAX_TO 100
-+
-+#define L1F_PCIE_MSIC 0x021C
-+#define L1F_PCIE_MSIC_MSIX_DIS BIT(22)
-+#define L1F_PCIE_MSIC_MSI_DIS BIT(21)
-+
-+#define L1F_PPHY_MISC1 0x1000
-+#define L1F_PPHY_MISC1_RCVDET BIT(2)
-+#define L1F_PPHY_MISC1_NFTS_MASK ASHFT16(0xFFUL)
-+#define L1F_PPHY_MISC1_NFTS_SHIFT 16
-+#define L1F_PPHY_MISC1_NFTS_HIPERF 0xA0 /* ???? */
-+
-+#define L1F_PPHY_MISC2 0x1004
-+#define L1F_PPHY_MISC2_L0S_TH_MASK ASHFT18(0x3UL)
-+#define L1F_PPHY_MISC2_L0S_TH_SHIFT 18
-+#define L1F_PPHY_MISC2_CDR_BW_MASK ASHFT16(0x3UL)
-+#define L1F_PPHY_MISC2_CDR_BW_SHIFT 16
-+
-+#define L1F_PDLL_TRNS1 0x1104
-+#define L1F_PDLL_TRNS1_D3PLLOFF_EN BIT(11)
-+#define L1F_PDLL_TRNS1_REGCLK_SEL_NORM BIT(10)
-+#define L1F_PDLL_TRNS1_REPLY_TO_MASK ASHFT0(0x3FFUL)
-+#define L1F_PDLL_TRNS1_REPLY_TO_SHIFT 0
-+
-+
-+#define L1F_TLEXTN_STATS 0x1208
-+#define L1F_TLEXTN_STATS_DEVNO_MASK ASHFT16(0x1FUL)
-+#define L1F_TLEXTN_STATS_DEVNO_SHIFT 16
-+#define L1F_TLEXTN_STATS_BUSNO_MASK ASHFT8(0xFFUL)
-+#define L1F_TLEXTN_STATS_BUSNO_SHIFT 8
-+
-+#define L1F_EFUSE_CTRL 0x12C0
-+#define L1F_EFUSE_CTRL_FLAG BIT(31) /* 0:read,1:write */
-+#define L1F_EUFSE_CTRL_ACK BIT(30)
-+#define L1F_EFUSE_CTRL_ADDR_MASK ASHFT16(0x3FFUL)
-+#define L1F_EFUSE_CTRL_ADDR_SHIFT 16
-+
-+#define L1F_EFUSE_DATA 0x12C4
-+
-+#define L1F_SPI_OP1 0x12C8
-+#define L1F_SPI_OP1_RDID_MASK ASHFT24(0xFFUL)
-+#define L1F_SPI_OP1_RDID_SHIFT 24
-+#define L1F_SPI_OP1_CE_MASK ASHFT16(0xFFUL)
-+#define L1F_SPI_OP1_CE_SHIFT 16
-+#define L1F_SPI_OP1_SE_MASK ASHFT8(0xFFUL)
-+#define L1F_SPI_OP1_SE_SHIFT 8
-+#define L1F_SPI_OP1_PRGRM_MASK ASHFT0(0xFFUL)
-+#define L1F_SPI_OP1_PRGRM_SHIFT 0
-+
-+#define L1F_SPI_OP2 0x12CC
-+#define L1F_SPI_OP2_READ_MASK ASHFT24(0xFFUL)
-+#define L1F_SPI_OP2_READ_SHIFT 24
-+#define L1F_SPI_OP2_WRSR_MASK ASHFT16(0xFFUL)
-+#define L1F_SPI_OP2_WRSR_SHIFT 16
-+#define L1F_SPI_OP2_RDSR_MASK ASHFT8(0xFFUL)
-+#define L1F_SPI_OP2_RDSR_SHIFT 8
-+#define L1F_SPI_OP2_WREN_MASK ASHFT0(0xFFUL)
-+#define L1F_SPI_OP2_WREN_SHIFT 0
-+
-+#define L1F_SPI_OP3 0x12E4
-+#define L1F_SPI_OP3_WRDI_MASK ASHFT8(0xFFUL)
-+#define L1F_SPI_OP3_WRDI_SHIFT 8
-+#define L1F_SPI_OP3_EWSR_MASK ASHFT0(0xFFUL)
-+#define L1F_SPI_OP3_EWSR_SHIFT 0
-+
-+#define L1F_EF_CTRL 0x12D0
-+#define L1F_EF_CTRL_FSTS_MASK ASHFT20(0xFFUL)
-+#define L1F_EF_CTRL_FSTS_SHIFT 20
-+#define L1F_EF_CTRL_CLASS_MASK ASHFT16(7UL)
-+#define L1F_EF_CTRL_CLASS_SHIFT 16
-+#define L1F_EF_CTRL_CLASS_F_UNKNOWN 0
-+#define L1F_EF_CTRL_CLASS_F_STD 1
-+#define L1F_EF_CTRL_CLASS_F_SST 2
-+#define L1F_EF_CTRL_CLASS_E_UNKNOWN 0
-+#define L1F_EF_CTRL_CLASS_E_1K 1
-+#define L1F_EF_CTRL_CLASS_E_4K 2
-+#define L1F_EF_CTRL_FRET BIT(15) /* 0:OK,1:fail */
-+#define L1F_EF_CTRL_TYP_MASK ASHFT12(3UL)
-+#define L1F_EF_CTRL_TYP_SHIFT 12
-+#define L1F_EF_CTRL_TYP_NONE 0
-+#define L1F_EF_CTRL_TYP_F 1
-+#define L1F_EF_CTRL_TYP_E 2
-+#define L1F_EF_CTRL_TYP_UNKNOWN 3
-+#define L1F_EF_CTRL_ONE_CLK BIT(10)
-+#define L1F_EF_CTRL_ECLK_MASK ASHFT8(3UL)
-+#define L1F_EF_CTRL_ECLK_SHIFT 8
-+#define L1F_EF_CTRL_ECLK_125K 0
-+#define L1F_EF_CTRL_ECLK_250K 1
-+#define L1F_EF_CTRL_ECLK_500K 2
-+#define L1F_EF_CTRL_ECLK_1M 3
-+#define L1F_EF_CTRL_FBUSY BIT(7)
-+#define L1F_EF_CTRL_ACTION BIT(6) /* 1:start,0:stop */
-+#define L1F_EF_CTRL_AUTO_OP BIT(5)
-+#define L1F_EF_CTRL_SST_MODE BIT(4) /* force using sst */
-+#define L1F_EF_CTRL_INST_MASK ASHFT0(0xFUL)
-+#define L1F_EF_CTRL_INST_SHIFT 0
-+#define L1F_EF_CTRL_INST_NONE 0
-+#define L1F_EF_CTRL_INST_READ 1 /* for flash & eeprom */
-+#define L1F_EF_CTRL_INST_RDID 2
-+#define L1F_EF_CTRL_INST_RDSR 3
-+#define L1F_EF_CTRL_INST_WREN 4
-+#define L1F_EF_CTRL_INST_PRGRM 5
-+#define L1F_EF_CTRL_INST_SE 6
-+#define L1F_EF_CTRL_INST_CE 7
-+#define L1F_EF_CTRL_INST_WRSR 10
-+#define L1F_EF_CTRL_INST_EWSR 11
-+#define L1F_EF_CTRL_INST_WRDI 12
-+#define L1F_EF_CTRL_INST_WRITE 2 /* only for eeprom */
-+
-+#define L1F_EF_ADDR 0x12D4
-+#define L1F_EF_DATA 0x12D8
-+#define L1F_SPI_ID 0x12DC
-+
-+#define L1F_SPI_CFG_START 0x12E0
-+
-+#define L1F_PMCTRL 0x12F8
-+#define L1F_PMCTRL_HOTRST_WTEN BIT(31)
-+#define L1F_PMCTRL_ASPM_FCEN BIT(30) /* L0s/L1 dis by MAC based on
-+ * thrghput(setting in 15A0) */
-+#define L1F_PMCTRL_SADLY_EN BIT(29)
-+#define L1F_PMCTRL_L0S_BUFSRX_EN BIT(28)
-+#define L1F_PMCTRL_LCKDET_TIMER_MASK ASHFT24(0xFUL)
-+#define L1F_PMCTRL_LCKDET_TIMER_SHIFT 24
-+#define L1F_PMCTRL_LCKDET_TIMER_DEF 0xC
-+#define L1F_PMCTRL_L1REQ_TO_MASK ASHFT20(0xFUL)
-+#define L1F_PMCTRL_L1REQ_TO_SHIFT 20 /* pm_request_l1 time > @
-+ * ->L0s not L1 */
-+#define L1F_PMCTRL_L1REG_TO_DEF 0xC
-+#define L1F_PMCTRL_TXL1_AFTER_L0S BIT(19)
-+#define L1F_PMCTRL_L1_TIMER_MASK ASHFT16(7UL)
-+#define L1F_PMCTRL_L1_TIMER_SHIFT 16
-+#define L1F_PMCTRL_L1_TIMER_DIS 0
-+#define L1F_PMCTRL_L1_TIMER_2US 1
-+#define L1F_PMCTRL_L1_TIMER_4US 2
-+#define L1F_PMCTRL_L1_TIMER_8US 3
-+#define L1F_PMCTRL_L1_TIMER_16US 4
-+#define L1F_PMCTRL_L1_TIMER_24US 5
-+#define L1F_PMCTRL_L1_TIMER_32US 6
-+#define L1F_PMCTRL_L1_TIMER_63US 7
-+#define L1F_PMCTRL_RCVR_WT_1US BIT(15) /* 1:1us, 0:2ms */
-+#define L1F_PMCTRL_PWM_VER_11 BIT(14) /* 0:1.0a,1:1.1 */
-+#define L1F_PMCTRL_L1_CLKSW_EN BIT(13) /* en pcie clk sw in L1 */
-+#define L1F_PMCTRL_L0S_EN BIT(12)
-+#define L1F_PMCTRL_RXL1_AFTER_L0S BIT(11)
-+#define L1F_PMCTRL_L0S_TIMER_MASK ASHFT8(7UL)
-+#define L1F_PMCTRL_L0S_TIMER_SHIFT 8
-+#define L1F_PMCTRL_L1_BUFSRX_EN BIT(7)
-+#define L1F_PMCTRL_L1_SRDSRX_PWD BIT(6) /* power down serdes rx */
-+#define L1F_PMCTRL_L1_SRDSPLL_EN BIT(5)
-+#define L1F_PMCTRL_L1_SRDS_EN BIT(4)
-+#define L1F_PMCTRL_L1_EN BIT(3)
-+#define L1F_PMCTRL_CLKREQ_EN BIT(2)
-+#define L1F_PMCTRL_RBER_EN BIT(1)
-+#define L1F_PMCTRL_SPRSDWER_EN BIT(0)
-+
-+#define L1F_LTSSM_CTRL 0x12FC
-+#define L1F_LTSSM_WRO_EN BIT(12)
-+
-+
-+/******************************************************************************/
-+
-+#define L1F_MASTER 0x1400
-+#define L1F_MASTER_OTP_FLG BIT(31)
-+#define L1F_MASTER_DEV_NUM_MASK ASHFT24(0x7FUL)
-+#define L1F_MASTER_DEV_NUM_SHIFT 24
-+#define L1F_MASTER_REV_NUM_MASK ASHFT16(0xFFUL)
-+#define L1F_MASTER_REV_NUM_SHIFT 16
-+#define L1F_MASTER_DEASSRT BIT(15) /*ISSUE DE-ASSERT MSG */
-+#define L1F_MASTER_RDCLR_INT BIT(14)
-+#define L1F_MASTER_DMA_RST BIT(13)
-+#define L1F_MASTER_PCLKSEL_SRDS BIT(12) /* 1:alwys sel pclk from
-+ * serdes, not sw to 25M */
-+#define L1F_MASTER_IRQMOD2_EN BIT(11) /* IRQ MODURATION FOR RX */
-+#define L1F_MASTER_IRQMOD1_EN BIT(10) /* MODURATION FOR TX/RX */
-+#define L1F_MASTER_MANU_INT BIT(9) /* SOFT MANUAL INT */
-+#define L1F_MASTER_MANUTIMER_EN BIT(8)
-+#define L1F_MASTER_SYSALVTIMER_EN BIT(7) /* SYS ALIVE TIMER EN */
-+#define L1F_MASTER_OOB_DIS BIT(6) /* OUT OF BOX DIS */
-+#define L1F_MASTER_WAKEN_25M BIT(5) /* WAKE WO. PCIE CLK */
-+#define L1F_MASTER_BERT_START BIT(4)
-+#define L1F_MASTER_PCIE_TSTMOD_MASK ASHFT2(3UL)
-+#define L1F_MASTER_PCIE_TSTMOD_SHIFT 2
-+#define L1F_MASTER_PCIE_RST BIT(1)
-+#define L1F_MASTER_DMA_MAC_RST BIT(0) /* RST MAC & DMA */
-+#define L1F_DMA_MAC_RST_TO 50
-+
-+#define L1F_MANU_TIMER 0x1404
-+
-+#define L1F_IRQ_MODU_TIMER 0x1408
-+#define L1F_IRQ_MODU_TIMER2_MASK ASHFT16(0xFFFFUL)
-+#define L1F_IRQ_MODU_TIMER2_SHIFT 16 /* ONLY FOR RX */
-+#define L1F_IRQ_MODU_TIMER1_MASK ASHFT0(0xFFFFUL)
-+#define L1F_IRQ_MODU_TIMER1_SHIFT 0
-+
-+#define L1F_PHY_CTRL 0x140C
-+#define L1F_PHY_CTRL_ADDR_MASK ASHFT19(0x1FUL)
-+#define L1F_PHY_CTRL_ADDR_SHIFT 19
-+#define L1F_PHY_CTRL_BP_VLTGSW BIT(18)
-+#define L1F_PHY_CTRL_100AB_EN BIT(17)
-+#define L1F_PHY_CTRL_10AB_EN BIT(16)
-+#define L1F_PHY_CTRL_PLL_BYPASS BIT(15)
-+#define L1F_PHY_CTRL_POWER_DOWN BIT(14) /* affect MAC & PHY,
-+ * go to low power sts */
-+#define L1F_PHY_CTRL_PLL_ON BIT(13) /* 1:PLL ALWAYS ON
-+ * 0:CAN SWITCH IN LPW */
-+#define L1F_PHY_CTRL_RST_ANALOG BIT(12)
-+#define L1F_PHY_CTRL_HIB_PULSE BIT(11)
-+#define L1F_PHY_CTRL_HIB_EN BIT(10)
-+#define L1F_PHY_CTRL_GIGA_DIS BIT(9)
-+#define L1F_PHY_CTRL_IDDQ_DIS BIT(8) /* POWER ON RST */
-+#define L1F_PHY_CTRL_IDDQ BIT(7) /* WHILE REBOOT, BIT8(1)
-+ * EFFECTS BIT7 */
-+#define L1F_PHY_CTRL_LPW_EXIT BIT(6)
-+#define L1F_PHY_CTRL_GATE_25M BIT(5)
-+#define L1F_PHY_CTRL_RVRS_ANEG BIT(4)
-+#define L1F_PHY_CTRL_ANEG_NOW BIT(3)
-+#define L1F_PHY_CTRL_LED_MODE BIT(2)
-+#define L1F_PHY_CTRL_RTL_MODE BIT(1)
-+#define L1F_PHY_CTRL_DSPRST_OUT BIT(0) /* OUT OF DSP RST STATE */
-+#define L1F_PHY_CTRL_DSPRST_TO 80
-+#define L1F_PHY_CTRL_CLS (\
-+ L1F_PHY_CTRL_LED_MODE |\
-+ L1F_PHY_CTRL_100AB_EN |\
-+ L1F_PHY_CTRL_PLL_ON)
-+
-+#define L1F_MAC_STS 0x1410
-+#define L1F_MAC_STS_SFORCE_MASK ASHFT14(0xFUL)
-+#define L1F_MAC_STS_SFORCE_SHIFT 14
-+#define L1F_MAC_STS_CALIB_DONE BIT13
-+#define L1F_MAC_STS_CALIB_RES_MASK ASHFT8(0x1FUL)
-+#define L1F_MAC_STS_CALIB_RES_SHIFT 8
-+#define L1F_MAC_STS_CALIBERR_MASK ASHFT4(0xFUL)
-+#define L1F_MAC_STS_CALIBERR_SHIFT 4
-+#define L1F_MAC_STS_TXQ_BUSY BIT(3)
-+#define L1F_MAC_STS_RXQ_BUSY BIT(2)
-+#define L1F_MAC_STS_TXMAC_BUSY BIT(1)
-+#define L1F_MAC_STS_RXMAC_BUSY BIT(0)
-+#define L1F_MAC_STS_IDLE (\
-+ L1F_MAC_STS_TXQ_BUSY |\
-+ L1F_MAC_STS_RXQ_BUSY |\
-+ L1F_MAC_STS_TXMAC_BUSY |\
-+ L1F_MAC_STS_RXMAC_BUSY)
-+
-+#define L1F_MDIO 0x1414
-+#define L1F_MDIO_MODE_EXT BIT(30) /* 0:normal,1:ext */
-+#define L1F_MDIO_POST_READ BIT(29)
-+#define L1F_MDIO_AUTO_POLLING BIT(28)
-+#define L1F_MDIO_BUSY BIT(27)
-+#define L1F_MDIO_CLK_SEL_MASK ASHFT24(7UL)
-+#define L1F_MDIO_CLK_SEL_SHIFT 24
-+#define L1F_MDIO_CLK_SEL_25MD4 0 /* 25M DIV 4 */
-+#define L1F_MDIO_CLK_SEL_25MD6 2
-+#define L1F_MDIO_CLK_SEL_25MD8 3
-+#define L1F_MDIO_CLK_SEL_25MD10 4
-+#define L1F_MDIO_CLK_SEL_25MD32 5
-+#define L1F_MDIO_CLK_SEL_25MD64 6
-+#define L1F_MDIO_CLK_SEL_25MD128 7
-+#define L1F_MDIO_START BIT(23)
-+#define L1F_MDIO_SPRES_PRMBL BIT(22)
-+#define L1F_MDIO_OP_READ BIT(21) /* 1:read,0:write */
-+#define L1F_MDIO_REG_MASK ASHFT16(0x1FUL)
-+#define L1F_MDIO_REG_SHIFT 16
-+#define L1F_MDIO_DATA_MASK ASHFT0(0xFFFFUL)
-+#define L1F_MDIO_DATA_SHIFT 0
-+#define L1F_MDIO_MAX_AC_TO 120
-+
-+#define L1F_MDIO_EXTN 0x1448
-+#define L1F_MDIO_EXTN_PORTAD_MASK ASHFT21(0x1FUL)
-+#define L1F_MDIO_EXTN_PORTAD_SHIFT 21
-+#define L1F_MDIO_EXTN_DEVAD_MASK ASHFT16(0x1FUL)
-+#define L1F_MDIO_EXTN_DEVAD_SHIFT 16
-+#define L1F_MDIO_EXTN_REG_MASK ASHFT0(0xFFFFUL)
-+#define L1F_MDIO_EXTN_REG_SHIFT 0
-+
-+#define L1F_PHY_STS 0x1418
-+#define L1F_PHY_STS_LPW BIT(31)
-+#define L1F_PHY_STS_LPI BIT(30)
-+#define L1F_PHY_STS_PWON_STRIP_MASK ASHFT16(0xFFFUL)
-+#define L1F_PHY_STS_PWON_STRIP_SHIFT 16
-+
-+#define L1F_PHY_STS_DUPLEX BIT(3)
-+#define L1F_PHY_STS_LINKUP BIT(2)
-+#define L1F_PHY_STS_SPEED_MASK ASHFT0(3UL)
-+#define L1F_PHY_STS_SPEED_SHIFT 0
-+#define L1F_PHY_STS_SPEED_1000M 2
-+#define L1F_PHY_STS_SPEED_100M 1
-+#define L1F_PHY_STS_SPEED_10M 0
-+
-+#define L1F_BIST0 0x141C
-+#define L1F_BIST0_COL_MASK ASHFT24(0x3FUL)
-+#define L1F_BIST0_COL_SHIFT 24
-+#define L1F_BIST0_ROW_MASK ASHFT12(0xFFFUL)
-+#define L1F_BIST0_ROW_SHIFT 12
-+#define L1F_BIST0_STEP_MASK ASHFT8(0xFUL)
-+#define L1F_BIST0_STEP_SHIFT 8
-+#define L1F_BIST0_PATTERN_MASK ASHFT4(7UL)
-+#define L1F_BIST0_PATTERN_SHIFT 4
-+#define L1F_BIST0_CRIT BIT(3)
-+#define L1F_BIST0_FIXED BIT(2)
-+#define L1F_BIST0_FAIL BIT(1)
-+#define L1F_BIST0_START BIT(0)
-+
-+#define L1F_BIST1 0x1420
-+#define L1F_BIST1_COL_MASK ASHFT24(0x3FUL)
-+#define L1F_BIST1_COL_SHIFT 24
-+#define L1F_BIST1_ROW_MASK ASHFT12(0xFFFUL)
-+#define L1F_BIST1_ROW_SHIFT 12
-+#define L1F_BIST1_STEP_MASK ASHFT8(0xFUL)
-+#define L1F_BIST1_STEP_SHIFT 8
-+#define L1F_BIST1_PATTERN_MASK ASHFT4(7UL)
-+#define L1F_BIST1_PATTERN_SHIFT 4
-+#define L1F_BIST1_CRIT BIT(3)
-+#define L1F_BIST1_FIXED BIT(2)
-+#define L1F_BIST1_FAIL BIT(1)
-+#define L1F_BIST1_START BIT(0)
-+
-+#define L1F_SERDES 0x1424
-+#define L1F_SERDES_PHYCLK_SLWDWN BIT(18)
-+#define L1F_SERDES_MACCLK_SLWDWN BIT(17)
-+#define L1F_SERDES_SELFB_PLL_MASK ASHFT14(3UL)
-+#define L1F_SERDES_SELFB_PLL_SHIFT 14
-+#define L1F_SERDES_PHYCLK_SEL_GTX BIT(13) /* 1:gtx_clk, 0:25M */
-+#define L1F_SERDES_PCIECLK_SEL_SRDS BIT(12) /* 1:serdes,0:25M */
-+#define L1F_SERDES_BUFS_RX_EN BIT(11)
-+#define L1F_SERDES_PD_RX BIT(10)
-+#define L1F_SERDES_PLL_EN BIT(9)
-+#define L1F_SERDES_EN BIT(8)
-+#define L1F_SERDES_SELFB_PLL_SEL_CSR BIT(6) /* 0:state-machine,1:csr */
-+#define L1F_SERDES_SELFB_PLL_CSR_MASK ASHFT4(3UL)
-+#define L1F_SERDES_SELFB_PLL_CSR_SHIFT 4
-+#define L1F_SERDES_SELFB_PLL_CSR_4 3 /* 4-12% OV-CLK */
-+#define L1F_SERDES_SELFB_PLL_CSR_0 2 /* 0-4% OV-CLK */
-+#define L1F_SERDES_SELFB_PLL_CSR_12 1 /* 12-18% OV-CLK */
-+#define L1F_SERDES_SELFB_PLL_CSR_18 0 /* 18-25% OV-CLK */
-+#define L1F_SERDES_VCO_SLOW BIT(3)
-+#define L1F_SERDES_VCO_FAST BIT(2)
-+#define L1F_SERDES_LOCKDCT_EN BIT(1)
-+#define L1F_SERDES_LOCKDCTED BIT(0)
-+
-+#define L1F_LED_CTRL 0x1428
-+#define L1F_LED_CTRL_PATMAP2_MASK ASHFT8(3UL)
-+#define L1F_LED_CTRL_PATMAP2_SHIFT 8
-+#define L1F_LED_CTRL_PATMAP1_MASK ASHFT6(3UL)
-+#define L1F_LED_CTRL_PATMAP1_SHIFT 6
-+#define L1F_LED_CTRL_PATMAP0_MASK ASHFT4(3UL)
-+#define L1F_LED_CTRL_PATMAP0_SHIFT 4
-+#define L1F_LED_CTRL_D3_MODE_MASK ASHFT2(3UL)
-+#define L1F_LED_CTRL_D3_MODE_SHIFT 2
-+#define L1F_LED_CTRL_D3_MODE_NORMAL 0
-+#define L1F_LED_CTRL_D3_MODE_WOL_DIS 1
-+#define L1F_LED_CTRL_D3_MODE_WOL_ANY 2
-+#define L1F_LED_CTRL_D3_MODE_WOL_EN 3
-+#define L1F_LED_CTRL_DUTY_CYCL_MASK ASHFT0(3UL)
-+#define L1F_LED_CTRL_DUTY_CYCL_SHIFT 0
-+#define L1F_LED_CTRL_DUTY_CYCL_50 0 /* 50% */
-+#define L1F_LED_CTRL_DUTY_CYCL_125 1 /* 12.5% */
-+#define L1F_LED_CTRL_DUTY_CYCL_25 2 /* 25% */
-+#define L1F_LED_CTRL_DUTY_CYCL_75 3 /* 75% */
-+
-+#define L1F_LED_PATN 0x142C
-+#define L1F_LED_PATN1_MASK ASHFT16(0xFFFFUL)
-+#define L1F_LED_PATN1_SHIFT 16
-+#define L1F_LED_PATN0_MASK ASHFT0(0xFFFFUL)
-+#define L1F_LED_PATN0_SHIFT 0
-+
-+#define L1F_LED_PATN2 0x1430
-+#define L1F_LED_PATN2_MASK ASHFT0(0xFFFFUL)
-+#define L1F_LED_PATN2_SHIFT 0
-+
-+#define L1F_SYSALV 0x1434
-+#define L1F_SYSALV_FLAG BIT(0)
-+
-+#define L1F_PCIERR_INST 0x1438
-+#define L1F_PCIERR_INST_TX_RATE_MASK ASHFT4(0xFUL)
-+#define L1F_PCIERR_INST_TX_RATE_SHIFT 4
-+#define L1F_PCIERR_INST_RX_RATE_MASK ASHFT0(0xFUL)
-+#define L1F_PCIERR_INST_RX_RATE_SHIFT 0
-+
-+#define L1F_LPI_DECISN_TIMER 0x143C
-+
-+#define L1F_LPI_CTRL 0x1440
-+#define L1F_LPI_CTRL_CHK_DA BIT(31)
-+#define L1F_LPI_CTRL_ENH_TO_MASK ASHFT12(0x1FFFUL)
-+#define L1F_LPI_CTRL_ENH_TO_SHIFT 12
-+#define L1F_LPI_CTRL_ENH_TH_MASK ASHFT6(0x1FUL)
-+#define L1F_LPI_CTRL_ENH_TH_SHIFT 6
-+#define L1F_LPI_CTRL_ENH_EN BIT(5)
-+#define L1F_LPI_CTRL_CHK_RX BIT(4)
-+#define L1F_LPI_CTRL_CHK_STATE BIT(3)
-+#define L1F_LPI_CTRL_GMII BIT(2)
-+#define L1F_LPI_CTRL_TO_PHY BIT(1)
-+#define L1F_LPI_CTRL_EN BIT(0)
-+
-+#define L1F_LPI_WAIT 0x1444
-+#define L1F_LPI_WAIT_TIMER_MASK ASHFT0(0xFFFFUL)
-+#define L1F_LPI_WAIT_TIMER_SHIFT 0
-+
-+#define L1F_HRTBT_VLAN 0x1450 /* HEARTBEAT, FOR CIFS */
-+#define L1F_HRTBT_VLANID_MASK ASHFT0(0xFFFFUL) /* OR CLOUD */
-+#define L1F_HRRBT_VLANID_SHIFT 0
-+
-+#define L1F_HRTBT_CTRL 0x1454
-+#define L1F_HRTBT_CTRL_EN BIT(31)
-+#define L1F_HRTBT_CTRL_PERIOD_MASK ASHFT25(0x3FUL)
-+#define L1F_HRTBT_CTRL_PERIOD_SHIFT 25
-+#define L1F_HRTBT_CTRL_HASVLAN BIT(24)
-+#define L1F_HRTBT_CTRL_HDRADDR_MASK ASHFT12(0xFFFUL) /* A0 */
-+#define L1F_HRTBT_CTRL_HDRADDR_SHIFT 12
-+#define L1F_HRTBT_CTRL_HDRADDRB0_MASK ASHFT13(0x7FFUL) /* B0 */
-+#define L1F_HRTBT_CTRL_HDRADDRB0_SHIFT 13
-+#define L1F_HRTBT_CTRL_PKT_FRAG BIT(12) /* B0 */
-+#define L1F_HRTBT_CTRL_PKTLEN_MASK ASHFT0(0xFFFUL)
-+#define L1F_HRTBT_CTRL_PKTLEN_SHIFT 0
-+
-+#define L1F_HRTBT_EXT_CTRL 0x1AD0 /* B0 */
-+#define L1F_HRTBT_EXT_CTRL_NS_EN BIT(12)
-+#define L1F_HRTBT_EXT_CTRL_FRAG_LEN_MASK ASHFT4(0xFFUL)
-+#define L1F_HRTBT_EXT_CTRL_FRAG_LEN_SHIFT 4
-+#define L1F_HRTBT_EXT_CTRL_IS_8023 BIT(3)
-+#define L1F_HRTBT_EXT_CTRL_IS_IPV6 BIT(2)
-+#define L1F_HRTBT_EXT_CTRL_WAKEUP_EN BIT(1)
-+#define L1F_HRTBT_EXT_CTRL_ARP_EN BIT(0)
-+
-+#define L1F_HRTBT_REM_IPV4_ADDR 0x1AD4
-+#define L1F_HRTBT_HOST_IPV4_ADDR 0x1478/*use L1F_TRD_BUBBLE_DA_IP4*/
-+#define L1F_HRTBT_REM_IPV6_ADDR3 0x1AD8
-+#define L1F_HRTBT_REM_IPV6_ADDR2 0x1ADC
-+#define L1F_HRTBT_REM_IPV6_ADDR1 0x1AE0
-+#define L1F_HRTBT_REM_IPV6_ADDR0 0x1AE4
-+/*SWOI_HOST_IPV6_ADDR reuse reg1a60-1a6c, 1a70-1a7c, 1aa0-1aac, 1ab0-1abc.*/
-+#define L1F_HRTBT_WAKEUP_PORT 0x1AE8
-+#define L1F_HRTBT_WAKEUP_PORT_SRC_MASK ASHFT16(0xFFFFUL)
-+#define L1F_HRTBT_WAKEUP_PORT_SRC_SHIFT 16
-+#define L1F_HRTBT_WAKEUP_PORT_DEST_MASK ASHFT0(0xFFFFUL)
-+#define L1F_HRTBT_WAKEUP_PORT_DEST_SHIFT 0
-+
-+#define L1F_HRTBT_WAKEUP_DATA7 0x1AEC
-+#define L1F_HRTBT_WAKEUP_DATA6 0x1AF0
-+#define L1F_HRTBT_WAKEUP_DATA5 0x1AF4
-+#define L1F_HRTBT_WAKEUP_DATA4 0x1AF8
-+#define L1F_HRTBT_WAKEUP_DATA3 0x1AFC
-+#define L1F_HRTBT_WAKEUP_DATA2 0x1B80
-+#define L1F_HRTBT_WAKEUP_DATA1 0x1B84
-+#define L1F_HRTBT_WAKEUP_DATA0 0x1B88
-+
-+#define L1F_RXPARSE 0x1458
-+#define L1F_RXPARSE_FLT6_L4_MASK ASHFT30(3UL)
-+#define L1F_RXPARSE_FLT6_L4_SHIFT 30
-+#define L1F_RXPARSE_FLT6_L3_MASK ASHFT28(3UL)
-+#define L1F_RXPARSE_FLT6_L3_SHIFT 28
-+#define L1F_RXPARSE_FLT5_L4_MASK ASHFT26(3UL)
-+#define L1F_RXPARSE_FLT5_L4_SHIFT 26
-+#define L1F_RXPARSE_FLT5_L3_MASK ASHFT24(3UL)
-+#define L1F_RXPARSE_FLT5_L3_SHIFT 24
-+#define L1F_RXPARSE_FLT4_L4_MASK ASHFT22(3UL)
-+#define L1F_RXPARSE_FLT4_L4_SHIFT 22
-+#define L1F_RXPARSE_FLT4_L3_MASK ASHFT20(3UL)
-+#define L1F_RXPARSE_FLT4_L3_SHIFT 20
-+#define L1F_RXPARSE_FLT3_L4_MASK ASHFT18(3UL)
-+#define L1F_RXPARSE_FLT3_L4_SHIFT 18
-+#define L1F_RXPARSE_FLT3_L3_MASK ASHFT16(3UL)
-+#define L1F_RXPARSE_FLT3_L3_SHIFT 16
-+#define L1F_RXPARSE_FLT2_L4_MASK ASHFT14(3UL)
-+#define L1F_RXPARSE_FLT2_L4_SHIFT 14
-+#define L1F_RXPARSE_FLT2_L3_MASK ASHFT12(3UL)
-+#define L1F_RXPARSE_FLT2_L3_SHIFT 12
-+#define L1F_RXPARSE_FLT1_L4_MASK ASHFT10(3UL)
-+#define L1F_RXPARSE_FLT1_L4_SHIFT 10
-+#define L1F_RXPARSE_FLT1_L3_MASK ASHFT8(3UL)
-+#define L1F_RXPARSE_FLT1_L3_SHIFT 8
-+#define L1F_RXPARSE_FLT6_EN BIT(5)
-+#define L1F_RXPARSE_FLT5_EN BIT(4)
-+#define L1F_RXPARSE_FLT4_EN BIT(3)
-+#define L1F_RXPARSE_FLT3_EN BIT(2)
-+#define L1F_RXPARSE_FLT2_EN BIT(1)
-+#define L1F_RXPARSE_FLT1_EN BIT(0)
-+#define L1F_RXPARSE_FLT_L4_UDP 0
-+#define L1F_RXPARSE_FLT_L4_TCP 1
-+#define L1F_RXPARSE_FLT_L4_BOTH 2
-+#define L1F_RXPARSE_FLT_L4_NONE 3
-+#define L1F_RXPARSE_FLT_L3_IPV6 0
-+#define L1F_RXPARSE_FLT_L3_IPV4 1
-+#define L1F_RXPARSE_FLT_L3_BOTH 2
-+
-+/* Terodo support */
-+#define L1F_TRD_CTRL 0x145C
-+#define L1F_TRD_CTRL_EN BIT(31)
-+#define L1F_TRD_CTRL_BUBBLE_WAKE_EN BIT(30)
-+#define L1F_TRD_CTRL_PREFIX_CMP_HW BIT(28)
-+#define L1F_TRD_CTRL_RSHDR_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1F_TRD_CTRL_RSHDR_ADDR_SHIFT 16
-+#define L1F_TRD_CTRL_SINTV_MAX_MASK ASHFT8(0xFFUL)
-+#define L1F_TRD_CTRL_SINTV_MAX_SHIFT 8
-+#define L1F_TRD_CTRL_SINTV_MIN_MASK ASHFT0(0xFFUL)
-+#define L1F_TRD_CTRL_SINTV_MIN_SHIFT 0
-+
-+#define L1F_TRD_RS 0x1460
-+#define L1F_TRD_RS_SZ_MASK ASHFT20(0xFFFUL)
-+#define L1F_TRD_RS_SZ_SHIFT 20
-+#define L1F_TRD_RS_NONCE_OFS_MASK ASHFT8(0xFFFUL)
-+#define L1F_TRD_RS_NONCE_OFS_SHIFT 8
-+#define L1F_TRD_RS_SEQ_OFS_MASK ASHFT0(0xFFUL)
-+#define L1F_TRD_RS_SEQ_OFS_SHIFT 0
-+
-+#define L1F_TRD_SRV_IP4 0x1464
-+
-+#define L1F_TRD_CLNT_EXTNL_IP4 0x1468
-+
-+#define L1F_TRD_PORT 0x146C
-+#define L1F_TRD_PORT_CLNT_EXTNL_MASK ASHFT16(0xFFFFUL)
-+#define L1F_TRD_PORT_CLNT_EXTNL_SHIFT 16
-+#define L1F_TRD_PORT_SRV_MASK ASHFT0(0xFFFFUL)
-+#define L1F_TRD_PORT_SRV_SHIFT 0
-+
-+#define L1F_TRD_PREFIX 0x1470
-+
-+#define L1F_TRD_BUBBLE_DA_IP4 0x1478
-+
-+#define L1F_TRD_BUBBLE_DA_PORT 0x147C
-+
-+
-+#define L1F_IDLE_DECISN_TIMER 0x1474 /* B0 */
-+#define L1F_IDLE_DECISN_TIMER_DEF 0x400 /* 1ms */
-+
-+
-+#define L1F_MAC_CTRL 0x1480
-+#define L1F_MAC_CTRL_FAST_PAUSE BIT(31)
-+#define L1F_MAC_CTRL_WOLSPED_SWEN BIT(30)
-+#define L1F_MAC_CTRL_MHASH_ALG_HI5B BIT(29) /* 1:legacy, 0:marvl(low5b)*/
-+#define L1F_MAC_CTRL_SPAUSE_EN BIT(28)
-+#define L1F_MAC_CTRL_DBG_EN BIT(27)
-+#define L1F_MAC_CTRL_BRD_EN BIT(26)
-+#define L1F_MAC_CTRL_MULTIALL_EN BIT(25)
-+#define L1F_MAC_CTRL_RX_XSUM_EN BIT(24)
-+#define L1F_MAC_CTRL_THUGE BIT(23)
-+#define L1F_MAC_CTRL_MBOF BIT(22)
-+#define L1F_MAC_CTRL_SPEED_MASK ASHFT20(3UL)
-+#define L1F_MAC_CTRL_SPEED_SHIFT 20
-+#define L1F_MAC_CTRL_SPEED_10_100 1
-+#define L1F_MAC_CTRL_SPEED_1000 2
-+#define L1F_MAC_CTRL_SIMR BIT(19)
-+#define L1F_MAC_CTRL_SSTCT BIT(17)
-+#define L1F_MAC_CTRL_TPAUSE BIT(16)
-+#define L1F_MAC_CTRL_PROMISC_EN BIT(15)
-+#define L1F_MAC_CTRL_VLANSTRIP BIT(14)
-+#define L1F_MAC_CTRL_PRMBLEN_MASK ASHFT10(0xFUL)
-+#define L1F_MAC_CTRL_PRMBLEN_SHIFT 10
-+#define L1F_MAC_CTRL_RHUGE_EN BIT(9)
-+#define L1F_MAC_CTRL_FLCHK BIT(8)
-+#define L1F_MAC_CTRL_PCRCE BIT(7)
-+#define L1F_MAC_CTRL_CRCE BIT(6)
-+#define L1F_MAC_CTRL_FULLD BIT(5)
-+#define L1F_MAC_CTRL_LPBACK_EN BIT(4)
-+#define L1F_MAC_CTRL_RXFC_EN BIT(3)
-+#define L1F_MAC_CTRL_TXFC_EN BIT(2)
-+#define L1F_MAC_CTRL_RX_EN BIT(1)
-+#define L1F_MAC_CTRL_TX_EN BIT(0)
-+
-+#define L1F_GAP 0x1484
-+#define L1F_GAP_IPGR2_MASK ASHFT24(0x7FUL)
-+#define L1F_GAP_IPGR2_SHIFT 24
-+#define L1F_GAP_IPGR1_MASK ASHFT16(0x7FUL)
-+#define L1F_GAP_IPGR1_SHIFT 16
-+#define L1F_GAP_MIN_IFG_MASK ASHFT8(0xFFUL)
-+#define L1F_GAP_MIN_IFG_SHIFT 8
-+#define L1F_GAP_IPGT_MASK ASHFT0(0x7FUL) /* A0 diff with B0 */
-+#define L1F_GAP_IPGT_SHIFT 0
-+
-+#define L1F_STAD0 0x1488
-+#define L1F_STAD1 0x148C
-+
-+#define L1F_HASH_TBL0 0x1490
-+#define L1F_HASH_TBL1 0x1494
-+
-+#define L1F_HALFD 0x1498
-+#define L1F_HALFD_JAM_IPG_MASK ASHFT24(0xFUL)
-+#define L1F_HALFD_JAM_IPG_SHIFT 24
-+#define L1F_HALFD_ABEBT_MASK ASHFT20(0xFUL)
-+#define L1F_HALFD_ABEBT_SHIFT 20
-+#define L1F_HALFD_ABEBE BIT(19)
-+#define L1F_HALFD_BPNB BIT(18)
-+#define L1F_HALFD_NOBO BIT(17)
-+#define L1F_HALFD_EDXSDFR BIT(16)
-+#define L1F_HALFD_RETRY_MASK ASHFT12(0xFUL)
-+#define L1F_HALFD_RETRY_SHIFT 12
-+#define L1F_HALFD_LCOL_MASK ASHFT0(0x3FFUL)
-+#define L1F_HALFD_LCOL_SHIFT 0
-+
-+#define L1F_MTU 0x149C
-+#define L1F_MTU_JUMBO_TH 1514
-+#define L1F_MTU_STD_ALGN 1536
-+#define L1F_MTU_MIN 64
-+
-+#define L1F_SRAM0 0x1500
-+#define L1F_SRAM_RFD_TAIL_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1F_SRAM_RFD_TAIL_ADDR_SHIFT 16
-+#define L1F_SRAM_RFD_HEAD_ADDR_MASK ASHFT0(0xFFFUL)
-+#define L1F_SRAM_RFD_HEAD_ADDR_SHIFT 0
-+
-+#define L1F_SRAM1 0x1510
-+#define L1F_SRAM_RFD_LEN_MASK ASHFT0(0xFFFUL) /* 8BYTES UNIT */
-+#define L1F_SRAM_RFD_LEN_SHIFT 0
-+
-+#define L1F_SRAM2 0x1518
-+#define L1F_SRAM_TRD_TAIL_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1F_SRAM_TRD_TAIL_ADDR_SHIFT 16
-+#define L1F_SRMA_TRD_HEAD_ADDR_MASK ASHFT0(0xFFFUL)
-+#define L1F_SRAM_TRD_HEAD_ADDR_SHIFT 0
-+
-+#define L1F_SRAM3 0x151C
-+#define L1F_SRAM_TRD_LEN_MASK ASHFT0(0xFFFUL) /* 8BYTES UNIT */
-+#define L1F_SRAM_TRD_LEN_SHIFT 0
-+
-+#define L1F_SRAM4 0x1520
-+#define L1F_SRAM_RXF_TAIL_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1F_SRAM_RXF_TAIL_ADDR_SHIFT 16
-+#define L1F_SRAM_RXF_HEAD_ADDR_MASK ASHFT0(0xFFFUL)
-+#define L1F_SRAM_RXF_HEAD_ADDR_SHIFT 0
-+
-+#define L1F_SRAM5 0x1524
-+#define L1F_SRAM_RXF_LEN_MASK ASHFT0(0xFFFUL) /* 8BYTES UNIT */
-+#define L1F_SRAM_RXF_LEN_SHIFT 0
-+#define L1F_SRAM_RXF_LEN_8K (8*1024)
-+
-+#define L1F_SRAM6 0x1528
-+#define L1F_SRAM_TXF_TAIL_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1F_SRAM_TXF_TAIL_ADDR_SHIFT 16
-+#define L1F_SRAM_TXF_HEAD_ADDR_MASK ASHFT0(0xFFFUL)
-+#define L1F_SRAM_TXF_HEAD_ADDR_SHIFT 0
-+
-+#define L1F_SRAM7 0x152C
-+#define L1F_SRAM_TXF_LEN_MASK ASHFT0(0xFFFUL) /* 8BYTES UNIT */
-+#define L1F_SRAM_TXF_LEN_SHIFT 0
-+
-+#define L1F_SRAM8 0x1530
-+#define L1F_SRAM_PATTERN_ADDR_MASK ASHFT16(0xFFFUL)
-+#define L1F_SRAM_PATTERN_ADDR_SHIFT 16
-+#define L1F_SRAM_TSO_ADDR_MASK ASHFT0(0xFFFUL)
-+#define L1F_SRAM_TSO_ADDR_SHIFT 0
-+
-+#define L1F_SRAM9 0x1534
-+#define L1F_SRAM_LOAD_PTR BIT(0)
-+
-+#define L1F_RX_BASE_ADDR_HI 0x1540
-+
-+#define L1F_TX_BASE_ADDR_HI 0x1544
-+
-+#define L1F_RFD_ADDR_LO 0x1550
-+#define L1F_RFD_RING_SZ 0x1560
-+#define L1F_RFD_BUF_SZ 0x1564
-+#define L1F_RFD_BUF_SZ_MASK ASHFT0(0xFFFFUL)
-+#define L1F_RFD_BUF_SZ_SHIFT 0
-+
-+#define L1F_RRD_ADDR_LO 0x1568
-+#define L1F_RRD_RING_SZ 0x1578
-+#define L1F_RRD_RING_SZ_MASK ASHFT0(0xFFFUL)
-+#define L1F_RRD_RING_SZ_SHIFT 0
-+
-+#define L1F_TPD_PRI3_ADDR_LO 0x14E4 /* HIGHEST PRIORITY */
-+#define L1F_TPD_PRI2_ADDR_LO 0x14E0
-+#define L1F_TPD_PRI1_ADDR_LO 0x157C
-+#define L1F_TPD_PRI0_ADDR_LO 0x1580 /* LOWEST PRORITY */
-+
-+#define L1F_TPD_PRI3_PIDX 0x1618 /* 16BIT */
-+#define L1F_TPD_PRI2_PIDX 0x161A /* 16BIT */
-+#define L1F_TPD_PRI1_PIDX 0x15F0 /* 16BIT */
-+#define L1F_TPD_PRI0_PIDX 0x15F2 /* 16BIT */
-+
-+#define L1F_TPD_PRI3_CIDX 0x161C /* 16BIT */
-+#define L1F_TPD_PRI2_CIDX 0x161E /* 16BIT */
-+#define L1F_TPD_PRI1_CIDX 0x15F4 /* 16BIT */
-+#define L1F_TPD_PRI0_CIDX 0x15F6 /* 16BIT */
-+
-+#define L1F_TPD_RING_SZ 0x1584
-+#define L1F_TPD_RING_SZ_MASK ASHFT0(0xFFFFUL)
-+#define L1F_TPD_RING_SZ_SHIFT 0
-+
-+#define L1F_CMB_ADDR_LO 0x1588 /* NOT USED */
-+
-+#define L1F_TXQ0 0x1590
-+#define L1F_TXQ0_TXF_BURST_PREF_MASK ASHFT16(0xFFFFUL)
-+#define L1F_TXQ0_TXF_BURST_PREF_SHIFT 16
-+#define L1F_TXQ_TXF_BURST_PREF_DEF 0x200
-+#define L1F_TXQ0_PEDING_CLR BIT(8)
-+#define L1F_TXQ0_LSO_8023_EN BIT(7)
-+#define L1F_TXQ0_MODE_ENHANCE BIT(6)
-+#define L1F_TXQ0_EN BIT(5)
-+#define L1F_TXQ0_SUPT_IPOPT BIT(4)
-+#define L1F_TXQ0_TPD_BURSTPREF_MASK ASHFT0(0xFUL)
-+#define L1F_TXQ0_TPD_BURSTPREF_SHIFT 0
-+#define L1F_TXQ_TPD_BURSTPREF_DEF 5
-+
-+#define L1F_TXQ1 0x1594
-+#define L1F_TXQ1_ERRLGPKT_DROP_EN BIT(11) /* drop error large
-+ * (>rfd buf) packet */
-+#define L1F_TXQ1_JUMBO_TSOTHR_MASK ASHFT0(0x7FFUL) /* 8BYTES UNIT */
-+#define L1F_TXQ1_JUMBO_TSOTHR_SHIFT 0
-+#define L1F_TXQ1_JUMBO_TSO_TH (7*1024) /* byte */
-+
-+#define L1F_TXQ2 0x1598 /* ENTER L1 CONTROL */
-+#define L1F_TXQ2_BURST_EN BIT(31)
-+#define L1F_TXQ2_BURST_HI_WM_MASK ASHFT16(0xFFFUL)
-+#define L1F_TXQ2_BURST_HI_WM_SHIFT 16
-+#define L1F_TXQ2_BURST_LO_WM_MASK ASHFT0(0xFFFUL)
-+#define L1F_TXQ2_BURST_LO_WM_SHIFT 0
-+
-+#define L1F_RXQ0 0x15A0
-+#define L1F_RXQ0_EN BIT(31)
-+#define L1F_RXQ0_CUT_THRU_EN BIT(30)
-+#define L1F_RXQ0_RSS_HASH_EN BIT(29)
-+#define L1F_RXQ0_NON_IP_QTBL BIT(28) /* 0:q0,1:table */
-+#define L1F_RXQ0_RSS_MODE_MASK ASHFT26(3UL)
-+#define L1F_RXQ0_RSS_MODE_SHIFT 26
-+#define L1F_RXQ0_RSS_MODE_DIS 0
-+#define L1F_RXQ0_RSS_MODE_SQSI 1
-+#define L1F_RXQ0_RSS_MODE_MQSI 2
-+#define L1F_RXQ0_RSS_MODE_MQMI 3
-+#define L1F_RXQ0_NUM_RFD_PREF_MASK ASHFT20(0x3FUL)
-+#define L1F_RXQ0_NUM_RFD_PREF_SHIFT 20
-+#define L1F_RXQ0_NUM_RFD_PREF_DEF 8
-+#define L1F_RXQ0_IDT_TBL_SIZE_MASK ASHFT8(0x1FFUL)
-+#define L1F_RXQ0_IDT_TBL_SIZE_SHIFT 8
-+#define L1F_RXQ0_IDT_TBL_SIZE_DEF 0x100
-+#define L1F_RXQ0_IPV6_PARSE_EN BIT(7)
-+#define L1F_RXQ0_RSS_HSTYP_IPV6_TCP_EN BIT(5)
-+#define L1F_RXQ0_RSS_HSTYP_IPV6_EN BIT(4)
-+#define L1F_RXQ0_RSS_HSTYP_IPV4_TCP_EN BIT(3)
-+#define L1F_RXQ0_RSS_HSTYP_IPV4_EN BIT(2)
-+#define L1F_RXQ0_RSS_HSTYP_ALL (\
-+ L1F_RXQ0_RSS_HSTYP_IPV6_TCP_EN |\
-+ L1F_RXQ0_RSS_HSTYP_IPV4_TCP_EN |\
-+ L1F_RXQ0_RSS_HSTYP_IPV6_EN |\
-+ L1F_RXQ0_RSS_HSTYP_IPV4_EN)
-+#define L1F_RXQ0_ASPM_THRESH_MASK ASHFT0(3UL)
-+#define L1F_RXQ0_ASPM_THRESH_SHIFT 0
-+#define L1F_RXQ0_ASPM_THRESH_NO 0
-+#define L1F_RXQ0_ASPM_THRESH_1M 1
-+#define L1F_RXQ0_ASPM_THRESH_10M 2
-+#define L1F_RXQ0_ASPM_THRESH_100M 3
-+
-+#define L1F_RXQ1 0x15A4
-+#define L1F_RXQ1_JUMBO_LKAH_MASK ASHFT12(0xFUL) /* 32BYTES UNIT */
-+#define L1F_RXQ1_JUMBO_LKAH_SHIFT 12
-+#define L1F_RXQ1_RFD_PREF_DOWN_MASK ASHFT6(0x3FUL)
-+#define L1F_RXQ1_RFD_PREF_DOWN_SHIFT 6
-+#define L1F_RXQ1_RFD_PREF_UP_MASK ASHFT0(0x3FUL)
-+#define L1F_RXQ1_RFD_PREF_UP_SHIFT 0
-+
-+#define L1F_RXQ2 0x15A8
-+/* XOFF: USED SRAM LOWER THAN IT, THEN NOTIFY THE PEER TO SEND AGAIN */
-+#define L1F_RXQ2_RXF_XOFF_THRESH_MASK ASHFT16(0xFFFUL)
-+#define L1F_RXQ2_RXF_XOFF_THRESH_SHIFT 16
-+#define L1F_RXQ2_RXF_XON_THRESH_MASK ASHFT0(0xFFFUL)
-+#define L1F_RXQ2_RXF_XON_THRESH_SHIFT 0
-+
-+#define L1F_RXQ3 0x15AC
-+#define L1F_RXQ3_RXD_TIMER_MASK ASHFT16(0x7FFFUL)
-+#define L1F_RXQ3_RXD_TIMER_SHIFT 16
-+#define L1F_RXQ3_RXD_THRESH_MASK ASHFT0(0xFFFUL) /* 8BYTES UNIT */
-+#define L1F_RXQ3_RXD_THRESH_SHIFT 0
-+
-+#define L1F_DMA 0x15C0
-+#define L1F_DMA_SMB_NOW BIT(31)
-+#define L1F_DMA_WPEND_CLR BIT(30)
-+#define L1F_DMA_RPEND_CLR BIT(29)
-+#define L1F_DMA_WSRAM_RDCTRL BIT(28)
-+#define L1F_DMA_RCHNL_SEL_MASK ASHFT26(3UL)
-+#define L1F_DMA_RCHNL_SEL_SHIFT 26
-+#define L1F_DMA_RCHNL_SEL_1 0
-+#define L1F_DMA_RCHNL_SEL_2 1
-+#define L1F_DMA_RCHNL_SEL_3 2
-+#define L1F_DMA_RCHNL_SEL_4 3
-+#define L1F_DMA_SMB_EN BIT(21) /* smb dma enable */
-+#define L1F_DMA_WDLY_CNT_MASK ASHFT16(0xFUL)
-+#define L1F_DMA_WDLY_CNT_SHIFT 16
-+#define L1F_DMA_WDLY_CNT_DEF 4
-+#define L1F_DMA_RDLY_CNT_MASK ASHFT11(0x1FUL)
-+#define L1F_DMA_RDLY_CNT_SHIFT 11
-+#define L1F_DMA_RDLY_CNT_DEF 15
-+#define L1F_DMA_RREQ_PRI_DATA BIT(10) /* 0:tpd, 1:data */
-+#define L1F_DMA_WREQ_BLEN_MASK ASHFT7(7UL)
-+#define L1F_DMA_WREQ_BLEN_SHIFT 7
-+#define L1F_DMA_RREQ_BLEN_MASK ASHFT4(7UL)
-+#define L1F_DMA_RREQ_BLEN_SHIFT 4
-+#define L1F_DMA_PENDING_AUTO_RST BIT(3)
-+#define L1F_DMA_RORDER_MODE_MASK ASHFT0(7UL)
-+#define L1F_DMA_RORDER_MODE_SHIFT 0
-+#define L1F_DMA_RORDER_MODE_OUT 4
-+#define L1F_DMA_RORDER_MODE_ENHANCE 2
-+#define L1F_DMA_RORDER_MODE_IN 1
-+
-+#define L1F_WOL0 0x14A0
-+#define L1F_WOL0_PT7_MATCH BIT(31)
-+#define L1F_WOL0_PT6_MATCH BIT(30)
-+#define L1F_WOL0_PT5_MATCH BIT(29)
-+#define L1F_WOL0_PT4_MATCH BIT(28)
-+#define L1F_WOL0_PT3_MATCH BIT(27)
-+#define L1F_WOL0_PT2_MATCH BIT(26)
-+#define L1F_WOL0_PT1_MATCH BIT(25)
-+#define L1F_WOL0_PT0_MATCH BIT(24)
-+#define L1F_WOL0_PT7_EN BIT(23)
-+#define L1F_WOL0_PT6_EN BIT(22)
-+#define L1F_WOL0_PT5_EN BIT(21)
-+#define L1F_WOL0_PT4_EN BIT(20)
-+#define L1F_WOL0_PT3_EN BIT(19)
-+#define L1F_WOL0_PT2_EN BIT(18)
-+#define L1F_WOL0_PT1_EN BIT(17)
-+#define L1F_WOL0_PT0_EN BIT(16)
-+#define L1F_WOL0_IPV4_SYNC_EVT BIT(14)
-+#define L1F_WOL0_IPV6_SYNC_EVT BIT(13)
-+#define L1F_WOL0_LINK_EVT BIT(10)
-+#define L1F_WOL0_MAGIC_EVT BIT(9)
-+#define L1F_WOL0_PATTERN_EVT BIT(8)
-+#define L1F_WOL0_OOB_EN BIT(6)
-+#define L1F_WOL0_PME_LINK BIT(5)
-+#define L1F_WOL0_LINK_EN BIT(4)
-+#define L1F_WOL0_PME_MAGIC_EN BIT(3)
-+#define L1F_WOL0_MAGIC_EN BIT(2)
-+#define L1F_WOL0_PME_PATTERN_EN BIT(1)
-+#define L1F_WOL0_PATTERN_EN BIT(0)
-+
-+#define L1F_WOL1 0x14A4
-+#define L1F_WOL1_PT3_LEN_MASK ASHFT24(0xFFUL)
-+#define L1F_WOL1_PT3_LEN_SHIFT 24
-+#define L1F_WOL1_PT2_LEN_MASK ASHFT16(0xFFUL)
-+#define L1F_WOL1_PT2_LEN_SHIFT 16
-+#define L1F_WOL1_PT1_LEN_MASK ASHFT8(0xFFUL)
-+#define L1F_WOL1_PT1_LEN_SHIFT 8
-+#define L1F_WOL1_PT0_LEN_MASK ASHFT0(0xFFUL)
-+#define L1F_WOL1_PT0_LEN_SHIFT 0
-+
-+#define L1F_WOL2 0x14A8
-+#define L1F_WOL2_PT7_LEN_MASK ASHFT24(0xFFUL)
-+#define L1F_WOL2_PT7_LEN_SHIFT 24
-+#define L1F_WOL2_PT6_LEN_MASK ASHFT16(0xFFUL)
-+#define L1F_WOL2_PT6_LEN_SHIFT 16
-+#define L1F_WOL2_PT5_LEN_MASK ASHFT8(0xFFUL)
-+#define L1F_WOL2_PT5_LEN_SHIFT 8
-+#define L1F_WOL2_PT4_LEN_MASK ASHFT0(0xFFUL)
-+#define L1F_WOL2_PT4_LEN_SHIFT 0
-+
-+#define L1F_RFD_PIDX 0x15E0
-+#define L1F_RFD_PIDX_MASK ASHFT0(0xFFFUL)
-+#define L1F_RFD_PIDX_SHIFT 0
-+
-+#define L1F_RFD_CIDX 0x15F8
-+#define L1F_RFD_CIDX_MASK ASHFT0(0xFFFUL)
-+#define L1F_RFD_CIDX_SHIFT 0
-+
-+/* MIB */
-+#define L1F_MIB_BASE 0x1700
-+#define L1F_MIB_RX_OK (L1F_MIB_BASE + 0)
-+#define L1F_MIB_RX_BC (L1F_MIB_BASE + 4)
-+#define L1F_MIB_RX_MC (L1F_MIB_BASE + 8)
-+#define L1F_MIB_RX_PAUSE (L1F_MIB_BASE + 12)
-+#define L1F_MIB_RX_CTRL (L1F_MIB_BASE + 16)
-+#define L1F_MIB_RX_FCS (L1F_MIB_BASE + 20)
-+#define L1F_MIB_RX_LENERR (L1F_MIB_BASE + 24)
-+#define L1F_MIB_RX_BYTCNT (L1F_MIB_BASE + 28)
-+#define L1F_MIB_RX_RUNT (L1F_MIB_BASE + 32)
-+#define L1F_MIB_RX_FRAGMENT (L1F_MIB_BASE + 36)
-+#define L1F_MIB_RX_64B (L1F_MIB_BASE + 40)
-+#define L1F_MIB_RX_127B (L1F_MIB_BASE + 44)
-+#define L1F_MIB_RX_255B (L1F_MIB_BASE + 48)
-+#define L1F_MIB_RX_511B (L1F_MIB_BASE + 52)
-+#define L1F_MIB_RX_1023B (L1F_MIB_BASE + 56)
-+#define L1F_MIB_RX_1518B (L1F_MIB_BASE + 60)
-+#define L1F_MIB_RX_SZMAX (L1F_MIB_BASE + 64)
-+#define L1F_MIB_RX_OVSZ (L1F_MIB_BASE + 68)
-+#define L1F_MIB_RXF_OV (L1F_MIB_BASE + 72)
-+#define L1F_MIB_RRD_OV (L1F_MIB_BASE + 76)
-+#define L1F_MIB_RX_ALIGN (L1F_MIB_BASE + 80)
-+#define L1F_MIB_RX_BCCNT (L1F_MIB_BASE + 84)
-+#define L1F_MIB_RX_MCCNT (L1F_MIB_BASE + 88)
-+#define L1F_MIB_RX_ERRADDR (L1F_MIB_BASE + 92)
-+#define L1F_MIB_TX_OK (L1F_MIB_BASE + 96)
-+#define L1F_MIB_TX_BC (L1F_MIB_BASE + 100)
-+#define L1F_MIB_TX_MC (L1F_MIB_BASE + 104)
-+#define L1F_MIB_TX_PAUSE (L1F_MIB_BASE + 108)
-+#define L1F_MIB_TX_EXCDEFER (L1F_MIB_BASE + 112)
-+#define L1F_MIB_TX_CTRL (L1F_MIB_BASE + 116)
-+#define L1F_MIB_TX_DEFER (L1F_MIB_BASE + 120)
-+#define L1F_MIB_TX_BYTCNT (L1F_MIB_BASE + 124)
-+#define L1F_MIB_TX_64B (L1F_MIB_BASE + 128)
-+#define L1F_MIB_TX_127B (L1F_MIB_BASE + 132)
-+#define L1F_MIB_TX_255B (L1F_MIB_BASE + 136)
-+#define L1F_MIB_TX_511B (L1F_MIB_BASE + 140)
-+#define L1F_MIB_TX_1023B (L1F_MIB_BASE + 144)
-+#define L1F_MIB_TX_1518B (L1F_MIB_BASE + 148)
-+#define L1F_MIB_TX_SZMAX (L1F_MIB_BASE + 152)
-+#define L1F_MIB_TX_1COL (L1F_MIB_BASE + 156)
-+#define L1F_MIB_TX_2COL (L1F_MIB_BASE + 160)
-+#define L1F_MIB_TX_LATCOL (L1F_MIB_BASE + 164)
-+#define L1F_MIB_TX_ABRTCOL (L1F_MIB_BASE + 168)
-+#define L1F_MIB_TX_UNDRUN (L1F_MIB_BASE + 172)
-+#define L1F_MIB_TX_TRDBEOP (L1F_MIB_BASE + 176)
-+#define L1F_MIB_TX_LENERR (L1F_MIB_BASE + 180)
-+#define L1F_MIB_TX_TRUNC (L1F_MIB_BASE + 184)
-+#define L1F_MIB_TX_BCCNT (L1F_MIB_BASE + 188)
-+#define L1F_MIB_TX_MCCNT (L1F_MIB_BASE + 192)
-+#define L1F_MIB_UPDATE (L1F_MIB_BASE + 196)
-+
-+/******************************************************************************/
-+
-+#define L1F_ISR 0x1600
-+#define L1F_ISR_DIS BIT(31)
-+#define L1F_ISR_RX_Q7 BIT(30)
-+#define L1F_ISR_RX_Q6 BIT(29)
-+#define L1F_ISR_RX_Q5 BIT(28)
-+#define L1F_ISR_RX_Q4 BIT(27)
-+#define L1F_ISR_PCIE_LNKDOWN BIT(26)
-+#define L1F_ISR_PCIE_CERR BIT(25)
-+#define L1F_ISR_PCIE_NFERR BIT(24)
-+#define L1F_ISR_PCIE_FERR BIT(23)
-+#define L1F_ISR_PCIE_UR BIT(22)
-+#define L1F_ISR_MAC_TX BIT(21)
-+#define L1F_ISR_MAC_RX BIT(20)
-+#define L1F_ISR_RX_Q3 BIT(19)
-+#define L1F_ISR_RX_Q2 BIT(18)
-+#define L1F_ISR_RX_Q1 BIT(17)
-+#define L1F_ISR_RX_Q0 BIT(16)
-+#define L1F_ISR_TX_Q0 BIT(15)
-+#define L1F_ISR_TXQ_TO BIT(14)
-+#define L1F_ISR_PHY_LPW BIT(13)
-+#define L1F_ISR_PHY BIT(12)
-+#define L1F_ISR_TX_CREDIT BIT(11)
-+#define L1F_ISR_DMAW BIT(10)
-+#define L1F_ISR_DMAR BIT(9)
-+#define L1F_ISR_TXF_UR BIT(8)
-+#define L1F_ISR_TX_Q3 BIT(7)
-+#define L1F_ISR_TX_Q2 BIT(6)
-+#define L1F_ISR_TX_Q1 BIT(5)
-+#define L1F_ISR_RFD_UR BIT(4)
-+#define L1F_ISR_RXF_OV BIT(3)
-+#define L1F_ISR_MANU BIT(2)
-+#define L1F_ISR_TIMER BIT(1)
-+#define L1F_ISR_SMB BIT(0)
-+
-+#define L1F_IMR 0x1604
-+
-+#define L1F_INT_RETRIG 0x1608 /* re-send deassrt/assert
-+ * if sw no reflect */
-+#define L1F_INT_RETRIG_TIMER_MASK ASHFT0(0xFFFFUL)
-+#define L1F_INT_RETRIG_TIMER_SHIFT 0
-+#define L1F_INT_RETRIG_TO 20000 /* 40ms */
-+
-+#define L1F_INT_DEASST_TIMER 0x1614 /* re-send deassert
-+ * if sw no reflect */
-+
-+#define L1F_PATTERN_MASK 0x1620 /* 128bytes, sleep state */
-+#define L1F_PATTERN_MASK_LEN 128
-+
-+
-+#define L1F_FLT1_SRC_IP0 0x1A00
-+#define L1F_FLT1_SRC_IP1 0x1A04
-+#define L1F_FLT1_SRC_IP2 0x1A08
-+#define L1F_FLT1_SRC_IP3 0x1A0C
-+#define L1F_FLT1_DST_IP0 0x1A10
-+#define L1F_FLT1_DST_IP1 0x1A14
-+#define L1F_FLT1_DST_IP2 0x1A18
-+#define L1F_FLT1_DST_IP3 0x1A1C
-+#define L1F_FLT1_PORT 0x1A20
-+#define L1F_FLT1_PORT_DST_MASK ASHFT16(0xFFFFUL)
-+#define L1F_FLT1_PORT_DST_SHIFT 16
-+#define L1F_FLT1_PORT_SRC_MASK ASHFT0(0xFFFFUL)
-+#define L1F_FLT1_PORT_SRC_SHIFT 0
-+
-+#define L1F_FLT2_SRC_IP0 0x1A24
-+#define L1F_FLT2_SRC_IP1 0x1A28
-+#define L1F_FLT2_SRC_IP2 0x1A2C
-+#define L1F_FLT2_SRC_IP3 0x1A30
-+#define L1F_FLT2_DST_IP0 0x1A34
-+#define L1F_FLT2_DST_IP1 0x1A38
-+#define L1F_FLT2_DST_IP2 0x1A40
-+#define L1F_FLT2_DST_IP3 0x1A44
-+#define L1F_FLT2_PORT 0x1A48
-+#define L1F_FLT2_PORT_DST_MASK ASHFT16(0xFFFFUL)
-+#define L1F_FLT2_PORT_DST_SHIFT 16
-+#define L1F_FLT2_PORT_SRC_MASK ASHFT0(0xFFFFUL)
-+#define L1F_FLT2_PORT_SRC_SHIFT 0
-+
-+#define L1F_FLT3_SRC_IP0 0x1A4C
-+#define L1F_FLT3_SRC_IP1 0x1A50
-+#define L1F_FLT3_SRC_IP2 0x1A54
-+#define L1F_FLT3_SRC_IP3 0x1A58
-+#define L1F_FLT3_DST_IP0 0x1A5C
-+#define L1F_FLT3_DST_IP1 0x1A60
-+#define L1F_FLT3_DST_IP2 0x1A64
-+#define L1F_FLT3_DST_IP3 0x1A68
-+#define L1F_FLT3_PORT 0x1A6C
-+#define L1F_FLT3_PORT_DST_MASK ASHFT16(0xFFFFUL)
-+#define L1F_FLT3_PORT_DST_SHIFT 16
-+#define L1F_FLT3_PORT_SRC_MASK ASHFT0(0xFFFFUL)
-+#define L1F_FLT3_PORT_SRC_SHIFT 0
-+
-+#define L1F_FLT4_SRC_IP0 0x1A70
-+#define L1F_FLT4_SRC_IP1 0x1A74
-+#define L1F_FLT4_SRC_IP2 0x1A78
-+#define L1F_FLT4_SRC_IP3 0x1A7C
-+#define L1F_FLT4_DST_IP0 0x1A80
-+#define L1F_FLT4_DST_IP1 0x1A84
-+#define L1F_FLT4_DST_IP2 0x1A88
-+#define L1F_FLT4_DST_IP3 0x1A8C
-+#define L1F_FLT4_PORT 0x1A90
-+#define L1F_FLT4_PORT_DST_MASK ASHFT16(0xFFFFUL)
-+#define L1F_FLT4_PORT_DST_SHIFT 16
-+#define L1F_FLT4_PORT_SRC_MASK ASHFT0(0xFFFFUL)
-+#define L1F_FLT4_PORT_SRC_SHIFT 0
-+
-+#define L1F_FLT5_SRC_IP0 0x1A94
-+#define L1F_FLT5_SRC_IP1 0x1A98
-+#define L1F_FLT5_SRC_IP2 0x1A9C
-+#define L1F_FLT5_SRC_IP3 0x1AA0
-+#define L1F_FLT5_DST_IP0 0x1AA4
-+#define L1F_FLT5_DST_IP1 0x1AA8
-+#define L1F_FLT5_DST_IP2 0x1AAC
-+#define L1F_FLT5_DST_IP3 0x1AB0
-+#define L1F_FLT5_PORT 0x1AB4
-+#define L1F_FLT5_PORT_DST_MASK ASHFT16(0xFFFFUL)
-+#define L1F_FLT5_PORT_DST_SHIFT 16
-+#define L1F_FLT5_PORT_SRC_MASK ASHFT0(0xFFFFUL)
-+#define L1F_FLT5_PORT_SRC_SHIFT 0
-+
-+#define L1F_FLT6_SRC_IP0 0x1AB8
-+#define L1F_FLT6_SRC_IP1 0x1ABC
-+#define L1F_FLT6_SRC_IP2 0x1AC0
-+#define L1F_FLT6_SRC_IP3 0x1AC8
-+#define L1F_FLT6_DST_IP0 0x1620 /* only S0 state */
-+#define L1F_FLT6_DST_IP1 0x1624
-+#define L1F_FLT6_DST_IP2 0x1628
-+#define L1F_FLT6_DST_IP3 0x162C
-+#define L1F_FLT6_PORT 0x1630
-+#define L1F_FLT6_PORT_DST_MASK ASHFT16(0xFFFFUL)
-+#define L1F_FLT6_PORT_DST_SHIFT 16
-+#define L1F_FLT6_PORT_SRC_MASK ASHFT0(0xFFFFUL)
-+#define L1F_FLT6_PORT_SRC_SHIFT 0
-+
-+#define L1F_FLTCTRL 0x1634
-+#define L1F_FLTCTRL_PSTHR_TIMER_MASK ASHFT24(0xFFUL)
-+#define L1F_FLTCTRL_PSTHR_TIMER_SHIFT 24
-+#define L1F_FLTCTRL_CHK_DSTPRT6 BIT(23)
-+#define L1F_FLTCTRL_CHK_SRCPRT6 BIT(22)
-+#define L1F_FLTCTRL_CHK_DSTIP6 BIT(21)
-+#define L1F_FLTCTRL_CHK_SRCIP6 BIT(20)
-+#define L1F_FLTCTRL_CHK_DSTPRT5 BIT(19)
-+#define L1F_FLTCTRL_CHK_SRCPRT5 BIT(18)
-+#define L1F_FLTCTRL_CHK_DSTIP5 BIT(17)
-+#define L1F_FLTCTRL_CHK_SRCIP5 BIT(16)
-+#define L1F_FLTCTRL_CHK_DSTPRT4 BIT(15)
-+#define L1F_FLTCTRL_CHK_SRCPRT4 BIT(14)
-+#define L1F_FLTCTRL_CHK_DSTIP4 BIT(13)
-+#define L1F_FLTCTRL_CHK_SRCIP4 BIT(12)
-+#define L1F_FLTCTRL_CHK_DSTPRT3 BIT(11)
-+#define L1F_FLTCTRL_CHK_SRCPRT3 BIT(10)
-+#define L1F_FLTCTRL_CHK_DSTIP3 BIT(9)
-+#define L1F_FLTCTRL_CHK_SRCIP3 BIT(8)
-+#define L1F_FLTCTRL_CHK_DSTPRT2 BIT(7)
-+#define L1F_FLTCTRL_CHK_SRCPRT2 BIT(6)
-+#define L1F_FLTCTRL_CHK_DSTIP2 BIT(5)
-+#define L1F_FLTCTRL_CHK_SRCIP2 BIT(4)
-+#define L1F_FLTCTRL_CHK_DSTPRT1 BIT(3)
-+#define L1F_FLTCTRL_CHK_SRCPRT1 BIT(2)
-+#define L1F_FLTCTRL_CHK_DSTIP1 BIT(1)
-+#define L1F_FLTCTRL_CHK_SRCIP1 BIT(0)
-+
-+#define L1F_DROP_ALG1 0x1638
-+#define L1F_DROP_ALG1_BWCHGVAL_MASK ASHFT12(0xFFFFFUL)
-+#define L1F_DROP_ALG1_BWCHGVAL_SHIFT 12
-+#define L1F_DROP_ALG1_BWCHGSCL_6 BIT(11) /* 0:3.125%, 1:6.25% */
-+#define L1F_DROP_ALG1_ASUR_LWQ_EN BIT(10)
-+#define L1F_DROP_ALG1_BWCHGVAL_EN BIT(9)
-+#define L1F_DROP_ALG1_BWCHGSCL_EN BIT(8)
-+#define L1F_DROP_ALG1_PSTHR_AUTO BIT(7) /* 0:manual, 1:auto */
-+#define L1F_DROP_ALG1_MIN_PSTHR_MASK ASHFT5(3UL)
-+#define L1F_DROP_ALG1_MIN_PSTHR_SHIFT 5
-+#define L1F_DROP_ALG1_MIN_PSTHR_1_16 0
-+#define L1F_DROP_ALG1_MIN_PSTHR_1_8 1
-+#define L1F_DROP_ALG1_MIN_PSTHR_1_4 2
-+#define L1F_DROP_ALG1_MIN_PSTHR_1_2 3
-+#define L1F_DROP_ALG1_PSCL_MASK ASHFT3(3UL)
-+#define L1F_DROP_ALG1_PSCL_SHIFT 3
-+#define L1F_DROP_ALG1_PSCL_1_4 0
-+#define L1F_DROP_ALG1_PSCL_1_8 1
-+#define L1F_DROP_ALG1_PSCL_1_16 2
-+#define L1F_DROP_ALG1_PSCL_1_32 3
-+#define L1F_DROP_ALG1_TIMESLOT_MASK ASHFT0(7UL)
-+#define L1F_DROP_ALG1_TIMESLOT_SHIFT 0
-+#define L1F_DROP_ALG1_TIMESLOT_4MS 0
-+#define L1F_DROP_ALG1_TIMESLOT_8MS 1
-+#define L1F_DROP_ALG1_TIMESLOT_16MS 2
-+#define L1F_DROP_ALG1_TIMESLOT_32MS 3
-+#define L1F_DROP_ALG1_TIMESLOT_64MS 4
-+#define L1F_DROP_ALG1_TIMESLOT_128MS 5
-+#define L1F_DROP_ALG1_TIMESLOT_256MS 6
-+#define L1F_DROP_ALG1_TIMESLOT_512MS 7
-+
-+#define L1F_DROP_ALG2 0x163C
-+#define L1F_DROP_ALG2_SMPLTIME_MASK ASHFT24(0xFUL)
-+#define L1F_DROP_ALG2_SMPLTIME_SHIFT 24
-+#define L1F_DROP_ALG2_LWQBW_MASK ASHFT0(0xFFFFFFUL)
-+#define L1F_DROP_ALG2_LWQBW_SHIFT 0
-+
-+#define L1F_SMB_TIMER 0x15C4
-+
-+#define L1F_TINT_TPD_THRSHLD 0x15C8
-+
-+#define L1F_TINT_TIMER 0x15CC
-+
-+#define L1F_CLK_GATE 0x1814
-+#define L1F_CLK_GATE_125M_SW_DIS_CR BIT(8) /* B0 */
-+#define L1F_CLK_GATE_125M_SW_AZ BIT(7) /* B0 */
-+#define L1F_CLK_GATE_125M_SW_IDLE BIT(6) /* B0 */
-+#define L1F_CLK_GATE_RXMAC BIT(5)
-+#define L1F_CLK_GATE_TXMAC BIT(4)
-+#define L1F_CLK_GATE_RXQ BIT(3)
-+#define L1F_CLK_GATE_TXQ BIT(2)
-+#define L1F_CLK_GATE_DMAR BIT(1)
-+#define L1F_CLK_GATE_DMAW BIT(0)
-+#define L1F_CLK_GATE_ALL_A0 (\
-+ L1F_CLK_GATE_RXMAC |\
-+ L1F_CLK_GATE_TXMAC |\
-+ L1F_CLK_GATE_RXQ |\
-+ L1F_CLK_GATE_TXQ |\
-+ L1F_CLK_GATE_DMAR |\
-+ L1F_CLK_GATE_DMAW)
-+#define L1F_CLK_GATE_ALL_B0 (\
-+ L1F_CLK_GATE_ALL_A0 |\
-+ L1F_CLK_GATE_125M_SW_AZ |\
-+ L1F_CLK_GATE_125M_SW_IDLE)
-+
-+
-+
-+
-+
-+#define L1F_BTROM_CFG 0x1800 /* pwon rst */
-+
-+#define L1F_DRV 0x1804
-+/* bit definition is in lx_hwcomm.h */
-+
-+#define L1F_DRV_ERR1 0x1808 /* perst */
-+#define L1F_DRV_ERR1_GEN BIT(31) /* geneneral err */
-+#define L1F_DRV_ERR1_NOR BIT(30) /* rrd.nor */
-+#define L1F_DRV_ERR1_TRUNC BIT(29)
-+#define L1F_DRV_ERR1_RES BIT(28)
-+#define L1F_DRV_ERR1_INTFATAL BIT(27)
-+#define L1F_DRV_ERR1_TXQPEND BIT(26)
-+#define L1F_DRV_ERR1_DMAW BIT(25)
-+#define L1F_DRV_ERR1_DMAR BIT(24)
-+#define L1F_DRV_ERR1_PCIELNKDWN BIT(23)
-+#define L1F_DRV_ERR1_PKTSIZE BIT(22)
-+#define L1F_DRV_ERR1_FIFOFUL BIT(21)
-+#define L1F_DRV_ERR1_RFDUR BIT(20)
-+#define L1F_DRV_ERR1_RRDSI BIT(19)
-+#define L1F_DRV_ERR1_UPDATE BIT(18)
-+
-+#define L1F_DRV_ERR2 0x180C
-+
-+#define L1F_DBG_ADDR 0x1900 /* DWORD reg */
-+#define L1F_DBG_DATA 0x1904 /* DWORD reg */
-+
-+#define L1F_SYNC_IPV4_SA 0x1A00
-+#define L1F_SYNC_IPV4_DA 0x1A04
-+
-+#define L1F_SYNC_V4PORT 0x1A08
-+#define L1F_SYNC_V4PORT_DST_MASK ASHFT16(0xFFFFUL)
-+#define L1F_SYNC_V4PORT_DST_SHIFT 16
-+#define L1F_SYNC_V4PORT_SRC_MASK ASHFT0(0xFFFFUL)
-+#define L1F_SYNC_V4PORT_SRC_SHIFT 0
-+
-+#define L1F_SYNC_IPV6_SA0 0x1A0C
-+#define L1F_SYNC_IPV6_SA1 0x1A10
-+#define L1F_SYNC_IPV6_SA2 0x1A14
-+#define L1F_SYNC_IPV6_SA3 0x1A18
-+#define L1F_SYNC_IPV6_DA0 0x1A1C
-+#define L1F_SYNC_IPV6_DA1 0x1A20
-+#define L1F_SYNC_IPV6_DA2 0x1A24
-+#define L1F_SYNC_IPV6_DA3 0x1A28
-+
-+#define L1F_SYNC_V6PORT 0x1A2C
-+#define L1F_SYNC_V6PORT_DST_MASK ASHFT16(0xFFFFUL)
-+#define L1F_SYNC_V6PORT_DST_SHIFT 16
-+#define L1F_SYNC_V6PORT_SRC_MASK ASHFT0(0xFFFFUL)
-+#define L1F_SYNC_V6PORT_SRC_SHIFT 0
-+
-+#define L1F_ARP_REMOTE_IPV4 0x1A30
-+#define L1F_ARP_HOST_IPV4 0x1A34
-+#define L1F_ARP_MAC0 0x1A38
-+#define L1F_ARP_MAC1 0x1A3C
-+
-+#define L1F_1ST_REMOTE_IPV6_0 0x1A40
-+#define L1F_1ST_REMOTE_IPV6_1 0x1A44
-+#define L1F_1ST_REMOTE_IPV6_2 0x1A48
-+#define L1F_1ST_REMOTE_IPV6_3 0x1A4C
-+
-+#define L1F_1ST_SN_IPV6_0 0x1A50
-+#define L1F_1ST_SN_IPV6_1 0x1A54
-+#define L1F_1ST_SN_IPV6_2 0x1A58
-+#define L1F_1ST_SN_IPV6_3 0x1A5C
-+
-+#define L1F_1ST_TAR_IPV6_1_0 0x1A60
-+#define L1F_1ST_TAR_IPV6_1_1 0x1A64
-+#define L1F_1ST_TAR_IPV6_1_2 0x1A68
-+#define L1F_1ST_TAR_IPV6_1_3 0x1A6C
-+#define L1F_1ST_TAR_IPV6_2_0 0x1A70
-+#define L1F_1ST_TAR_IPV6_2_1 0x1A74
-+#define L1F_1ST_TAR_IPV6_2_2 0x1A78
-+#define L1F_1ST_TAR_IPV6_2_3 0x1A7C
-+
-+#define L1F_2ND_REMOTE_IPV6_0 0x1A80
-+#define L1F_2ND_REMOTE_IPV6_1 0x1A84
-+#define L1F_2ND_REMOTE_IPV6_2 0x1A88
-+#define L1F_2ND_REMOTE_IPV6_3 0x1A8C
-+
-+#define L1F_2ND_SN_IPV6_0 0x1A90
-+#define L1F_2ND_SN_IPV6_1 0x1A94
-+#define L1F_2ND_SN_IPV6_2 0x1A98
-+#define L1F_2ND_SN_IPV6_3 0x1A9C
-+
-+#define L1F_2ND_TAR_IPV6_1_0 0x1AA0
-+#define L1F_2ND_TAR_IPV6_1_1 0x1AA4
-+#define L1F_2ND_TAR_IPV6_1_2 0x1AA8
-+#define L1F_2ND_TAR_IPV6_1_3 0x1AAC
-+#define L1F_2ND_TAR_IPV6_2_0 0x1AB0
-+#define L1F_2ND_TAR_IPV6_2_1 0x1AB4
-+#define L1F_2ND_TAR_IPV6_2_2 0x1AB8
-+#define L1F_2ND_TAR_IPV6_2_3 0x1ABC
-+
-+#define L1F_1ST_NS_MAC0 0x1AC0
-+#define L1F_1ST_NS_MAC1 0x1AC4
-+
-+#define L1F_2ND_NS_MAC0 0x1AC8
-+#define L1F_2ND_NS_MAC1 0x1ACC
-+
-+#define L1F_PMOFLD 0x144C
-+#define L1F_PMOFLD_ECMA_IGNR_FRG_SSSR BIT(11) /* B0 */
-+#define L1F_PMOFLD_ARP_CNFLCT_WAKEUP BIT(10) /* B0 */
-+#define L1F_PMOFLD_MULTI_SOLD BIT(9)
-+#define L1F_PMOFLD_ICMP_XSUM BIT(8)
-+#define L1F_PMOFLD_GARP_REPLY BIT(7)
-+#define L1F_PMOFLD_SYNCV6_ANY BIT(6)
-+#define L1F_PMOFLD_SYNCV4_ANY BIT(5)
-+#define L1F_PMOFLD_BY_HW BIT(4)
-+#define L1F_PMOFLD_NS_EN BIT(3)
-+#define L1F_PMOFLD_ARP_EN BIT(2)
-+#define L1F_PMOFLD_SYNCV6_EN BIT(1)
-+#define L1F_PMOFLD_SYNCV4_EN BIT(0)
-+
-+#define L1F_RSS_KEY0 0x14B0
-+#define L1F_RSS_KEY1 0x14B4
-+#define L1F_RSS_KEY2 0x14B8
-+#define L1F_RSS_KEY3 0x14BC
-+#define L1F_RSS_KEY4 0x14C0
-+#define L1F_RSS_KEY5 0x14C4
-+#define L1F_RSS_KEY6 0x14C8
-+#define L1F_RSS_KEY7 0x14CC
-+#define L1F_RSS_KEY8 0x14D0
-+#define L1F_RSS_KEY9 0x14D4
-+
-+#define L1F_RSS_IDT_TBL0 0x1B00
-+#define L1F_RSS_IDT_TBL1 0x1B04
-+#define L1F_RSS_IDT_TBL2 0x1B08
-+#define L1F_RSS_IDT_TBL3 0x1B0C
-+#define L1F_RSS_IDT_TBL4 0x1B10
-+#define L1F_RSS_IDT_TBL5 0x1B14
-+#define L1F_RSS_IDT_TBL6 0x1B18
-+#define L1F_RSS_IDT_TBL7 0x1B1C
-+#define L1F_RSS_IDT_TBL8 0x1B20
-+#define L1F_RSS_IDT_TBL9 0x1B24
-+#define L1F_RSS_IDT_TBL10 0x1B28
-+#define L1F_RSS_IDT_TBL11 0x1B2C
-+#define L1F_RSS_IDT_TBL12 0x1B30
-+#define L1F_RSS_IDT_TBL13 0x1B34
-+#define L1F_RSS_IDT_TBL14 0x1B38
-+#define L1F_RSS_IDT_TBL15 0x1B3C
-+#define L1F_RSS_IDT_TBL16 0x1B40
-+#define L1F_RSS_IDT_TBL17 0x1B44
-+#define L1F_RSS_IDT_TBL18 0x1B48
-+#define L1F_RSS_IDT_TBL19 0x1B4C
-+#define L1F_RSS_IDT_TBL20 0x1B50
-+#define L1F_RSS_IDT_TBL21 0x1B54
-+#define L1F_RSS_IDT_TBL22 0x1B58
-+#define L1F_RSS_IDT_TBL23 0x1B5C
-+#define L1F_RSS_IDT_TBL24 0x1B60
-+#define L1F_RSS_IDT_TBL25 0x1B64
-+#define L1F_RSS_IDT_TBL26 0x1B68
-+#define L1F_RSS_IDT_TBL27 0x1B6C
-+#define L1F_RSS_IDT_TBL28 0x1B70
-+#define L1F_RSS_IDT_TBL29 0x1B74
-+#define L1F_RSS_IDT_TBL30 0x1B78
-+#define L1F_RSS_IDT_TBL31 0x1B7C
-+
-+#define L1F_RSS_HASH_VAL 0x15B0
-+#define L1F_RSS_HASH_FLAG 0x15B4
-+
-+#define L1F_RSS_BASE_CPU_NUM 0x15B8
-+
-+#define L1F_MSI_MAP_TBL1 0x15D0
-+#define L1F_MSI_MAP_TBL1_ALERT_MASK ASHFT28(0xFUL)
-+#define L1F_MSI_MAP_TBL1_ALERT_SHIFT 28
-+#define L1F_MSI_MAP_TBL1_TIMER_MASK ASHFT24(0xFUL)
-+#define L1F_MSI_MAP_TBL1_TIMER_SHIFT 24
-+#define L1F_MSI_MAP_TBL1_TXQ1_MASK ASHFT20(0xFUL)
-+#define L1F_MSI_MAP_TBL1_TXQ1_SHIFT 20
-+#define L1F_MSI_MAP_TBL1_TXQ0_MASK ASHFT16(0xFUL)
-+#define L1F_MSI_MAP_TBL1_TXQ0_SHIFT 16
-+#define L1F_MSI_MAP_TBL1_RXQ3_MASK ASHFT12(0xFUL)
-+#define L1F_MSI_MAP_TBL1_RXQ3_SHIFT 12
-+#define L1F_MSI_MAP_TBL1_RXQ2_MASK ASHFT8(0xFUL)
-+#define L1F_MSI_MAP_TBL1_RXQ2_SHIFT 8
-+#define L1F_MSI_MAP_TBL1_RXQ1_MASK ASHFT4(0xFUL)
-+#define L1F_MSI_MAP_TBL1_RXQ1_SHIFT 4
-+#define L1F_MSI_MAP_TBL1_RXQ0_MASK ASHFT0(0xFUL)
-+#define L1F_MSI_MAP_TBL1_RXQ0_SHIFT 0
-+
-+#define L1F_MSI_MAP_TBL2 0x15D8
-+#define L1F_MSI_MAP_TBL2_PHY_MASK ASHFT28(0xFUL)
-+#define L1F_MSI_MAP_TBL2_PHY_SHIFT 28
-+#define L1F_MSI_MAP_TBL2_SMB_MASK ASHFT24(0xFUL)
-+#define L1F_MSI_MAP_TBL2_SMB_SHIFT 24
-+#define L1F_MSI_MAP_TBL2_TXQ3_MASK ASHFT20(0xFUL)
-+#define L1F_MSI_MAP_TBL2_TXQ3_SHIFT 20
-+#define L1F_MSI_MAP_TBL2_TXQ2_MASK ASHFT16(0xFUL)
-+#define L1F_MSI_MAP_TBL2_TXQ2_SHIFT 16
-+#define L1F_MSI_MAP_TBL2_RXQ7_MASK ASHFT12(0xFUL)
-+#define L1F_MSI_MAP_TBL2_RXQ7_SHIFT 12
-+#define L1F_MSI_MAP_TBL2_RXQ6_MASK ASHFT8(0xFUL)
-+#define L1F_MSI_MAP_TBL2_RXQ6_SHIFT 8
-+#define L1F_MSI_MAP_TBL2_RXQ5_MASK ASHFT4(0xFUL)
-+#define L1F_MSI_MAP_TBL2_RXQ5_SHIFT 4
-+#define L1F_MSI_MAP_TBL2_RXQ4_MASK ASHFT0(0xFUL)
-+#define L1F_MSI_MAP_TBL2_RXQ4_SHIFT 0
-+
-+#define L1F_MSI_ID_MAP 0x15D4
-+#define L1F_MSI_ID_MAP_RXQ7 BIT(30)
-+#define L1F_MSI_ID_MAP_RXQ6 BIT(29)
-+#define L1F_MSI_ID_MAP_RXQ5 BIT(28)
-+#define L1F_MSI_ID_MAP_RXQ4 BIT(27)
-+#define L1F_MSI_ID_MAP_PCIELNKDW BIT(26) /* 0:common,1:timer */
-+#define L1F_MSI_ID_MAP_PCIECERR BIT(25)
-+#define L1F_MSI_ID_MAP_PCIENFERR BIT(24)
-+#define L1F_MSI_ID_MAP_PCIEFERR BIT(23)
-+#define L1F_MSI_ID_MAP_PCIEUR BIT(22)
-+#define L1F_MSI_ID_MAP_MACTX BIT(21)
-+#define L1F_MSI_ID_MAP_MACRX BIT(20)
-+#define L1F_MSI_ID_MAP_RXQ3 BIT(19)
-+#define L1F_MSI_ID_MAP_RXQ2 BIT(18)
-+#define L1F_MSI_ID_MAP_RXQ1 BIT(17)
-+#define L1F_MSI_ID_MAP_RXQ0 BIT(16)
-+#define L1F_MSI_ID_MAP_TXQ0 BIT(15)
-+#define L1F_MSI_ID_MAP_TXQTO BIT(14)
-+#define L1F_MSI_ID_MAP_LPW BIT(13)
-+#define L1F_MSI_ID_MAP_PHY BIT(12)
-+#define L1F_MSI_ID_MAP_TXCREDIT BIT(11)
-+#define L1F_MSI_ID_MAP_DMAW BIT(10)
-+#define L1F_MSI_ID_MAP_DMAR BIT(9)
-+#define L1F_MSI_ID_MAP_TXFUR BIT(8)
-+#define L1F_MSI_ID_MAP_TXQ3 BIT(7)
-+#define L1F_MSI_ID_MAP_TXQ2 BIT(6)
-+#define L1F_MSI_ID_MAP_TXQ1 BIT(5)
-+#define L1F_MSI_ID_MAP_RFDUR BIT(4)
-+#define L1F_MSI_ID_MAP_RXFOV BIT(3)
-+#define L1F_MSI_ID_MAP_MANU BIT(2)
-+#define L1F_MSI_ID_MAP_TIMER BIT(1)
-+#define L1F_MSI_ID_MAP_SMB BIT(0)
-+
-+#define L1F_MSI_RETRANS_TIMER 0x1920
-+#define L1F_MSI_MASK_SEL_LINE BIT(16) /* 1:line,0:standard*/
-+#define L1F_MSI_RETRANS_TM_MASK ASHFT0(0xFFFFUL)
-+#define L1F_MSI_RETRANS_TM_SHIFT 0
-+
-+#define L1F_CR_DMA_CTRL 0x1930
-+#define L1F_CR_DMA_CTRL_PRI BIT(22)
-+#define L1F_CR_DMA_CTRL_RRDRXD_JOINT BIT(21)
-+#define L1F_CR_DMA_CTRL_BWCREDIT_MASK ASHFT19(0x3UL)
-+#define L1F_CR_DMA_CTRL_BWCREDIT_SHIFT 19
-+#define L1F_CR_DMA_CTRL_BWCREDIT_2KB 0
-+#define L1F_CR_DMA_CTRL_BWCREDIT_1KB 1
-+#define L1F_CR_DMA_CTRL_BWCREDIT_4KB 2
-+#define L1F_CR_DMA_CTRL_BWCREDIT_8KB 3
-+#define L1F_CR_DMA_CTRL_BW_EN BIT(18)
-+#define L1F_CR_DMA_CTRL_BW_RATIO_MASK ASHFT16(0x3UL)
-+#define L1F_CR_DMA_CTRL_BW_RATIO_1_2 0
-+#define L1F_CR_DMA_CTRL_BW_RATIO_1_4 1
-+#define L1F_CR_DMA_CTRL_BW_RATIO_1_8 2
-+#define L1F_CR_DMA_CTRL_BW_RATIO_2_1 3
-+#define L1F_CR_DMA_CTRL_SOFT_RST BIT(11)
-+#define L1F_CR_DMA_CTRL_TXEARLY_EN BIT(10)
-+#define L1F_CR_DMA_CTRL_RXEARLY_EN BIT(9)
-+#define L1F_CR_DMA_CTRL_WEARLY_EN BIT(8)
-+#define L1F_CR_DMA_CTRL_RXTH_MASK ASHFT4(0xFUL)
-+#define L1F_CR_DMA_CTRL_WTH_MASK ASHFT0(0xFUL)
-+
-+
-+#define L1F_EFUSE_BIST 0x1934
-+#define L1F_EFUSE_BIST_COL_MASK ASHFT24(0x3FUL)
-+#define L1F_EFUSE_BIST_COL_SHIFT 24
-+#define L1F_EFUSE_BIST_ROW_MASK ASHFT12(0x7FUL)
-+#define L1F_EFUSE_BIST_ROW_SHIFT 12
-+#define L1F_EFUSE_BIST_STEP_MASK ASHFT8(0xFUL)
-+#define L1F_EFUSE_BIST_STEP_SHIFT 8
-+#define L1F_EFUSE_BIST_PAT_MASK ASHFT4(0x7UL)
-+#define L1F_EFUSE_BIST_PAT_SHIFT 4
-+#define L1F_EFUSE_BIST_CRITICAL BIT(3)
-+#define L1F_EFUSE_BIST_FIXED BIT(2)
-+#define L1F_EFUSE_BIST_FAIL BIT(1)
-+#define L1F_EFUSE_BIST_NOW BIT(0)
-+
-+/* CR DMA ctrl */
-+
-+/* TX QoS */
-+#define L1F_WRR 0x1938
-+#define L1F_WRR_PRI_MASK ASHFT29(3UL)
-+#define L1F_WRR_PRI_SHIFT 29
-+#define L1F_WRR_PRI_RESTRICT_ALL 0
-+#define L1F_WRR_PRI_RESTRICT_HI 1
-+#define L1F_WRR_PRI_RESTRICT_HI2 2
-+#define L1F_WRR_PRI_RESTRICT_NONE 3
-+#define L1F_WRR_PRI3_MASK ASHFT24(0x1FUL)
-+#define L1F_WRR_PRI3_SHIFT 24
-+#define L1F_WRR_PRI2_MASK ASHFT16(0x1FUL)
-+#define L1F_WRR_PRI2_SHIFT 16
-+#define L1F_WRR_PRI1_MASK ASHFT8(0x1FUL)
-+#define L1F_WRR_PRI1_SHIFT 8
-+#define L1F_WRR_PRI0_MASK ASHFT0(0x1FUL)
-+#define L1F_WRR_PRI0_SHIFT 0
-+
-+#define L1F_HQTPD 0x193C
-+#define L1F_HQTPD_BURST_EN BIT(31)
-+#define L1F_HQTPD_Q3_NUMPREF_MASK ASHFT8(0xFUL)
-+#define L1F_HQTPD_Q3_NUMPREF_SHIFT 8
-+#define L1F_HQTPD_Q2_NUMPREF_MASK ASHFT4(0xFUL)
-+#define L1F_HQTPD_Q2_NUMPREF_SHIFT 4
-+#define L1F_HQTPD_Q1_NUMPREF_MASK ASHFT0(0xFUL)
-+#define L1F_HQTPD_Q1_NUMPREF_SHIFT 0
-+
-+#define L1F_CPUMAP1 0x19A0
-+#define L1F_CPUMAP1_VCT7_MASK ASHFT28(0xFUL)
-+#define L1F_CPUMAP1_VCT7_SHIFT 28
-+#define L1F_CPUMAP1_VCT6_MASK ASHFT24(0xFUL)
-+#define L1F_CPUMAP1_VCT6_SHIFT 24
-+#define L1F_CPUMAP1_VCT5_MASK ASHFT20(0xFUL)
-+#define L1F_CPUMAP1_VCT5_SHIFT 20
-+#define L1F_CPUMAP1_VCT4_MASK ASHFT16(0xFUL)
-+#define L1F_CPUMAP1_VCT4_SHIFT 16
-+#define L1F_CPUMAP1_VCT3_MASK ASHFT12(0xFUL)
-+#define L1F_CPUMAP1_VCT3_SHIFT 12
-+#define L1F_CPUMAP1_VCT2_MASK ASHFT8(0xFUL)
-+#define L1F_CPUMAP1_VCT2_SHIFT 8
-+#define L1F_CPUMAP1_VCT1_MASK ASHFT4(0xFUL)
-+#define L1F_CPUMAP1_VCT1_SHIFT 4
-+#define L1F_CPUMAP1_VCT0_MASK ASHFT0(0xFUL)
-+#define L1F_CPUMAP1_VCT0_SHIFT 0
-+
-+#define L1F_CPUMAP2 0x19A4
-+#define L1F_CPUMAP2_VCT15_MASK ASHFT28(0xFUL)
-+#define L1F_CPUMAP2_VCT15_SHIFT 28
-+#define L1F_CPUMAP2_VCT14_MASK ASHFT24(0xFUL)
-+#define L1F_CPUMAP2_VCT14_SHIFT 24
-+#define L1F_CPUMAP2_VCT13_MASK ASHFT20(0xFUL)
-+#define L1F_CPUMAP2_VCT13_SHIFT 20
-+#define L1F_CPUMAP2_VCT12_MASK ASHFT16(0xFUL)
-+#define L1F_CPUMAP2_VCT12_SHIFT 16
-+#define L1F_CPUMAP2_VCT11_MASK ASHFT12(0xFUL)
-+#define L1F_CPUMAP2_VCT11_SHIFT 12
-+#define L1F_CPUMAP2_VCT10_MASK ASHFT8(0xFUL)
-+#define L1F_CPUMAP2_VCT10_SHIFT 8
-+#define L1F_CPUMAP2_VCT9_MASK ASHFT4(0xFUL)
-+#define L1F_CPUMAP2_VCT9_SHIFT 4
-+#define L1F_CPUMAP2_VCT8_MASK ASHFT0(0xFUL)
-+#define L1F_CPUMAP2_VCT8_SHIFT 0
-+
-+#define L1F_MISC 0x19C0
-+#define L1F_MISC_MODU BIT(31) /* 0:vector,1:cpu */
-+#define L1F_MISC_OVERCUR BIT(29)
-+#define L1F_MISC_PSWR_EN BIT(28)
-+#define L1F_MISC_PSW_CTRL_MASK ASHFT24(0xFUL)
-+#define L1F_MISC_PSW_CTRL_SHIFT 24
-+#define L1F_MISC_PSW_OCP_MASK ASHFT21(7UL)
-+#define L1F_MISC_PSW_OCP_SHIFT 21
-+#define L1F_MISC_V18_HIGH BIT(20)
-+#define L1F_MISC_LPO_CTRL_MASK ASHFT16(0xFUL)
-+#define L1F_MISC_LPO_CTRL_SHIFT 16
-+#define L1F_MISC_ISO_EN BIT(12)
-+#define L1F_MISC_XSTANA_ALWAYS_ON BIT(11)
-+#define L1F_MISC_SYS25M_SEL_ADAPTIVE BIT(10)
-+#define L1F_MISC_SPEED_SIM BIT(9)
-+#define L1F_MISC_S1_LWP_EN BIT(8)
-+#define L1F_MISC_MACLPW BIT(7) /* pcie/mac do pwsaving
-+ * as phy in lpw state */
-+#define L1F_MISC_125M_SW BIT(6)
-+#define L1F_MISC_INTNLOSC_OFF_EN BIT(5)
-+#define L1F_MISC_EXTN25M_SEL BIT(4) /* 0:chipset,1:cystle */
-+#define L1F_MISC_INTNLOSC_OPEN BIT(3)
-+#define L1F_MISC_SMBUS_AT_LED BIT(2)
-+#define L1F_MISC_PPS_AT_LED_MASK ASHFT0(3UL)
-+#define L1F_MISC_PPS_AT_LED_SHIFT 0
-+#define L1F_MISC_PPS_AT_LED_ACT 1
-+#define L1F_MISC_PPS_AT_LED_10_100 2
-+#define L1F_MISC_PPS_AT_LED_1000 3
-+
-+#define L1F_MISC1 0x19C4
-+#define L1F_MSC1_BLK_CRASPM_REQ BIT(15)
-+
-+#define L1F_MISC3 0x19CC
-+#define L1F_MISC3_25M_BY_SW BIT(1) /* 1:Software control 25M */
-+#define L1F_MISC3_25M_NOTO_INTNL BIT(0) /* 0:25M switch to intnl OSC */
-+
-+
-+
-+/***************************** IO mapping registers ***************************/
-+#define L1F_IO_ADDR 0x00 /* DWORD reg */
-+#define L1F_IO_DATA 0x04 /* DWORD reg */
-+#define L1F_IO_MASTER 0x08 /* DWORD same as reg0x1400 */
-+#define L1F_IO_MAC_CTRL 0x0C /* DWORD same as reg0x1480*/
-+#define L1F_IO_ISR 0x10 /* DWORD same as reg0x1600 */
-+#define L1F_IO_IMR 0x14 /* DWORD same as reg0x1604 */
-+#define L1F_IO_TPD_PRI1_PIDX 0x18 /* WORD same as reg0x15F0 */
-+#define L1F_IO_TPD_PRI0_PIDX 0x1A /* WORD same as reg0x15F2 */
-+#define L1F_IO_TPD_PRI1_CIDX 0x1C /* WORD same as reg0x15F4 */
-+#define L1F_IO_TPD_PRI0_CIDX 0x1E /* WORD same as reg0x15F6 */
-+#define L1F_IO_RFD_PIDX 0x20 /* WORD same as reg0x15E0 */
-+#define L1F_IO_RFD_CIDX 0x30 /* WORD same as reg0x15F8 */
-+#define L1F_IO_MDIO 0x38 /* WORD same as reg0x1414 */
-+#define L1F_IO_PHY_CTRL 0x3C /* DWORD same as reg0x140C */
-+
-+
-+/********************* PHY regs definition ***************************/
-+
-+/* Autoneg Advertisement Register */
-+#define L1F_ADVERTISE_SPEED_MASK 0x01E0
-+#define L1F_ADVERTISE_DEFAULT_CAP 0x1DE0 /* diff with L1C */
-+
-+/* 1000BASE-T Control Register (0x9) */
-+#define L1F_GIGA_CR_1000T_HD_CAPS 0x0100
-+#define L1F_GIGA_CR_1000T_FD_CAPS 0x0200
-+#define L1F_GIGA_CR_1000T_REPEATER_DTE 0x0400
-+
-+#define L1F_GIGA_CR_1000T_MS_VALUE 0x0800
-+
-+#define L1F_GIGA_CR_1000T_MS_ENABLE 0x1000
-+
-+#define L1F_GIGA_CR_1000T_TEST_MODE_NORMAL 0x0000
-+#define L1F_GIGA_CR_1000T_TEST_MODE_1 0x2000
-+#define L1F_GIGA_CR_1000T_TEST_MODE_2 0x4000
-+#define L1F_GIGA_CR_1000T_TEST_MODE_3 0x6000
-+#define L1F_GIGA_CR_1000T_TEST_MODE_4 0x8000
-+#define L1F_GIGA_CR_1000T_SPEED_MASK 0x0300
-+#define L1F_GIGA_CR_1000T_DEFAULT_CAP 0x0300
-+
-+/* 1000BASE-T Status Register */
-+#define L1F_MII_GIGA_SR 0x0A
-+
-+/* PHY Specific Status Register */
-+#define L1F_MII_GIGA_PSSR 0x11
-+#define L1F_GIGA_PSSR_FC_RXEN 0x0004
-+#define L1F_GIGA_PSSR_FC_TXEN 0x0008
-+#define L1F_GIGA_PSSR_SPD_DPLX_RESOLVED 0x0800
-+#define L1F_GIGA_PSSR_DPLX 0x2000
-+#define L1F_GIGA_PSSR_SPEED 0xC000
-+#define L1F_GIGA_PSSR_10MBS 0x0000
-+#define L1F_GIGA_PSSR_100MBS 0x4000
-+#define L1F_GIGA_PSSR_1000MBS 0x8000
-+
-+/* PHY Interrupt Enable Register */
-+#define L1F_MII_IER 0x12
-+#define L1F_IER_LINK_UP 0x0400
-+#define L1F_IER_LINK_DOWN 0x0800
-+
-+/* PHY Interrupt Status Register */
-+#define L1F_MII_ISR 0x13
-+#define L1F_ISR_LINK_UP 0x0400
-+#define L1F_ISR_LINK_DOWN 0x0800
-+
-+/* Cable-Detect-Test Control Register */
-+#define L1F_MII_CDTC 0x16
-+#define L1F_CDTC_EN 1 /* sc */
-+#define L1F_CDTC_PAIR_MASK ASHFT8(3U)
-+#define L1F_CDTC_PAIR_SHIFT 8
-+
-+
-+/* Cable-Detect-Test Status Register */
-+#define L1F_MII_CDTS 0x1C
-+#define L1F_CDTS_STATUS_MASK ASHFT8(3U)
-+#define L1F_CDTS_STATUS_SHIFT 8
-+#define L1F_CDTS_STATUS_NORMAL 0
-+#define L1F_CDTS_STATUS_SHORT 1
-+#define L1F_CDTS_STATUS_OPEN 2
-+#define L1F_CDTS_STATUS_INVALID 3
-+
-+#define L1F_MII_DBG_ADDR 0x1D
-+#define L1F_MII_DBG_DATA 0x1E
-+
-+/***************************** debug port *************************************/
-+
-+#define L1F_MIIDBG_ANACTRL 0x00
-+#define L1F_ANACTRL_CLK125M_DELAY_EN BIT(15)
-+#define L1F_ANACTRL_VCO_FAST BIT(14)
-+#define L1F_ANACTRL_VCO_SLOW BIT(13)
-+#define L1F_ANACTRL_AFE_MODE_EN BIT(12)
-+#define L1F_ANACTRL_LCKDET_PHY BIT(11)
-+#define L1F_ANACTRL_LCKDET_EN BIT(10)
-+#define L1F_ANACTRL_OEN_125M BIT(9)
-+#define L1F_ANACTRL_HBIAS_EN BIT(8)
-+#define L1F_ANACTRL_HB_EN BIT(7)
-+#define L1F_ANACTRL_SEL_HSP BIT(6)
-+#define L1F_ANACTRL_CLASSA_EN BIT(5)
-+#define L1F_ANACTRL_MANUSWON_SWR_MASK ASHFT2(3U)
-+#define L1F_ANACTRL_MANUSWON_SWR_SHIFT 2
-+#define L1F_ANACTRL_MANUSWON_SWR_2V 0
-+#define L1F_ANACTRL_MANUSWON_SWR_1P9V 1
-+#define L1F_ANACTRL_MANUSWON_SWR_1P8V 2
-+#define L1F_ANACTRL_MANUSWON_SWR_1P7V 3
-+#define L1F_ANACTRL_MANUSWON_BW3_4M BIT(1)
-+#define L1F_ANACTRL_RESTART_CAL BIT(0)
-+#define L1F_ANACTRL_DEF 0x02EF
-+
-+
-+#define L1F_MIIDBG_SYSMODCTRL 0x04
-+#define L1F_SYSMODCTRL_IECHOADJ_PFMH_PHY BIT(15)
-+#define L1F_SYSMODCTRL_IECHOADJ_BIASGEN BIT(14)
-+#define L1F_SYSMODCTRL_IECHOADJ_PFML_PHY BIT(13)
-+#define L1F_SYSMODCTRL_IECHOADJ_PS_MASK ASHFT10(3U)
-+#define L1F_SYSMODCTRL_IECHOADJ_PS_SHIFT 10
-+#define L1F_SYSMODCTRL_IECHOADJ_PS_40 3
-+#define L1F_SYSMODCTRL_IECHOADJ_PS_20 2
-+#define L1F_SYSMODCTRL_IECHOADJ_PS_0 1
-+#define L1F_SYSMODCTRL_IECHOADJ_10BT_100MV BIT(6) /* 1:100mv, 0:200mv */
-+#define L1F_SYSMODCTRL_IECHOADJ_HLFAP_MASK ASHFT4(3U)
-+#define L1F_SYSMODCTRL_IECHOADJ_HLFAP_SHIFT 4
-+#define L1F_SYSMODCTRL_IECHOADJ_VDFULBW BIT(3)
-+#define L1F_SYSMODCTRL_IECHOADJ_VDBIASHLF BIT(2)
-+#define L1F_SYSMODCTRL_IECHOADJ_VDAMPHLF BIT(1)
-+#define L1F_SYSMODCTRL_IECHOADJ_VDLANSW BIT(0)
-+#define L1F_SYSMODCTRL_IECHOADJ_DEF 0xBB8B /* en half bias */
-+
-+
-+#define L1F_MIIDBG_SRDSYSMOD 0x05
-+#define L1F_SRDSYSMOD_LCKDET_EN BIT(13)
-+#define L1F_SRDSYSMOD_PLL_EN BIT(11)
-+#define L1F_SRDSYSMOD_SEL_HSP BIT(10)
-+#define L1F_SRDSYSMOD_HLFTXDR BIT(9)
-+#define L1F_SRDSYSMOD_TXCLK_DELAY_EN BIT(8)
-+#define L1F_SRDSYSMOD_TXELECIDLE BIT(7)
-+#define L1F_SRDSYSMOD_DEEMP_EN BIT(6)
-+#define L1F_SRDSYSMOD_MS_PAD BIT(2)
-+#define L1F_SRDSYSMOD_CDR_ADC_VLTG BIT(1)
-+#define L1F_SRDSYSMOD_CDR_DAC_1MA BIT(0)
-+#define L1F_SRDSYSMOD_DEF 0x2C46
-+
-+
-+#define L1F_MIIDBG_HIBNEG 0x0B
-+#define L1F_HIBNEG_PSHIB_EN BIT(15)
-+#define L1F_HIBNEG_WAKE_BOTH BIT(14)
-+#define L1F_HIBNEG_ONOFF_ANACHG_SUDEN BIT(13)
-+#define L1F_HIBNEG_HIB_PULSE BIT(12)
-+#define L1F_HIBNEG_GATE_25M_EN BIT(11)
-+#define L1F_HIBNEG_RST_80U BIT(10)
-+#define L1F_HIBNEG_RST_TIMER_MASK ASHFT8(3U)
-+#define L1F_HIBNEG_RST_TIMER_SHIFT 8
-+#define L1F_HIBNEG_GTX_CLK_DELAY_MASK ASHFT5(3U)
-+#define L1F_HIBNEG_GTX_CLK_DELAY_SHIFT 5
-+#define L1F_HIBNEG_BYPSS_BRKTIMER BIT(4)
-+#define L1F_HIBNEG_DEF 0xBC40
-+
-+#define L1F_MIIDBG_TST10BTCFG 0x12
-+#define L1F_TST10BTCFG_INTV_TIMER_MASK ASHFT14(3U)
-+#define L1F_TST10BTCFG_INTV_TIMER_SHIFT 14
-+#define L1F_TST10BTCFG_TRIGER_TIMER_MASK ASHFT12(3U)
-+#define L1F_TST10BTCFG_TRIGER_TIMER_SHIFT 12
-+#define L1F_TST10BTCFG_DIV_MAN_MLT3_EN BIT(11)
-+#define L1F_TST10BTCFG_OFF_DAC_IDLE BIT(10)
-+#define L1F_TST10BTCFG_LPBK_DEEP BIT(2) /* 1:deep,0:shallow */
-+#define L1F_TST10BTCFG_DEF 0x4C04
-+
-+#define L1F_MIIDBG_AZ_ANADECT 0x15
-+#define L1F_AZ_ANADECT_10BTRX_TH BIT(15)
-+#define L1F_AZ_ANADECT_BOTH_01CHNL BIT(14)
-+#define L1F_AZ_ANADECT_INTV_MASK ASHFT8(0x3FU)
-+#define L1F_AZ_ANADECT_INTV_SHIFT 8
-+#define L1F_AZ_ANADECT_THRESH_MASK ASHFT4(0xFU)
-+#define L1F_AZ_ANADECT_THRESH_SHIFT 4
-+#define L1F_AZ_ANADECT_CHNL_MASK ASHFT0(0xFU)
-+#define L1F_AZ_ANADECT_CHNL_SHIFT 0
-+#define L1F_AZ_ANADECT_DEF 0x3220
-+#define L1F_AZ_ANADECT_LONG 0x3210
-+
-+#define L1F_MIIDBG_AGC 0x23
-+#define L1F_AGC_2_VGA_MASK ASHFT8(0x3FU)
-+#define L1F_AGC_2_VGA_SHIFT 8
-+#define L1F_AGC_LONG1G_LIMT 40
-+#define L1F_AGC_LONG100M_LIMT 44
-+
-+#define L1F_MIIDBG_LEGCYPS 0x29
-+#define L1F_LEGCYPS_EN BIT(15)
-+#define L1F_LEGCYPS_DAC_AMP1000_MASK ASHFT12(7U)
-+#define L1F_LEGCYPS_DAC_AMP1000_SHIFT 12
-+#define L1F_LEGCYPS_DAC_AMP100_MASK ASHFT9(7U)
-+#define L1F_LEGCYPS_DAC_AMP100_SHIFT 9
-+#define L1F_LEGCYPS_DAC_AMP10_MASK ASHFT6(7U)
-+#define L1F_LEGCYPS_DAC_AMP10_SHIFT 6
-+#define L1F_LEGCYPS_UNPLUG_TIMER_MASK ASHFT3(7U)
-+#define L1F_LEGCYPS_UNPLUG_TIMER_SHIFT 3
-+#define L1F_LEGCYPS_UNPLUG_DECT_EN BIT(2)
-+#define L1F_LEGCYPS_ECNC_PS_EN BIT(0)
-+#define L1F_LEGCYPS_DEF 0x129D
-+
-+#define L1F_MIIDBG_TST100BTCFG 0x36
-+#define L1F_TST100BTCFG_NORMAL_BW_EN BIT(15)
-+#define L1F_TST100BTCFG_BADLNK_BYPASS BIT(14)
-+#define L1F_TST100BTCFG_SHORTCABL_TH_MASK ASHFT8(0x3FU)
-+#define L1F_TST100BTCFG_SHORTCABL_TH_SHIFT 8
-+#define L1F_TST100BTCFG_LITCH_EN BIT(7)
-+#define L1F_TST100BTCFG_VLT_SW BIT(6)
-+#define L1F_TST100BTCFG_LONGCABL_TH_MASK ASHFT0(0x3FU)
-+#define L1F_TST100BTCFG_LONGCABL_TH_SHIFT 0
-+#define L1F_TST100BTCFG_DEF 0xE12C
-+
-+#define L1F_MIIDBG_GREENCFG 0x3B
-+#define L1F_GREENCFG_MSTPS_MSETH2_MASK ASHFT8(0xFFU)
-+#define L1F_GREENCFG_MSTPS_MSETH2_SHIFT 8
-+#define L1F_GREENCFG_MSTPS_MSETH1_MASK ASHFT0(0xFFU)
-+#define L1F_GREENCFG_MSTPS_MSETH1_SHIFT 0
-+#define L1F_GREENCFG_DEF 0x7078
-+
-+#define L1F_MIIDBG_GREENCFG2 0x3D
-+#define L1F_GREENCFG2_GATE_DFSE_EN BIT(7)
-+
-+
-+/***************************** extension **************************************/
-+
-+/******* dev 3 *********/
-+#define L1F_MIIEXT_PCS 3
-+
-+#define L1F_MIIEXT_CLDCTRL6 0x8006
-+#define L1F_CLDCTRL6_CAB_LEN_MASK ASHFT0(0xFFU)
-+#define L1F_CLDCTRL6_CAB_LEN_SHIFT 0
-+#define L1F_CLDCTRL6_CAB_LEN_SHORT1G 116
-+#define L1F_CLDCTRL6_CAB_LEN_SHORT100M 152
-+
-+#define L1F_MIIEXT_CLDCTRL7 0x8007
-+#define L1F_CLDCTRL7_VDHLF_BIAS_TH_MASK ASHFT9(0x7FU)
-+#define L1F_CLDCTRL7_VDHLF_BIAS_TH_SHIFT 9
-+#define L1F_CLDCTRL7_AFE_AZ_MASK ASHFT4(0x1FU)
-+#define L1F_CLDCTRL7_AFE_AZ_SHIFT 4
-+#define L1F_CLDCTRL7_SIDE_PEAK_TH_MASK ASHFT0(0xFU)
-+#define L1F_CLDCTRL7_SIDE_PEAK_TH_SHIFT 0
-+#define L1F_CLDCTRL7_DEF 0x6BF6 /* ???? */
-+
-+#define L1F_MIIEXT_AZCTRL 0x8008
-+#define L1F_AZCTRL_SHORT_TH_MASK ASHFT8(0xFFU)
-+#define L1F_AZCTRL_SHORT_TH_SHIFT 8
-+#define L1F_AZCTRL_LONG_TH_MASK ASHFT0(0xFFU)
-+#define L1F_AZCTRL_LONG_TH_SHIFT 0
-+#define L1F_AZCTRL_DEF 0x1629
-+
-+#define L1F_MIIEXT_AZCTRL2 0x8009
-+#define L1F_AZCTRL2_WAKETRNING_MASK ASHFT8(0xFFU)
-+#define L1F_AZCTRL2_WAKETRNING_SHIFT 8
-+#define L1F_AZCTRL2_QUIET_TIMER_MASH ASHFT6(3U)
-+#define L1F_AZCTRL2_QUIET_TIMER_SHIFT 6
-+#define L1F_AZCTRL2_PHAS_JMP2 BIT(4)
-+#define L1F_AZCTRL2_CLKTRCV_125MD16 BIT(3)
-+#define L1F_AZCTRL2_GATE1000_EN BIT(2)
-+#define L1F_AZCTRL2_AVRG_FREQ BIT(1)
-+#define L1F_AZCTRL2_PHAS_JMP4 BIT(0)
-+#define L1F_AZCTRL2_DEF 0x32C0
-+
-+#define L1F_MIIEXT_AZCTRL6 0x800D
-+
-+#define L1F_MIIEXT_VDRVBIAS 0x8062
-+#define L1F_VDRVBIAS_SEL_MASK ASHFT0(0x3U)
-+#define L1F_VDRVBIAS_SEL_SHIFT 0
-+#define L1F_VDRVBIAS_DEF 0x3
-+
-+/********* dev 7 **********/
-+#define L1F_MIIEXT_ANEG 7
-+
-+#define L1F_MIIEXT_LOCAL_EEEADV 0x3C
-+#define L1F_LOCAL_EEEADV_1000BT BIT(2)
-+#define L1F_LOCAL_EEEADV_100BT BIT(1)
-+
-+#define L1F_MIIEXT_REMOTE_EEEADV 0x3D
-+#define L1F_REMOTE_EEEADV_1000BT BIT(2)
-+#define L1F_REMOTE_EEEADV_100BT BIT(1)
-+
-+#define L1F_MIIEXT_EEE_ANEG 0x8000
-+#define L1F_EEE_ANEG_1000M BIT(2)
-+#define L1F_EEE_ANEG_100M BIT(1)
-+
-+#define L1F_MIIEXT_AFE 0x801A
-+#define L1F_AFE_10BT_100M_TH BIT(6)
-+
-+
-+#define L1F_MIIEXT_NLP34 0x8025
-+#define L1F_MIIEXT_NLP34_DEF 0x1010 /* for 160m */
-+
-+#define L1F_MIIEXT_NLP56 0x8026
-+#define L1F_MIIEXT_NLP56_DEF 0x1010 /* for 160m */
-+
-+#define L1F_MIIEXT_NLP78 0x8027
-+#define L1F_MIIEXT_NLP78_160M_DEF 0x8D05 /* for 160m */
-+#define L1F_MIIEXT_NLP78_120M_DEF 0x8A05 /* for 120m */
-+
-+
-+
-+/******************************************************************************/
-+
-+/* functions */
-+
-+
-+/* get permanent mac address from
-+ * return
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1f_get_perm_macaddr(struct alx_hw *hw, u8 *addr);
-+
-+
-+/* reset mac & dma
-+ * return
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1f_reset_mac(struct alx_hw *hw);
-+
-+/* reset phy
-+ * return
-+ * 0: success
-+ * non-0:fail
-+ */
-+u16 l1f_reset_phy(struct alx_hw *hw, bool pws_en, bool az_en, bool ptp_en);
-+
-+
-+/* reset pcie
-+ * just reset pcie relative registers (pci command, clk, aspm...)
-+ * return
-+ * 0:success
-+ * non-0:fail
-+ */
-+u16 l1f_reset_pcie(struct alx_hw *hw, bool l0s_en, bool l1_en);
-+
-+
-+/* disable/enable MAC/RXQ/TXQ
-+ * en
-+ * true:enable
-+ * false:disable
-+ * return
-+ * 0:success
-+ * non-0-fail
-+ */
-+u16 l1f_enable_mac(struct alx_hw *hw, bool en, u16 en_ctrl);
-+
-+
-+/* enable/disable aspm support
-+ * that will change settings for phy/mac/pcie
-+ */
-+u16 l1f_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en, u8 lnk_stat);
-+
-+
-+/* initialize phy for speed / flow control
-+ * lnk_cap
-+ * if autoNeg, is link capability to tell the peer
-+ * if force mode, is forced speed/duplex
-+ */
-+u16 l1f_init_phy_spdfc(struct alx_hw *hw, bool auto_neg,
-+ u8 lnk_cap, bool fc_en);
-+
-+/* do post setting on phy if link up/down event occur
-+ */
-+u16 l1f_post_phy_link(struct alx_hw *hw, bool linkon, u8 wire_spd);
-+
-+
-+/* do power saving setting befor enter suspend mode
-+ * NOTE:
-+ * 1. phy link must be established before calling this function
-+ * 2. wol option (pattern,magic,link,etc.) is configed before call it.
-+ */
-+u16 l1f_powersaving(struct alx_hw *hw, u8 wire_spd, bool wol_en,
-+ bool mahw_en, bool macrx_en, bool pws_en);
-+
-+/* read phy register */
-+u16 l1f_read_phy(struct alx_hw *hw, bool ext, u8 dev, bool fast, u16 reg,
-+ u16 *data);
-+
-+/* write phy register */
-+u16 l1f_write_phy(struct alx_hw *hw, bool ext, u8 dev, bool fast, u16 reg,
-+ u16 data);
-+
-+/* phy debug port */
-+u16 l1f_read_phydbg(struct alx_hw *hw, bool fast, u16 reg, u16 *data);
-+u16 l1f_write_phydbg(struct alx_hw *hw, bool fast, u16 reg, u16 data);
-+
-+
-+/* check the configuration of the PHY */
-+u16 l1f_get_phy_config(struct alx_hw *hw);
-+
-+/*
-+ * initialize mac basically
-+ * most of hi-feature no init
-+ * MAC/PHY should be reset before call this function
-+ */
-+u16 l1f_init_mac(struct alx_hw *hw, u8 *addr, u32 txmem_hi,
-+ u32 *tx_mem_lo, u8 tx_qnum, u16 txring_sz,
-+ u32 rxmem_hi, u32 rfdmem_lo, u32 rrdmem_lo,
-+ u16 rxring_sz, u16 rxbuf_sz, u16 smb_timer,
-+ u16 mtu, u16 int_mod, bool hash_legacy);
-+
-+
-+
-+#endif/*L1F_HW_H_*/
-+
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alx.h
-@@ -0,0 +1,670 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef _ALX_H_
-+#define _ALX_H_
-+
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/netdevice.h>
-+#include <linux/vmalloc.h>
-+#include <linux/string.h>
-+#include <linux/in.h>
-+#include <linux/interrupt.h>
-+#include <linux/ip.h>
-+#include <linux/tcp.h>
-+#include <linux/sctp.h>
-+#include <linux/pkt_sched.h>
-+#include <linux/ipv6.h>
-+#include <linux/slab.h>
-+#include <net/checksum.h>
-+#include <net/ip6_checksum.h>
-+#include <linux/ethtool.h>
-+#include <linux/if_vlan.h>
-+#include <linux/mii.h>
-+#include <linux/cpumask.h>
-+#include <linux/aer.h>
-+
-+#include "alx_sw.h"
-+
-+/*
-+ * Definition to enable some features
-+ */
-+#undef CONFIG_ALX_MSIX
-+#undef CONFIG_ALX_MSI
-+#undef CONFIG_ALX_MTQ
-+#undef CONFIG_ALX_MRQ
-+#undef CONFIG_ALX_RSS
-+/* #define CONFIG_ALX_MSIX */
-+#define CONFIG_ALX_MSI
-+#define CONFIG_ALX_MTQ
-+#define CONFIG_ALX_MRQ
-+#ifdef CONFIG_ALX_MRQ
-+#define CONFIG_ALX_RSS
-+#endif
-+
-+#define ALX_MSG_DEFAULT 0
-+
-+/* Logging functions and macros */
-+#define alx_err(adpt, fmt, ...) \
-+ netdev_err(adpt->netdev, fmt, ##__VA_ARGS__)
-+
-+#define ALX_VLAN_TO_TAG(_vlan, _tag) \
-+ do { \
-+ _tag = ((((_vlan) >> 8) & 0xFF) | (((_vlan) & 0xFF) << 8)); \
-+ } while (0)
-+
-+#define ALX_TAG_TO_VLAN(_tag, _vlan) \
-+ do { \
-+ _vlan = ((((_tag) >> 8) & 0xFF) | (((_tag) & 0xFF) << 8)) ; \
-+ } while (0)
-+
-+/* Coalescing Message Block */
-+struct coals_msg_block {
-+ int test;
-+};
-+
-+
-+#define BAR_0 0
-+
-+#define ALX_DEF_RX_BUF_SIZE 1536
-+#define ALX_MAX_JUMBO_PKT_SIZE (9*1024)
-+#define ALX_MAX_TSO_PKT_SIZE (7*1024)
-+
-+#define ALX_MAX_ETH_FRAME_SIZE ALX_MAX_JUMBO_PKT_SIZE
-+#define ALX_MIN_ETH_FRAME_SIZE 68
-+
-+
-+#define ALX_MAX_RX_QUEUES 8
-+#define ALX_MAX_TX_QUEUES 4
-+#define ALX_MAX_HANDLED_INTRS 5
-+
-+#define ALX_WATCHDOG_TIME (5 * HZ)
-+
-+struct alx_cmb {
-+ char name[IFNAMSIZ + 9];
-+ void *cmb;
-+ dma_addr_t dma;
-+};
-+struct alx_smb {
-+ char name[IFNAMSIZ + 9];
-+ void *smb;
-+ dma_addr_t dma;
-+};
-+
-+
-+/*
-+ * RRD : definition
-+ */
-+
-+/* general parameter format of rrd */
-+struct alx_rrdes_general {
-+ u32 xsum:16;
-+ u32 nor:4; /* number of RFD */
-+ u32 si:12; /* start index of rfd-ring */
-+
-+ u32 hash;
-+
-+ /* dword 3 */
-+ u32 vlan_tag:16; /* vlan-tag */
-+ u32 pid:8; /* Header Length of Header-Data Split. WORD unit */
-+ u32 reserve0:1;
-+ u32 rss_cpu:3; /* CPU number used by RSS */
-+ u32 rss_flag:4; /* rss_flag 0, TCP(IPv6) flag for RSS hash algrithm
-+ * rss_flag 1, IPv6 flag for RSS hash algrithm
-+ * rss_flag 2, TCP(IPv4) flag for RSS hash algrithm
-+ * rss_flag 3, IPv4 flag for RSS hash algrithm
-+ */
-+
-+ /* dword 3 */
-+ u32 pkt_len:14; /* length of the packet */
-+ u32 l4f:1; /* L4(TCP/UDP) checksum failed */
-+ u32 ipf:1; /* IP checksum failed */
-+ u32 vlan_flag:1;/* vlan tag */
-+ u32 reserve:3;
-+ u32 res:1; /* received error summary */
-+ u32 crc:1; /* crc error */
-+ u32 fae:1; /* frame alignment error */
-+ u32 trunc:1; /* truncated packet, larger than MTU */
-+ u32 runt:1; /* runt packet */
-+ u32 icmp:1; /* incomplete packet,
-+ * due to insufficient rx-descriptor
-+ */
-+ u32 bar:1; /* broadcast address received */
-+ u32 mar:1; /* multicast address received */
-+ u32 type:1; /* ethernet type */
-+ u32 fov:1; /* fifo overflow*/
-+ u32 lene:1; /* length error */
-+ u32 update:1; /* update*/
-+};
-+
-+union alx_rrdesc {
-+ /* dword flat format */
-+ struct {
-+ __le32 dw0;
-+ __le32 dw1;
-+ __le32 dw2;
-+ __le32 dw3;
-+ } dfmt;
-+
-+ /* qword flat format */
-+ struct {
-+ __le64 qw0;
-+ __le64 qw1;
-+ } qfmt;
-+};
-+
-+/*
-+ * XXX: we should not use this guy, best to just
-+ * do all le32_to_cpu() conversions on the spot.
-+ */
-+union alx_sw_rrdesc {
-+ struct alx_rrdes_general genr;
-+
-+ /* dword flat format */
-+ struct {
-+ u32 dw0;
-+ u32 dw1;
-+ u32 dw2;
-+ u32 dw3;
-+ } dfmt;
-+
-+ /* qword flat format */
-+ struct {
-+ u64 qw0;
-+ u64 qw1;
-+ } qfmt;
-+};
-+
-+/*
-+ * RFD : definition
-+ */
-+
-+/* general parameter format of rfd */
-+struct alx_rfdes_general {
-+ u64 addr;
-+};
-+
-+union alx_rfdesc {
-+ /* dword flat format */
-+ struct {
-+ __le32 dw0;
-+ __le32 dw1;
-+ } dfmt;
-+
-+ /* qword flat format */
-+ struct {
-+ __le64 qw0;
-+ } qfmt;
-+};
-+
-+/*
-+ * XXX: we should not use this guy, best to just
-+ * do all le32_to_cpu() conversions on the spot.
-+ */
-+union alx_sw_rfdesc {
-+ struct alx_rfdes_general genr;
-+
-+ /* dword flat format */
-+ struct {
-+ u32 dw0;
-+ u32 dw1;
-+ } dfmt;
-+
-+ /* qword flat format */
-+ struct {
-+ u64 qw0;
-+ } qfmt;
-+};
-+
-+/*
-+ * TPD : definition
-+ */
-+
-+/* general parameter format of tpd */
-+struct alx_tpdes_general {
-+ u32 buffer_len:16; /* include 4-byte CRC */
-+ u32 vlan_tag:16;
-+
-+ u32 l4hdr_offset:8; /* tcp/udp header offset to the 1st byte of
-+ * the packet */
-+ u32 c_csum:1; /* must be 0 in this format */
-+ u32 ip_csum:1; /* do ip(v4) header checksum offload */
-+ u32 tcp_csum:1; /* do tcp checksum offload, both ipv4 and ipv6 */
-+ u32 udp_csum:1; /* do udp checksum offlaod, both ipv4 and ipv6 */
-+ u32 lso:1;
-+ u32 lso_v2:1; /* must be 0 in this format */
-+ u32 vtagged:1; /* vlan-id tagged already */
-+ u32 instag:1; /* insert vlan tag */
-+
-+ u32 ipv4:1; /* ipv4 packet */
-+ u32 type:1; /* type of packet (ethernet_ii(1) or snap(0)) */
-+ u32 reserve:12; /* reserved, must be 0 */
-+ u32 epad:1; /* even byte padding when this packet */
-+ u32 last_frag:1; /* last fragment(buffer) of the packet */
-+
-+ u64 addr;
-+};
-+
-+/* custom checksum parameter format of tpd */
-+struct alx_tpdes_checksum {
-+ u32 buffer_len:16; /* include 4-byte CRC */
-+ u32 vlan_tag:16;
-+
-+ u32 payld_offset:8; /* payload offset to the 1st byte of
-+ * the packet
-+ */
-+ u32 c_sum:1; /* do custom chekcusm offload,
-+ * must be 1 in this format
-+ */
-+ u32 ip_sum:1; /* must be 0 in thhis format */
-+ u32 tcp_sum:1; /* must be 0 in this format */
-+ u32 udp_sum:1; /* must be 0 in this format */
-+ u32 lso:1; /* must be 0 in this format */
-+ u32 lso_v2:1; /* must be 0 in this format */
-+ u32 vtagged:1; /* vlan-id tagged already */
-+ u32 instag:1; /* insert vlan tag */
-+
-+ u32 ipv4:1; /* ipv4 packet */
-+ u32 type:1; /* type of packet (ethernet_ii(1) or snap(0)) */
-+ u32 cxsum_offset:8; /* checksum offset to the 1st byte of
-+ * the packet
-+ */
-+ u32 reserve:4; /* reserved, must be 0 */
-+ u32 epad:1; /* even byte padding when this packet */
-+ u32 last_frag:1; /* last fragment(buffer) of the packet */
-+
-+ u64 addr;
-+};
-+
-+
-+/* tcp large send format (v1/v2) of tpd */
-+struct alx_tpdes_tso {
-+ u32 buffer_len:16; /* include 4-byte CRC */
-+ u32 vlan_tag:16;
-+
-+ u32 tcphdr_offset:8; /* tcp hdr offset to the 1st byte of packet */
-+ u32 c_sum:1; /* must be 0 in this format */
-+ u32 ip_sum:1; /* must be 0 in thhis format */
-+ u32 tcp_sum:1; /* must be 0 in this format */
-+ u32 udp_sum:1; /* must be 0 in this format */
-+ u32 lso:1; /* do tcp large send (ipv4 only) */
-+ u32 lso_v2:1; /* must be 0 in this format */
-+ u32 vtagged:1; /* vlan-id tagged already */
-+ u32 instag:1; /* insert vlan tag */
-+
-+ u32 ipv4:1; /* ipv4 packet */
-+ u32 type:1; /* type of packet (ethernet_ii(1) or snap(0)) */
-+ u32 mss:13; /* MSS if do tcp large send */
-+ u32 last_frag:1; /* last fragment(buffer) of the packet */
-+
-+ u32 addr_lo;
-+ u32 addr_hi;
-+};
-+
-+union alx_tpdesc {
-+ /* dword flat format */
-+ struct {
-+ __le32 dw0;
-+ __le32 dw1;
-+ __le32 dw2;
-+ __le32 dw3;
-+ } dfmt;
-+
-+ /* qword flat format */
-+ struct {
-+ __le64 qw0;
-+ __le64 qw1;
-+ } qfmt;
-+};
-+
-+/*
-+ * XXX: we should not use this guy, best to just
-+ * do all le32_to_cpu() conversions on the spot.
-+ */
-+union alx_sw_tpdesc {
-+ struct alx_tpdes_general genr;
-+ struct alx_tpdes_checksum csum;
-+ struct alx_tpdes_tso tso;
-+
-+ /* dword flat format */
-+ struct {
-+ u32 dw0;
-+ u32 dw1;
-+ u32 dw2;
-+ u32 dw3;
-+ } dfmt;
-+
-+ /* qword flat format */
-+ struct {
-+ u64 qw0;
-+ u64 qw1;
-+ } qfmt;
-+};
-+
-+#define ALX_RRD(_que, _i) \
-+ (&(((union alx_rrdesc *)(_que)->rrq.rrdesc)[(_i)]))
-+#define ALX_RFD(_que, _i) \
-+ (&(((union alx_rfdesc *)(_que)->rfq.rfdesc)[(_i)]))
-+#define ALX_TPD(_que, _i) \
-+ (&(((union alx_tpdesc *)(_que)->tpq.tpdesc)[(_i)]))
-+
-+
-+/*
-+ * alx_ring_header represents a single, contiguous block of DMA space
-+ * mapped for the three descriptor rings (tpd, rfd, rrd) and the two
-+ * message blocks (cmb, smb) described below
-+ */
-+struct alx_ring_header {
-+ void *desc; /* virtual address */
-+ dma_addr_t dma; /* physical address*/
-+ unsigned int size; /* length in bytes */
-+ unsigned int used;
-+};
-+
-+
-+/*
-+ * alx_buffer is wrapper around a pointer to a socket buffer
-+ * so a DMA handle can be stored along with the skb
-+ */
-+struct alx_buffer {
-+ struct sk_buff *skb; /* socket buffer */
-+ u16 length; /* rx buffer length */
-+ dma_addr_t dma;
-+};
-+
-+struct alx_sw_buffer {
-+ struct sk_buff *skb; /* socket buffer */
-+ u32 vlan_tag:16;
-+ u32 vlan_flag:1;
-+ u32 reserved:15;
-+};
-+
-+/* receive free descriptor (rfd) queue */
-+struct alx_rfd_queue {
-+ struct alx_buffer *rfbuff;
-+ union alx_rfdesc *rfdesc; /* virtual address */
-+ dma_addr_t rfdma; /* physical address */
-+ u16 size; /* length in bytes */
-+ u16 count; /* number of descriptors in the ring */
-+ u16 produce_idx; /* it's written to rxque->produce_reg */
-+ u16 consume_idx; /* unused*/
-+};
-+
-+/* receive return desciptor (rrd) queue */
-+struct alx_rrd_queue {
-+ union alx_rrdesc *rrdesc; /* virtual address */
-+ dma_addr_t rrdma; /* physical address */
-+ u16 size; /* length in bytes */
-+ u16 count; /* number of descriptors in the ring */
-+ u16 produce_idx; /* unused */
-+ u16 consume_idx; /* rxque->consume_reg */
-+};
-+
-+/* software desciptor (swd) queue */
-+struct alx_swd_queue {
-+ struct alx_sw_buffer *swbuff;
-+ u16 count; /* number of descriptors in the ring */
-+ u16 produce_idx;
-+ u16 consume_idx;
-+};
-+
-+/* rx queue */
-+struct alx_rx_queue {
-+ struct device *dev; /* device for dma mapping */
-+ struct net_device *netdev; /* netdev ring belongs to */
-+ struct alx_msix_param *msix;
-+ struct alx_rrd_queue rrq;
-+ struct alx_rfd_queue rfq;
-+ struct alx_swd_queue swq;
-+
-+ u16 que_idx; /* index in multi rx queues*/
-+ u16 max_packets; /* max work per interrupt */
-+ u16 produce_reg;
-+ u16 consume_reg;
-+ u32 flags;
-+};
-+#define ALX_RX_FLAG_SW_QUE 0x00000001
-+#define ALX_RX_FLAG_HW_QUE 0x00000002
-+#define CHK_RX_FLAG(_flag) CHK_FLAG(rxque, RX, _flag)
-+#define SET_RX_FLAG(_flag) SET_FLAG(rxque, RX, _flag)
-+#define CLI_RX_FLAG(_flag) CLI_FLAG(rxque, RX, _flag)
-+
-+#define GET_RF_BUFFER(_rque, _i) (&((_rque)->rfq.rfbuff[(_i)]))
-+#define GET_SW_BUFFER(_rque, _i) (&((_rque)->swq.swbuff[(_i)]))
-+
-+
-+/* transimit packet descriptor (tpd) ring */
-+struct alx_tpd_queue {
-+ struct alx_buffer *tpbuff;
-+ union alx_tpdesc *tpdesc; /* virtual address */
-+ dma_addr_t tpdma; /* physical address */
-+
-+ u16 size; /* length in bytes */
-+ u16 count; /* number of descriptors in the ring */
-+ u16 produce_idx;
-+ u16 consume_idx;
-+ u16 last_produce_idx;
-+};
-+
-+/* tx queue */
-+struct alx_tx_queue {
-+ struct device *dev; /* device for dma mapping */
-+ struct net_device *netdev; /* netdev ring belongs to */
-+ struct alx_tpd_queue tpq;
-+ struct alx_msix_param *msix;
-+
-+ u16 que_idx; /* needed for multiqueue queue management */
-+ u16 max_packets; /* max packets per interrupt */
-+ u16 produce_reg;
-+ u16 consume_reg;
-+};
-+#define GET_TP_BUFFER(_tque, _i) (&((_tque)->tpq.tpbuff[(_i)]))
-+
-+
-+/*
-+ * definition for array allocations.
-+ */
-+#define ALX_MAX_MSIX_INTRS 16
-+#define ALX_MAX_RX_QUEUES 8
-+#define ALX_MAX_TX_QUEUES 4
-+
-+enum alx_msix_type {
-+ alx_msix_type_rx,
-+ alx_msix_type_tx,
-+ alx_msix_type_other,
-+};
-+#define ALX_MSIX_TYPE_OTH_TIMER 0
-+#define ALX_MSIX_TYPE_OTH_ALERT 1
-+#define ALX_MSIX_TYPE_OTH_SMB 2
-+#define ALX_MSIX_TYPE_OTH_PHY 3
-+
-+/* ALX_MAX_MSIX_INTRS of these are allocated,
-+ * but we only use one per queue-specific vector.
-+ */
-+struct alx_msix_param {
-+ struct alx_adapter *adpt;
-+ unsigned int vec_idx; /* index in HW interrupt vector */
-+ char name[IFNAMSIZ + 9];
-+
-+ /* msix interrupts for queue */
-+ u8 rx_map[ALX_MAX_RX_QUEUES];
-+ u8 tx_map[ALX_MAX_TX_QUEUES];
-+ u8 rx_count; /* Rx ring count assigned to this vector */
-+ u8 tx_count; /* Tx ring count assigned to this vector */
-+
-+ struct napi_struct napi;
-+ cpumask_var_t affinity_mask;
-+ u32 flags;
-+};
-+
-+#define ALX_MSIX_FLAG_RX0 0x00000001
-+#define ALX_MSIX_FLAG_RX1 0x00000002
-+#define ALX_MSIX_FLAG_RX2 0x00000004
-+#define ALX_MSIX_FLAG_RX3 0x00000008
-+#define ALX_MSIX_FLAG_RX4 0x00000010
-+#define ALX_MSIX_FLAG_RX5 0x00000020
-+#define ALX_MSIX_FLAG_RX6 0x00000040
-+#define ALX_MSIX_FLAG_RX7 0x00000080
-+#define ALX_MSIX_FLAG_TX0 0x00000100
-+#define ALX_MSIX_FLAG_TX1 0x00000200
-+#define ALX_MSIX_FLAG_TX2 0x00000400
-+#define ALX_MSIX_FLAG_TX3 0x00000800
-+#define ALX_MSIX_FLAG_TIMER 0x00001000
-+#define ALX_MSIX_FLAG_ALERT 0x00002000
-+#define ALX_MSIX_FLAG_SMB 0x00004000
-+#define ALX_MSIX_FLAG_PHY 0x00008000
-+
-+#define ALX_MSIX_FLAG_RXS (\
-+ ALX_MSIX_FLAG_RX0 |\
-+ ALX_MSIX_FLAG_RX1 |\
-+ ALX_MSIX_FLAG_RX2 |\
-+ ALX_MSIX_FLAG_RX3 |\
-+ ALX_MSIX_FLAG_RX4 |\
-+ ALX_MSIX_FLAG_RX5 |\
-+ ALX_MSIX_FLAG_RX6 |\
-+ ALX_MSIX_FLAG_RX7)
-+#define ALX_MSIX_FLAG_TXS (\
-+ ALX_MSIX_FLAG_TX0 |\
-+ ALX_MSIX_FLAG_TX1 |\
-+ ALX_MSIX_FLAG_TX2 |\
-+ ALX_MSIX_FLAG_TX3)
-+#define ALX_MSIX_FLAG_ALL (\
-+ ALX_MSIX_FLAG_RXS |\
-+ ALX_MSIX_FLAG_TXS |\
-+ ALX_MSIX_FLAG_TIMER |\
-+ ALX_MSIX_FLAG_ALERT |\
-+ ALX_MSIX_FLAG_SMB |\
-+ ALX_MSIX_FLAG_PHY)
-+
-+#define CHK_MSIX_FLAG(_flag) CHK_FLAG(msix, MSIX, _flag)
-+#define SET_MSIX_FLAG(_flag) SET_FLAG(msix, MSIX, _flag)
-+#define CLI_MSIX_FLAG(_flag) CLI_FLAG(msix, MSIX, _flag)
-+
-+/*
-+ *board specific private data structure
-+ */
-+struct alx_adapter {
-+ struct net_device *netdev;
-+ struct pci_dev *pdev;
-+ struct net_device_stats net_stats;
-+ bool netdev_registered;
-+ u16 bd_number; /* board number;*/
-+
-+ struct alx_msix_param *msix[ALX_MAX_MSIX_INTRS];
-+ struct msix_entry *msix_entries;
-+ int num_msix_rxques;
-+ int num_msix_txques;
-+ int num_msix_noques; /* true count of msix_noques for device */
-+ int num_msix_intrs;
-+
-+ int min_msix_intrs;
-+ int max_msix_intrs;
-+
-+ /* All Descriptor memory */
-+ struct alx_ring_header ring_header;
-+
-+ /* TX */
-+ struct alx_tx_queue *tx_queue[ALX_MAX_TX_QUEUES];
-+ /* RX */
-+ struct alx_rx_queue *rx_queue[ALX_MAX_RX_QUEUES];
-+
-+ u16 num_txques;
-+ u16 num_rxques; /* equal max(num_hw_rxques, num_sw_rxques) */
-+ u16 num_hw_rxques;
-+ u16 num_sw_rxques;
-+ u16 max_rxques;
-+ u16 max_txques;
-+
-+ u16 num_txdescs;
-+ u16 num_rxdescs;
-+
-+ u32 rxbuf_size;
-+
-+ struct alx_cmb cmb;
-+ struct alx_smb smb;
-+
-+ /* structs defined in alx_hw.h */
-+ struct alx_hw hw;
-+ struct alx_hw_stats hw_stats;
-+
-+ u32 *config_space;
-+
-+ struct work_struct alx_task;
-+ struct timer_list alx_timer;
-+
-+ unsigned long link_jiffies;
-+
-+ u32 wol;
-+ spinlock_t tx_lock;
-+ spinlock_t rx_lock;
-+ atomic_t irq_sem;
-+
-+ u16 msg_enable;
-+ unsigned long flags[2];
-+};
-+
-+#define ALX_ADPT_FLAG_0_MSI_CAP 0x00000001
-+#define ALX_ADPT_FLAG_0_MSI_EN 0x00000002
-+#define ALX_ADPT_FLAG_0_MSIX_CAP 0x00000004
-+#define ALX_ADPT_FLAG_0_MSIX_EN 0x00000008
-+#define ALX_ADPT_FLAG_0_MRQ_CAP 0x00000010
-+#define ALX_ADPT_FLAG_0_MRQ_EN 0x00000020
-+#define ALX_ADPT_FLAG_0_MTQ_CAP 0x00000040
-+#define ALX_ADPT_FLAG_0_MTQ_EN 0x00000080
-+#define ALX_ADPT_FLAG_0_SRSS_CAP 0x00000100
-+#define ALX_ADPT_FLAG_0_SRSS_EN 0x00000200
-+#define ALX_ADPT_FLAG_0_FIXED_MSIX 0x00000400
-+
-+#define ALX_ADPT_FLAG_0_TASK_REINIT_REQ 0x00010000 /* reinit */
-+#define ALX_ADPT_FLAG_0_TASK_LSC_REQ 0x00020000
-+
-+#define ALX_ADPT_FLAG_1_STATE_TESTING 0x00000001
-+#define ALX_ADPT_FLAG_1_STATE_RESETTING 0x00000002
-+#define ALX_ADPT_FLAG_1_STATE_DOWN 0x00000004
-+#define ALX_ADPT_FLAG_1_STATE_WATCH_DOG 0x00000008
-+#define ALX_ADPT_FLAG_1_STATE_DIAG_RUNNING 0x00000010
-+#define ALX_ADPT_FLAG_1_STATE_INACTIVE 0x00000020
-+
-+
-+#define CHK_ADPT_FLAG(_idx, _flag) \
-+ CHK_FLAG_ARRAY(adpt, _idx, ADPT, _flag)
-+#define SET_ADPT_FLAG(_idx, _flag) \
-+ SET_FLAG_ARRAY(adpt, _idx, ADPT, _flag)
-+#define CLI_ADPT_FLAG(_idx, _flag) \
-+ CLI_FLAG_ARRAY(adpt, _idx, ADPT, _flag)
-+
-+/* default to trying for four seconds */
-+#define ALX_TRY_LINK_TIMEOUT (4 * HZ)
-+
-+
-+#define ALX_OPEN_CTRL_IRQ_EN 0x00000001
-+#define ALX_OPEN_CTRL_RESET_MAC 0x00000002
-+#define ALX_OPEN_CTRL_RESET_PHY 0x00000004
-+#define ALX_OPEN_CTRL_RESET_ALL (\
-+ ALX_OPEN_CTRL_RESET_MAC |\
-+ ALX_OPEN_CTRL_RESET_PHY)
-+
-+/* needed by alx_ethtool.c */
-+extern char alx_drv_name[];
-+extern void alx_reinit_locked(struct alx_adapter *adpt);
-+extern void alx_set_ethtool_ops(struct net_device *netdev);
-+#ifdef ETHTOOL_OPS_COMPAT
-+extern int ethtool_ioctl(struct ifreq *ifr);
-+#endif
-+
-+#endif /* _ALX_H_ */
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alx_ethtool.c
-@@ -0,0 +1,519 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/netdevice.h>
-+#include <linux/ethtool.h>
-+#include <linux/slab.h>
-+
-+#include "alx.h"
-+#include "alx_hwcom.h"
-+
-+#ifdef ETHTOOL_OPS_COMPAT
-+#include "alx_compat_ethtool.c"
-+#endif
-+
-+
-+static int alx_get_settings(struct net_device *netdev,
-+ struct ethtool_cmd *ecmd)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ u32 link_speed = hw->link_speed;
-+ bool link_up = hw->link_up;
-+
-+ ecmd->supported = (SUPPORTED_10baseT_Half |
-+ SUPPORTED_10baseT_Full |
-+ SUPPORTED_100baseT_Half |
-+ SUPPORTED_100baseT_Full |
-+ SUPPORTED_Autoneg |
-+ SUPPORTED_TP);
-+ if (CHK_HW_FLAG(GIGA_CAP))
-+ ecmd->supported |= SUPPORTED_1000baseT_Full;
-+
-+ ecmd->advertising = ADVERTISED_TP;
-+
-+ ecmd->advertising |= ADVERTISED_Autoneg;
-+ ecmd->advertising |= hw->autoneg_advertised;
-+
-+ ecmd->port = PORT_TP;
-+ ecmd->phy_address = 0;
-+ ecmd->autoneg = AUTONEG_ENABLE;
-+ ecmd->transceiver = XCVR_INTERNAL;
-+
-+ if (!in_interrupt()) {
-+ hw->cbs.check_phy_link(hw, &link_speed, &link_up);
-+ hw->link_speed = link_speed;
-+ hw->link_up = link_up;
-+ }
-+
-+ if (link_up) {
-+ switch (link_speed) {
-+ case ALX_LINK_SPEED_10_HALF:
-+ ethtool_cmd_speed_set(ecmd, SPEED_10);
-+ ecmd->duplex = DUPLEX_HALF;
-+ break;
-+ case ALX_LINK_SPEED_10_FULL:
-+ ethtool_cmd_speed_set(ecmd, SPEED_10);
-+ ecmd->duplex = DUPLEX_FULL;
-+ break;
-+ case ALX_LINK_SPEED_100_HALF:
-+ ethtool_cmd_speed_set(ecmd, SPEED_100);
-+ ecmd->duplex = DUPLEX_HALF;
-+ break;
-+ case ALX_LINK_SPEED_100_FULL:
-+ ethtool_cmd_speed_set(ecmd, SPEED_100);
-+ ecmd->duplex = DUPLEX_FULL;
-+ break;
-+ case ALX_LINK_SPEED_1GB_FULL:
-+ ethtool_cmd_speed_set(ecmd, SPEED_1000);
-+ ecmd->duplex = DUPLEX_FULL;
-+ break;
-+ default:
-+ ecmd->speed = -1;
-+ ecmd->duplex = -1;
-+ break;
-+ }
-+ } else {
-+ ethtool_cmd_speed_set(ecmd, -1);
-+ ecmd->duplex = -1;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int alx_set_settings(struct net_device *netdev,
-+ struct ethtool_cmd *ecmd)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ u32 advertised, old;
-+ int error = 0;
-+
-+ while (CHK_ADPT_FLAG(1, STATE_RESETTING))
-+ msleep(20);
-+ SET_ADPT_FLAG(1, STATE_RESETTING);
-+
-+ old = hw->autoneg_advertised;
-+ advertised = 0;
-+ if (ecmd->autoneg == AUTONEG_ENABLE) {
-+ advertised = ALX_LINK_SPEED_DEFAULT;
-+ } else {
-+ u32 speed = ethtool_cmd_speed(ecmd);
-+ if (speed == SPEED_1000) {
-+ if (ecmd->duplex != DUPLEX_FULL) {
-+ dev_warn(&adpt->pdev->dev,
-+ "1000M half is invalid\n");
-+ CLI_ADPT_FLAG(1, STATE_RESETTING);
-+ return -EINVAL;
-+ }
-+ advertised = ALX_LINK_SPEED_1GB_FULL;
-+ } else if (speed == SPEED_100) {
-+ if (ecmd->duplex == DUPLEX_FULL)
-+ advertised = ALX_LINK_SPEED_100_FULL;
-+ else
-+ advertised = ALX_LINK_SPEED_100_HALF;
-+ } else {
-+ if (ecmd->duplex == DUPLEX_FULL)
-+ advertised = ALX_LINK_SPEED_10_FULL;
-+ else
-+ advertised = ALX_LINK_SPEED_10_HALF;
-+ }
-+ }
-+
-+ if (hw->autoneg_advertised == advertised) {
-+ CLI_ADPT_FLAG(1, STATE_RESETTING);
-+ return error;
-+ }
-+
-+ error = hw->cbs.setup_phy_link_speed(hw, advertised, true,
-+ !hw->disable_fc_autoneg);
-+ if (error) {
-+ dev_err(&adpt->pdev->dev,
-+ "setup link failed with code %d\n", error);
-+ hw->cbs.setup_phy_link_speed(hw, old, true,
-+ !hw->disable_fc_autoneg);
-+ }
-+ CLI_ADPT_FLAG(1, STATE_RESETTING);
-+ return error;
-+}
-+
-+
-+static void alx_get_pauseparam(struct net_device *netdev,
-+ struct ethtool_pauseparam *pause)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+
-+
-+ if (hw->disable_fc_autoneg ||
-+ hw->cur_fc_mode == alx_fc_none)
-+ pause->autoneg = 0;
-+ else
-+ pause->autoneg = 1;
-+
-+ if (hw->cur_fc_mode == alx_fc_rx_pause) {
-+ pause->rx_pause = 1;
-+ } else if (hw->cur_fc_mode == alx_fc_tx_pause) {
-+ pause->tx_pause = 1;
-+ } else if (hw->cur_fc_mode == alx_fc_full) {
-+ pause->rx_pause = 1;
-+ pause->tx_pause = 1;
-+ }
-+}
-+
-+
-+static int alx_set_pauseparam(struct net_device *netdev,
-+ struct ethtool_pauseparam *pause)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ enum alx_fc_mode req_fc_mode;
-+ bool disable_fc_autoneg;
-+ int retval;
-+
-+ while (CHK_ADPT_FLAG(1, STATE_RESETTING))
-+ msleep(20);
-+ SET_ADPT_FLAG(1, STATE_RESETTING);
-+
-+ req_fc_mode = hw->req_fc_mode;
-+ disable_fc_autoneg = hw->disable_fc_autoneg;
-+
-+
-+ if (pause->autoneg != AUTONEG_ENABLE)
-+ disable_fc_autoneg = true;
-+ else
-+ disable_fc_autoneg = false;
-+
-+ if ((pause->rx_pause && pause->tx_pause) || pause->autoneg)
-+ req_fc_mode = alx_fc_full;
-+ else if (pause->rx_pause && !pause->tx_pause)
-+ req_fc_mode = alx_fc_rx_pause;
-+ else if (!pause->rx_pause && pause->tx_pause)
-+ req_fc_mode = alx_fc_tx_pause;
-+ else if (!pause->rx_pause && !pause->tx_pause)
-+ req_fc_mode = alx_fc_none;
-+ else
-+ return -EINVAL;
-+
-+ if ((hw->req_fc_mode != req_fc_mode) ||
-+ (hw->disable_fc_autoneg != disable_fc_autoneg)) {
-+ hw->req_fc_mode = req_fc_mode;
-+ hw->disable_fc_autoneg = disable_fc_autoneg;
-+ if (!hw->disable_fc_autoneg)
-+ retval = hw->cbs.setup_phy_link(hw,
-+ hw->autoneg_advertised, true, true);
-+
-+ if (hw->cbs.config_fc)
-+ hw->cbs.config_fc(hw);
-+ }
-+
-+ CLI_ADPT_FLAG(1, STATE_RESETTING);
-+ return 0;
-+}
-+
-+
-+static u32 alx_get_msglevel(struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ return adpt->msg_enable;
-+}
-+
-+
-+static void alx_set_msglevel(struct net_device *netdev, u32 data)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ adpt->msg_enable = data;
-+}
-+
-+
-+static int alx_get_regs_len(struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ return hw->hwreg_sz * sizeof(32);
-+}
-+
-+
-+static void alx_get_regs(struct net_device *netdev,
-+ struct ethtool_regs *regs, void *buff)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+
-+ regs->version = 0;
-+
-+ memset(buff, 0, hw->hwreg_sz * sizeof(u32));
-+ if (hw->cbs.get_ethtool_regs)
-+ hw->cbs.get_ethtool_regs(hw, buff);
-+}
-+
-+
-+static int alx_get_eeprom_len(struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ return hw->eeprom_sz;
-+}
-+
-+
-+static int alx_get_eeprom(struct net_device *netdev,
-+ struct ethtool_eeprom *eeprom, u8 *bytes)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ bool eeprom_exist = false;
-+ u32 *eeprom_buff;
-+ int first_dword, last_dword;
-+ int retval = 0;
-+ int i;
-+
-+ if (eeprom->len == 0)
-+ return -EINVAL;
-+
-+ if (hw->cbs.check_nvram)
-+ hw->cbs.check_nvram(hw, &eeprom_exist);
-+ if (!eeprom_exist)
-+ return -EOPNOTSUPP;
-+
-+ eeprom->magic = adpt->pdev->vendor |
-+ (adpt->pdev->device << 16);
-+
-+ first_dword = eeprom->offset >> 2;
-+ last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
-+
-+ eeprom_buff = kmalloc(sizeof(u32) *
-+ (last_dword - first_dword + 1), GFP_KERNEL);
-+ if (eeprom_buff == NULL)
-+ return -ENOMEM;
-+
-+ for (i = first_dword; i < last_dword; i++) {
-+ if (hw->cbs.read_nvram) {
-+ retval = hw->cbs.read_nvram(hw, i*4,
-+ &(eeprom_buff[i-first_dword]));
-+ if (retval) {
-+ retval = -EIO;
-+ goto out;
-+ }
-+ }
-+ }
-+
-+ /* Device's eeprom is always little-endian, word addressable */
-+ for (i = 0; i < last_dword - first_dword; i++)
-+ le32_to_cpus(&eeprom_buff[i]);
-+
-+ memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3), eeprom->len);
-+out:
-+ kfree(eeprom_buff);
-+ return retval;
-+}
-+
-+
-+static int alx_set_eeprom(struct net_device *netdev,
-+ struct ethtool_eeprom *eeprom, u8 *bytes)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ bool eeprom_exist = false;
-+ u32 *eeprom_buff;
-+ u32 *ptr;
-+ int first_dword, last_dword;
-+ int retval = 0;
-+ int i;
-+
-+ if (eeprom->len == 0)
-+ return -EINVAL;
-+
-+ if (hw->cbs.check_nvram)
-+ hw->cbs.check_nvram(hw, &eeprom_exist);
-+ if (!eeprom_exist)
-+ return -EOPNOTSUPP;
-+
-+
-+ if (eeprom->magic != (adpt->pdev->vendor |
-+ (adpt->pdev->device << 16)))
-+ return -EINVAL;
-+
-+ first_dword = eeprom->offset >> 2;
-+ last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
-+ eeprom_buff = kmalloc(ALX_MAX_EEPROM_LEN, GFP_KERNEL);
-+ if (eeprom_buff == NULL)
-+ return -ENOMEM;
-+
-+ ptr = (u32 *)eeprom_buff;
-+
-+ if (eeprom->offset & 3) {
-+ /* need read/modify/write of first changed EEPROM word */
-+ /* only the second byte of the word is being modified */
-+ if (hw->cbs.read_nvram) {
-+ retval = hw->cbs.read_nvram(hw, first_dword * 4,
-+ &(eeprom_buff[0]));
-+ if (retval) {
-+ retval = -EIO;
-+ goto out;
-+ }
-+ }
-+ ptr++;
-+ }
-+
-+ if (((eeprom->offset + eeprom->len) & 3)) {
-+ /* need read/modify/write of last changed EEPROM word */
-+ /* only the first byte of the word is being modified */
-+ if (hw->cbs.read_nvram) {
-+ retval = hw->cbs.read_nvram(hw, last_dword * 4,
-+ &(eeprom_buff[last_dword - first_dword]));
-+ if (retval) {
-+ retval = -EIO;
-+ goto out;
-+ }
-+ }
-+ }
-+
-+ /* Device's eeprom is always little-endian, word addressable */
-+ memcpy(ptr, bytes, eeprom->len);
-+ for (i = 0; i < last_dword - first_dword + 1; i++) {
-+ if (hw->cbs.write_nvram) {
-+ retval = hw->cbs.write_nvram(hw, (first_dword + i) * 4,
-+ eeprom_buff[i]);
-+ if (retval) {
-+ retval = -EIO;
-+ goto out;
-+ }
-+ }
-+ }
-+out:
-+ kfree(eeprom_buff);
-+ return retval;
-+}
-+
-+
-+static void alx_get_drvinfo(struct net_device *netdev,
-+ struct ethtool_drvinfo *drvinfo)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+
-+ strlcpy(drvinfo->driver, alx_drv_name, sizeof(drvinfo->driver));
-+ strlcpy(drvinfo->fw_version, "alx", 32);
-+ strlcpy(drvinfo->bus_info, pci_name(adpt->pdev),
-+ sizeof(drvinfo->bus_info));
-+ drvinfo->n_stats = 0;
-+ drvinfo->testinfo_len = 0;
-+ drvinfo->regdump_len = adpt->hw.hwreg_sz;
-+ drvinfo->eedump_len = adpt->hw.eeprom_sz;
-+}
-+
-+
-+static int alx_wol_exclusion(struct alx_adapter *adpt,
-+ struct ethtool_wolinfo *wol)
-+{
-+ struct alx_hw *hw = &adpt->hw;
-+ int retval = 1;
-+
-+ /* WOL not supported except for the following */
-+ switch (hw->pci_devid) {
-+ case ALX_DEV_ID_AR8131:
-+ case ALX_DEV_ID_AR8132:
-+ case ALX_DEV_ID_AR8151_V1:
-+ case ALX_DEV_ID_AR8151_V2:
-+ case ALX_DEV_ID_AR8152_V1:
-+ case ALX_DEV_ID_AR8152_V2:
-+ case ALX_DEV_ID_AR8161:
-+ case ALX_DEV_ID_AR8162:
-+ retval = 0;
-+ break;
-+ default:
-+ wol->supported = 0;
-+ }
-+
-+ return retval;
-+}
-+
-+
-+static void alx_get_wol(struct net_device *netdev,
-+ struct ethtool_wolinfo *wol)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+
-+ wol->supported = WAKE_MAGIC | WAKE_PHY;
-+ wol->wolopts = 0;
-+
-+ if (adpt->wol & ALX_WOL_MAGIC)
-+ wol->wolopts |= WAKE_MAGIC;
-+ if (adpt->wol & ALX_WOL_PHY)
-+ wol->wolopts |= WAKE_PHY;
-+
-+ netif_info(adpt, wol, adpt->netdev,
-+ "wol->wolopts = %x\n", wol->wolopts);
-+}
-+
-+
-+static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+
-+ if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
-+ WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
-+ return -EOPNOTSUPP;
-+
-+ if (alx_wol_exclusion(adpt, wol))
-+ return wol->wolopts ? -EOPNOTSUPP : 0;
-+
-+ adpt->wol = 0;
-+
-+ if (wol->wolopts & WAKE_MAGIC)
-+ adpt->wol |= ALX_WOL_MAGIC;
-+ if (wol->wolopts & WAKE_PHY)
-+ adpt->wol |= ALX_WOL_PHY;
-+
-+ device_set_wakeup_enable(&adpt->pdev->dev, adpt->wol);
-+
-+ return 0;
-+}
-+
-+
-+static int alx_nway_reset(struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ if (netif_running(netdev))
-+ alx_reinit_locked(adpt);
-+ return 0;
-+}
-+
-+
-+static const struct ethtool_ops alx_ethtool_ops = {
-+ .get_settings = alx_get_settings,
-+ .set_settings = alx_set_settings,
-+ .get_pauseparam = alx_get_pauseparam,
-+ .set_pauseparam = alx_set_pauseparam,
-+ .get_drvinfo = alx_get_drvinfo,
-+ .get_regs_len = alx_get_regs_len,
-+ .get_regs = alx_get_regs,
-+ .get_wol = alx_get_wol,
-+ .set_wol = alx_set_wol,
-+ .get_msglevel = alx_get_msglevel,
-+ .set_msglevel = alx_set_msglevel,
-+ .nway_reset = alx_nway_reset,
-+ .get_link = ethtool_op_get_link,
-+ .get_eeprom_len = alx_get_eeprom_len,
-+ .get_eeprom = alx_get_eeprom,
-+ .set_eeprom = alx_set_eeprom,
-+};
-+
-+
-+void alx_set_ethtool_ops(struct net_device *netdev)
-+{
-+ SET_ETHTOOL_OPS(netdev, &alx_ethtool_ops);
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alx_hwcom.h
-@@ -0,0 +1,187 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef _ALX_HWCOMMON_H_
-+#define _ALX_HWCOMMON_H_
-+
-+#include <linux/bitops.h>
-+#include "alx_sw.h"
-+
-+
-+#define BIT_ALL 0xffffffffUL
-+
-+#define ASHFT31(_x) ((_x) << 31)
-+#define ASHFT30(_x) ((_x) << 30)
-+#define ASHFT29(_x) ((_x) << 29)
-+#define ASHFT28(_x) ((_x) << 28)
-+#define ASHFT27(_x) ((_x) << 27)
-+#define ASHFT26(_x) ((_x) << 26)
-+#define ASHFT25(_x) ((_x) << 25)
-+#define ASHFT24(_x) ((_x) << 24)
-+#define ASHFT23(_x) ((_x) << 23)
-+#define ASHFT22(_x) ((_x) << 22)
-+#define ASHFT21(_x) ((_x) << 21)
-+#define ASHFT20(_x) ((_x) << 20)
-+#define ASHFT19(_x) ((_x) << 19)
-+#define ASHFT18(_x) ((_x) << 18)
-+#define ASHFT17(_x) ((_x) << 17)
-+#define ASHFT16(_x) ((_x) << 16)
-+#define ASHFT15(_x) ((_x) << 15)
-+#define ASHFT14(_x) ((_x) << 14)
-+#define ASHFT13(_x) ((_x) << 13)
-+#define ASHFT12(_x) ((_x) << 12)
-+#define ASHFT11(_x) ((_x) << 11)
-+#define ASHFT10(_x) ((_x) << 10)
-+#define ASHFT9(_x) ((_x) << 9)
-+#define ASHFT8(_x) ((_x) << 8)
-+#define ASHFT7(_x) ((_x) << 7)
-+#define ASHFT6(_x) ((_x) << 6)
-+#define ASHFT5(_x) ((_x) << 5)
-+#define ASHFT4(_x) ((_x) << 4)
-+#define ASHFT3(_x) ((_x) << 3)
-+#define ASHFT2(_x) ((_x) << 2)
-+#define ASHFT1(_x) ((_x) << 1)
-+#define ASHFT0(_x) ((_x) << 0)
-+
-+
-+#define FIELD_GETX(_x, _name) (((_x) & (_name##_MASK)) >> (_name##_SHIFT))
-+#define FIELD_SETS(_x, _name, _v) (\
-+(_x) = \
-+((_x) & ~(_name##_MASK)) |\
-+(((u16)(_v) << (_name##_SHIFT)) & (_name##_MASK)))
-+#define FIELD_SETL(_x, _name, _v) (\
-+(_x) = \
-+((_x) & ~(_name##_MASK)) |\
-+(((u32)(_v) << (_name##_SHIFT)) & (_name##_MASK)))
-+#define FIELDL(_name, _v) (((u32)(_v) << (_name##_SHIFT)) & (_name##_MASK))
-+#define FIELDS(_name, _v) (((u16)(_v) << (_name##_SHIFT)) & (_name##_MASK))
-+
-+
-+
-+#define LX_SWAP_DW(_x) (\
-+ (((_x) << 24) & 0xFF000000UL) |\
-+ (((_x) << 8) & 0x00FF0000UL) |\
-+ (((_x) >> 8) & 0x0000FF00UL) |\
-+ (((_x) >> 24) & 0x000000FFUL))
-+
-+#define LX_SWAP_W(_x) (\
-+ (((_x) >> 8) & 0x00FFU) |\
-+ (((_x) << 8) & 0xFF00U))
-+
-+
-+#define LX_ERR_SUCCESS 0x0000
-+#define LX_ERR_ALOAD 0x0001
-+#define LX_ERR_RSTMAC 0x0002
-+#define LX_ERR_PARM 0x0003
-+#define LX_ERR_MIIBUSY 0x0004
-+
-+/* link capability */
-+#define LX_LC_10H 0x01
-+#define LX_LC_10F 0x02
-+#define LX_LC_100H 0x04
-+#define LX_LC_100F 0x08
-+#define LX_LC_1000F 0x10
-+#define LX_LC_ALL \
-+ (LX_LC_10H|LX_LC_10F|LX_LC_100H|LX_LC_100F|LX_LC_1000F)
-+
-+/* options for MAC contrl */
-+#define LX_MACSPEED_1000 BIT(0) /* 1:1000M, 0:10/100M */
-+#define LX_MACDUPLEX_FULL BIT(1) /* 1:full, 0:half */
-+#define LX_FLT_BROADCAST BIT(2) /* 1:enable rx-broadcast */
-+#define LX_FLT_MULTI_ALL BIT(3)
-+#define LX_FLT_DIRECT BIT(4)
-+#define LX_FLT_PROMISC BIT(5)
-+#define LX_FC_TXEN BIT(6)
-+#define LX_FC_RXEN BIT(7)
-+#define LX_VLAN_STRIP BIT(8)
-+#define LX_LOOPBACK BIT(9)
-+#define LX_ADD_FCS BIT(10)
-+#define LX_SINGLE_PAUSE BIT(11)
-+
-+
-+/* interop between drivers */
-+#define LX_DRV_TYPE_MASK ASHFT27(0x1FUL)
-+#define LX_DRV_TYPE_SHIFT 27
-+#define LX_DRV_TYPE_UNKNOWN 0
-+#define LX_DRV_TYPE_BIOS 1
-+#define LX_DRV_TYPE_BTROM 2
-+#define LX_DRV_TYPE_PKT 3
-+#define LX_DRV_TYPE_NDS2 4
-+#define LX_DRV_TYPE_UEFI 5
-+#define LX_DRV_TYPE_NDS5 6
-+#define LX_DRV_TYPE_NDS62 7
-+#define LX_DRV_TYPE_NDS63 8
-+#define LX_DRV_TYPE_LNX 9
-+#define LX_DRV_TYPE_ODI16 10
-+#define LX_DRV_TYPE_ODI32 11
-+#define LX_DRV_TYPE_FRBSD 12
-+#define LX_DRV_TYPE_NTBSD 13
-+#define LX_DRV_TYPE_WCE 14
-+#define LX_DRV_PHY_AUTO BIT(26) /* 1:auto, 0:force */
-+#define LX_DRV_PHY_1000 BIT(25)
-+#define LX_DRV_PHY_100 BIT(24)
-+#define LX_DRV_PHY_10 BIT(23)
-+#define LX_DRV_PHY_DUPLEX BIT(22) /* 1:full, 0:half */
-+#define LX_DRV_PHY_FC BIT(21) /* 1:en flow control */
-+#define LX_DRV_PHY_MASK ASHFT21(0x1FUL)
-+#define LX_DRV_PHY_SHIFT 21
-+#define LX_DRV_PHY_UNKNOWN 0
-+#define LX_DRV_DISABLE BIT(18)
-+#define LX_DRV_WOLS5_EN BIT(17)
-+#define LX_DRV_WOLS5_BIOS_EN BIT(16)
-+#define LX_DRV_AZ_EN BIT(12)
-+#define LX_DRV_WOLPATTERN_EN BIT(11)
-+#define LX_DRV_WOLLINKUP_EN BIT(10)
-+#define LX_DRV_WOLMAGIC_EN BIT(9)
-+#define LX_DRV_WOLCAP_BIOS_EN BIT(8)
-+#define LX_DRV_ASPM_SPD1000LMT_MASK ASHFT4(3UL)
-+#define LX_DRV_ASPM_SPD1000LMT_SHIFT 4
-+#define LX_DRV_ASPM_SPD1000LMT_100M 0
-+#define LX_DRV_ASPM_SPD1000LMT_NO 1
-+#define LX_DRV_ASPM_SPD1000LMT_1M 2
-+#define LX_DRV_ASPM_SPD1000LMT_10M 3
-+#define LX_DRV_ASPM_SPD100LMT_MASK ASHFT2(3UL)
-+#define LX_DRV_ASPM_SPD100LMT_SHIFT 2
-+#define LX_DRV_ASPM_SPD100LMT_1M 0
-+#define LX_DRV_ASPM_SPD100LMT_10M 1
-+#define LX_DRV_ASPM_SPD100LMT_100M 2
-+#define LX_DRV_ASPM_SPD100LMT_NO 3
-+#define LX_DRV_ASPM_SPD10LMT_MASK ASHFT0(3UL)
-+#define LX_DRV_ASPM_SPD10LMT_SHIFT 0
-+#define LX_DRV_ASPM_SPD10LMT_1M 0
-+#define LX_DRV_ASPM_SPD10LMT_10M 1
-+#define LX_DRV_ASPM_SPD10LMT_100M 2
-+#define LX_DRV_ASPM_SPD10LMT_NO 3
-+
-+/* flag of phy inited */
-+#define LX_PHY_INITED 0x003F
-+
-+/* check if the mac address is valid */
-+#define macaddr_valid(_addr) (\
-+ ((*(u8 *)(_addr))&1) == 0 && \
-+ !(*(u32 *)(_addr) == 0 && *((u16 *)(_addr)+2) == 0))
-+
-+#define test_set_or_clear(_val, _ctrl, _flag, _bit) \
-+do { \
-+ if ((_ctrl) & (_flag)) \
-+ (_val) |= (_bit); \
-+ else \
-+ (_val) &= ~(_bit); \
-+} while (0)
-+
-+
-+#endif/*_ALX_HWCOMMON_H_*/
-+
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alx_main.c
-@@ -0,0 +1,3899 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include "alx.h"
-+#include "alx_hwcom.h"
-+
-+char alx_drv_name[] = "alx";
-+static const char alx_drv_description[] =
-+ "Qualcomm Atheros(R) "
-+ "AR813x/AR815x/AR816x PCI-E Ethernet Network Driver";
-+
-+/* alx_pci_tbl - PCI Device ID Table
-+ *
-+ * Wildcard entries (PCI_ANY_ID) should come last
-+ * Last entry must be all 0s
-+ *
-+ * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
-+ * Class, Class Mask, private data (not used) }
-+ */
-+#define ALX_ETHER_DEVICE(device_id) {\
-+ PCI_DEVICE(ALX_VENDOR_ID, device_id)}
-+static DEFINE_PCI_DEVICE_TABLE(alx_pci_tbl) = {
-+ ALX_ETHER_DEVICE(ALX_DEV_ID_AR8131),
-+ ALX_ETHER_DEVICE(ALX_DEV_ID_AR8132),
-+ ALX_ETHER_DEVICE(ALX_DEV_ID_AR8151_V1),
-+ ALX_ETHER_DEVICE(ALX_DEV_ID_AR8151_V2),
-+ ALX_ETHER_DEVICE(ALX_DEV_ID_AR8152_V1),
-+ ALX_ETHER_DEVICE(ALX_DEV_ID_AR8152_V2),
-+ ALX_ETHER_DEVICE(ALX_DEV_ID_AR8161),
-+ ALX_ETHER_DEVICE(ALX_DEV_ID_AR8162),
-+ {0,}
-+};
-+MODULE_DEVICE_TABLE(pci, alx_pci_tbl);
-+MODULE_AUTHOR("Qualcomm Corporation, <nic-devel@qualcomm.com>");
-+MODULE_DESCRIPTION("Qualcomm Atheros Gigabit Ethernet Driver");
-+MODULE_LICENSE("Dual BSD/GPL");
-+
-+static int alx_open_internal(struct alx_adapter *adpt, u32 ctrl);
-+static void alx_stop_internal(struct alx_adapter *adpt, u32 ctrl);
-+
-+int alx_cfg_r16(const struct alx_hw *hw, int reg, u16 *pval)
-+{
-+ if (!(hw && hw->adpt && hw->adpt->pdev))
-+ return -EINVAL;
-+ return pci_read_config_word(hw->adpt->pdev, reg, pval);
-+}
-+
-+
-+int alx_cfg_w16(const struct alx_hw *hw, int reg, u16 val)
-+{
-+ if (!(hw && hw->adpt && hw->adpt->pdev))
-+ return -EINVAL;
-+ return pci_write_config_word(hw->adpt->pdev, reg, val);
-+}
-+
-+
-+void alx_mem_flush(const struct alx_hw *hw)
-+{
-+ readl(hw->hw_addr);
-+}
-+
-+
-+void alx_mem_r32(const struct alx_hw *hw, int reg, u32 *val)
-+{
-+ if (unlikely(!hw->link_up))
-+ readl(hw->hw_addr + reg);
-+ *(u32 *)val = readl(hw->hw_addr + reg);
-+}
-+
-+
-+void alx_mem_w32(const struct alx_hw *hw, int reg, u32 val)
-+{
-+ if (hw->mac_type == alx_mac_l2cb_v20 && reg < 0x1400)
-+ readl(hw->hw_addr + reg);
-+ writel(val, hw->hw_addr + reg);
-+}
-+
-+
-+static void alx_mem_r16(const struct alx_hw *hw, int reg, u16 *val)
-+{
-+ if (unlikely(!hw->link_up))
-+ readl(hw->hw_addr + reg);
-+ *(u16 *)val = readw(hw->hw_addr + reg);
-+}
-+
-+
-+static void alx_mem_w16(const struct alx_hw *hw, int reg, u16 val)
-+{
-+ if (hw->mac_type == alx_mac_l2cb_v20 && reg < 0x1400)
-+ readl(hw->hw_addr + reg);
-+ writew(val, hw->hw_addr + reg);
-+}
-+
-+
-+void alx_mem_w8(const struct alx_hw *hw, int reg, u8 val)
-+{
-+ if (hw->mac_type == alx_mac_l2cb_v20 && reg < 0x1400)
-+ readl(hw->hw_addr + reg);
-+ writeb(val, hw->hw_addr + reg);
-+}
-+
-+
-+/*
-+ * alx_hw_printk
-+ */
-+void alx_hw_printk(const char *level, const struct alx_hw *hw,
-+ const char *fmt, ...)
-+{
-+ struct va_format vaf;
-+ va_list args;
-+
-+ va_start(args, fmt);
-+ vaf.fmt = fmt;
-+ vaf.va = &args;
-+
-+ if (hw && hw->adpt && hw->adpt->netdev)
-+ __netdev_printk(level, hw->adpt->netdev, &vaf);
-+ else
-+ printk("%salx_hw: %pV", level, &vaf);
-+
-+ va_end(args);
-+}
-+
-+
-+/*
-+ * alx_validate_mac_addr - Validate MAC address
-+ */
-+static int alx_validate_mac_addr(u8 *mac_addr)
-+{
-+ int retval = 0;
-+
-+ if (mac_addr[0] & 0x01) {
-+ printk(KERN_DEBUG "MAC address is multicast\n");
-+ retval = -EADDRNOTAVAIL;
-+ } else if (mac_addr[0] == 0xff && mac_addr[1] == 0xff) {
-+ printk(KERN_DEBUG "MAC address is broadcast\n");
-+ retval = -EADDRNOTAVAIL;
-+ } else if (mac_addr[0] == 0 && mac_addr[1] == 0 &&
-+ mac_addr[2] == 0 && mac_addr[3] == 0 &&
-+ mac_addr[4] == 0 && mac_addr[5] == 0) {
-+ printk(KERN_DEBUG "MAC address is all zeros\n");
-+ retval = -EADDRNOTAVAIL;
-+ }
-+ return retval;
-+}
-+
-+
-+/*
-+ * alx_set_mac_type - Sets MAC type
-+ */
-+static int alx_set_mac_type(struct alx_adapter *adpt)
-+{
-+ struct alx_hw *hw = &adpt->hw;
-+ int retval = 0;
-+
-+ if (hw->pci_venid == ALX_VENDOR_ID) {
-+ switch (hw->pci_devid) {
-+ case ALX_DEV_ID_AR8131:
-+ hw->mac_type = alx_mac_l1c;
-+ break;
-+ case ALX_DEV_ID_AR8132:
-+ hw->mac_type = alx_mac_l2c;
-+ break;
-+ case ALX_DEV_ID_AR8151_V1:
-+ hw->mac_type = alx_mac_l1d_v1;
-+ break;
-+ case ALX_DEV_ID_AR8151_V2:
-+ /* just use l1d configure */
-+ hw->mac_type = alx_mac_l1d_v2;
-+ break;
-+ case ALX_DEV_ID_AR8152_V1:
-+ hw->mac_type = alx_mac_l2cb_v1;
-+ break;
-+ case ALX_DEV_ID_AR8152_V2:
-+ if (hw->pci_revid == ALX_REV_ID_AR8152_V2_0)
-+ hw->mac_type = alx_mac_l2cb_v20;
-+ else
-+ hw->mac_type = alx_mac_l2cb_v21;
-+ break;
-+ case ALX_DEV_ID_AR8161:
-+ hw->mac_type = alx_mac_l1f;
-+ break;
-+ case ALX_DEV_ID_AR8162:
-+ hw->mac_type = alx_mac_l2f;
-+ break;
-+ default:
-+ retval = -EINVAL;
-+ break;
-+ }
-+ } else {
-+ retval = -EINVAL;
-+ }
-+
-+ netif_info(adpt, hw, adpt->netdev,
-+ "found mac: %d, returns: %d\n", hw->mac_type, retval);
-+ return retval;
-+}
-+
-+
-+/*
-+ * alx_init_hw_callbacks
-+ */
-+static int alx_init_hw_callbacks(struct alx_adapter *adpt)
-+{
-+ struct alx_hw *hw = &adpt->hw;
-+ int retval = 0;
-+
-+ alx_set_mac_type(adpt);
-+
-+ switch (hw->mac_type) {
-+ case alx_mac_l1f:
-+ case alx_mac_l2f:
-+ retval = alf_init_hw_callbacks(hw);
-+ break;
-+ case alx_mac_l1c:
-+ case alx_mac_l2c:
-+ case alx_mac_l2cb_v1:
-+ case alx_mac_l2cb_v20:
-+ case alx_mac_l2cb_v21:
-+ case alx_mac_l1d_v1:
-+ case alx_mac_l1d_v2:
-+ retval = alc_init_hw_callbacks(hw);
-+ break;
-+ default:
-+ retval = -EINVAL;
-+ break;
-+ }
-+ return retval;
-+}
-+
-+
-+void alx_reinit_locked(struct alx_adapter *adpt)
-+{
-+ WARN_ON(in_interrupt());
-+
-+ while (CHK_ADPT_FLAG(1, STATE_RESETTING))
-+ msleep(20);
-+ SET_ADPT_FLAG(1, STATE_RESETTING);
-+
-+ alx_stop_internal(adpt, ALX_OPEN_CTRL_RESET_MAC);
-+ alx_open_internal(adpt, ALX_OPEN_CTRL_RESET_MAC);
-+
-+ CLI_ADPT_FLAG(1, STATE_RESETTING);
-+}
-+
-+
-+static void alx_task_schedule(struct alx_adapter *adpt)
-+{
-+ if (!CHK_ADPT_FLAG(1, STATE_DOWN) &&
-+ !CHK_ADPT_FLAG(1, STATE_WATCH_DOG)) {
-+ SET_ADPT_FLAG(1, STATE_WATCH_DOG);
-+ schedule_work(&adpt->alx_task);
-+ }
-+}
-+
-+
-+static void alx_check_lsc(struct alx_adapter *adpt)
-+{
-+ SET_ADPT_FLAG(0, TASK_LSC_REQ);
-+ adpt->link_jiffies = jiffies + ALX_TRY_LINK_TIMEOUT;
-+
-+ if (!CHK_ADPT_FLAG(1, STATE_DOWN))
-+ alx_task_schedule(adpt);
-+}
-+
-+
-+/*
-+ * alx_tx_timeout - Respond to a Tx Hang
-+ */
-+static void alx_tx_timeout(struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+
-+ /* Do the reset outside of interrupt context */
-+ if (!CHK_ADPT_FLAG(1, STATE_DOWN)) {
-+ SET_ADPT_FLAG(0, TASK_REINIT_REQ);
-+ alx_task_schedule(adpt);
-+ }
-+}
-+
-+
-+/*
-+ * alx_set_multicase_list - Multicast and Promiscuous mode set
-+ */
-+static void alx_set_multicase_list(struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ struct netdev_hw_addr *ha;
-+
-+ /* Check for Promiscuous and All Multicast modes */
-+ if (netdev->flags & IFF_PROMISC) {
-+ SET_HW_FLAG(PROMISC_EN);
-+ } else if (netdev->flags & IFF_ALLMULTI) {
-+ SET_HW_FLAG(MULTIALL_EN);
-+ CLI_HW_FLAG(PROMISC_EN);
-+ } else {
-+ CLI_HW_FLAG(MULTIALL_EN);
-+ CLI_HW_FLAG(PROMISC_EN);
-+ }
-+ hw->cbs.config_mac_ctrl(hw);
-+
-+ /* clear the old settings from the multicast hash table */
-+ hw->cbs.clear_mc_addr(hw);
-+
-+ /* comoute mc addresses' hash value ,and put it into hash table */
-+ netdev_for_each_mc_addr(ha, netdev)
-+ hw->cbs.set_mc_addr(hw, ha->addr);
-+}
-+
-+
-+/*
-+ * alx_set_mac - Change the Ethernet Address of the NIC
-+ */
-+static int alx_set_mac_address(struct net_device *netdev, void *data)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ struct sockaddr *addr = data;
-+
-+ if (!is_valid_ether_addr(addr->sa_data))
-+ return -EADDRNOTAVAIL;
-+
-+ if (netif_running(netdev))
-+ return -EBUSY;
-+
-+ if (netdev->addr_assign_type & NET_ADDR_RANDOM)
-+ netdev->addr_assign_type ^= NET_ADDR_RANDOM;
-+
-+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-+ memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
-+
-+ if (hw->cbs.set_mac_addr)
-+ hw->cbs.set_mac_addr(hw, hw->mac_addr);
-+ return 0;
-+}
-+
-+
-+/*
-+ * Read / Write Ptr Initialize:
-+ */
-+static void alx_init_ring_ptrs(struct alx_adapter *adpt)
-+{
-+ int i, j;
-+
-+ for (i = 0; i < adpt->num_txques; i++) {
-+ struct alx_tx_queue *txque = adpt->tx_queue[i];
-+ struct alx_buffer *tpbuf = txque->tpq.tpbuff;
-+ txque->tpq.produce_idx = 0;
-+ txque->tpq.consume_idx = 0;
-+ for (j = 0; j < txque->tpq.count; j++)
-+ tpbuf[j].dma = 0;
-+ }
-+
-+ for (i = 0; i < adpt->num_hw_rxques; i++) {
-+ struct alx_rx_queue *rxque = adpt->rx_queue[i];
-+ struct alx_buffer *rfbuf = rxque->rfq.rfbuff;
-+ rxque->rrq.produce_idx = 0;
-+ rxque->rrq.consume_idx = 0;
-+ rxque->rfq.produce_idx = 0;
-+ rxque->rfq.consume_idx = 0;
-+ for (j = 0; j < rxque->rfq.count; j++)
-+ rfbuf[j].dma = 0;
-+ }
-+
-+ if (CHK_ADPT_FLAG(0, SRSS_EN))
-+ goto srrs_enable;
-+
-+ return;
-+
-+srrs_enable:
-+ for (i = 0; i < adpt->num_sw_rxques; i++) {
-+ struct alx_rx_queue *rxque = adpt->rx_queue[i];
-+ rxque->swq.produce_idx = 0;
-+ rxque->swq.consume_idx = 0;
-+ }
-+}
-+
-+
-+static void alx_config_rss(struct alx_adapter *adpt)
-+{
-+ static const u8 key[40] = {
-+ 0xE2, 0x91, 0xD7, 0x3D, 0x18, 0x05, 0xEC, 0x6C,
-+ 0x2A, 0x94, 0xB3, 0x0D, 0xA5, 0x4F, 0x2B, 0xEC,
-+ 0xEA, 0x49, 0xAF, 0x7C, 0xE2, 0x14, 0xAD, 0x3D,
-+ 0xB8, 0x55, 0xAA, 0xBE, 0x6A, 0x3E, 0x67, 0xEA,
-+ 0x14, 0x36, 0x4D, 0x17, 0x3B, 0xED, 0x20, 0x0D};
-+
-+ struct alx_hw *hw = &adpt->hw;
-+ u32 reta = 0;
-+ int i, j;
-+
-+ /* initialize rss hash type and idt table size */
-+ hw->rss_hstype = ALX_RSS_HSTYP_ALL_EN;
-+ hw->rss_idt_size = 0x100;
-+
-+ /* Fill out redirection table */
-+ memcpy(hw->rss_key, key, sizeof(hw->rss_key));
-+
-+ /* Fill out redirection table */
-+ memset(hw->rss_idt, 0x0, sizeof(hw->rss_idt));
-+ for (i = 0, j = 0; i < 256; i++, j++) {
-+ if (j == adpt->max_rxques)
-+ j = 0;
-+ reta |= (j << ((i & 7) * 4));
-+ if ((i & 7) == 7) {
-+ hw->rss_idt[i>>3] = reta;
-+ reta = 0;
-+ }
-+ }
-+
-+ if (hw->cbs.config_rss)
-+ hw->cbs.config_rss(hw, CHK_ADPT_FLAG(0, SRSS_EN));
-+}
-+
-+
-+/*
-+ * alx_receive_skb
-+ */
-+static void alx_receive_skb(struct alx_adapter *adpt,
-+ struct sk_buff *skb,
-+ u16 vlan_tag, bool vlan_flag)
-+{
-+ if (vlan_flag) {
-+ u16 vlan;
-+ ALX_TAG_TO_VLAN(vlan_tag, vlan);
-+ __vlan_hwaccel_put_tag(skb, vlan);
-+ }
-+ netif_receive_skb(skb);
-+}
-+
-+
-+static bool alx_get_rrdesc(struct alx_rx_queue *rxque,
-+ union alx_sw_rrdesc *srrd)
-+{
-+ union alx_rrdesc *hrrd =
-+ ALX_RRD(rxque, rxque->rrq.consume_idx);
-+
-+ srrd->dfmt.dw0 = le32_to_cpu(hrrd->dfmt.dw0);
-+ srrd->dfmt.dw1 = le32_to_cpu(hrrd->dfmt.dw1);
-+ srrd->dfmt.dw2 = le32_to_cpu(hrrd->dfmt.dw2);
-+ srrd->dfmt.dw3 = le32_to_cpu(hrrd->dfmt.dw3);
-+
-+ if (!srrd->genr.update)
-+ return false;
-+
-+ if (likely(srrd->genr.nor != 1)) {
-+ /* TODO support mul rfd*/
-+ printk(KERN_EMERG "Multi rfd not support yet!\n");
-+ }
-+
-+ srrd->genr.update = 0;
-+ hrrd->dfmt.dw3 = cpu_to_le32(srrd->dfmt.dw3);
-+ if (++rxque->rrq.consume_idx == rxque->rrq.count)
-+ rxque->rrq.consume_idx = 0;
-+
-+ return true;
-+}
-+
-+
-+static bool alx_set_rfdesc(struct alx_rx_queue *rxque,
-+ union alx_sw_rfdesc *srfd)
-+{
-+ union alx_rfdesc *hrfd =
-+ ALX_RFD(rxque, rxque->rfq.produce_idx);
-+
-+ hrfd->qfmt.qw0 = cpu_to_le64(srfd->qfmt.qw0);
-+
-+ if (++rxque->rfq.produce_idx == rxque->rfq.count)
-+ rxque->rfq.produce_idx = 0;
-+
-+ return true;
-+}
-+
-+
-+static bool alx_set_tpdesc(struct alx_tx_queue *txque,
-+ union alx_sw_tpdesc *stpd)
-+{
-+ union alx_tpdesc *htpd;
-+
-+ txque->tpq.last_produce_idx = txque->tpq.produce_idx;
-+ htpd = ALX_TPD(txque, txque->tpq.produce_idx);
-+
-+ if (++txque->tpq.produce_idx == txque->tpq.count)
-+ txque->tpq.produce_idx = 0;
-+
-+ htpd->dfmt.dw0 = cpu_to_le32(stpd->dfmt.dw0);
-+ htpd->dfmt.dw1 = cpu_to_le32(stpd->dfmt.dw1);
-+ htpd->qfmt.qw1 = cpu_to_le64(stpd->qfmt.qw1);
-+
-+ return true;
-+}
-+
-+
-+static void alx_set_tpdesc_lastfrag(struct alx_tx_queue *txque)
-+{
-+ union alx_tpdesc *htpd;
-+#define ALX_TPD_LAST_FLAGMENT 0x80000000
-+ htpd = ALX_TPD(txque, txque->tpq.last_produce_idx);
-+ htpd->dfmt.dw1 |= cpu_to_le32(ALX_TPD_LAST_FLAGMENT);
-+}
-+
-+
-+static int alx_refresh_rx_buffer(struct alx_rx_queue *rxque)
-+{
-+ struct alx_adapter *adpt = netdev_priv(rxque->netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ struct alx_buffer *curr_rxbuf;
-+ struct alx_buffer *next_rxbuf;
-+ union alx_sw_rfdesc srfd;
-+ struct sk_buff *skb;
-+ void *skb_data = NULL;
-+ u16 count = 0;
-+ u16 next_produce_idx;
-+
-+ next_produce_idx = rxque->rfq.produce_idx;
-+ if (++next_produce_idx == rxque->rfq.count)
-+ next_produce_idx = 0;
-+ curr_rxbuf = GET_RF_BUFFER(rxque, rxque->rfq.produce_idx);
-+ next_rxbuf = GET_RF_BUFFER(rxque, next_produce_idx);
-+
-+ /* this always has a blank rx_buffer*/
-+ while (next_rxbuf->dma == 0) {
-+ skb = dev_alloc_skb(adpt->rxbuf_size);
-+ if (unlikely(!skb)) {
-+ alx_err(adpt, "alloc rx buffer failed\n");
-+ break;
-+ }
-+
-+ /*
-+ * Make buffer alignment 2 beyond a 16 byte boundary
-+ * this will result in a 16 byte aligned IP header after
-+ * the 14 byte MAC header is removed
-+ */
-+ skb_data = skb->data;
-+ /*skb_reserve(skb, NET_IP_ALIGN);*/
-+ curr_rxbuf->skb = skb;
-+ curr_rxbuf->length = adpt->rxbuf_size;
-+ curr_rxbuf->dma = dma_map_single(rxque->dev,
-+ skb_data,
-+ curr_rxbuf->length,
-+ DMA_FROM_DEVICE);
-+ srfd.genr.addr = curr_rxbuf->dma;
-+ alx_set_rfdesc(rxque, &srfd);
-+
-+ next_produce_idx = rxque->rfq.produce_idx;
-+ if (++next_produce_idx == rxque->rfq.count)
-+ next_produce_idx = 0;
-+ curr_rxbuf = GET_RF_BUFFER(rxque, rxque->rfq.produce_idx);
-+ next_rxbuf = GET_RF_BUFFER(rxque, next_produce_idx);
-+ count++;
-+ }
-+
-+ if (count) {
-+ wmb();
-+ alx_mem_w16(hw, rxque->produce_reg, rxque->rfq.produce_idx);
-+ netif_info(adpt, rx_err, adpt->netdev,
-+ "RX[%d]: prod_reg[%x] = 0x%x, rfq.prod_idx = 0x%x\n",
-+ rxque->que_idx, rxque->produce_reg,
-+ rxque->rfq.produce_idx, rxque->rfq.produce_idx);
-+ }
-+ return count;
-+}
-+
-+
-+static void alx_clean_rfdesc(struct alx_rx_queue *rxque,
-+ union alx_sw_rrdesc *srrd)
-+{
-+ struct alx_buffer *rfbuf = rxque->rfq.rfbuff;
-+ u32 consume_idx = srrd->genr.si;
-+ u32 i;
-+
-+ for (i = 0; i < srrd->genr.nor; i++) {
-+ rfbuf[consume_idx].skb = NULL;
-+ if (++consume_idx == rxque->rfq.count)
-+ consume_idx = 0;
-+ }
-+ rxque->rfq.consume_idx = consume_idx;
-+}
-+
-+
-+static bool alx_dispatch_rx_irq(struct alx_msix_param *msix,
-+ struct alx_rx_queue *rxque)
-+{
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct pci_dev *pdev = adpt->pdev;
-+ struct net_device *netdev = adpt->netdev;
-+
-+ union alx_sw_rrdesc srrd;
-+ struct alx_buffer *rfbuf;
-+ struct sk_buff *skb;
-+ struct alx_rx_queue *swque;
-+ struct alx_sw_buffer *curr_swbuf;
-+ struct alx_sw_buffer *next_swbuf;
-+
-+ u16 next_produce_idx;
-+ u16 count = 0;
-+
-+ while (1) {
-+ if (!alx_get_rrdesc(rxque, &srrd))
-+ break;
-+
-+ if (srrd.genr.res || srrd.genr.lene) {
-+ alx_clean_rfdesc(rxque, &srrd);
-+ netif_warn(adpt, rx_err, adpt->netdev,
-+ "wrong packet! rrd->word3 is 0x%08x\n",
-+ srrd.dfmt.dw3);
-+ continue;
-+ }
-+
-+ /* Good Receive */
-+ if (likely(srrd.genr.nor == 1)) {
-+ rfbuf = GET_RF_BUFFER(rxque, srrd.genr.si);
-+ pci_unmap_single(pdev, rfbuf->dma,
-+ rfbuf->length, DMA_FROM_DEVICE);
-+ rfbuf->dma = 0;
-+ skb = rfbuf->skb;
-+ netif_info(adpt, rx_err, adpt->netdev,
-+ "skb addr = %p, rxbuf_len = %x\n",
-+ skb->data, rfbuf->length);
-+ } else {
-+ /* TODO */
-+ alx_err(adpt, "Multil rfd not support yet!\n");
-+ break;
-+ }
-+ alx_clean_rfdesc(rxque, &srrd);
-+
-+ skb_put(skb, srrd.genr.pkt_len - ETH_FCS_LEN);
-+ skb->protocol = eth_type_trans(skb, netdev);
-+ skb_checksum_none_assert(skb);
-+
-+ /* start to dispatch */
-+ swque = adpt->rx_queue[srrd.genr.rss_cpu];
-+ next_produce_idx = swque->swq.produce_idx;
-+ if (++next_produce_idx == swque->swq.count)
-+ next_produce_idx = 0;
-+
-+ curr_swbuf = GET_SW_BUFFER(swque, swque->swq.produce_idx);
-+ next_swbuf = GET_SW_BUFFER(swque, next_produce_idx);
-+
-+ /*
-+ * if full, will discard the packet,
-+ * and at lease has a blank sw_buffer.
-+ */
-+ if (!next_swbuf->skb) {
-+ curr_swbuf->skb = skb;
-+ curr_swbuf->vlan_tag = srrd.genr.vlan_tag;
-+ curr_swbuf->vlan_flag = srrd.genr.vlan_flag;
-+ if (++swque->swq.produce_idx == swque->swq.count)
-+ swque->swq.produce_idx = 0;
-+ }
-+
-+ count++;
-+ if (count == 32)
-+ break;
-+ }
-+ if (count)
-+ alx_refresh_rx_buffer(rxque);
-+ return true;
-+}
-+
-+
-+static bool alx_handle_srx_irq(struct alx_msix_param *msix,
-+ struct alx_rx_queue *rxque,
-+ int *num_pkts, int max_pkts)
-+{
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct alx_sw_buffer *swbuf;
-+ bool retval = true;
-+
-+ while (rxque->swq.consume_idx != rxque->swq.produce_idx) {
-+ swbuf = GET_SW_BUFFER(rxque, rxque->swq.consume_idx);
-+
-+ alx_receive_skb(adpt, swbuf->skb, (u16)swbuf->vlan_tag,
-+ (bool)swbuf->vlan_flag);
-+ swbuf->skb = NULL;
-+
-+ if (++rxque->swq.consume_idx == rxque->swq.count)
-+ rxque->swq.consume_idx = 0;
-+
-+ (*num_pkts)++;
-+ if (*num_pkts >= max_pkts) {
-+ retval = false;
-+ break;
-+ }
-+ }
-+ return retval;
-+}
-+
-+
-+static bool alx_handle_rx_irq(struct alx_msix_param *msix,
-+ struct alx_rx_queue *rxque,
-+ int *num_pkts, int max_pkts)
-+{
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct alx_hw *hw = &adpt->hw;
-+ struct pci_dev *pdev = adpt->pdev;
-+ struct net_device *netdev = adpt->netdev;
-+
-+ union alx_sw_rrdesc srrd;
-+ struct alx_buffer *rfbuf;
-+ struct sk_buff *skb;
-+
-+ u16 hw_consume_idx, num_consume_pkts;
-+ u16 count = 0;
-+
-+ alx_mem_r16(hw, rxque->consume_reg, &hw_consume_idx);
-+ num_consume_pkts = (hw_consume_idx > rxque->rrq.consume_idx) ?
-+ (hw_consume_idx - rxque->rrq.consume_idx) :
-+ (hw_consume_idx + rxque->rrq.count - rxque->rrq.consume_idx);
-+
-+ while (1) {
-+ if (!num_consume_pkts)
-+ break;
-+
-+ if (!alx_get_rrdesc(rxque, &srrd))
-+ break;
-+
-+ if (srrd.genr.res || srrd.genr.lene) {
-+ alx_clean_rfdesc(rxque, &srrd);
-+ netif_warn(adpt, rx_err, adpt->netdev,
-+ "wrong packet! rrd->word3 is 0x%08x\n",
-+ srrd.dfmt.dw3);
-+ continue;
-+ }
-+
-+ /* TODO: Good Receive */
-+ if (likely(srrd.genr.nor == 1)) {
-+ rfbuf = GET_RF_BUFFER(rxque, srrd.genr.si);
-+ pci_unmap_single(pdev, rfbuf->dma, rfbuf->length,
-+ DMA_FROM_DEVICE);
-+ rfbuf->dma = 0;
-+ skb = rfbuf->skb;
-+ } else {
-+ /* TODO */
-+ alx_err(adpt, "Multil rfd not support yet!\n");
-+ break;
-+ }
-+ alx_clean_rfdesc(rxque, &srrd);
-+
-+ skb_put(skb, srrd.genr.pkt_len - ETH_FCS_LEN);
-+ skb->protocol = eth_type_trans(skb, netdev);
-+ skb_checksum_none_assert(skb);
-+ alx_receive_skb(adpt, skb, (u16)srrd.genr.vlan_tag,
-+ (bool)srrd.genr.vlan_flag);
-+
-+ num_consume_pkts--;
-+ count++;
-+ (*num_pkts)++;
-+ if (*num_pkts >= max_pkts)
-+ break;
-+ }
-+ if (count)
-+ alx_refresh_rx_buffer(rxque);
-+
-+ return true;
-+}
-+
-+
-+static bool alx_handle_tx_irq(struct alx_msix_param *msix,
-+ struct alx_tx_queue *txque)
-+{
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct alx_hw *hw = &adpt->hw;
-+ struct alx_buffer *tpbuf;
-+ u16 consume_data;
-+
-+ alx_mem_r16(hw, txque->consume_reg, &consume_data);
-+ netif_info(adpt, tx_err, adpt->netdev,
-+ "TX[%d]: consume_reg[0x%x] = 0x%x, tpq.consume_idx = 0x%x\n",
-+ txque->que_idx, txque->consume_reg, consume_data,
-+ txque->tpq.consume_idx);
-+
-+
-+ while (txque->tpq.consume_idx != consume_data) {
-+ tpbuf = GET_TP_BUFFER(txque, txque->tpq.consume_idx);
-+ if (tpbuf->dma) {
-+ pci_unmap_page(adpt->pdev, tpbuf->dma, tpbuf->length,
-+ DMA_TO_DEVICE);
-+ tpbuf->dma = 0;
-+ }
-+
-+ if (tpbuf->skb) {
-+ dev_kfree_skb_irq(tpbuf->skb);
-+ tpbuf->skb = NULL;
-+ }
-+
-+ if (++txque->tpq.consume_idx == txque->tpq.count)
-+ txque->tpq.consume_idx = 0;
-+ }
-+
-+ if (netif_queue_stopped(adpt->netdev) &&
-+ netif_carrier_ok(adpt->netdev)) {
-+ netif_wake_queue(adpt->netdev);
-+ }
-+ return true;
-+}
-+
-+
-+static irqreturn_t alx_msix_timer(int irq, void *data)
-+{
-+ struct alx_msix_param *msix = data;
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct alx_hw *hw = &adpt->hw;
-+ u32 isr;
-+
-+ hw->cbs.disable_msix_intr(hw, msix->vec_idx);
-+
-+ alx_mem_r32(hw, ALX_ISR, &isr);
-+ isr = isr & (ALX_ISR_TIMER | ALX_ISR_MANU);
-+
-+
-+ if (isr == 0) {
-+ hw->cbs.enable_msix_intr(hw, msix->vec_idx);
-+ return IRQ_NONE;
-+ }
-+
-+ /* Ack ISR */
-+ alx_mem_w32(hw, ALX_ISR, isr);
-+
-+ if (isr & ALX_ISR_MANU) {
-+ adpt->net_stats.tx_carrier_errors++;
-+ alx_check_lsc(adpt);
-+ }
-+
-+ hw->cbs.enable_msix_intr(hw, msix->vec_idx);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+
-+static irqreturn_t alx_msix_alert(int irq, void *data)
-+{
-+ struct alx_msix_param *msix = data;
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct alx_hw *hw = &adpt->hw;
-+ u32 isr;
-+
-+ hw->cbs.disable_msix_intr(hw, msix->vec_idx);
-+
-+ alx_mem_r32(hw, ALX_ISR, &isr);
-+ isr = isr & ALX_ISR_ALERT_MASK;
-+
-+ if (isr == 0) {
-+ hw->cbs.enable_msix_intr(hw, msix->vec_idx);
-+ return IRQ_NONE;
-+ }
-+ alx_mem_w32(hw, ALX_ISR, isr);
-+
-+ hw->cbs.enable_msix_intr(hw, msix->vec_idx);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+
-+static irqreturn_t alx_msix_smb(int irq, void *data)
-+{
-+ struct alx_msix_param *msix = data;
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct alx_hw *hw = &adpt->hw;
-+
-+ hw->cbs.disable_msix_intr(hw, msix->vec_idx);
-+
-+ hw->cbs.enable_msix_intr(hw, msix->vec_idx);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+
-+static irqreturn_t alx_msix_phy(int irq, void *data)
-+{
-+ struct alx_msix_param *msix = data;
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct alx_hw *hw = &adpt->hw;
-+
-+ hw->cbs.disable_msix_intr(hw, msix->vec_idx);
-+
-+ if (hw->cbs.ack_phy_intr)
-+ hw->cbs.ack_phy_intr(hw);
-+
-+ adpt->net_stats.tx_carrier_errors++;
-+ alx_check_lsc(adpt);
-+
-+ hw->cbs.enable_msix_intr(hw, msix->vec_idx);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+
-+/*
-+ * alx_msix_rtx
-+ */
-+static irqreturn_t alx_msix_rtx(int irq, void *data)
-+{
-+ struct alx_msix_param *msix = data;
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct alx_hw *hw = &adpt->hw;
-+
-+ netif_info(adpt, intr, adpt->netdev,
-+ "msix vec_idx = %d\n", msix->vec_idx);
-+
-+ hw->cbs.disable_msix_intr(hw, msix->vec_idx);
-+ if (!msix->rx_count && !msix->tx_count) {
-+ hw->cbs.enable_msix_intr(hw, msix->vec_idx);
-+ return IRQ_HANDLED;
-+ }
-+
-+ napi_schedule(&msix->napi);
-+ return IRQ_HANDLED;
-+}
-+
-+
-+/*
-+ * alx_napi_msix_rtx
-+ */
-+static int alx_napi_msix_rtx(struct napi_struct *napi, int max_pkts)
-+{
-+ struct alx_msix_param *msix =
-+ container_of(napi, struct alx_msix_param, napi);
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct alx_hw *hw = &adpt->hw;
-+ struct alx_rx_queue *rxque;
-+ struct alx_rx_queue *swque;
-+ struct alx_tx_queue *txque;
-+ unsigned long flags = 0;
-+ bool complete = true;
-+ int num_pkts = 0;
-+ int rque_idx, tque_idx;
-+ int i, j;
-+
-+ netif_info(adpt, intr, adpt->netdev,
-+ "NAPI: msix vec_idx = %d\n", msix->vec_idx);
-+
-+ /* RX */
-+ for (i = 0; i < msix->rx_count; i++) {
-+ rque_idx = msix->rx_map[i];
-+ num_pkts = 0;
-+ if (CHK_ADPT_FLAG(0, SRSS_EN)) {
-+ if (!spin_trylock_irqsave(&adpt->rx_lock, flags))
-+ goto clean_sw_irq;
-+
-+ for (j = 0; j < adpt->num_hw_rxques; j++)
-+ alx_dispatch_rx_irq(msix, adpt->rx_queue[j]);
-+
-+ spin_unlock_irqrestore(&adpt->rx_lock, flags);
-+clean_sw_irq:
-+ swque = adpt->rx_queue[rque_idx];
-+ complete &= alx_handle_srx_irq(msix, swque, &num_pkts,
-+ max_pkts);
-+
-+ } else {
-+ rxque = adpt->rx_queue[rque_idx];
-+ complete &= alx_handle_rx_irq(msix, rxque, &num_pkts,
-+ max_pkts);
-+ }
-+ }
-+
-+
-+ /* Handle TX */
-+ for (i = 0; i < msix->tx_count; i++) {
-+ tque_idx = msix->tx_map[i];
-+ txque = adpt->tx_queue[tque_idx];
-+ complete &= alx_handle_tx_irq(msix, txque);
-+ }
-+
-+ if (!complete) {
-+ netif_info(adpt, intr, adpt->netdev,
-+ "Some packets in the queue are not handled!\n");
-+ num_pkts = max_pkts;
-+ }
-+
-+ netif_info(adpt, intr, adpt->netdev,
-+ "num_pkts = %d, max_pkts = %d\n", num_pkts, max_pkts);
-+ /* If all work done, exit the polling mode */
-+ if (num_pkts < max_pkts) {
-+ napi_complete(napi);
-+ if (!CHK_ADPT_FLAG(1, STATE_DOWN))
-+ hw->cbs.enable_msix_intr(hw, msix->vec_idx);
-+ }
-+
-+ return num_pkts;
-+}
-+
-+
-+
-+/*
-+ * alx_napi_legacy_rtx - NAPI Rx polling callback
-+ */
-+static int alx_napi_legacy_rtx(struct napi_struct *napi, int max_pkts)
-+{
-+ struct alx_msix_param *msix =
-+ container_of(napi, struct alx_msix_param, napi);
-+ struct alx_adapter *adpt = msix->adpt;
-+ struct alx_hw *hw = &adpt->hw;
-+ int complete = true;
-+ int num_pkts = 0;
-+ int que_idx;
-+
-+ netif_info(adpt, intr, adpt->netdev,
-+ "NAPI: msix vec_idx = %d\n", msix->vec_idx);
-+
-+ /* Keep link state information with original netdev */
-+ if (!netif_carrier_ok(adpt->netdev))
-+ goto enable_rtx_irq;
-+
-+ for (que_idx = 0; que_idx < adpt->num_txques; que_idx++)
-+ complete &= alx_handle_tx_irq(msix, adpt->tx_queue[que_idx]);
-+
-+ for (que_idx = 0; que_idx < adpt->num_hw_rxques; que_idx++) {
-+ num_pkts = 0;
-+ complete &= alx_handle_rx_irq(msix, adpt->rx_queue[que_idx],
-+ &num_pkts, max_pkts);
-+ }
-+
-+ if (!complete)
-+ num_pkts = max_pkts;
-+
-+ if (num_pkts < max_pkts) {
-+enable_rtx_irq:
-+ napi_complete(napi);
-+ hw->intr_mask |= (ALX_ISR_RXQ | ALX_ISR_TXQ);
-+ alx_mem_w32(hw, ALX_IMR, hw->intr_mask);
-+ }
-+ return num_pkts;
-+}
-+
-+
-+static void alx_set_msix_flags(struct alx_msix_param *msix,
-+ enum alx_msix_type type, int index)
-+{
-+ if (type == alx_msix_type_rx) {
-+ switch (index) {
-+ case 0:
-+ SET_MSIX_FLAG(RX0);
-+ break;
-+ case 1:
-+ SET_MSIX_FLAG(RX1);
-+ break;
-+ case 2:
-+ SET_MSIX_FLAG(RX2);
-+ break;
-+ case 3:
-+ SET_MSIX_FLAG(RX3);
-+ break;
-+ case 4:
-+ SET_MSIX_FLAG(RX4);
-+ break;
-+ case 5:
-+ SET_MSIX_FLAG(RX5);
-+ break;
-+ case 6:
-+ SET_MSIX_FLAG(RX6);
-+ break;
-+ case 7:
-+ SET_MSIX_FLAG(RX7);
-+ break;
-+ default:
-+ printk(KERN_ERR "alx_set_msix_flags: rx error.");
-+ break;
-+ }
-+ } else if (type == alx_msix_type_tx) {
-+ switch (index) {
-+ case 0:
-+ SET_MSIX_FLAG(TX0);
-+ break;
-+ case 1:
-+ SET_MSIX_FLAG(TX1);
-+ break;
-+ case 2:
-+ SET_MSIX_FLAG(TX2);
-+ break;
-+ case 3:
-+ SET_MSIX_FLAG(TX3);
-+ break;
-+ default:
-+ printk(KERN_ERR "alx_set_msix_flags: tx error.");
-+ break;
-+ }
-+ } else if (type == alx_msix_type_other) {
-+ switch (index) {
-+ case ALX_MSIX_TYPE_OTH_TIMER:
-+ SET_MSIX_FLAG(TIMER);
-+ break;
-+ case ALX_MSIX_TYPE_OTH_ALERT:
-+ SET_MSIX_FLAG(ALERT);
-+ break;
-+ case ALX_MSIX_TYPE_OTH_SMB:
-+ SET_MSIX_FLAG(SMB);
-+ break;
-+ case ALX_MSIX_TYPE_OTH_PHY:
-+ SET_MSIX_FLAG(PHY);
-+ break;
-+ default:
-+ printk(KERN_ERR "alx_set_msix_flags: other error.");
-+ break;
-+ }
-+ }
-+}
-+
-+
-+/* alx_setup_msix_maps */
-+static int alx_setup_msix_maps(struct alx_adapter *adpt)
-+{
-+ int msix_idx = 0;
-+ int que_idx = 0;
-+ int num_rxques = adpt->num_rxques;
-+ int num_txques = adpt->num_txques;
-+ int num_msix_rxques = adpt->num_msix_rxques;
-+ int num_msix_txques = adpt->num_msix_txques;
-+ int num_msix_noques = adpt->num_msix_noques;
-+
-+ if (CHK_ADPT_FLAG(0, FIXED_MSIX))
-+ goto fixed_msix_map;
-+
-+ netif_warn(adpt, ifup, adpt->netdev,
-+ "don't support non-fixed msix map\n");
-+ return -EINVAL;
-+
-+fixed_msix_map:
-+ /*
-+ * For RX queue msix map
-+ */
-+ msix_idx = 0;
-+ for (que_idx = 0; que_idx < num_msix_rxques; que_idx++, msix_idx++) {
-+ struct alx_msix_param *msix = adpt->msix[msix_idx];
-+ if (que_idx < num_rxques) {
-+ adpt->rx_queue[que_idx]->msix = msix;
-+ msix->rx_map[msix->rx_count] = que_idx;
-+ msix->rx_count++;
-+ alx_set_msix_flags(msix, alx_msix_type_rx, que_idx);
-+ }
-+ }
-+ if (msix_idx != num_msix_rxques)
-+ netif_warn(adpt, ifup, adpt->netdev, "msix_idx is wrong\n");
-+
-+ /*
-+ * For TX queue msix map
-+ */
-+ for (que_idx = 0; que_idx < num_msix_txques; que_idx++, msix_idx++) {
-+ struct alx_msix_param *msix = adpt->msix[msix_idx];
-+ if (que_idx < num_txques) {
-+ adpt->tx_queue[que_idx]->msix = msix;
-+ msix->tx_map[msix->tx_count] = que_idx;
-+ msix->tx_count++;
-+ alx_set_msix_flags(msix, alx_msix_type_tx, que_idx);
-+ }
-+ }
-+ if (msix_idx != (num_msix_rxques + num_msix_txques))
-+ netif_warn(adpt, ifup, adpt->netdev, "msix_idx is wrong\n");
-+
-+
-+ /*
-+ * For NON queue msix map
-+ */
-+ for (que_idx = 0; que_idx < num_msix_noques; que_idx++, msix_idx++) {
-+ struct alx_msix_param *msix = adpt->msix[msix_idx];
-+ alx_set_msix_flags(msix, alx_msix_type_other, que_idx);
-+ }
-+ return 0;
-+}
-+
-+
-+static inline void alx_reset_msix_maps(struct alx_adapter *adpt)
-+{
-+ int que_idx, msix_idx;
-+
-+ for (que_idx = 0; que_idx < adpt->num_rxques; que_idx++)
-+ adpt->rx_queue[que_idx]->msix = NULL;
-+ for (que_idx = 0; que_idx < adpt->num_txques; que_idx++)
-+ adpt->tx_queue[que_idx]->msix = NULL;
-+
-+ for (msix_idx = 0; msix_idx < adpt->num_msix_intrs; msix_idx++) {
-+ struct alx_msix_param *msix = adpt->msix[msix_idx];
-+ memset(msix->rx_map, 0, sizeof(msix->rx_map));
-+ memset(msix->tx_map, 0, sizeof(msix->tx_map));
-+ msix->rx_count = 0;
-+ msix->tx_count = 0;
-+ CLI_MSIX_FLAG(ALL);
-+ }
-+}
-+
-+
-+/*
-+ * alx_enable_intr - Enable default interrupt generation settings
-+ */
-+static inline void alx_enable_intr(struct alx_adapter *adpt)
-+{
-+ struct alx_hw *hw = &adpt->hw;
-+ int i;
-+
-+ if (!atomic_dec_and_test(&adpt->irq_sem))
-+ return;
-+
-+ if (hw->cbs.enable_legacy_intr)
-+ hw->cbs.enable_legacy_intr(hw);
-+
-+ /* enable all MSIX IRQs */
-+ for (i = 0; i < adpt->num_msix_intrs; i++) {
-+ if (hw->cbs.disable_msix_intr)
-+ hw->cbs.disable_msix_intr(hw, i);
-+ if (hw->cbs.enable_msix_intr)
-+ hw->cbs.enable_msix_intr(hw, i);
-+ }
-+}
-+
-+
-+/* alx_disable_intr - Mask off interrupt generation on the NIC */
-+static inline void alx_disable_intr(struct alx_adapter *adpt)
-+{
-+ struct alx_hw *hw = &adpt->hw;
-+ atomic_inc(&adpt->irq_sem);
-+
-+ if (hw->cbs.disable_legacy_intr)
-+ hw->cbs.disable_legacy_intr(hw);
-+
-+ if (CHK_ADPT_FLAG(0, MSIX_EN)) {
-+ int i;
-+ for (i = 0; i < adpt->num_msix_intrs; i++) {
-+ synchronize_irq(adpt->msix_entries[i].vector);
-+ hw->cbs.disable_msix_intr(hw, i);
-+ }
-+ } else {
-+ synchronize_irq(adpt->pdev->irq);
-+ }
-+
-+
-+}
-+
-+
-+/*
-+ * alx_interrupt - Interrupt Handler
-+ */
-+static irqreturn_t alx_interrupt(int irq, void *data)
-+{
-+ struct net_device *netdev = data;
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ struct alx_msix_param *msix = adpt->msix[0];
-+ int max_intrs = ALX_MAX_HANDLED_INTRS;
-+ u32 isr, status;
-+
-+ do {
-+ alx_mem_r32(hw, ALX_ISR, &isr);
-+ status = isr & hw->intr_mask;
-+
-+ if (status == 0) {
-+ alx_mem_w32(hw, ALX_ISR, 0);
-+ if (max_intrs != ALX_MAX_HANDLED_INTRS)
-+ return IRQ_HANDLED;
-+ return IRQ_NONE;
-+ }
-+
-+ /* ack ISR to PHY register */
-+ if (status & ALX_ISR_PHY)
-+ hw->cbs.ack_phy_intr(hw);
-+ /* ack ISR to MAC register */
-+ alx_mem_w32(hw, ALX_ISR, status | ALX_ISR_DIS);
-+
-+ if (status & ALX_ISR_ERROR) {
-+ netif_warn(adpt, intr, adpt->netdev,
-+ "isr error (status = 0x%x)\n",
-+ status & ALX_ISR_ERROR);
-+ if (status & ALX_ISR_PCIE_FERR) {
-+ alx_mem_w16(hw, ALX_DEV_STAT,
-+ ALX_DEV_STAT_FERR |
-+ ALX_DEV_STAT_NFERR |
-+ ALX_DEV_STAT_CERR);
-+ }
-+ /* reset MAC */
-+ SET_ADPT_FLAG(0, TASK_REINIT_REQ);
-+ alx_task_schedule(adpt);
-+ return IRQ_HANDLED;
-+ }
-+
-+ if (status & (ALX_ISR_RXQ | ALX_ISR_TXQ)) {
-+ if (napi_schedule_prep(&(msix->napi))) {
-+ hw->intr_mask &= ~(ALX_ISR_RXQ | ALX_ISR_TXQ);
-+ alx_mem_w32(hw, ALX_IMR, hw->intr_mask);
-+ __napi_schedule(&(msix->napi));
-+ }
-+ }
-+
-+ if (status & ALX_ISR_OVER) {
-+ netif_warn(adpt, intr, adpt->netdev,
-+ "TX/RX overflow (status = 0x%x)\n",
-+ status & ALX_ISR_OVER);
-+ }
-+
-+ /* link event */
-+ if (status & (ALX_ISR_PHY | ALX_ISR_MANU)) {
-+ netdev->stats.tx_carrier_errors++;
-+ alx_check_lsc(adpt);
-+ break;
-+ }
-+
-+ } while (--max_intrs > 0);
-+ /* re-enable Interrupt*/
-+ alx_mem_w32(hw, ALX_ISR, 0);
-+ return IRQ_HANDLED;
-+}
-+
-+
-+/*
-+ * alx_request_msix_irqs - Initialize MSI-X interrupts
-+ */
-+static int alx_request_msix_irq(struct alx_adapter *adpt)
-+{
-+ struct net_device *netdev = adpt->netdev;
-+ irqreturn_t (*handler)(int, void *);
-+ int msix_idx;
-+ int num_msix_intrs = adpt->num_msix_intrs;
-+ int rx_idx = 0, tx_idx = 0;
-+ int i;
-+ int retval;
-+
-+ retval = alx_setup_msix_maps(adpt);
-+ if (retval)
-+ return retval;
-+
-+ for (msix_idx = 0; msix_idx < num_msix_intrs; msix_idx++) {
-+ struct alx_msix_param *msix = adpt->msix[msix_idx];
-+
-+ if (CHK_MSIX_FLAG(RXS) && CHK_MSIX_FLAG(TXS)) {
-+ handler = alx_msix_rtx;
-+ sprintf(msix->name, "%s:%s%d",
-+ netdev->name, "rtx", rx_idx);
-+ rx_idx++;
-+ tx_idx++;
-+ } else if (CHK_MSIX_FLAG(RXS)) {
-+ handler = alx_msix_rtx;
-+ sprintf(msix->name, "%s:%s%d",
-+ netdev->name, "rx", rx_idx);
-+ rx_idx++;
-+ } else if (CHK_MSIX_FLAG(TXS)) {
-+ handler = alx_msix_rtx;
-+ sprintf(msix->name, "%s:%s%d",
-+ netdev->name, "tx", tx_idx);
-+ tx_idx++;
-+ } else if (CHK_MSIX_FLAG(TIMER)) {
-+ handler = alx_msix_timer;
-+ sprintf(msix->name, "%s:%s", netdev->name, "timer");
-+ } else if (CHK_MSIX_FLAG(ALERT)) {
-+ handler = alx_msix_alert;
-+ sprintf(msix->name, "%s:%s", netdev->name, "alert");
-+ } else if (CHK_MSIX_FLAG(SMB)) {
-+ handler = alx_msix_smb;
-+ sprintf(msix->name, "%s:%s", netdev->name, "smb");
-+ } else if (CHK_MSIX_FLAG(PHY)) {
-+ handler = alx_msix_phy;
-+ sprintf(msix->name, "%s:%s", netdev->name, "phy");
-+ } else {
-+ netif_info(adpt, ifup, adpt->netdev,
-+ "MSIX entry [%d] is blank\n",
-+ msix->vec_idx);
-+ continue;
-+ }
-+ netif_info(adpt, ifup, adpt->netdev,
-+ "MSIX entry [%d] is %s\n",
-+ msix->vec_idx, msix->name);
-+ retval = request_irq(adpt->msix_entries[msix_idx].vector,
-+ handler, 0, msix->name, msix);
-+ if (retval)
-+ goto free_msix_irq;
-+
-+ /* assign the mask for this irq */
-+ irq_set_affinity_hint(adpt->msix_entries[msix_idx].vector,
-+ msix->affinity_mask);
-+ }
-+ return retval;
-+
-+
-+free_msix_irq:
-+ for (i = 0; i < msix_idx; i++) {
-+ irq_set_affinity_hint(adpt->msix_entries[i].vector, NULL);
-+ free_irq(adpt->msix_entries[i].vector, adpt->msix[i]);
-+ }
-+ CLI_ADPT_FLAG(0, MSIX_EN);
-+ pci_disable_msix(adpt->pdev);
-+ kfree(adpt->msix_entries);
-+ adpt->msix_entries = NULL;
-+ return retval;
-+}
-+
-+
-+/*
-+ * alx_request_irq - initialize interrupts
-+ */
-+static int alx_request_irq(struct alx_adapter *adpt)
-+{
-+ struct net_device *netdev = adpt->netdev;
-+ int retval;
-+
-+ /* request MSIX irq */
-+ if (CHK_ADPT_FLAG(0, MSIX_EN)) {
-+ retval = alx_request_msix_irq(adpt);
-+ if (retval) {
-+ alx_err(adpt, "request msix irq failed, error = %d\n",
-+ retval);
-+ }
-+ goto out;
-+ }
-+
-+ /* request MSI irq */
-+ if (CHK_ADPT_FLAG(0, MSI_EN)) {
-+ retval = request_irq(adpt->pdev->irq, alx_interrupt, 0,
-+ netdev->name, netdev);
-+ if (retval) {
-+ alx_err(adpt, "request msix irq failed, error = %d\n",
-+ retval);
-+ }
-+ goto out;
-+ }
-+
-+ /* request shared irq */
-+ retval = request_irq(adpt->pdev->irq, alx_interrupt, IRQF_SHARED,
-+ netdev->name, netdev);
-+ if (retval) {
-+ alx_err(adpt, "request shared irq failed, error = %d\n",
-+ retval);
-+ }
-+out:
-+ return retval;
-+}
-+
-+
-+static void alx_free_irq(struct alx_adapter *adpt)
-+{
-+ struct net_device *netdev = adpt->netdev;
-+ int i;
-+
-+ if (CHK_ADPT_FLAG(0, MSIX_EN)) {
-+ for (i = 0; i < adpt->num_msix_intrs; i++) {
-+ struct alx_msix_param *msix = adpt->msix[i];
-+ netif_info(adpt, ifdown, adpt->netdev,
-+ "msix entry = %d\n", i);
-+ if (!CHK_MSIX_FLAG(ALL))
-+ continue;
-+ if (CHK_MSIX_FLAG(RXS) || CHK_MSIX_FLAG(TXS)) {
-+ irq_set_affinity_hint(
-+ adpt->msix_entries[i].vector, NULL);
-+ }
-+ free_irq(adpt->msix_entries[i].vector, msix);
-+ }
-+ alx_reset_msix_maps(adpt);
-+ } else {
-+ free_irq(adpt->pdev->irq, netdev);
-+ }
-+}
-+
-+
-+static void alx_vlan_mode(struct net_device *netdev,
-+ netdev_features_t features)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+
-+ if (!CHK_ADPT_FLAG(1, STATE_DOWN))
-+ alx_disable_intr(adpt);
-+
-+ if (features & NETIF_F_HW_VLAN_RX) {
-+ /* enable VLAN tag insert/strip */
-+ SET_HW_FLAG(VLANSTRIP_EN);
-+ } else {
-+ /* disable VLAN tag insert/strip */
-+ CLI_HW_FLAG(VLANSTRIP_EN);
-+ }
-+ hw->cbs.config_mac_ctrl(hw);
-+
-+ if (!CHK_ADPT_FLAG(1, STATE_DOWN))
-+ alx_enable_intr(adpt);
-+}
-+
-+
-+static void alx_restore_vlan(struct alx_adapter *adpt)
-+{
-+ alx_vlan_mode(adpt->netdev, adpt->netdev->features);
-+}
-+
-+
-+static void alx_napi_enable_all(struct alx_adapter *adpt)
-+{
-+ struct alx_msix_param *msix;
-+ int num_msix_intrs = adpt->num_msix_intrs;
-+ int msix_idx;
-+
-+ if (!CHK_ADPT_FLAG(0, MSIX_EN))
-+ num_msix_intrs = 1;
-+
-+ for (msix_idx = 0; msix_idx < num_msix_intrs; msix_idx++) {
-+ struct napi_struct *napi;
-+ msix = adpt->msix[msix_idx];
-+ napi = &msix->napi;
-+ napi_enable(napi);
-+ }
-+}
-+
-+
-+static void alx_napi_disable_all(struct alx_adapter *adpt)
-+{
-+ struct alx_msix_param *msix;
-+ int num_msix_intrs = adpt->num_msix_intrs;
-+ int msix_idx;
-+
-+ if (!CHK_ADPT_FLAG(0, MSIX_EN))
-+ num_msix_intrs = 1;
-+
-+ for (msix_idx = 0; msix_idx < num_msix_intrs; msix_idx++) {
-+ msix = adpt->msix[msix_idx];
-+ napi_disable(&msix->napi);
-+ }
-+}
-+
-+
-+static void alx_clean_tx_queue(struct alx_tx_queue *txque)
-+{
-+ struct device *dev = txque->dev;
-+ unsigned long size;
-+ u16 i;
-+
-+ /* ring already cleared, nothing to do */
-+ if (!txque->tpq.tpbuff)
-+ return;
-+
-+ for (i = 0; i < txque->tpq.count; i++) {
-+ struct alx_buffer *tpbuf;
-+ tpbuf = GET_TP_BUFFER(txque, i);
-+ if (tpbuf->dma) {
-+ pci_unmap_single(to_pci_dev(dev),
-+ tpbuf->dma,
-+ tpbuf->length,
-+ DMA_TO_DEVICE);
-+ tpbuf->dma = 0;
-+ }
-+ if (tpbuf->skb) {
-+ dev_kfree_skb_any(tpbuf->skb);
-+ tpbuf->skb = NULL;
-+ }
-+ }
-+
-+ size = sizeof(struct alx_buffer) * txque->tpq.count;
-+ memset(txque->tpq.tpbuff, 0, size);
-+
-+ /* Zero out Tx-buffers */
-+ memset(txque->tpq.tpdesc, 0, txque->tpq.size);
-+
-+ txque->tpq.consume_idx = 0;
-+ txque->tpq.produce_idx = 0;
-+}
-+
-+
-+/*
-+ * alx_clean_all_tx_queues
-+ */
-+static void alx_clean_all_tx_queues(struct alx_adapter *adpt)
-+{
-+ int i;
-+
-+ for (i = 0; i < adpt->num_txques; i++)
-+ alx_clean_tx_queue(adpt->tx_queue[i]);
-+}
-+
-+
-+static void alx_clean_rx_queue(struct alx_rx_queue *rxque)
-+{
-+ struct device *dev = rxque->dev;
-+ unsigned long size;
-+ int i;
-+
-+ if (CHK_RX_FLAG(HW_QUE)) {
-+ /* ring already cleared, nothing to do */
-+ if (!rxque->rfq.rfbuff)
-+ goto clean_sw_queue;
-+
-+ for (i = 0; i < rxque->rfq.count; i++) {
-+ struct alx_buffer *rfbuf;
-+ rfbuf = GET_RF_BUFFER(rxque, i);
-+
-+ if (rfbuf->dma) {
-+ pci_unmap_single(to_pci_dev(dev),
-+ rfbuf->dma,
-+ rfbuf->length,
-+ DMA_FROM_DEVICE);
-+ rfbuf->dma = 0;
-+ }
-+ if (rfbuf->skb) {
-+ dev_kfree_skb(rfbuf->skb);
-+ rfbuf->skb = NULL;
-+ }
-+ }
-+ size = sizeof(struct alx_buffer) * rxque->rfq.count;
-+ memset(rxque->rfq.rfbuff, 0, size);
-+
-+ /* zero out the descriptor ring */
-+ memset(rxque->rrq.rrdesc, 0, rxque->rrq.size);
-+ rxque->rrq.produce_idx = 0;
-+ rxque->rrq.consume_idx = 0;
-+
-+ memset(rxque->rfq.rfdesc, 0, rxque->rfq.size);
-+ rxque->rfq.produce_idx = 0;
-+ rxque->rfq.consume_idx = 0;
-+ }
-+clean_sw_queue:
-+ if (CHK_RX_FLAG(SW_QUE)) {
-+ /* ring already cleared, nothing to do */
-+ if (!rxque->swq.swbuff)
-+ return;
-+
-+ for (i = 0; i < rxque->swq.count; i++) {
-+ struct alx_sw_buffer *swbuf;
-+ swbuf = GET_SW_BUFFER(rxque, i);
-+
-+ /* swq doesn't map DMA*/
-+
-+ if (swbuf->skb) {
-+ dev_kfree_skb(swbuf->skb);
-+ swbuf->skb = NULL;
-+ }
-+ }
-+ size = sizeof(struct alx_buffer) * rxque->swq.count;
-+ memset(rxque->swq.swbuff, 0, size);
-+
-+ /* swq doesn't have any descripter rings */
-+ rxque->swq.produce_idx = 0;
-+ rxque->swq.consume_idx = 0;
-+ }
-+}
-+
-+
-+/*
-+ * alx_clean_all_rx_queues
-+ */
-+static void alx_clean_all_rx_queues(struct alx_adapter *adpt)
-+{
-+ int i;
-+ for (i = 0; i < adpt->num_rxques; i++)
-+ alx_clean_rx_queue(adpt->rx_queue[i]);
-+}
-+
-+
-+/*
-+ * alx_set_rss_queues: Allocate queues for RSS
-+ */
-+static inline void alx_set_num_txques(struct alx_adapter *adpt)
-+{
-+ struct alx_hw *hw = &adpt->hw;
-+
-+ if (hw->mac_type == alx_mac_l1f || hw->mac_type == alx_mac_l2f)
-+ adpt->num_txques = 4;
-+ else
-+ adpt->num_txques = 2;
-+}
-+
-+
-+/*
-+ * alx_set_rss_queues: Allocate queues for RSS
-+ */
-+static inline void alx_set_num_rxques(struct alx_adapter *adpt)
-+{
-+ if (CHK_ADPT_FLAG(0, SRSS_CAP)) {
-+ adpt->num_hw_rxques = 1;
-+ adpt->num_sw_rxques = adpt->max_rxques;
-+ adpt->num_rxques =
-+ max_t(u16, adpt->num_hw_rxques, adpt->num_sw_rxques);
-+ }
-+}
-+
-+
-+/*
-+ * alx_set_num_queues: Allocate queues for device, feature dependant
-+ */
-+static void alx_set_num_queues(struct alx_adapter *adpt)
-+{
-+ /* Start with default case */
-+ adpt->num_txques = 1;
-+ adpt->num_rxques = 1;
-+ adpt->num_hw_rxques = 1;
-+ adpt->num_sw_rxques = 0;
-+
-+ alx_set_num_rxques(adpt);
-+ alx_set_num_txques(adpt);
-+}
-+
-+
-+/* alx_alloc_all_rtx_queue - allocate all queues */
-+static int alx_alloc_all_rtx_queue(struct alx_adapter *adpt)
-+{
-+ int que_idx;
-+
-+ for (que_idx = 0; que_idx < adpt->num_txques; que_idx++) {
-+ struct alx_tx_queue *txque = adpt->tx_queue[que_idx];
-+
-+ txque = kzalloc(sizeof(struct alx_tx_queue), GFP_KERNEL);
-+ if (!txque)
-+ goto err_alloc_tx_queue;
-+ txque->tpq.count = adpt->num_txdescs;
-+ txque->que_idx = que_idx;
-+ txque->dev = &adpt->pdev->dev;
-+ txque->netdev = adpt->netdev;
-+
-+ adpt->tx_queue[que_idx] = txque;
-+ }
-+
-+ for (que_idx = 0; que_idx < adpt->num_rxques; que_idx++) {
-+ struct alx_rx_queue *rxque = adpt->rx_queue[que_idx];
-+
-+ rxque = kzalloc(sizeof(struct alx_rx_queue), GFP_KERNEL);
-+ if (!rxque)
-+ goto err_alloc_rx_queue;
-+ rxque->rrq.count = adpt->num_rxdescs;
-+ rxque->rfq.count = adpt->num_rxdescs;
-+ rxque->swq.count = adpt->num_rxdescs;
-+ rxque->que_idx = que_idx;
-+ rxque->dev = &adpt->pdev->dev;
-+ rxque->netdev = adpt->netdev;
-+
-+ if (CHK_ADPT_FLAG(0, SRSS_EN)) {
-+ if (que_idx < adpt->num_hw_rxques)
-+ SET_RX_FLAG(HW_QUE);
-+ if (que_idx < adpt->num_sw_rxques)
-+ SET_RX_FLAG(SW_QUE);
-+ } else {
-+ SET_RX_FLAG(HW_QUE);
-+ }
-+ adpt->rx_queue[que_idx] = rxque;
-+ }
-+ netif_dbg(adpt, probe, adpt->netdev,
-+ "num_tx_descs = %d, num_rx_descs = %d\n",
-+ adpt->num_txdescs, adpt->num_rxdescs);
-+ return 0;
-+
-+err_alloc_rx_queue:
-+ alx_err(adpt, "goto err_alloc_rx_queue");
-+ for (que_idx = 0; que_idx < adpt->num_rxques; que_idx++)
-+ kfree(adpt->rx_queue[que_idx]);
-+err_alloc_tx_queue:
-+ alx_err(adpt, "goto err_alloc_tx_queue");
-+ for (que_idx = 0; que_idx < adpt->num_txques; que_idx++)
-+ kfree(adpt->tx_queue[que_idx]);
-+ return -ENOMEM;
-+}
-+
-+
-+/* alx_free_all_rtx_queue */
-+static void alx_free_all_rtx_queue(struct alx_adapter *adpt)
-+{
-+ int que_idx;
-+
-+ for (que_idx = 0; que_idx < adpt->num_txques; que_idx++) {
-+ kfree(adpt->tx_queue[que_idx]);
-+ adpt->tx_queue[que_idx] = NULL;
-+ }
-+ for (que_idx = 0; que_idx < adpt->num_rxques; que_idx++) {
-+ kfree(adpt->rx_queue[que_idx]);
-+ adpt->rx_queue[que_idx] = NULL;
-+ }
-+}
-+
-+
-+/* alx_set_interrupt_param - set interrupt parameter */
-+static int alx_set_interrupt_param(struct alx_adapter *adpt)
-+{
-+ struct alx_msix_param *msix;
-+ int (*poll)(struct napi_struct *, int);
-+ int msix_idx;
-+
-+ if (CHK_ADPT_FLAG(0, MSIX_EN)) {
-+ poll = &alx_napi_msix_rtx;
-+ } else {
-+ adpt->num_msix_intrs = 1;
-+ poll = &alx_napi_legacy_rtx;
-+ }
-+
-+ for (msix_idx = 0; msix_idx < adpt->num_msix_intrs; msix_idx++) {
-+ msix = kzalloc(sizeof(struct alx_msix_param),
-+ GFP_KERNEL);
-+ if (!msix)
-+ goto err_alloc_msix;
-+ msix->adpt = adpt;
-+ msix->vec_idx = msix_idx;
-+ /* Allocate the affinity_hint cpumask, configure the mask */
-+ if (!alloc_cpumask_var(&msix->affinity_mask, GFP_KERNEL))
-+ goto err_alloc_cpumask;
-+
-+ cpumask_set_cpu((msix_idx % num_online_cpus()),
-+ msix->affinity_mask);
-+
-+ netif_napi_add(adpt->netdev, &msix->napi, (*poll), 64);
-+ adpt->msix[msix_idx] = msix;
-+ }
-+ return 0;
-+
-+err_alloc_cpumask:
-+ kfree(msix);
-+ adpt->msix[msix_idx] = NULL;
-+err_alloc_msix:
-+ for (msix_idx--; msix_idx >= 0; msix_idx--) {
-+ msix = adpt->msix[msix_idx];
-+ netif_napi_del(&msix->napi);
-+ free_cpumask_var(msix->affinity_mask);
-+ kfree(msix);
-+ adpt->msix[msix_idx] = NULL;
-+ }
-+ alx_err(adpt, "can't allocate memory\n");
-+ return -ENOMEM;
-+}
-+
-+
-+/*
-+ * alx_reset_interrupt_param - Free memory allocated for interrupt vectors
-+ */
-+static void alx_reset_interrupt_param(struct alx_adapter *adpt)
-+{
-+ int msix_idx;
-+
-+ for (msix_idx = 0; msix_idx < adpt->num_msix_intrs; msix_idx++) {
-+ struct alx_msix_param *msix = adpt->msix[msix_idx];
-+ netif_napi_del(&msix->napi);
-+ free_cpumask_var(msix->affinity_mask);
-+ kfree(msix);
-+ adpt->msix[msix_idx] = NULL;
-+ }
-+}
-+
-+
-+/* set msix interrupt mode */
-+static int alx_set_msix_interrupt_mode(struct alx_adapter *adpt)
-+{
-+ int msix_intrs, msix_idx;
-+ int retval = 0;
-+
-+ adpt->msix_entries = kcalloc(adpt->max_msix_intrs,
-+ sizeof(struct msix_entry), GFP_KERNEL);
-+ if (!adpt->msix_entries) {
-+ netif_info(adpt, probe, adpt->netdev,
-+ "can't allocate msix entry\n");
-+ CLI_ADPT_FLAG(0, MSIX_EN);
-+ goto try_msi_mode;
-+ }
-+
-+ for (msix_idx = 0; msix_idx < adpt->max_msix_intrs; msix_idx++)
-+ adpt->msix_entries[msix_idx].entry = msix_idx;
-+
-+
-+ msix_intrs = adpt->max_msix_intrs;
-+ while (msix_intrs >= adpt->min_msix_intrs) {
-+ retval = pci_enable_msix(adpt->pdev, adpt->msix_entries,
-+ msix_intrs);
-+ if (!retval) /* Success in acquiring all requested vectors. */
-+ break;
-+ else if (retval < 0)
-+ msix_intrs = 0; /* Nasty failure, quit now */
-+ else /* error == number of vectors we should try again with */
-+ msix_intrs = retval;
-+ }
-+ if (msix_intrs < adpt->min_msix_intrs) {
-+ netif_info(adpt, probe, adpt->netdev,
-+ "can't enable MSI-X interrupts\n");
-+ CLI_ADPT_FLAG(0, MSIX_EN);
-+ kfree(adpt->msix_entries);
-+ adpt->msix_entries = NULL;
-+ goto try_msi_mode;
-+ }
-+
-+ netif_info(adpt, probe, adpt->netdev,
-+ "enable MSI-X interrupts, num_msix_intrs = %d\n",
-+ msix_intrs);
-+ SET_ADPT_FLAG(0, MSIX_EN);
-+ if (CHK_ADPT_FLAG(0, SRSS_CAP))
-+ SET_ADPT_FLAG(0, SRSS_EN);
-+
-+ adpt->num_msix_intrs = min_t(int, msix_intrs, adpt->max_msix_intrs);
-+ retval = 0;
-+ return retval;
-+
-+try_msi_mode:
-+ CLI_ADPT_FLAG(0, SRSS_CAP);
-+ CLI_ADPT_FLAG(0, SRSS_EN);
-+ alx_set_num_queues(adpt);
-+ retval = -1;
-+ return retval;
-+}
-+
-+
-+/* set msi interrupt mode */
-+static int alx_set_msi_interrupt_mode(struct alx_adapter *adpt)
-+{
-+ int retval;
-+
-+ retval = pci_enable_msi(adpt->pdev);
-+ if (retval) {
-+ netif_info(adpt, probe, adpt->netdev,
-+ "can't enable MSI interrupt, error = %d\n", retval);
-+ return retval;
-+ }
-+ SET_ADPT_FLAG(0, MSI_EN);
-+ return retval;
-+}
-+
-+
-+/* set interrupt mode */
-+static int alx_set_interrupt_mode(struct alx_adapter *adpt)
-+{
-+ int retval = 0;
-+
-+ if (CHK_ADPT_FLAG(0, MSIX_CAP)) {
-+ netif_info(adpt, probe, adpt->netdev,
-+ "try to set MSIX interrupt\n");
-+ retval = alx_set_msix_interrupt_mode(adpt);
-+ if (!retval)
-+ return retval;
-+ }
-+
-+ if (CHK_ADPT_FLAG(0, MSI_CAP)) {
-+ netif_info(adpt, probe, adpt->netdev,
-+ "try to set MSI interrupt\n");
-+ retval = alx_set_msi_interrupt_mode(adpt);
-+ if (!retval)
-+ return retval;
-+ }
-+
-+ netif_info(adpt, probe, adpt->netdev,
-+ "can't enable MSIX and MSI, will enable shared interrupt\n");
-+ retval = 0;
-+ return retval;
-+}
-+
-+
-+static void alx_reset_interrupt_mode(struct alx_adapter *adpt)
-+{
-+ if (CHK_ADPT_FLAG(0, MSIX_EN)) {
-+ CLI_ADPT_FLAG(0, MSIX_EN);
-+ pci_disable_msix(adpt->pdev);
-+ kfree(adpt->msix_entries);
-+ adpt->msix_entries = NULL;
-+ } else if (CHK_ADPT_FLAG(0, MSI_EN)) {
-+ CLI_ADPT_FLAG(0, MSI_EN);
-+ pci_disable_msi(adpt->pdev);
-+ }
-+}
-+
-+
-+static int __devinit alx_init_adapter_special(struct alx_adapter *adpt)
-+{
-+ switch (adpt->hw.mac_type) {
-+ case alx_mac_l1f:
-+ case alx_mac_l2f:
-+ goto init_alf_adapter;
-+ break;
-+ case alx_mac_l1c:
-+ case alx_mac_l1d_v1:
-+ case alx_mac_l1d_v2:
-+ case alx_mac_l2c:
-+ case alx_mac_l2cb_v1:
-+ case alx_mac_l2cb_v20:
-+ case alx_mac_l2cb_v21:
-+ goto init_alc_adapter;
-+ break;
-+ default:
-+ break;
-+ }
-+ return -1;
-+
-+init_alc_adapter:
-+ if (CHK_ADPT_FLAG(0, MSIX_CAP))
-+ alx_err(adpt, "ALC doesn't support MSIX\n");
-+
-+ /* msi for tx, rx and none queues */
-+ adpt->num_msix_txques = 0;
-+ adpt->num_msix_rxques = 0;
-+ adpt->num_msix_noques = 0;
-+ return 0;
-+
-+init_alf_adapter:
-+ if (CHK_ADPT_FLAG(0, MSIX_CAP)) {
-+ /* msix for tx, rx and none queues */
-+ adpt->num_msix_txques = 4;
-+ adpt->num_msix_rxques = 8;
-+ adpt->num_msix_noques = ALF_MAX_MSIX_NOQUE_INTRS;
-+
-+ /* msix vector range */
-+ adpt->max_msix_intrs = ALF_MAX_MSIX_INTRS;
-+ adpt->min_msix_intrs = ALF_MIN_MSIX_INTRS;
-+ } else {
-+ /* msi for tx, rx and none queues */
-+ adpt->num_msix_txques = 0;
-+ adpt->num_msix_rxques = 0;
-+ adpt->num_msix_noques = 0;
-+ }
-+ return 0;
-+
-+}
-+
-+
-+/*
-+ * alx_init_adapter
-+ */
-+static int __devinit alx_init_adapter(struct alx_adapter *adpt)
-+{
-+ struct alx_hw *hw = &adpt->hw;
-+ struct pci_dev *pdev = adpt->pdev;
-+ u16 revision;
-+ int max_frame;
-+
-+ /* PCI config space info */
-+ hw->pci_venid = pdev->vendor;
-+ hw->pci_devid = pdev->device;
-+ alx_cfg_r16(hw, PCI_CLASS_REVISION, &revision);
-+ hw->pci_revid = revision & 0xFF;
-+ hw->pci_sub_venid = pdev->subsystem_vendor;
-+ hw->pci_sub_devid = pdev->subsystem_device;
-+
-+ if (alx_init_hw_callbacks(adpt) != 0) {
-+ alx_err(adpt, "set HW function pointers failed\n");
-+ return -1;
-+ }
-+
-+ if (hw->cbs.identify_nic(hw) != 0) {
-+ alx_err(adpt, "HW is disabled\n");
-+ return -1;
-+ }
-+
-+ /* Set adapter flags */
-+ switch (hw->mac_type) {
-+ case alx_mac_l1f:
-+ case alx_mac_l2f:
-+#ifdef CONFIG_ALX_MSI
-+ SET_ADPT_FLAG(0, MSI_CAP);
-+#endif
-+#ifdef CONFIG_ALX_MSIX
-+ SET_ADPT_FLAG(0, MSIX_CAP);
-+#endif
-+ if (CHK_ADPT_FLAG(0, MSIX_CAP)) {
-+ SET_ADPT_FLAG(0, FIXED_MSIX);
-+ SET_ADPT_FLAG(0, MRQ_CAP);
-+#ifdef CONFIG_ALX_RSS
-+ SET_ADPT_FLAG(0, SRSS_CAP);
-+#endif
-+ }
-+ pdev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;
-+ break;
-+ case alx_mac_l1c:
-+ case alx_mac_l1d_v1:
-+ case alx_mac_l1d_v2:
-+ case alx_mac_l2c:
-+ case alx_mac_l2cb_v1:
-+ case alx_mac_l2cb_v20:
-+ case alx_mac_l2cb_v21:
-+#ifdef CONFIG_ALX_MSI
-+ SET_ADPT_FLAG(0, MSI_CAP);
-+#endif
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ /* set default for alx_adapter */
-+ adpt->max_msix_intrs = 1;
-+ adpt->min_msix_intrs = 1;
-+ max_frame = adpt->netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
-+ adpt->rxbuf_size = adpt->netdev->mtu > ALX_DEF_RX_BUF_SIZE ?
-+ ALIGN(max_frame, 8) : ALX_DEF_RX_BUF_SIZE;
-+ adpt->wol = 0;
-+ device_set_wakeup_enable(&pdev->dev, false);
-+
-+ /* set default for alx_hw */
-+ hw->link_up = false;
-+ hw->link_speed = ALX_LINK_SPEED_UNKNOWN;
-+ hw->preamble = 7;
-+ hw->intr_mask = ALX_IMR_NORMAL_MASK;
-+ hw->smb_timer = 400; /* 400ms */
-+ hw->mtu = adpt->netdev->mtu;
-+ hw->imt = 100; /* set to 200us */
-+
-+ /* set default for wrr */
-+ hw->wrr_prio0 = 4;
-+ hw->wrr_prio1 = 4;
-+ hw->wrr_prio2 = 4;
-+ hw->wrr_prio3 = 4;
-+ hw->wrr_mode = alx_wrr_mode_none;
-+
-+ /* set default flow control settings */
-+ hw->req_fc_mode = alx_fc_full;
-+ hw->cur_fc_mode = alx_fc_full; /* init for ethtool output */
-+ hw->disable_fc_autoneg = false;
-+ hw->fc_was_autonegged = false;
-+ hw->fc_single_pause = true;
-+
-+ /* set default for rss info*/
-+ hw->rss_hstype = 0;
-+ hw->rss_mode = alx_rss_mode_disable;
-+ hw->rss_idt_size = 0;
-+ hw->rss_base_cpu = 0;
-+ memset(hw->rss_idt, 0x0, sizeof(hw->rss_idt));
-+ memset(hw->rss_key, 0x0, sizeof(hw->rss_key));
-+
-+ atomic_set(&adpt->irq_sem, 1);
-+ spin_lock_init(&adpt->tx_lock);
-+ spin_lock_init(&adpt->rx_lock);
-+
-+ alx_init_adapter_special(adpt);
-+
-+ if (hw->cbs.init_phy) {
-+ if (hw->cbs.init_phy(hw))
-+ return -EINVAL;
-+ }
-+
-+ SET_ADPT_FLAG(1, STATE_DOWN);
-+ return 0;
-+}
-+
-+
-+static int alx_set_register_info_special(struct alx_adapter *adpt)
-+{
-+ struct alx_hw *hw = &adpt->hw;
-+ int num_txques = adpt->num_txques;
-+
-+ switch (adpt->hw.mac_type) {
-+ case alx_mac_l1f:
-+ case alx_mac_l2f:
-+ goto cache_alf_register;
-+ break;
-+ case alx_mac_l1c:
-+ case alx_mac_l1d_v1:
-+ case alx_mac_l1d_v2:
-+ case alx_mac_l2c:
-+ case alx_mac_l2cb_v1:
-+ case alx_mac_l2cb_v20:
-+ case alx_mac_l2cb_v21:
-+ goto cache_alc_register;
-+ break;
-+ default:
-+ break;
-+ }
-+ return -1;
-+
-+cache_alc_register:
-+ /* setting for Produce Index and Consume Index */
-+ adpt->rx_queue[0]->produce_reg = hw->rx_prod_reg[0];
-+ adpt->rx_queue[0]->consume_reg = hw->rx_cons_reg[0];
-+
-+ switch (num_txques) {
-+ case 2:
-+ adpt->tx_queue[1]->produce_reg = hw->tx_prod_reg[1];
-+ adpt->tx_queue[1]->consume_reg = hw->tx_cons_reg[1];
-+ case 1:
-+ adpt->tx_queue[0]->produce_reg = hw->tx_prod_reg[0];
-+ adpt->tx_queue[0]->consume_reg = hw->tx_cons_reg[0];
-+ break;
-+ }
-+ return 0;
-+
-+cache_alf_register:
-+ /* setting for Produce Index and Consume Index */
-+ adpt->rx_queue[0]->produce_reg = hw->rx_prod_reg[0];
-+ adpt->rx_queue[0]->consume_reg = hw->rx_cons_reg[0];
-+
-+ switch (num_txques) {
-+ case 4:
-+ adpt->tx_queue[3]->produce_reg = hw->tx_prod_reg[3];
-+ adpt->tx_queue[3]->consume_reg = hw->tx_cons_reg[3];
-+ case 3:
-+ adpt->tx_queue[2]->produce_reg = hw->tx_prod_reg[2];
-+ adpt->tx_queue[2]->consume_reg = hw->tx_cons_reg[2];
-+ case 2:
-+ adpt->tx_queue[1]->produce_reg = hw->tx_prod_reg[1];
-+ adpt->tx_queue[1]->consume_reg = hw->tx_cons_reg[1];
-+ case 1:
-+ adpt->tx_queue[0]->produce_reg = hw->tx_prod_reg[0];
-+ adpt->tx_queue[0]->consume_reg = hw->tx_cons_reg[0];
-+ }
-+ return 0;
-+}
-+
-+
-+/* alx_alloc_tx_descriptor - allocate Tx Descriptors */
-+static int alx_alloc_tx_descriptor(struct alx_adapter *adpt,
-+ struct alx_tx_queue *txque)
-+{
-+ struct alx_ring_header *ring_header = &adpt->ring_header;
-+ int size;
-+
-+ netif_info(adpt, ifup, adpt->netdev,
-+ "tpq.count = %d\n", txque->tpq.count);
-+
-+ size = sizeof(struct alx_buffer) * txque->tpq.count;
-+ txque->tpq.tpbuff = kzalloc(size, GFP_KERNEL);
-+ if (!txque->tpq.tpbuff)
-+ goto err_alloc_tpq_buffer;
-+
-+ /* round up to nearest 4K */
-+ txque->tpq.size = txque->tpq.count * sizeof(union alx_tpdesc);
-+
-+ txque->tpq.tpdma = ring_header->dma + ring_header->used;
-+ txque->tpq.tpdesc = ring_header->desc + ring_header->used;
-+ adpt->hw.tpdma[txque->que_idx] = (u64)txque->tpq.tpdma;
-+ ring_header->used += ALIGN(txque->tpq.size, 8);
-+
-+ txque->tpq.produce_idx = 0;
-+ txque->tpq.consume_idx = 0;
-+ txque->max_packets = txque->tpq.count;
-+ return 0;
-+
-+err_alloc_tpq_buffer:
-+ alx_err(adpt, "Unable to allocate memory for the Tx descriptor\n");
-+ return -ENOMEM;
-+}
-+
-+
-+/* alx_alloc_all_tx_descriptor - allocate all Tx Descriptors */
-+static int alx_alloc_all_tx_descriptor(struct alx_adapter *adpt)
-+{
-+ int i, retval = 0;
-+ netif_info(adpt, ifup, adpt->netdev,
-+ "num_tques = %d\n", adpt->num_txques);
-+
-+ for (i = 0; i < adpt->num_txques; i++) {
-+ retval = alx_alloc_tx_descriptor(adpt, adpt->tx_queue[i]);
-+ if (!retval)
-+ continue;
-+
-+ alx_err(adpt, "Allocation for Tx Queue %u failed\n", i);
-+ break;
-+ }
-+
-+ return retval;
-+}
-+
-+
-+/* alx_alloc_rx_descriptor - allocate Rx Descriptors */
-+static int alx_alloc_rx_descriptor(struct alx_adapter *adpt,
-+ struct alx_rx_queue *rxque)
-+{
-+ struct alx_ring_header *ring_header = &adpt->ring_header;
-+ int size;
-+
-+ netif_info(adpt, ifup, adpt->netdev,
-+ "RRD.count = %d, RFD.count = %d, SWD.count = %d\n",
-+ rxque->rrq.count, rxque->rfq.count, rxque->swq.count);
-+
-+ if (CHK_RX_FLAG(HW_QUE)) {
-+ /* alloc buffer info */
-+ size = sizeof(struct alx_buffer) * rxque->rfq.count;
-+ rxque->rfq.rfbuff = kzalloc(size, GFP_KERNEL);
-+ if (!rxque->rfq.rfbuff)
-+ goto err_alloc_rfq_buffer;
-+ /*
-+ * set dma's point of rrq and rfq
-+ */
-+
-+ /* Round up to nearest 4K */
-+ rxque->rrq.size =
-+ rxque->rrq.count * sizeof(union alx_rrdesc);
-+ rxque->rfq.size =
-+ rxque->rfq.count * sizeof(union alx_rfdesc);
-+
-+ rxque->rrq.rrdma = ring_header->dma + ring_header->used;
-+ rxque->rrq.rrdesc = ring_header->desc + ring_header->used;
-+ adpt->hw.rrdma[rxque->que_idx] = (u64)rxque->rrq.rrdma;
-+ ring_header->used += ALIGN(rxque->rrq.size, 8);
-+
-+ rxque->rfq.rfdma = ring_header->dma + ring_header->used;
-+ rxque->rfq.rfdesc = ring_header->desc + ring_header->used;
-+ adpt->hw.rfdma[rxque->que_idx] = (u64)rxque->rfq.rfdma;
-+ ring_header->used += ALIGN(rxque->rfq.size, 8);
-+
-+ /* clean all counts within rxque */
-+ rxque->rrq.produce_idx = 0;
-+ rxque->rrq.consume_idx = 0;
-+
-+ rxque->rfq.produce_idx = 0;
-+ rxque->rfq.consume_idx = 0;
-+ }
-+
-+ if (CHK_RX_FLAG(SW_QUE)) {
-+ size = sizeof(struct alx_sw_buffer) * rxque->swq.count;
-+ rxque->swq.swbuff = kzalloc(size, GFP_KERNEL);
-+ if (!rxque->swq.swbuff)
-+ goto err_alloc_swq_buffer;
-+
-+ rxque->swq.consume_idx = 0;
-+ rxque->swq.produce_idx = 0;
-+ }
-+
-+ rxque->max_packets = rxque->rrq.count / 2;
-+ return 0;
-+
-+err_alloc_swq_buffer:
-+ kfree(rxque->rfq.rfbuff);
-+ rxque->rfq.rfbuff = NULL;
-+err_alloc_rfq_buffer:
-+ alx_err(adpt, "Unable to allocate memory for the Rx descriptor\n");
-+ return -ENOMEM;
-+}
-+
-+
-+/* alx_alloc_all_rx_descriptor - allocate all Rx Descriptors */
-+static int alx_alloc_all_rx_descriptor(struct alx_adapter *adpt)
-+{
-+ int i, error = 0;
-+
-+ for (i = 0; i < adpt->num_rxques; i++) {
-+ error = alx_alloc_rx_descriptor(adpt, adpt->rx_queue[i]);
-+ if (!error)
-+ continue;
-+ alx_err(adpt, "Allocation for Rx Queue %u failed\n", i);
-+ break;
-+ }
-+
-+ return error;
-+}
-+
-+
-+/* alx_free_tx_descriptor - Free Tx Descriptor */
-+static void alx_free_tx_descriptor(struct alx_tx_queue *txque)
-+{
-+ alx_clean_tx_queue(txque);
-+
-+ kfree(txque->tpq.tpbuff);
-+ txque->tpq.tpbuff = NULL;
-+
-+ /* if not set, then don't free */
-+ if (!txque->tpq.tpdesc)
-+ return;
-+ txque->tpq.tpdesc = NULL;
-+}
-+
-+
-+/* alx_free_all_tx_descriptor - Free all Tx Descriptor */
-+static void alx_free_all_tx_descriptor(struct alx_adapter *adpt)
-+{
-+ int i;
-+
-+ for (i = 0; i < adpt->num_txques; i++)
-+ alx_free_tx_descriptor(adpt->tx_queue[i]);
-+}
-+
-+
-+/* alx_free_all_rx_descriptor - Free all Rx Descriptor */
-+static void alx_free_rx_descriptor(struct alx_rx_queue *rxque)
-+{
-+ alx_clean_rx_queue(rxque);
-+
-+ if (CHK_RX_FLAG(HW_QUE)) {
-+ kfree(rxque->rfq.rfbuff);
-+ rxque->rfq.rfbuff = NULL;
-+
-+ /* if not set, then don't free */
-+ if (!rxque->rrq.rrdesc)
-+ return;
-+ rxque->rrq.rrdesc = NULL;
-+
-+ if (!rxque->rfq.rfdesc)
-+ return;
-+ rxque->rfq.rfdesc = NULL;
-+ }
-+
-+ if (CHK_RX_FLAG(SW_QUE)) {
-+ kfree(rxque->swq.swbuff);
-+ rxque->swq.swbuff = NULL;
-+ }
-+}
-+
-+
-+/* alx_free_all_rx_descriptor - Free all Rx Descriptor */
-+static void alx_free_all_rx_descriptor(struct alx_adapter *adpt)
-+{
-+ int i;
-+ for (i = 0; i < adpt->num_rxques; i++)
-+ alx_free_rx_descriptor(adpt->rx_queue[i]);
-+}
-+
-+
-+/*
-+ * alx_alloc_all_rtx_descriptor - allocate Tx / RX descriptor queues
-+ */
-+static int alx_alloc_all_rtx_descriptor(struct alx_adapter *adpt)
-+{
-+ struct device *dev = &adpt->pdev->dev;
-+ struct alx_ring_header *ring_header = &adpt->ring_header;
-+ int num_tques = adpt->num_txques;
-+ int num_rques = adpt->num_hw_rxques;
-+ unsigned int num_tx_descs = adpt->num_txdescs;
-+ unsigned int num_rx_descs = adpt->num_rxdescs;
-+ int retval;
-+
-+ /*
-+ * real ring DMA buffer
-+ * each ring/block may need up to 8 bytes for alignment, hence the
-+ * additional bytes tacked onto the end.
-+ */
-+ ring_header->size =
-+ num_tques * num_tx_descs * sizeof(union alx_tpdesc) +
-+ num_rques * num_rx_descs * sizeof(union alx_rfdesc) +
-+ num_rques * num_rx_descs * sizeof(union alx_rrdesc) +
-+ sizeof(struct coals_msg_block) +
-+ sizeof(struct alx_hw_stats) +
-+ num_tques * 8 + num_rques * 2 * 8 + 8 * 2;
-+ netif_info(adpt, ifup, adpt->netdev,
-+ "num_tques = %d, num_tx_descs = %d\n",
-+ num_tques, num_tx_descs);
-+ netif_info(adpt, ifup, adpt->netdev,
-+ "num_rques = %d, num_rx_descs = %d\n",
-+ num_rques, num_rx_descs);
-+
-+ ring_header->used = 0;
-+ ring_header->desc = dma_alloc_coherent(dev, ring_header->size,
-+ &ring_header->dma, GFP_KERNEL);
-+
-+ if (!ring_header->desc) {
-+ alx_err(adpt, "dma_alloc_coherent failed\n");
-+ retval = -ENOMEM;
-+ goto err_alloc_dma;
-+ }
-+ memset(ring_header->desc, 0, ring_header->size);
-+ ring_header->used = ALIGN(ring_header->dma, 8) - ring_header->dma;
-+
-+ netif_info(adpt, ifup, adpt->netdev,
-+ "ring header: size = %d, used= %d\n",
-+ ring_header->size, ring_header->used);
-+
-+ /* allocate receive descriptors */
-+ retval = alx_alloc_all_tx_descriptor(adpt);
-+ if (retval)
-+ goto err_alloc_tx;
-+
-+ /* allocate receive descriptors */
-+ retval = alx_alloc_all_rx_descriptor(adpt);
-+ if (retval)
-+ goto err_alloc_rx;
-+
-+ /* Init CMB dma address */
-+ adpt->cmb.dma = ring_header->dma + ring_header->used;
-+ adpt->cmb.cmb = (u8 *) ring_header->desc + ring_header->used;
-+ ring_header->used += ALIGN(sizeof(struct coals_msg_block), 8);
-+
-+ adpt->smb.dma = ring_header->dma + ring_header->used;
-+ adpt->smb.smb = (u8 *)ring_header->desc + ring_header->used;
-+ ring_header->used += ALIGN(sizeof(struct alx_hw_stats), 8);
-+
-+ return 0;
-+
-+err_alloc_rx:
-+ alx_free_all_rx_descriptor(adpt);
-+err_alloc_tx:
-+ alx_free_all_tx_descriptor(adpt);
-+err_alloc_dma:
-+ return retval;
-+}
-+
-+
-+/*
-+ * alx_alloc_all_rtx_descriptor - allocate Tx / RX descriptor queues
-+ */
-+static void alx_free_all_rtx_descriptor(struct alx_adapter *adpt)
-+{
-+ struct pci_dev *pdev = adpt->pdev;
-+ struct alx_ring_header *ring_header = &adpt->ring_header;
-+
-+ alx_free_all_tx_descriptor(adpt);
-+ alx_free_all_rx_descriptor(adpt);
-+
-+ adpt->cmb.dma = 0;
-+ adpt->cmb.cmb = NULL;
-+ adpt->smb.dma = 0;
-+ adpt->smb.smb = NULL;
-+
-+ pci_free_consistent(pdev, ring_header->size, ring_header->desc,
-+ ring_header->dma);
-+ ring_header->desc = NULL;
-+ ring_header->size = ring_header->used = 0;
-+}
-+
-+
-+static netdev_features_t alx_fix_features(struct net_device *netdev,
-+ netdev_features_t features)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ /*
-+ * Since there is no support for separate rx/tx vlan accel
-+ * enable/disable make sure tx flag is always in same state as rx.
-+ */
-+ if (features & NETIF_F_HW_VLAN_RX)
-+ features |= NETIF_F_HW_VLAN_TX;
-+ else
-+ features &= ~NETIF_F_HW_VLAN_TX;
-+
-+ if (netdev->mtu > ALX_MAX_TSO_PKT_SIZE ||
-+ adpt->hw.mac_type == alx_mac_l1c ||
-+ adpt->hw.mac_type == alx_mac_l2c)
-+ features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-+
-+ return features;
-+}
-+
-+
-+static int alx_set_features(struct net_device *netdev,
-+ netdev_features_t features)
-+{
-+ netdev_features_t changed = netdev->features ^ features;
-+
-+ if (changed & NETIF_F_HW_VLAN_RX)
-+ alx_vlan_mode(netdev, features);
-+ return 0;
-+}
-+/*
-+ * alx_change_mtu - Change the Maximum Transfer Unit
-+ */
-+static int alx_change_mtu(struct net_device *netdev, int new_mtu)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ int old_mtu = netdev->mtu;
-+ int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
-+
-+ if ((max_frame < ALX_MIN_ETH_FRAME_SIZE) ||
-+ (max_frame > ALX_MAX_ETH_FRAME_SIZE)) {
-+ alx_err(adpt, "invalid MTU setting\n");
-+ return -EINVAL;
-+ }
-+ /* set MTU */
-+ if (old_mtu != new_mtu && netif_running(netdev)) {
-+ netif_info(adpt, hw, adpt->netdev,
-+ "changing MTU from %d to %d\n",
-+ netdev->mtu, new_mtu);
-+ netdev->mtu = new_mtu;
-+ adpt->hw.mtu = new_mtu;
-+ adpt->rxbuf_size = new_mtu > ALX_DEF_RX_BUF_SIZE ?
-+ ALIGN(max_frame, 8) : ALX_DEF_RX_BUF_SIZE;
-+ netdev_update_features(netdev);
-+ alx_reinit_locked(adpt);
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int alx_open_internal(struct alx_adapter *adpt, u32 ctrl)
-+{
-+ struct alx_hw *hw = &adpt->hw;
-+ int retval = 0;
-+ int i;
-+
-+ alx_init_ring_ptrs(adpt);
-+
-+ alx_set_multicase_list(adpt->netdev);
-+ alx_restore_vlan(adpt);
-+
-+ if (hw->cbs.config_mac)
-+ retval = hw->cbs.config_mac(hw, adpt->rxbuf_size,
-+ adpt->num_hw_rxques, adpt->num_rxdescs,
-+ adpt->num_txques, adpt->num_txdescs);
-+
-+ if (hw->cbs.config_tx)
-+ retval = hw->cbs.config_tx(hw);
-+
-+ if (hw->cbs.config_rx)
-+ retval = hw->cbs.config_rx(hw);
-+
-+ alx_config_rss(adpt);
-+
-+ for (i = 0; i < adpt->num_hw_rxques; i++)
-+ alx_refresh_rx_buffer(adpt->rx_queue[i]);
-+
-+ /* configure HW regsiters of MSIX */
-+ if (hw->cbs.config_msix)
-+ retval = hw->cbs.config_msix(hw, adpt->num_msix_intrs,
-+ CHK_ADPT_FLAG(0, MSIX_EN),
-+ CHK_ADPT_FLAG(0, MSI_EN));
-+
-+ if (ctrl & ALX_OPEN_CTRL_IRQ_EN) {
-+ retval = alx_request_irq(adpt);
-+ if (retval)
-+ goto err_request_irq;
-+ }
-+
-+ /* enable NAPI, INTR and TX */
-+ alx_napi_enable_all(adpt);
-+
-+ alx_enable_intr(adpt);
-+
-+ netif_tx_start_all_queues(adpt->netdev);
-+
-+ CLI_ADPT_FLAG(1, STATE_DOWN);
-+
-+ /* check link status */
-+ SET_ADPT_FLAG(0, TASK_LSC_REQ);
-+ adpt->link_jiffies = jiffies + ALX_TRY_LINK_TIMEOUT;
-+ mod_timer(&adpt->alx_timer, jiffies);
-+
-+ return retval;
-+
-+err_request_irq:
-+ alx_clean_all_rx_queues(adpt);
-+ return retval;
-+}
-+
-+
-+static void alx_stop_internal(struct alx_adapter *adpt, u32 ctrl)
-+{
-+ struct net_device *netdev = adpt->netdev;
-+ struct alx_hw *hw = &adpt->hw;
-+
-+ SET_ADPT_FLAG(1, STATE_DOWN);
-+
-+ netif_tx_stop_all_queues(netdev);
-+ /* call carrier off first to avoid false dev_watchdog timeouts */
-+ netif_carrier_off(netdev);
-+ netif_tx_disable(netdev);
-+
-+ alx_disable_intr(adpt);
-+
-+ alx_napi_disable_all(adpt);
-+
-+ if (ctrl & ALX_OPEN_CTRL_IRQ_EN)
-+ alx_free_irq(adpt);
-+
-+ CLI_ADPT_FLAG(0, TASK_LSC_REQ);
-+ CLI_ADPT_FLAG(0, TASK_REINIT_REQ);
-+ del_timer_sync(&adpt->alx_timer);
-+
-+ if (ctrl & ALX_OPEN_CTRL_RESET_PHY)
-+ hw->cbs.reset_phy(hw);
-+
-+ if (ctrl & ALX_OPEN_CTRL_RESET_MAC)
-+ hw->cbs.reset_mac(hw);
-+
-+ adpt->hw.link_speed = ALX_LINK_SPEED_UNKNOWN;
-+
-+ alx_clean_all_tx_queues(adpt);
-+ alx_clean_all_rx_queues(adpt);
-+}
-+
-+
-+/*
-+ * alx_open - Called when a network interface is made active
-+ */
-+static int alx_open(struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ int retval;
-+
-+ /* disallow open during test */
-+ if (CHK_ADPT_FLAG(1, STATE_TESTING) ||
-+ CHK_ADPT_FLAG(1, STATE_DIAG_RUNNING))
-+ return -EBUSY;
-+
-+ netif_carrier_off(netdev);
-+
-+ /* allocate rx/tx dma buffer & descriptors */
-+ retval = alx_alloc_all_rtx_descriptor(adpt);
-+ if (retval) {
-+ alx_err(adpt, "error in alx_alloc_all_rtx_descriptor\n");
-+ goto err_alloc_rtx;
-+ }
-+
-+ retval = alx_open_internal(adpt, ALX_OPEN_CTRL_IRQ_EN);
-+ if (retval)
-+ goto err_open_internal;
-+
-+ return retval;
-+
-+err_open_internal:
-+ alx_stop_internal(adpt, ALX_OPEN_CTRL_IRQ_EN);
-+err_alloc_rtx:
-+ alx_free_all_rtx_descriptor(adpt);
-+ hw->cbs.reset_mac(hw);
-+ return retval;
-+}
-+
-+
-+/*
-+ * alx_stop - Disables a network interface
-+ */
-+static int alx_stop(struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+
-+ if (CHK_ADPT_FLAG(1, STATE_RESETTING))
-+ netif_warn(adpt, ifdown, adpt->netdev,
-+ "flag STATE_RESETTING has already set\n");
-+
-+ alx_stop_internal(adpt, ALX_OPEN_CTRL_IRQ_EN |
-+ ALX_OPEN_CTRL_RESET_MAC);
-+ alx_free_all_rtx_descriptor(adpt);
-+
-+ return 0;
-+}
-+
-+
-+static int alx_shutdown_internal(struct pci_dev *pdev, bool *wakeup)
-+{
-+ struct alx_adapter *adpt = pci_get_drvdata(pdev);
-+ struct net_device *netdev = adpt->netdev;
-+ struct alx_hw *hw = &adpt->hw;
-+ u32 wufc = adpt->wol;
-+ u16 lpa;
-+ u32 speed, adv_speed, misc;
-+ bool link_up;
-+ int i;
-+ int retval = 0;
-+
-+ hw->cbs.config_aspm(hw, false, false);
-+
-+ netif_device_detach(netdev);
-+ if (netif_running(netdev))
-+ alx_stop_internal(adpt, 0);
-+
-+#ifdef CONFIG_PM_SLEEP
-+ retval = pci_save_state(pdev);
-+ if (retval)
-+ return retval;
-+#endif
-+ hw->cbs.check_phy_link(hw, &speed, &link_up);
-+
-+ if (link_up) {
-+ if (hw->mac_type == alx_mac_l1f ||
-+ hw->mac_type == alx_mac_l2f) {
-+ alx_mem_r32(hw, ALX_MISC, &misc);
-+ misc |= ALX_MISC_INTNLOSC_OPEN;
-+ alx_mem_w32(hw, ALX_MISC, misc);
-+ }
-+
-+ retval = hw->cbs.read_phy_reg(hw, MII_LPA, &lpa);
-+ if (retval)
-+ return retval;
-+
-+ adv_speed = ALX_LINK_SPEED_10_HALF;
-+ if (lpa & LPA_10FULL)
-+ adv_speed = ALX_LINK_SPEED_10_FULL;
-+ else if (lpa & LPA_10HALF)
-+ adv_speed = ALX_LINK_SPEED_10_HALF;
-+ else if (lpa & LPA_100FULL)
-+ adv_speed = ALX_LINK_SPEED_100_FULL;
-+ else if (lpa & LPA_100HALF)
-+ adv_speed = ALX_LINK_SPEED_100_HALF;
-+
-+ retval = hw->cbs.setup_phy_link(hw, adv_speed, true,
-+ !hw->disable_fc_autoneg);
-+ if (retval)
-+ return retval;
-+
-+ for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) {
-+ mdelay(100);
-+ retval = hw->cbs.check_phy_link(hw, &speed, &link_up);
-+ if (retval)
-+ continue;
-+ if (link_up)
-+ break;
-+ }
-+ } else {
-+ speed = ALX_LINK_SPEED_10_HALF;
-+ link_up = false;
-+ }
-+ hw->link_speed = speed;
-+ hw->link_up = link_up;
-+
-+ retval = hw->cbs.config_wol(hw, wufc);
-+ if (retval)
-+ return retval;
-+
-+ /* clear phy interrupt */
-+ retval = hw->cbs.ack_phy_intr(hw);
-+ if (retval)
-+ return retval;
-+
-+ if (wufc) {
-+ /* pcie patch */
-+ device_set_wakeup_enable(&pdev->dev, 1);
-+ }
-+
-+ retval = hw->cbs.config_pow_save(hw, adpt->hw.link_speed,
-+ (wufc ? true : false), false,
-+ (wufc & ALX_WOL_MAGIC ? true : false), true);
-+ if (retval)
-+ return retval;
-+
-+ *wakeup = wufc ? true : false;
-+ pci_disable_device(pdev);
-+ return 0;
-+}
-+
-+
-+static void alx_shutdown(struct pci_dev *pdev)
-+{
-+ bool wakeup;
-+ alx_shutdown_internal(pdev, &wakeup);
-+
-+ pci_wake_from_d3(pdev, wakeup);
-+ pci_set_power_state(pdev, PCI_D3hot);
-+}
-+
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int alx_suspend(struct device *dev)
-+{
-+ struct pci_dev *pdev = to_pci_dev(dev);
-+ int retval;
-+ bool wakeup;
-+
-+ retval = alx_shutdown_internal(pdev, &wakeup);
-+ if (retval)
-+ return retval;
-+
-+ if (wakeup) {
-+ pci_prepare_to_sleep(pdev);
-+ } else {
-+ pci_wake_from_d3(pdev, false);
-+ pci_set_power_state(pdev, PCI_D3hot);
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int alx_resume(struct device *dev)
-+{
-+ struct pci_dev *pdev = to_pci_dev(dev);
-+ struct alx_adapter *adpt = pci_get_drvdata(pdev);
-+ struct net_device *netdev = adpt->netdev;
-+ struct alx_hw *hw = &adpt->hw;
-+ u32 retval;
-+
-+ pci_set_power_state(pdev, PCI_D0);
-+ pci_restore_state(pdev);
-+ /*
-+ * pci_restore_state clears dev->state_saved so call
-+ * pci_save_state to restore it.
-+ */
-+ pci_save_state(pdev);
-+
-+ pci_enable_wake(pdev, PCI_D3hot, 0);
-+ pci_enable_wake(pdev, PCI_D3cold, 0);
-+
-+ retval = hw->cbs.reset_pcie(hw, true, true);
-+ retval = hw->cbs.reset_phy(hw);
-+ retval = hw->cbs.reset_mac(hw);
-+ retval = hw->cbs.setup_phy_link(hw, hw->autoneg_advertised, true,
-+ !hw->disable_fc_autoneg);
-+
-+ retval = hw->cbs.config_wol(hw, 0);
-+
-+ if (netif_running(netdev)) {
-+ retval = alx_open_internal(adpt, 0);
-+ if (retval)
-+ return retval;
-+ }
-+
-+ netif_device_attach(netdev);
-+ return 0;
-+}
-+#endif
-+
-+
-+/*
-+ * alx_update_hw_stats - Update the board statistics counters.
-+ */
-+static void alx_update_hw_stats(struct alx_adapter *adpt)
-+{
-+ struct net_device_stats *net_stats;
-+ struct alx_hw *hw = &adpt->hw;
-+ struct alx_hw_stats *hwstats = &adpt->hw_stats;
-+ unsigned long *hwstat_item = NULL;
-+ u32 hwstat_reg;
-+ u32 hwstat_data;
-+
-+ if (CHK_ADPT_FLAG(1, STATE_DOWN) || CHK_ADPT_FLAG(1, STATE_RESETTING))
-+ return;
-+
-+ /* update RX status */
-+ hwstat_reg = hw->rxstat_reg;
-+ hwstat_item = &hwstats->rx_ok;
-+ while (hwstat_reg < hw->rxstat_reg + hw->rxstat_sz) {
-+ alx_mem_r32(hw, hwstat_reg, &hwstat_data);
-+ *hwstat_item += hwstat_data;
-+ hwstat_reg += 4;
-+ hwstat_item++;
-+ }
-+
-+ /* update TX status */
-+ hwstat_reg = hw->txstat_reg;
-+ hwstat_item = &hwstats->tx_ok;
-+ while (hwstat_reg < hw->txstat_reg + hw->txstat_sz) {
-+ alx_mem_r32(hw, hwstat_reg, &hwstat_data);
-+ *hwstat_item += hwstat_data;
-+ hwstat_reg += 4;
-+ hwstat_item++;
-+ }
-+
-+ net_stats = &adpt->netdev->stats;
-+ net_stats->rx_packets = hwstats->rx_ok;
-+ net_stats->tx_packets = hwstats->tx_ok;
-+ net_stats->rx_bytes = hwstats->rx_byte_cnt;
-+ net_stats->tx_bytes = hwstats->tx_byte_cnt;
-+ net_stats->multicast = hwstats->rx_mcast;
-+ net_stats->collisions = hwstats->tx_single_col +
-+ hwstats->tx_multi_col * 2 +
-+ hwstats->tx_late_col + hwstats->tx_abort_col;
-+
-+ net_stats->rx_errors = hwstats->rx_frag + hwstats->rx_fcs_err +
-+ hwstats->rx_len_err + hwstats->rx_ov_sz +
-+ hwstats->rx_ov_rrd + hwstats->rx_align_err;
-+
-+ net_stats->rx_fifo_errors = hwstats->rx_ov_rxf;
-+ net_stats->rx_length_errors = hwstats->rx_len_err;
-+ net_stats->rx_crc_errors = hwstats->rx_fcs_err;
-+ net_stats->rx_frame_errors = hwstats->rx_align_err;
-+ net_stats->rx_over_errors = hwstats->rx_ov_rrd + hwstats->rx_ov_rxf;
-+
-+ net_stats->rx_missed_errors = hwstats->rx_ov_rrd + hwstats->rx_ov_rxf;
-+
-+ net_stats->tx_errors = hwstats->tx_late_col + hwstats->tx_abort_col +
-+ hwstats->tx_underrun + hwstats->tx_trunc;
-+ net_stats->tx_fifo_errors = hwstats->tx_underrun;
-+ net_stats->tx_aborted_errors = hwstats->tx_abort_col;
-+ net_stats->tx_window_errors = hwstats->tx_late_col;
-+}
-+
-+
-+/*
-+ * alx_get_stats - Get System Network Statistics
-+ *
-+ * Returns the address of the device statistics structure.
-+ * The statistics are actually updated from the timer callback.
-+ */
-+static struct net_device_stats *alx_get_stats(struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+
-+ alx_update_hw_stats(adpt);
-+ return &netdev->stats;
-+}
-+
-+
-+static void alx_link_task_routine(struct alx_adapter *adpt)
-+{
-+ struct net_device *netdev = adpt->netdev;
-+ struct alx_hw *hw = &adpt->hw;
-+ char *link_desc;
-+
-+ if (!CHK_ADPT_FLAG(0, TASK_LSC_REQ))
-+ return;
-+ CLI_ADPT_FLAG(0, TASK_LSC_REQ);
-+
-+ if (CHK_ADPT_FLAG(1, STATE_DOWN))
-+ return;
-+
-+ if (hw->cbs.check_phy_link) {
-+ hw->cbs.check_phy_link(hw,
-+ &hw->link_speed, &hw->link_up);
-+ } else {
-+ /* always assume link is up, if no check link function */
-+ hw->link_speed = ALX_LINK_SPEED_1GB_FULL;
-+ hw->link_up = true;
-+ }
-+ netif_info(adpt, timer, adpt->netdev,
-+ "link_speed = %d, link_up = %d\n",
-+ hw->link_speed, hw->link_up);
-+
-+ if (!hw->link_up && time_after(adpt->link_jiffies, jiffies))
-+ SET_ADPT_FLAG(0, TASK_LSC_REQ);
-+
-+ if (hw->link_up) {
-+ if (netif_carrier_ok(netdev))
-+ return;
-+
-+ link_desc = (hw->link_speed == ALX_LINK_SPEED_1GB_FULL) ?
-+ "1 Gbps Duplex Full" :
-+ (hw->link_speed == ALX_LINK_SPEED_100_FULL ?
-+ "100 Mbps Duplex Full" :
-+ (hw->link_speed == ALX_LINK_SPEED_100_HALF ?
-+ "100 Mbps Duplex Half" :
-+ (hw->link_speed == ALX_LINK_SPEED_10_FULL ?
-+ "10 Mbps Duplex Full" :
-+ (hw->link_speed == ALX_LINK_SPEED_10_HALF ?
-+ "10 Mbps Duplex HALF" :
-+ "unknown speed"))));
-+ netif_info(adpt, timer, adpt->netdev,
-+ "NIC Link is Up %s\n", link_desc);
-+
-+ hw->cbs.config_aspm(hw, true, true);
-+ hw->cbs.start_mac(hw);
-+ netif_carrier_on(netdev);
-+ netif_tx_wake_all_queues(netdev);
-+ } else {
-+ /* only continue if link was up previously */
-+ if (!netif_carrier_ok(netdev))
-+ return;
-+
-+ hw->link_speed = 0;
-+ netif_info(adpt, timer, adpt->netdev, "NIC Link is Down\n");
-+ netif_carrier_off(netdev);
-+ netif_tx_stop_all_queues(netdev);
-+
-+ hw->cbs.stop_mac(hw);
-+ hw->cbs.config_aspm(hw, false, true);
-+ hw->cbs.setup_phy_link(hw, hw->autoneg_advertised, true,
-+ !hw->disable_fc_autoneg);
-+ }
-+}
-+
-+
-+static void alx_reinit_task_routine(struct alx_adapter *adpt)
-+{
-+ if (!CHK_ADPT_FLAG(0, TASK_REINIT_REQ))
-+ return;
-+ CLI_ADPT_FLAG(0, TASK_REINIT_REQ);
-+
-+ if (CHK_ADPT_FLAG(1, STATE_DOWN) || CHK_ADPT_FLAG(1, STATE_RESETTING))
-+ return;
-+
-+ alx_reinit_locked(adpt);
-+}
-+
-+
-+/*
-+ * alx_timer_routine - Timer Call-back
-+ */
-+static void alx_timer_routine(unsigned long data)
-+{
-+ struct alx_adapter *adpt = (struct alx_adapter *)data;
-+ unsigned long delay;
-+
-+ /* poll faster when waiting for link */
-+ if (CHK_ADPT_FLAG(0, TASK_LSC_REQ))
-+ delay = HZ / 10;
-+ else
-+ delay = HZ * 2;
-+
-+ /* Reset the timer */
-+ mod_timer(&adpt->alx_timer, delay + jiffies);
-+
-+ alx_task_schedule(adpt);
-+}
-+
-+
-+/*
-+ * alx_task_routine - manages and runs subtasks
-+ */
-+static void alx_task_routine(struct work_struct *work)
-+{
-+ struct alx_adapter *adpt = container_of(work,
-+ struct alx_adapter, alx_task);
-+ /* test state of adapter */
-+ if (!CHK_ADPT_FLAG(1, STATE_WATCH_DOG))
-+ netif_warn(adpt, timer, adpt->netdev,
-+ "flag STATE_WATCH_DOG doesn't set\n");
-+
-+ /* reinit task */
-+ alx_reinit_task_routine(adpt);
-+
-+ /* link task */
-+ alx_link_task_routine(adpt);
-+
-+ /* flush memory to make sure state is correct before next watchog */
-+ smp_mb__before_clear_bit();
-+
-+ CLI_ADPT_FLAG(1, STATE_WATCH_DOG);
-+}
-+
-+
-+/* Calculate the transmit packet descript needed*/
-+static bool alx_check_num_tpdescs(struct alx_tx_queue *txque,
-+ const struct sk_buff *skb)
-+{
-+ u16 num_required = 1;
-+ u16 num_available = 0;
-+ u16 produce_idx = txque->tpq.produce_idx;
-+ u16 consume_idx = txque->tpq.consume_idx;
-+ int i = 0;
-+
-+ u16 proto_hdr_len = 0;
-+ if (skb_is_gso(skb)) {
-+ proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-+ if (proto_hdr_len < skb_headlen(skb))
-+ num_required++;
-+ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
-+ num_required++;
-+ }
-+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-+ num_required++;
-+ num_available = (u16)(consume_idx > produce_idx) ?
-+ (consume_idx - produce_idx - 1) :
-+ (txque->tpq.count + consume_idx - produce_idx - 1);
-+
-+ return num_required < num_available;
-+}
-+
-+
-+static int alx_tso_csum(struct alx_adapter *adpt,
-+ struct alx_tx_queue *txque,
-+ struct sk_buff *skb,
-+ union alx_sw_tpdesc *stpd)
-+{
-+ struct pci_dev *pdev = adpt->pdev;
-+ u8 hdr_len;
-+ int retval;
-+
-+ if (skb_is_gso(skb)) {
-+ if (skb_header_cloned(skb)) {
-+ retval = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-+ if (unlikely(retval))
-+ return retval;
-+ }
-+
-+ if (skb->protocol == htons(ETH_P_IP)) {
-+ u32 pkt_len =
-+ ((unsigned char *)ip_hdr(skb) - skb->data) +
-+ ntohs(ip_hdr(skb)->tot_len);
-+ if (skb->len > pkt_len)
-+ pskb_trim(skb, pkt_len);
-+ }
-+
-+ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-+ if (unlikely(skb->len == hdr_len)) {
-+ /* we only need to do csum */
-+ dev_warn(&pdev->dev,
-+ "tso doesn't need, if packet with 0 data\n");
-+ goto do_csum;
-+ }
-+
-+ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) {
-+ ip_hdr(skb)->check = 0;
-+ tcp_hdr(skb)->check = ~csum_tcpudp_magic(
-+ ip_hdr(skb)->saddr,
-+ ip_hdr(skb)->daddr,
-+ 0, IPPROTO_TCP, 0);
-+ stpd->genr.ipv4 = 1;
-+ }
-+
-+ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
-+ /* ipv6 tso need an extra tpd */
-+ union alx_sw_tpdesc extra_tpd;
-+
-+ memset(stpd, 0, sizeof(union alx_sw_tpdesc));
-+ memset(&extra_tpd, 0, sizeof(union alx_sw_tpdesc));
-+
-+ ipv6_hdr(skb)->payload_len = 0;
-+ tcp_hdr(skb)->check = ~csum_ipv6_magic(
-+ &ipv6_hdr(skb)->saddr,
-+ &ipv6_hdr(skb)->daddr,
-+ 0, IPPROTO_TCP, 0);
-+ extra_tpd.tso.addr_lo = skb->len;
-+ extra_tpd.tso.lso = 0x1;
-+ extra_tpd.tso.lso_v2 = 0x1;
-+ alx_set_tpdesc(txque, &extra_tpd);
-+ stpd->tso.lso_v2 = 0x1;
-+ }
-+
-+ stpd->tso.lso = 0x1;
-+ stpd->tso.tcphdr_offset = skb_transport_offset(skb);
-+ stpd->tso.mss = skb_shinfo(skb)->gso_size;
-+ return 0;
-+ }
-+
-+do_csum:
-+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
-+ u8 css, cso;
-+ cso = skb_checksum_start_offset(skb);
-+
-+ if (unlikely(cso & 0x1)) {
-+ dev_err(&pdev->dev, "pay load offset should not be an "
-+ "event number\n");
-+ return -1;
-+ } else {
-+ css = cso + skb->csum_offset;
-+
-+ stpd->csum.payld_offset = cso >> 1;
-+ stpd->csum.cxsum_offset = css >> 1;
-+ stpd->csum.c_sum = 0x1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+static void alx_tx_map(struct alx_adapter *adpt,
-+ struct alx_tx_queue *txque,
-+ struct sk_buff *skb,
-+ union alx_sw_tpdesc *stpd)
-+{
-+ struct alx_buffer *tpbuf = NULL;
-+
-+ unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
-+
-+ unsigned int len = skb_headlen(skb);
-+
-+ u16 map_len = 0;
-+ u16 mapped_len = 0;
-+ u16 hdr_len = 0;
-+ u16 f;
-+ u32 tso = stpd->tso.lso;
-+
-+ if (tso) {
-+ /* TSO */
-+ map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-+
-+ tpbuf = GET_TP_BUFFER(txque, txque->tpq.produce_idx);
-+ tpbuf->length = map_len;
-+ tpbuf->dma = dma_map_single(txque->dev,
-+ skb->data, hdr_len, DMA_TO_DEVICE);
-+ mapped_len += map_len;
-+ stpd->genr.addr = tpbuf->dma;
-+ stpd->genr.buffer_len = tpbuf->length;
-+
-+ alx_set_tpdesc(txque, stpd);
-+ }
-+
-+ if (mapped_len < len) {
-+ tpbuf = GET_TP_BUFFER(txque, txque->tpq.produce_idx);
-+ tpbuf->length = len - mapped_len;
-+ tpbuf->dma =
-+ dma_map_single(txque->dev, skb->data + mapped_len,
-+ tpbuf->length, DMA_TO_DEVICE);
-+ stpd->genr.addr = tpbuf->dma;
-+ stpd->genr.buffer_len = tpbuf->length;
-+ alx_set_tpdesc(txque, stpd);
-+ }
-+
-+ for (f = 0; f < nr_frags; f++) {
-+ struct skb_frag_struct *frag;
-+
-+ frag = &skb_shinfo(skb)->frags[f];
-+
-+ tpbuf = GET_TP_BUFFER(txque, txque->tpq.produce_idx);
-+ tpbuf->length = skb_frag_size(frag);
-+ tpbuf->dma = skb_frag_dma_map(txque->dev, frag, 0,
-+ tpbuf->length, DMA_TO_DEVICE);
-+ stpd->genr.addr = tpbuf->dma;
-+ stpd->genr.buffer_len = tpbuf->length;
-+ alx_set_tpdesc(txque, stpd);
-+ }
-+
-+
-+ /* The last tpd */
-+ alx_set_tpdesc_lastfrag(txque);
-+ /*
-+ * The last buffer info contain the skb address,
-+ * so it will be free after unmap
-+ */
-+ tpbuf->skb = skb;
-+}
-+
-+
-+static netdev_tx_t alx_start_xmit_frame(struct alx_adapter *adpt,
-+ struct alx_tx_queue *txque,
-+ struct sk_buff *skb)
-+{
-+ struct alx_hw *hw = &adpt->hw;
-+ unsigned long flags = 0;
-+ union alx_sw_tpdesc stpd; /* normal*/
-+
-+ if (CHK_ADPT_FLAG(1, STATE_DOWN) ||
-+ CHK_ADPT_FLAG(1, STATE_DIAG_RUNNING)) {
-+ dev_kfree_skb_any(skb);
-+ return NETDEV_TX_OK;
-+ }
-+
-+ if (!spin_trylock_irqsave(&adpt->tx_lock, flags)) {
-+ alx_err(adpt, "tx locked!\n");
-+ return NETDEV_TX_LOCKED;
-+ }
-+
-+ if (!alx_check_num_tpdescs(txque, skb)) {
-+ /* no enough descriptor, just stop queue */
-+ netif_stop_queue(adpt->netdev);
-+ spin_unlock_irqrestore(&adpt->tx_lock, flags);
-+ return NETDEV_TX_BUSY;
-+ }
-+
-+ memset(&stpd, 0, sizeof(union alx_sw_tpdesc));
-+ /* do TSO and check sum */
-+ if (alx_tso_csum(adpt, txque, skb, &stpd) != 0) {
-+ spin_unlock_irqrestore(&adpt->tx_lock, flags);
-+ dev_kfree_skb_any(skb);
-+ return NETDEV_TX_OK;
-+ }
-+
-+ if (unlikely(vlan_tx_tag_present(skb))) {
-+ u16 vlan = vlan_tx_tag_get(skb);
-+ u16 tag;
-+ ALX_VLAN_TO_TAG(vlan, tag);
-+ stpd.genr.vlan_tag = tag;
-+ stpd.genr.instag = 0x1;
-+ }
-+
-+ if (skb_network_offset(skb) != ETH_HLEN)
-+ stpd.genr.type = 0x1; /* Ethernet frame */
-+
-+ alx_tx_map(adpt, txque, skb, &stpd);
-+
-+
-+ /* update produce idx */
-+ wmb();
-+ alx_mem_w16(hw, txque->produce_reg, txque->tpq.produce_idx);
-+ netif_info(adpt, tx_err, adpt->netdev,
-+ "TX[%d]: tpq.consume_idx = 0x%x, tpq.produce_idx = 0x%x\n",
-+ txque->que_idx, txque->tpq.consume_idx,
-+ txque->tpq.produce_idx);
-+ netif_info(adpt, tx_err, adpt->netdev,
-+ "TX[%d]: Produce Reg[%x] = 0x%x\n",
-+ txque->que_idx, txque->produce_reg, txque->tpq.produce_idx);
-+
-+ spin_unlock_irqrestore(&adpt->tx_lock, flags);
-+ return NETDEV_TX_OK;
-+}
-+
-+
-+static netdev_tx_t alx_start_xmit(struct sk_buff *skb,
-+ struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_tx_queue *txque;
-+
-+ txque = adpt->tx_queue[0];
-+ return alx_start_xmit_frame(adpt, txque, skb);
-+}
-+
-+
-+/*
-+ * alx_mii_ioctl
-+ */
-+static int alx_mii_ioctl(struct net_device *netdev,
-+ struct ifreq *ifr, int cmd)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ struct mii_ioctl_data *data = if_mii(ifr);
-+ int retval = 0;
-+
-+ if (!netif_running(netdev))
-+ return -EINVAL;
-+
-+ switch (cmd) {
-+ case SIOCGMIIPHY:
-+ data->phy_id = 0;
-+ break;
-+
-+ case SIOCGMIIREG:
-+ if (data->reg_num & ~(0x1F)) {
-+ retval = -EFAULT;
-+ goto out;
-+ }
-+
-+ retval = hw->cbs.read_phy_reg(hw, data->reg_num,
-+ &data->val_out);
-+ netif_dbg(adpt, hw, adpt->netdev, "read phy %02x %04x\n",
-+ data->reg_num, data->val_out);
-+ if (retval) {
-+ retval = -EIO;
-+ goto out;
-+ }
-+ break;
-+
-+ case SIOCSMIIREG:
-+ if (data->reg_num & ~(0x1F)) {
-+ retval = -EFAULT;
-+ goto out;
-+ }
-+
-+ retval = hw->cbs.write_phy_reg(hw, data->reg_num, data->val_in);
-+ netif_dbg(adpt, hw, adpt->netdev, "write phy %02x %04x\n",
-+ data->reg_num, data->val_in);
-+ if (retval) {
-+ retval = -EIO;
-+ goto out;
-+ }
-+ break;
-+ default:
-+ retval = -EOPNOTSUPP;
-+ break;
-+ }
-+out:
-+ return retval;
-+
-+}
-+
-+
-+static int alx_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-+{
-+ switch (cmd) {
-+ case SIOCGMIIPHY:
-+ case SIOCGMIIREG:
-+ case SIOCSMIIREG:
-+ return alx_mii_ioctl(netdev, ifr, cmd);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+static void alx_poll_controller(struct net_device *netdev)
-+{
-+ struct alx_adapter *adpt = netdev_priv(netdev);
-+ int num_msix_intrs = adpt->num_msix_intrs;
-+ int msix_idx;
-+
-+ /* if interface is down do nothing */
-+ if (CHK_ADPT_FLAG(1, STATE_DOWN))
-+ return;
-+
-+ if (CHK_ADPT_FLAG(0, MSIX_EN)) {
-+ for (msix_idx = 0; msix_idx < num_msix_intrs; msix_idx++) {
-+ struct alx_msix_param *msix = adpt->msix[msix_idx];
-+ if (CHK_MSIX_FLAG(RXS) || CHK_MSIX_FLAG(TXS))
-+ alx_msix_rtx(0, msix);
-+ else if (CHK_MSIX_FLAG(TIMER))
-+ alx_msix_timer(0, msix);
-+ else if (CHK_MSIX_FLAG(ALERT))
-+ alx_msix_alert(0, msix);
-+ else if (CHK_MSIX_FLAG(SMB))
-+ alx_msix_smb(0, msix);
-+ else if (CHK_MSIX_FLAG(PHY))
-+ alx_msix_phy(0, msix);
-+ }
-+ } else {
-+ alx_interrupt(adpt->pdev->irq, netdev);
-+ }
-+}
-+#endif
-+
-+
-+static const struct net_device_ops alx_netdev_ops = {
-+ .ndo_open = alx_open,
-+ .ndo_stop = alx_stop,
-+ .ndo_start_xmit = alx_start_xmit,
-+ .ndo_get_stats = alx_get_stats,
-+ .ndo_set_rx_mode = alx_set_multicase_list,
-+ .ndo_validate_addr = eth_validate_addr,
-+ .ndo_set_mac_address = alx_set_mac_address,
-+ .ndo_change_mtu = alx_change_mtu,
-+ .ndo_do_ioctl = alx_ioctl,
-+ .ndo_tx_timeout = alx_tx_timeout,
-+ .ndo_fix_features = alx_fix_features,
-+ .ndo_set_features = alx_set_features,
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+ .ndo_poll_controller = alx_poll_controller,
-+#endif
-+};
-+
-+
-+/*
-+ * alx_init - Device Initialization Routine
-+ */
-+static int __devinit alx_init(struct pci_dev *pdev,
-+ const struct pci_device_id *ent)
-+{
-+ struct net_device *netdev;
-+ struct alx_adapter *adpt = NULL;
-+ struct alx_hw *hw = NULL;
-+ static int cards_found;
-+ int retval;
-+
-+ /* enable device (incl. PCI PM wakeup and hotplug setup) */
-+ retval = pci_enable_device_mem(pdev);
-+ if (retval) {
-+ dev_err(&pdev->dev, "cannot enable PCI device\n");
-+ goto err_alloc_device;
-+ }
-+
-+ /*
-+ * The alx chip can DMA to 64-bit addresses, but it uses a single
-+ * shared register for the high 32 bits, so only a single, aligned,
-+ * 4 GB physical address range can be used at a time.
-+ */
-+ if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
-+ !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
-+ dev_info(&pdev->dev, "DMA to 64-BIT addresses\n");
-+ } else {
-+ retval = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
-+ if (retval) {
-+ retval = dma_set_coherent_mask(&pdev->dev,
-+ DMA_BIT_MASK(32));
-+ if (retval) {
-+ dev_err(&pdev->dev,
-+ "No usable DMA config, aborting\n");
-+ goto err_alloc_pci_res_mem;
-+ }
-+ }
-+ }
-+
-+ retval = pci_request_selected_regions(pdev, pci_select_bars(pdev,
-+ IORESOURCE_MEM), alx_drv_name);
-+ if (retval) {
-+ dev_err(&pdev->dev,
-+ "pci_request_selected_regions failed 0x%x\n", retval);
-+ goto err_alloc_pci_res_mem;
-+ }
-+
-+
-+ pci_enable_pcie_error_reporting(pdev);
-+ pci_set_master(pdev);
-+
-+ netdev = alloc_etherdev(sizeof(struct alx_adapter));
-+ if (netdev == NULL) {
-+ dev_err(&pdev->dev, "etherdev alloc failed\n");
-+ retval = -ENOMEM;
-+ goto err_alloc_netdev;
-+ }
-+
-+ SET_NETDEV_DEV(netdev, &pdev->dev);
-+ netdev->irq = pdev->irq;
-+
-+ adpt = netdev_priv(netdev);
-+ pci_set_drvdata(pdev, adpt);
-+ adpt->netdev = netdev;
-+ adpt->pdev = pdev;
-+ hw = &adpt->hw;
-+ hw->adpt = adpt;
-+ adpt->msg_enable = ALX_MSG_DEFAULT;
-+
-+ adpt->hw.hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
-+ pci_resource_len(pdev, BAR_0));
-+ if (!adpt->hw.hw_addr) {
-+ alx_err(adpt, "cannot map device registers\n");
-+ retval = -EIO;
-+ goto err_iomap;
-+ }
-+ netdev->base_addr = (unsigned long)adpt->hw.hw_addr;
-+
-+ /* set cb member of netdev structure*/
-+ netdev->netdev_ops = &alx_netdev_ops;
-+ alx_set_ethtool_ops(netdev);
-+ netdev->watchdog_timeo = ALX_WATCHDOG_TIME;
-+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
-+
-+ adpt->bd_number = cards_found;
-+
-+ /* init alx_adapte structure */
-+ retval = alx_init_adapter(adpt);
-+ if (retval) {
-+ alx_err(adpt, "net device private data init failed\n");
-+ goto err_init_adapter;
-+ }
-+
-+ /* reset pcie */
-+ retval = hw->cbs.reset_pcie(hw, true, true);
-+ if (retval) {
-+ alx_err(adpt, "PCIE Reset failed, error = %d\n", retval);
-+ retval = -EIO;
-+ goto err_init_adapter;
-+ }
-+
-+ /* Init GPHY as early as possible due to power saving issue */
-+ retval = hw->cbs.reset_phy(hw);
-+ if (retval) {
-+ alx_err(adpt, "PHY Reset failed, error = %d\n", retval);
-+ retval = -EIO;
-+ goto err_init_adapter;
-+ }
-+
-+ /* reset mac */
-+ retval = hw->cbs.reset_mac(hw);
-+ if (retval) {
-+ alx_err(adpt, "MAC Reset failed, error = %d\n", retval);
-+ retval = -EIO;
-+ goto err_init_adapter;
-+ }
-+
-+ /* setup link to put it in a known good starting state */
-+ retval = hw->cbs.setup_phy_link(hw, hw->autoneg_advertised, true,
-+ !hw->disable_fc_autoneg);
-+
-+ /* get user settings */
-+ adpt->num_txdescs = 1024;
-+ adpt->num_rxdescs = 512;
-+ adpt->max_rxques = min_t(int, ALX_MAX_RX_QUEUES, num_online_cpus());
-+ adpt->max_txques = min_t(int, ALX_MAX_TX_QUEUES, num_online_cpus());
-+
-+ netdev->hw_features = NETIF_F_SG |
-+ NETIF_F_HW_CSUM |
-+ NETIF_F_HW_VLAN_RX;
-+ if (adpt->hw.mac_type != alx_mac_l1c &&
-+ adpt->hw.mac_type != alx_mac_l2c) {
-+ netdev->hw_features = netdev->hw_features |
-+ NETIF_F_TSO |
-+ NETIF_F_TSO6;
-+ }
-+ netdev->features = netdev->hw_features |
-+ NETIF_F_HW_VLAN_TX;
-+
-+ /* get mac addr and perm mac addr, set to register */
-+ if (hw->cbs.get_mac_addr)
-+ retval = hw->cbs.get_mac_addr(hw, hw->mac_perm_addr);
-+ else
-+ retval = -EINVAL;
-+
-+ if (retval) {
-+ eth_hw_addr_random(netdev);
-+ memcpy(hw->mac_perm_addr, netdev->dev_addr, netdev->addr_len);
-+ }
-+
-+ memcpy(hw->mac_addr, hw->mac_perm_addr, netdev->addr_len);
-+ if (hw->cbs.set_mac_addr)
-+ hw->cbs.set_mac_addr(hw, hw->mac_addr);
-+
-+ memcpy(netdev->dev_addr, hw->mac_perm_addr, netdev->addr_len);
-+ memcpy(netdev->perm_addr, hw->mac_perm_addr, netdev->addr_len);
-+ retval = alx_validate_mac_addr(netdev->perm_addr);
-+ if (retval) {
-+ alx_err(adpt, "invalid MAC address\n");
-+ goto err_init_adapter;
-+ }
-+
-+ setup_timer(&adpt->alx_timer, &alx_timer_routine,
-+ (unsigned long)adpt);
-+ INIT_WORK(&adpt->alx_task, alx_task_routine);
-+
-+ /* Number of supported queues */
-+ alx_set_num_queues(adpt);
-+ retval = alx_set_interrupt_mode(adpt);
-+ if (retval) {
-+ alx_err(adpt, "can't set interrupt mode\n");
-+ goto err_set_interrupt_mode;
-+ }
-+
-+ retval = alx_set_interrupt_param(adpt);
-+ if (retval) {
-+ alx_err(adpt, "can't set interrupt parameter\n");
-+ goto err_set_interrupt_param;
-+ }
-+
-+ retval = alx_alloc_all_rtx_queue(adpt);
-+ if (retval) {
-+ alx_err(adpt, "can't allocate memory for queues\n");
-+ goto err_alloc_rtx_queue;
-+ }
-+
-+ alx_set_register_info_special(adpt);
-+
-+ netif_dbg(adpt, probe, adpt->netdev,
-+ "num_msix_noque_intrs = %d, num_msix_rxque_intrs = %d, "
-+ "num_msix_txque_intrs = %d\n",
-+ adpt->num_msix_noques, adpt->num_msix_rxques,
-+ adpt->num_msix_txques);
-+ netif_dbg(adpt, probe, adpt->netdev, "num_msix_all_intrs = %d\n",
-+ adpt->num_msix_intrs);
-+
-+ netif_dbg(adpt, probe, adpt->netdev,
-+ "RX Queue Count = %u, HRX Queue Count = %u, "
-+ "SRX Queue Count = %u, TX Queue Count = %u\n",
-+ adpt->num_rxques, adpt->num_hw_rxques, adpt->num_sw_rxques,
-+ adpt->num_txques);
-+
-+ /* WOL not supported for all but the following */
-+ switch (hw->pci_devid) {
-+ case ALX_DEV_ID_AR8131:
-+ case ALX_DEV_ID_AR8132:
-+ case ALX_DEV_ID_AR8151_V1:
-+ case ALX_DEV_ID_AR8151_V2:
-+ case ALX_DEV_ID_AR8152_V1:
-+ case ALX_DEV_ID_AR8152_V2:
-+ adpt->wol = (ALX_WOL_MAGIC | ALX_WOL_PHY);
-+ break;
-+ case ALX_DEV_ID_AR8161:
-+ case ALX_DEV_ID_AR8162:
-+ adpt->wol = (ALX_WOL_MAGIC | ALX_WOL_PHY);
-+ break;
-+ default:
-+ adpt->wol = 0;
-+ break;
-+ }
-+ device_set_wakeup_enable(&adpt->pdev->dev, adpt->wol);
-+
-+ SET_ADPT_FLAG(1, STATE_DOWN);
-+ strcpy(netdev->name, "eth%d");
-+ retval = register_netdev(netdev);
-+ if (retval) {
-+ alx_err(adpt, "register netdevice failed\n");
-+ goto err_register_netdev;
-+ }
-+ adpt->netdev_registered = true;
-+
-+ /* carrier off reporting is important to ethtool even BEFORE open */
-+ netif_carrier_off(netdev);
-+ /* keep stopping all the transmit queues for older kernels */
-+ netif_tx_stop_all_queues(netdev);
-+
-+ /* print the MAC address */
-+ netif_info(adpt, probe, adpt->netdev, "%pM\n", netdev->dev_addr);
-+
-+ /* print the adapter capability */
-+ if (CHK_ADPT_FLAG(0, MSI_CAP)) {
-+ netif_info(adpt, probe, adpt->netdev,
-+ "MSI Capable: %s\n",
-+ CHK_ADPT_FLAG(0, MSI_EN) ? "Enable" : "Disable");
-+ }
-+ if (CHK_ADPT_FLAG(0, MSIX_CAP)) {
-+ netif_info(adpt, probe, adpt->netdev,
-+ "MSIX Capable: %s\n",
-+ CHK_ADPT_FLAG(0, MSIX_EN) ? "Enable" : "Disable");
-+ }
-+ if (CHK_ADPT_FLAG(0, MRQ_CAP)) {
-+ netif_info(adpt, probe, adpt->netdev,
-+ "MRQ Capable: %s\n",
-+ CHK_ADPT_FLAG(0, MRQ_EN) ? "Enable" : "Disable");
-+ }
-+ if (CHK_ADPT_FLAG(0, MRQ_CAP)) {
-+ netif_info(adpt, probe, adpt->netdev,
-+ "MTQ Capable: %s\n",
-+ CHK_ADPT_FLAG(0, MTQ_EN) ? "Enable" : "Disable");
-+ }
-+ if (CHK_ADPT_FLAG(0, SRSS_CAP)) {
-+ netif_info(adpt, probe, adpt->netdev,
-+ "RSS(SW) Capable: %s\n",
-+ CHK_ADPT_FLAG(0, SRSS_EN) ? "Enable" : "Disable");
-+ }
-+
-+ printk(KERN_INFO "alx: Atheros Gigabit Network Connection\n");
-+ cards_found++;
-+ return 0;
-+
-+err_register_netdev:
-+ alx_free_all_rtx_queue(adpt);
-+err_alloc_rtx_queue:
-+ alx_reset_interrupt_param(adpt);
-+err_set_interrupt_param:
-+ alx_reset_interrupt_mode(adpt);
-+err_set_interrupt_mode:
-+err_init_adapter:
-+ iounmap(adpt->hw.hw_addr);
-+err_iomap:
-+ free_netdev(netdev);
-+err_alloc_netdev:
-+ pci_release_selected_regions(pdev,
-+ pci_select_bars(pdev, IORESOURCE_MEM));
-+err_alloc_pci_res_mem:
-+ pci_disable_device(pdev);
-+err_alloc_device:
-+ dev_err(&pdev->dev,
-+ "error when probe device, error = %d\n", retval);
-+ return retval;
-+}
-+
-+
-+/*
-+ * alx_remove - Device Removal Routine
-+ */
-+static void __devexit alx_remove(struct pci_dev *pdev)
-+{
-+ struct alx_adapter *adpt = pci_get_drvdata(pdev);
-+ struct alx_hw *hw = &adpt->hw;
-+ struct net_device *netdev = adpt->netdev;
-+
-+ SET_ADPT_FLAG(1, STATE_DOWN);
-+ cancel_work_sync(&adpt->alx_task);
-+
-+ hw->cbs.config_pow_save(hw, ALX_LINK_SPEED_UNKNOWN,
-+ false, false, false, false);
-+
-+ /* resume permanent mac address */
-+ hw->cbs.set_mac_addr(hw, hw->mac_perm_addr);
-+
-+ if (adpt->netdev_registered) {
-+ unregister_netdev(netdev);
-+ adpt->netdev_registered = false;
-+ }
-+
-+ alx_free_all_rtx_queue(adpt);
-+ alx_reset_interrupt_param(adpt);
-+ alx_reset_interrupt_mode(adpt);
-+
-+ iounmap(adpt->hw.hw_addr);
-+ pci_release_selected_regions(pdev,
-+ pci_select_bars(pdev, IORESOURCE_MEM));
-+
-+ netif_info(adpt, probe, adpt->netdev, "complete\n");
-+ free_netdev(netdev);
-+
-+ pci_disable_pcie_error_reporting(pdev);
-+
-+ pci_disable_device(pdev);
-+}
-+
-+
-+/*
-+ * alx_pci_error_detected
-+ */
-+static pci_ers_result_t alx_pci_error_detected(struct pci_dev *pdev,
-+ pci_channel_state_t state)
-+{
-+ struct alx_adapter *adpt = pci_get_drvdata(pdev);
-+ struct net_device *netdev = adpt->netdev;
-+ pci_ers_result_t retval = PCI_ERS_RESULT_NEED_RESET;
-+
-+ netif_device_detach(netdev);
-+
-+ if (state == pci_channel_io_perm_failure) {
-+ retval = PCI_ERS_RESULT_DISCONNECT;
-+ goto out;
-+ }
-+
-+ if (netif_running(netdev))
-+ alx_stop_internal(adpt, ALX_OPEN_CTRL_RESET_MAC);
-+ pci_disable_device(pdev);
-+out:
-+ return retval;
-+}
-+
-+
-+/*
-+ * alx_pci_error_slot_reset
-+ */
-+static pci_ers_result_t alx_pci_error_slot_reset(struct pci_dev *pdev)
-+{
-+ struct alx_adapter *adpt = pci_get_drvdata(pdev);
-+ pci_ers_result_t retval = PCI_ERS_RESULT_DISCONNECT;
-+
-+ if (pci_enable_device(pdev)) {
-+ alx_err(adpt, "cannot re-enable PCI device after reset\n");
-+ goto out;
-+ }
-+
-+ pci_set_master(pdev);
-+ pci_enable_wake(pdev, PCI_D3hot, 0);
-+ pci_enable_wake(pdev, PCI_D3cold, 0);
-+ adpt->hw.cbs.reset_mac(&adpt->hw);
-+ retval = PCI_ERS_RESULT_RECOVERED;
-+out:
-+ pci_cleanup_aer_uncorrect_error_status(pdev);
-+ return retval;
-+}
-+
-+
-+/*
-+ * alx_pci_error_resume
-+ */
-+static void alx_pci_error_resume(struct pci_dev *pdev)
-+{
-+ struct alx_adapter *adpt = pci_get_drvdata(pdev);
-+ struct net_device *netdev = adpt->netdev;
-+
-+ if (netif_running(netdev)) {
-+ if (alx_open_internal(adpt, 0))
-+ return;
-+ }
-+
-+ netif_device_attach(netdev);
-+}
-+
-+
-+static struct pci_error_handlers alx_err_handler = {
-+ .error_detected = alx_pci_error_detected,
-+ .slot_reset = alx_pci_error_slot_reset,
-+ .resume = alx_pci_error_resume,
-+};
-+
-+
-+#ifdef CONFIG_PM_SLEEP
-+static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
-+#define ALX_PM_OPS (&alx_pm_ops)
-+#else
-+#define ALX_PM_OPS NULL
-+#endif
-+
-+
-+static struct pci_driver alx_driver = {
-+ .name = alx_drv_name,
-+ .id_table = alx_pci_tbl,
-+ .probe = alx_init,
-+ .remove = __devexit_p(alx_remove),
-+ .shutdown = alx_shutdown,
-+ .err_handler = &alx_err_handler,
-+ .driver.pm = ALX_PM_OPS,
-+};
-+
-+
-+static int __init alx_init_module(void)
-+{
-+ int retval;
-+
-+ printk(KERN_INFO "%s\n", alx_drv_description);
-+ retval = pci_register_driver(&alx_driver);
-+
-+ return retval;
-+}
-+module_init(alx_init_module);
-+
-+
-+static void __exit alx_exit_module(void)
-+{
-+ pci_unregister_driver(&alx_driver);
-+}
-+
-+
-+module_exit(alx_exit_module);
---- /dev/null
-+++ b/drivers/net/ethernet/atheros/alx/alx_sw.h
-@@ -0,0 +1,493 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef _ALX_SW_H_
-+#define _ALX_SW_H_
-+
-+#include <linux/netdevice.h>
-+#include <linux/crc32.h>
-+
-+/* Vendor ID */
-+#define ALX_VENDOR_ID 0x1969
-+
-+/* Device IDs */
-+#define ALX_DEV_ID_AR8131 0x1063 /* l1c */
-+#define ALX_DEV_ID_AR8132 0x1062 /* l2c */
-+#define ALX_DEV_ID_AR8151_V1 0x1073 /* l1d_v1 */
-+#define ALX_DEV_ID_AR8151_V2 0x1083 /* l1d_v2 */
-+#define ALX_DEV_ID_AR8152_V1 0x2060 /* l2cb_v1 */
-+#define ALX_DEV_ID_AR8152_V2 0x2062 /* l2cb_v2 */
-+#define ALX_DEV_ID_AR8161 0x1091 /* l1f */
-+#define ALX_DEV_ID_AR8162 0x1090 /* l2f */
-+
-+#define ALX_REV_ID_AR8152_V1_0 0xc0
-+#define ALX_REV_ID_AR8152_V1_1 0xc1
-+#define ALX_REV_ID_AR8152_V2_0 0xc0
-+#define ALX_REV_ID_AR8152_V2_1 0xc1
-+#define ALX_REV_ID_AR8161_V2_0 0x10 /* B0 */
-+
-+/* Generic Registers */
-+#define ALX_DEV_STAT 0x62 /* 16 bits */
-+#define ALX_DEV_STAT_CERR 0x0001
-+#define ALX_DEV_STAT_NFERR 0x0002
-+#define ALX_DEV_STAT_FERR 0x0004
-+
-+#define ALX_ISR 0x1600
-+#define ALX_IMR 0x1604
-+#define ALX_ISR_SMB 0x00000001
-+#define ALX_ISR_TIMER 0x00000002
-+#define ALX_ISR_MANU 0x00000004
-+#define ALX_ISR_RXF_OV 0x00000008
-+#define ALX_ISR_RFD_UR 0x00000010
-+#define ALX_ISR_TX_Q1 0x00000020
-+#define ALX_ISR_TX_Q2 0x00000040
-+#define ALX_ISR_TX_Q3 0x00000080
-+#define ALX_ISR_TXF_UR 0x00000100
-+#define ALX_ISR_DMAR 0x00000200
-+#define ALX_ISR_DMAW 0x00000400
-+#define ALX_ISR_TX_CREDIT 0x00000800
-+#define ALX_ISR_PHY 0x00001000
-+#define ALX_ISR_PHY_LPW 0x00002000
-+#define ALX_ISR_TXQ_TO 0x00004000
-+#define ALX_ISR_TX_Q0 0x00008000
-+#define ALX_ISR_RX_Q0 0x00010000
-+#define ALX_ISR_RX_Q1 0x00020000
-+#define ALX_ISR_RX_Q2 0x00040000
-+#define ALX_ISR_RX_Q3 0x00080000
-+#define ALX_ISR_MAC_RX 0x00100000
-+#define ALX_ISR_MAC_TX 0x00200000
-+#define ALX_ISR_PCIE_UR 0x00400000
-+#define ALX_ISR_PCIE_FERR 0x00800000
-+#define ALX_ISR_PCIE_NFERR 0x01000000
-+#define ALX_ISR_PCIE_CERR 0x02000000
-+#define ALX_ISR_PCIE_LNKDOWN 0x04000000
-+#define ALX_ISR_RX_Q4 0x08000000
-+#define ALX_ISR_RX_Q5 0x10000000
-+#define ALX_ISR_RX_Q6 0x20000000
-+#define ALX_ISR_RX_Q7 0x40000000
-+#define ALX_ISR_DIS 0x80000000
-+
-+
-+#define ALX_IMR_NORMAL_MASK (\
-+ ALX_ISR_MANU |\
-+ ALX_ISR_OVER |\
-+ ALX_ISR_TXQ |\
-+ ALX_ISR_RXQ |\
-+ ALX_ISR_PHY_LPW |\
-+ ALX_ISR_PHY |\
-+ ALX_ISR_ERROR)
-+
-+#define ALX_ISR_ALERT_MASK (\
-+ ALX_ISR_DMAR |\
-+ ALX_ISR_DMAW |\
-+ ALX_ISR_TXQ_TO |\
-+ ALX_ISR_PCIE_FERR |\
-+ ALX_ISR_PCIE_LNKDOWN |\
-+ ALX_ISR_RFD_UR |\
-+ ALX_ISR_RXF_OV)
-+
-+#define ALX_ISR_TXQ (\
-+ ALX_ISR_TX_Q0 |\
-+ ALX_ISR_TX_Q1 |\
-+ ALX_ISR_TX_Q2 |\
-+ ALX_ISR_TX_Q3)
-+
-+#define ALX_ISR_RXQ (\
-+ ALX_ISR_RX_Q0 |\
-+ ALX_ISR_RX_Q1 |\
-+ ALX_ISR_RX_Q2 |\
-+ ALX_ISR_RX_Q3 |\
-+ ALX_ISR_RX_Q4 |\
-+ ALX_ISR_RX_Q5 |\
-+ ALX_ISR_RX_Q6 |\
-+ ALX_ISR_RX_Q7)
-+
-+#define ALX_ISR_OVER (\
-+ ALX_ISR_RFD_UR |\
-+ ALX_ISR_RXF_OV |\
-+ ALX_ISR_TXF_UR)
-+
-+#define ALX_ISR_ERROR (\
-+ ALX_ISR_DMAR |\
-+ ALX_ISR_TXQ_TO |\
-+ ALX_ISR_DMAW |\
-+ ALX_ISR_PCIE_ERROR)
-+
-+#define ALX_ISR_PCIE_ERROR (\
-+ ALX_ISR_PCIE_FERR |\
-+ ALX_ISR_PCIE_LNKDOWN)
-+
-+/* MISC Register */
-+#define ALX_MISC 0x19C0
-+#define ALX_MISC_INTNLOSC_OPEN 0x00000008
-+
-+#define ALX_CLK_GATE 0x1814
-+
-+/* DMA address */
-+#define DMA_ADDR_HI_MASK 0xffffffff00000000ULL
-+#define DMA_ADDR_LO_MASK 0x00000000ffffffffULL
-+
-+#define ALX_DMA_ADDR_HI(_addr) \
-+ ((u32)(((u64)(_addr) & DMA_ADDR_HI_MASK) >> 32))
-+#define ALX_DMA_ADDR_LO(_addr) \
-+ ((u32)((u64)(_addr) & DMA_ADDR_LO_MASK))
-+
-+/* mac address length */
-+#define ALX_ETH_LENGTH_OF_ADDRESS 6
-+#define ALX_ETH_LENGTH_OF_HEADER ETH_HLEN
-+
-+#define ALX_ETH_CRC(_addr, _len) ether_crc((_len), (_addr));
-+
-+/* Autonegotiation advertised speeds */
-+/* Link speed */
-+#define ALX_LINK_SPEED_UNKNOWN 0x0
-+#define ALX_LINK_SPEED_10_HALF 0x0001
-+#define ALX_LINK_SPEED_10_FULL 0x0002
-+#define ALX_LINK_SPEED_100_HALF 0x0004
-+#define ALX_LINK_SPEED_100_FULL 0x0008
-+#define ALX_LINK_SPEED_1GB_FULL 0x0020
-+#define ALX_LINK_SPEED_DEFAULT (\
-+ ALX_LINK_SPEED_10_HALF |\
-+ ALX_LINK_SPEED_10_FULL |\
-+ ALX_LINK_SPEED_100_HALF |\
-+ ALX_LINK_SPEED_100_FULL |\
-+ ALX_LINK_SPEED_1GB_FULL)
-+
-+#define ALX_MAX_SETUP_LNK_CYCLE 100
-+
-+/* Device Type definitions for new protocol MDIO commands */
-+#define ALX_MDIO_DEV_TYPE_NORM 0
-+
-+/* Wake On Lan */
-+#define ALX_WOL_PHY 0x00000001 /* PHY Status Change */
-+#define ALX_WOL_MAGIC 0x00000002 /* Magic Packet */
-+
-+#define ALX_MAX_EEPROM_LEN 0x200
-+#define ALX_MAX_HWREG_LEN 0x200
-+
-+/* RSS Settings */
-+enum alx_rss_mode {
-+ alx_rss_mode_disable = 0,
-+ alx_rss_sig_que = 1,
-+ alx_rss_mul_que_sig_int = 2,
-+ alx_rss_mul_que_mul_int = 4,
-+};
-+
-+/* Flow Control Settings */
-+enum alx_fc_mode {
-+ alx_fc_none = 0,
-+ alx_fc_rx_pause,
-+ alx_fc_tx_pause,
-+ alx_fc_full,
-+ alx_fc_default
-+};
-+
-+/* WRR Restrict Settings */
-+enum alx_wrr_mode {
-+ alx_wrr_mode_none = 0,
-+ alx_wrr_mode_high,
-+ alx_wrr_mode_high2,
-+ alx_wrr_mode_all
-+};
-+
-+enum alx_mac_type {
-+ alx_mac_unknown = 0,
-+ alx_mac_l1c,
-+ alx_mac_l2c,
-+ alx_mac_l1d_v1,
-+ alx_mac_l1d_v2,
-+ alx_mac_l2cb_v1,
-+ alx_mac_l2cb_v20,
-+ alx_mac_l2cb_v21,
-+ alx_mac_l1f,
-+ alx_mac_l2f,
-+};
-+
-+
-+/* Statistics counters collected by the MAC */
-+struct alx_hw_stats {
-+ /* rx */
-+ unsigned long rx_ok;
-+ unsigned long rx_bcast;
-+ unsigned long rx_mcast;
-+ unsigned long rx_pause;
-+ unsigned long rx_ctrl;
-+ unsigned long rx_fcs_err;
-+ unsigned long rx_len_err;
-+ unsigned long rx_byte_cnt;
-+ unsigned long rx_runt;
-+ unsigned long rx_frag;
-+ unsigned long rx_sz_64B;
-+ unsigned long rx_sz_127B;
-+ unsigned long rx_sz_255B;
-+ unsigned long rx_sz_511B;
-+ unsigned long rx_sz_1023B;
-+ unsigned long rx_sz_1518B;
-+ unsigned long rx_sz_max;
-+ unsigned long rx_ov_sz;
-+ unsigned long rx_ov_rxf;
-+ unsigned long rx_ov_rrd;
-+ unsigned long rx_align_err;
-+ unsigned long rx_bc_byte_cnt;
-+ unsigned long rx_mc_byte_cnt;
-+ unsigned long rx_err_addr;
-+
-+ /* tx */
-+ unsigned long tx_ok;
-+ unsigned long tx_bcast;
-+ unsigned long tx_mcast;
-+ unsigned long tx_pause;
-+ unsigned long tx_exc_defer;
-+ unsigned long tx_ctrl;
-+ unsigned long tx_defer;
-+ unsigned long tx_byte_cnt;
-+ unsigned long tx_sz_64B;
-+ unsigned long tx_sz_127B;
-+ unsigned long tx_sz_255B;
-+ unsigned long tx_sz_511B;
-+ unsigned long tx_sz_1023B;
-+ unsigned long tx_sz_1518B;
-+ unsigned long tx_sz_max;
-+ unsigned long tx_single_col;
-+ unsigned long tx_multi_col;
-+ unsigned long tx_late_col;
-+ unsigned long tx_abort_col;
-+ unsigned long tx_underrun;
-+ unsigned long tx_trd_eop;
-+ unsigned long tx_len_err;
-+ unsigned long tx_trunc;
-+ unsigned long tx_bc_byte_cnt;
-+ unsigned long tx_mc_byte_cnt;
-+ unsigned long update;
-+};
-+
-+/* HW callback function pointer table */
-+struct alx_hw;
-+struct alx_hw_callbacks {
-+ /* NIC */
-+ int (*identify_nic)(struct alx_hw *);
-+ /* PHY */
-+ int (*init_phy)(struct alx_hw *);
-+ int (*reset_phy)(struct alx_hw *);
-+ int (*read_phy_reg)(struct alx_hw *, u16, u16 *);
-+ int (*write_phy_reg)(struct alx_hw *, u16, u16);
-+ /* Link */
-+ int (*setup_phy_link)(struct alx_hw *, u32, bool, bool);
-+ int (*setup_phy_link_speed)(struct alx_hw *, u32, bool, bool);
-+ int (*check_phy_link)(struct alx_hw *, u32 *, bool *);
-+
-+ /* MAC */
-+ int (*reset_mac)(struct alx_hw *);
-+ int (*start_mac)(struct alx_hw *);
-+ int (*stop_mac)(struct alx_hw *);
-+ int (*config_mac)(struct alx_hw *, u16, u16, u16, u16, u16);
-+ int (*get_mac_addr)(struct alx_hw *, u8 *);
-+ int (*set_mac_addr)(struct alx_hw *, u8 *);
-+ int (*set_mc_addr)(struct alx_hw *, u8 *);
-+ int (*clear_mc_addr)(struct alx_hw *);
-+
-+ /* intr */
-+ int (*ack_phy_intr)(struct alx_hw *);
-+ int (*enable_legacy_intr)(struct alx_hw *);
-+ int (*disable_legacy_intr)(struct alx_hw *);
-+ int (*enable_msix_intr)(struct alx_hw *, u8);
-+ int (*disable_msix_intr)(struct alx_hw *, u8);
-+
-+ /* Configure */
-+ int (*config_rx)(struct alx_hw *);
-+ int (*config_tx)(struct alx_hw *);
-+ int (*config_fc)(struct alx_hw *);
-+ int (*config_rss)(struct alx_hw *, bool);
-+ int (*config_msix)(struct alx_hw *, u16, bool, bool);
-+ int (*config_wol)(struct alx_hw *, u32);
-+ int (*config_aspm)(struct alx_hw *, bool, bool);
-+ int (*config_mac_ctrl)(struct alx_hw *);
-+ int (*config_pow_save)(struct alx_hw *, u32,
-+ bool, bool, bool, bool);
-+ int (*reset_pcie)(struct alx_hw *, bool, bool);
-+
-+ /* NVRam function */
-+ int (*check_nvram)(struct alx_hw *, bool *);
-+ int (*read_nvram)(struct alx_hw *, u16, u32 *);
-+ int (*write_nvram)(struct alx_hw *, u16, u32);
-+
-+ /* Others */
-+ int (*get_ethtool_regs)(struct alx_hw *, void *);
-+};
-+
-+struct alx_hw {
-+ struct alx_adapter *adpt;
-+ struct alx_hw_callbacks cbs;
-+ u8 __iomem *hw_addr; /* inner register address */
-+ u16 pci_venid;
-+ u16 pci_devid;
-+ u16 pci_sub_devid;
-+ u16 pci_sub_venid;
-+ u8 pci_revid;
-+
-+ bool long_cable;
-+ bool aps_en;
-+ bool hi_txperf;
-+ bool msi_lnkpatch;
-+ u32 dma_chnl;
-+ u32 hwreg_sz;
-+ u32 eeprom_sz;
-+
-+ /* PHY parameter */
-+ u32 phy_id;
-+ u32 autoneg_advertised;
-+ u32 link_speed;
-+ bool link_up;
-+ spinlock_t mdio_lock;
-+
-+ /* MAC parameter */
-+ enum alx_mac_type mac_type;
-+ u8 mac_addr[ALX_ETH_LENGTH_OF_ADDRESS];
-+ u8 mac_perm_addr[ALX_ETH_LENGTH_OF_ADDRESS];
-+
-+ u32 mtu;
-+ u16 rxstat_reg;
-+ u16 rxstat_sz;
-+ u16 txstat_reg;
-+ u16 txstat_sz;
-+
-+ u16 tx_prod_reg[4];
-+ u16 tx_cons_reg[4];
-+ u16 rx_prod_reg[2];
-+ u16 rx_cons_reg[2];
-+ u64 tpdma[4];
-+ u64 rfdma[2];
-+ u64 rrdma[2];
-+
-+ /* WRR parameter */
-+ enum alx_wrr_mode wrr_mode;
-+ u32 wrr_prio0;
-+ u32 wrr_prio1;
-+ u32 wrr_prio2;
-+ u32 wrr_prio3;
-+
-+ /* RSS parameter */
-+ enum alx_rss_mode rss_mode;
-+ u8 rss_hstype;
-+ u8 rss_base_cpu;
-+ u16 rss_idt_size;
-+ u32 rss_idt[32];
-+ u8 rss_key[40];
-+
-+ /* flow control parameter */
-+ enum alx_fc_mode cur_fc_mode; /* FC mode in effect */
-+ enum alx_fc_mode req_fc_mode; /* FC mode requested by caller */
-+ bool disable_fc_autoneg; /* Do not autonegotiate FC */
-+ bool fc_was_autonegged; /* the result of autonegging */
-+ bool fc_single_pause;
-+
-+ /* Others */
-+ u32 preamble;
-+ u32 intr_mask;
-+ u16 smb_timer;
-+ u16 imt; /* Interrupt Moderator timer (2us) */
-+ u32 flags;
-+};
-+
-+#define ALX_HW_FLAG_L0S_CAP 0x00000001
-+#define ALX_HW_FLAG_L0S_EN 0x00000002
-+#define ALX_HW_FLAG_L1_CAP 0x00000004
-+#define ALX_HW_FLAG_L1_EN 0x00000008
-+#define ALX_HW_FLAG_PWSAVE_CAP 0x00000010
-+#define ALX_HW_FLAG_PWSAVE_EN 0x00000020
-+#define ALX_HW_FLAG_AZ_CAP 0x00000040
-+#define ALX_HW_FLAG_AZ_EN 0x00000080
-+#define ALX_HW_FLAG_PTP_CAP 0x00000100
-+#define ALX_HW_FLAG_PTP_EN 0x00000200
-+#define ALX_HW_FLAG_GIGA_CAP 0x00000400
-+
-+#define ALX_HW_FLAG_PROMISC_EN 0x00010000 /* for mac ctrl reg */
-+#define ALX_HW_FLAG_VLANSTRIP_EN 0x00020000 /* for mac ctrl reg */
-+#define ALX_HW_FLAG_MULTIALL_EN 0x00040000 /* for mac ctrl reg */
-+#define ALX_HW_FLAG_LOOPBACK_EN 0x00080000 /* for mac ctrl reg */
-+
-+#define CHK_HW_FLAG(_flag) CHK_FLAG(hw, HW, _flag)
-+#define SET_HW_FLAG(_flag) SET_FLAG(hw, HW, _flag)
-+#define CLI_HW_FLAG(_flag) CLI_FLAG(hw, HW, _flag)
-+
-+
-+/* RSS hstype Definitions */
-+#define ALX_RSS_HSTYP_IPV4_EN 0x00000001
-+#define ALX_RSS_HSTYP_TCP4_EN 0x00000002
-+#define ALX_RSS_HSTYP_IPV6_EN 0x00000004
-+#define ALX_RSS_HSTYP_TCP6_EN 0x00000008
-+#define ALX_RSS_HSTYP_ALL_EN (\
-+ ALX_RSS_HSTYP_IPV4_EN |\
-+ ALX_RSS_HSTYP_TCP4_EN |\
-+ ALX_RSS_HSTYP_IPV6_EN |\
-+ ALX_RSS_HSTYP_TCP6_EN)
-+
-+
-+/* definitions for flags */
-+
-+#define CHK_FLAG_ARRAY(_st, _idx, _type, _flag) \
-+ ((_st)->flags[_idx] & (ALX_##_type##_FLAG_##_idx##_##_flag))
-+#define CHK_FLAG(_st, _type, _flag) \
-+ ((_st)->flags & (ALX_##_type##_FLAG_##_flag))
-+
-+#define SET_FLAG_ARRAY(_st, _idx, _type, _flag) \
-+ ((_st)->flags[_idx] |= (ALX_##_type##_FLAG_##_idx##_##_flag))
-+#define SET_FLAG(_st, _type, _flag) \
-+ ((_st)->flags |= (ALX_##_type##_FLAG_##_flag))
-+
-+#define CLI_FLAG_ARRAY(_st, _idx, _type, _flag) \
-+ ((_st)->flags[_idx] &= ~(ALX_##_type##_FLAG_##_idx##_##_flag))
-+#define CLI_FLAG(_st, _type, _flag) \
-+ ((_st)->flags &= ~(ALX_##_type##_FLAG_##_flag))
-+
-+int alx_cfg_r16(const struct alx_hw *hw, int reg, u16 *pval);
-+int alx_cfg_w16(const struct alx_hw *hw, int reg, u16 val);
-+
-+
-+void alx_mem_flush(const struct alx_hw *hw);
-+void alx_mem_r32(const struct alx_hw *hw, int reg, u32 *val);
-+void alx_mem_w32(const struct alx_hw *hw, int reg, u32 val);
-+void alx_mem_w8(const struct alx_hw *hw, int reg, u8 val);
-+
-+
-+/* special definitions for hw */
-+#define ALF_MAX_MSIX_NOQUE_INTRS 4
-+#define ALF_MIN_MSIX_NOQUE_INTRS 4
-+#define ALF_MAX_MSIX_QUEUE_INTRS 12
-+#define ALF_MIN_MSIX_QUEUE_INTRS 12
-+#define ALF_MAX_MSIX_INTRS \
-+ (ALF_MAX_MSIX_QUEUE_INTRS + ALF_MAX_MSIX_NOQUE_INTRS)
-+#define ALF_MIN_MSIX_INTRS \
-+ (ALF_MIN_MSIX_NOQUE_INTRS + ALF_MIN_MSIX_QUEUE_INTRS)
-+
-+
-+/* function */
-+extern int alc_init_hw_callbacks(struct alx_hw *hw);
-+extern int alf_init_hw_callbacks(struct alx_hw *hw);
-+
-+/* Logging message functions */
-+void __printf(3, 4) alx_hw_printk(const char *level, const struct alx_hw *hw,
-+ const char *fmt, ...);
-+
-+#define alx_hw_err(_hw, _format, ...) \
-+ alx_hw_printk(KERN_ERR, _hw, _format, ##__VA_ARGS__)
-+#define alx_hw_warn(_hw, _format, ...) \
-+ alx_hw_printk(KERN_WARNING, _hw, _format, ##__VA_ARGS__)
-+#define alx_hw_info(_hw, _format, ...) \
-+ alx_hw_printk(KERN_INFO, _hw, _format, ##__VA_ARGS__)
-+
-+#endif /* _ALX_SW_H_ */
-+
+++ /dev/null
-From 1202ba3f79d5190f18ab3588ad2ea667fca0f273 Mon Sep 17 00:00:00 2001
-From: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
-Date: Thu, 28 Jun 2012 17:20:55 +0300
-Subject: [PATCH 6/6] wireless: adds the 802.11ad / 60 GHz wil6210 driver
-
-This is development snapshot of the driver for Wilocity 60ghz chip
-wil6210
-
-It depends on the 60ghz infrastructure patches submitted to the
-linux-wireless.
-
-What works:
-
-- sniffer. Due to hardware limitation it captures either only
-CP (control PHY) or DP (data PHY) frames
-
-- BSS between 2 peers. Both AP and managed modes supported. Single
-peer is hardware limitation. Iperf gives slightly above 1gbps
-
-Not yet:
-
-- P2P and FST flows
-- after disconnect, upon 2-nd connect hardware goes crazy
-- MSI interrupt
-- various offloads
-
-Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
-Signed-off-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
----
- drivers/net/wireless/ath/Kconfig | 1 +
- drivers/net/wireless/ath/wil6210/Makefile | 20 +
- drivers/net/wireless/ath/wil6210/cfg80211.c | 617 ++++++++++++++
- drivers/net/wireless/ath/wil6210/cfg80211.h | 23 +
- drivers/net/wireless/ath/wil6210/debug.c | 42 +
- drivers/net/wireless/ath/wil6210/debugfs.c | 458 ++++++++++
- drivers/net/wireless/ath/wil6210/ifc.sh | 20 +
- drivers/net/wireless/ath/wil6210/interrupt.c | 324 ++++++++
- drivers/net/wireless/ath/wil6210/main.c | 336 ++++++++
- drivers/net/wireless/ath/wil6210/memdump.sh | 9 +
- drivers/net/wireless/ath/wil6210/netdev.c | 166 ++++
- drivers/net/wireless/ath/wil6210/pcie_bus.c | 239 ++++++
- drivers/net/wireless/ath/wil6210/read_dw.sh | 7 +
- drivers/net/wireless/ath/wil6210/tools/Makefile | 4 +
- drivers/net/wireless/ath/wil6210/tools/trace.c | 190 +++++
- drivers/net/wireless/ath/wil6210/tools/vhex2bin.py | 17 +
- drivers/net/wireless/ath/wil6210/trace.sh | 4 +
- drivers/net/wireless/ath/wil6210/txdesc.sh | 8 +
- drivers/net/wireless/ath/wil6210/txrx.c | 871 ++++++++++++++++++++
- drivers/net/wireless/ath/wil6210/txrx.h | 352 ++++++++
- drivers/net/wireless/ath/wil6210/vrwatch.sh | 6 +
- drivers/net/wireless/ath/wil6210/wil6210.h | 234 ++++++
- drivers/net/wireless/ath/wil6210/wil6210_rgf.h | 93 +++
- drivers/net/wireless/ath/wil6210/wmi.c | 710 ++++++++++++++++
- drivers/net/wireless/ath/wil6210/wmi.h | 837 +++++++++++++++++++
- 25 files changed, 5588 insertions(+)
- create mode 100644 drivers/net/wireless/ath/wil6210/Makefile
- create mode 100644 drivers/net/wireless/ath/wil6210/cfg80211.c
- create mode 100644 drivers/net/wireless/ath/wil6210/cfg80211.h
- create mode 100644 drivers/net/wireless/ath/wil6210/debug.c
- create mode 100644 drivers/net/wireless/ath/wil6210/debugfs.c
- create mode 100755 drivers/net/wireless/ath/wil6210/ifc.sh
- create mode 100644 drivers/net/wireless/ath/wil6210/interrupt.c
- create mode 100644 drivers/net/wireless/ath/wil6210/main.c
- create mode 100755 drivers/net/wireless/ath/wil6210/memdump.sh
- create mode 100644 drivers/net/wireless/ath/wil6210/netdev.c
- create mode 100644 drivers/net/wireless/ath/wil6210/pcie_bus.c
- create mode 100755 drivers/net/wireless/ath/wil6210/read_dw.sh
- create mode 100644 drivers/net/wireless/ath/wil6210/tools/Makefile
- create mode 100644 drivers/net/wireless/ath/wil6210/tools/trace.c
- create mode 100755 drivers/net/wireless/ath/wil6210/tools/vhex2bin.py
- create mode 100755 drivers/net/wireless/ath/wil6210/trace.sh
- create mode 100755 drivers/net/wireless/ath/wil6210/txdesc.sh
- create mode 100644 drivers/net/wireless/ath/wil6210/txrx.c
- create mode 100644 drivers/net/wireless/ath/wil6210/txrx.h
- create mode 100755 drivers/net/wireless/ath/wil6210/vrwatch.sh
- create mode 100644 drivers/net/wireless/ath/wil6210/wil6210.h
- create mode 100644 drivers/net/wireless/ath/wil6210/wil6210_rgf.h
- create mode 100644 drivers/net/wireless/ath/wil6210/wmi.c
- create mode 100644 drivers/net/wireless/ath/wil6210/wmi.h
-
---- a/drivers/net/wireless/ath/Kconfig
-+++ b/drivers/net/wireless/ath/Kconfig
-@@ -26,5 +26,6 @@ source "drivers/net/wireless/ath/ath5k/K
- source "drivers/net/wireless/ath/ath9k/Kconfig"
- source "drivers/net/wireless/ath/carl9170/Kconfig"
- source "drivers/net/wireless/ath/ath6kl/Kconfig"
-+source "drivers/net/wireless/ath/wil6210/Kconfig"
-
- endif
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/Makefile
-@@ -0,0 +1,20 @@
-+obj-$(CONFIG_WIL6210) += wil6210.o
-+
-+wil6210-objs := main.o
-+wil6210-objs += netdev.o
-+wil6210-objs += cfg80211.o
-+wil6210-objs += pcie_bus.o
-+wil6210-objs += debugfs.o
-+wil6210-objs += wmi.o
-+wil6210-objs += interrupt.o
-+wil6210-objs += debug.o
-+wil6210-objs += txrx.o
-+
-+#subdir-ccflags-y += -Werror
-+
-+# Debug Tx/Rx flows
-+#subdir-ccflags-y += -DWIL_DEBUG_TXRX
-+
-+# Use Clear-On-Read
-+subdir-ccflags-y += -DWIL6210_ISR_COR=1
-+
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
-@@ -0,0 +1,615 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/sched.h>
-+#include <linux/etherdevice.h>
-+#include <linux/wireless.h>
-+#include <linux/ieee80211.h>
-+#include <linux/slab.h>
-+#include <linux/version.h>
-+#include <net/cfg80211.h>
-+
-+#include "wil6210.h"
-+#include "cfg80211.h"
-+#include "wmi.h"
-+
-+#define CHAN60G(_channel, _flags) { \
-+ .band = IEEE80211_BAND_60GHZ, \
-+ .center_freq = 56160 + (2160 * (_channel)), \
-+ .hw_value = (_channel), \
-+ .flags = (_flags), \
-+ .max_antenna_gain = 0, \
-+ .max_power = 40, \
-+}
-+
-+static struct ieee80211_channel wil_60ghz_channels[] = {
-+ CHAN60G(1, 0),
-+ CHAN60G(2, 0),
-+ CHAN60G(3, 0),
-+#if 0
-+ CHAN60G(4, 0),
-+#endif
-+};
-+
-+static struct ieee80211_supported_band wil_band_60ghz = {
-+ .channels = wil_60ghz_channels,
-+ .n_channels = ARRAY_SIZE(wil_60ghz_channels),
-+ .ht_cap = {
-+ .ht_supported = true,
-+ .cap = 0, /* TODO */
-+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, /* TODO */
-+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, /* TODO */
-+ .mcs = {
-+ .rx_mask = {0xfe, 0xff, 0xff, 0x0f}, /* 1..27 */
-+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, /* TODO */
-+ },
-+ },
-+};
-+
-+static const struct ieee80211_txrx_stypes
-+wil_mgmt_stypes[NUM_NL80211_IFTYPES] = {
-+ [NL80211_IFTYPE_STATION] = {
-+ .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-+ BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
-+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
-+ },
-+ [NL80211_IFTYPE_P2P_CLIENT] = {
-+ .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-+ BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
-+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
-+ },
-+ [NL80211_IFTYPE_P2P_GO] = {
-+ .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-+ BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
-+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
-+ },
-+};
-+
-+
-+
-+int iftype_nl2wmi(enum nl80211_iftype type)
-+{
-+ static const struct {
-+ enum nl80211_iftype nl;
-+ enum WMI_NETWORK_TYPE wmi;
-+ } __nl2wmi[] = {
-+ {NL80211_IFTYPE_ADHOC, ADHOC_NETWORK},
-+ {NL80211_IFTYPE_STATION, INFRA_NETWORK},
-+ {NL80211_IFTYPE_AP, AP_NETWORK},
-+ {NL80211_IFTYPE_P2P_CLIENT, P2P_NETWORK},
-+ {NL80211_IFTYPE_P2P_GO, P2P_NETWORK},
-+ {NL80211_IFTYPE_MONITOR, ADHOC_NETWORK}, /* FIXME */
-+ #if 0
-+ {NL80211_IFTYPE_AP_VLAN, 0},
-+ {NL80211_IFTYPE_WDS, 0},
-+ {NL80211_IFTYPE_MESH_POINT, 0},
-+ INFRA_NETWORK = 0x01,
-+ ADHOC_NETWORK = 0x02,
-+ ADHOC_CREATOR = 0x04,
-+ AP_NETWORK = 0x10,
-+ P2P_NETWORK = 0x20,
-+ WBE_NETWORK = 0x40,
-+ #endif
-+ };
-+ int i;
-+ for (i = 0; i < ARRAY_SIZE(__nl2wmi); i++) {
-+ if (__nl2wmi[i].nl == type)
-+ return __nl2wmi[i].wmi;
-+ }
-+ return -EOPNOTSUPP;
-+}
-+
-+static int wil_cfg80211_get_station(struct wiphy *wiphy,
-+ struct net_device *ndev,
-+ u8 *mac, struct station_info *sinfo)
-+{
-+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-+ int rc;
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_NOTIFY_REQ_CMD cmd;
-+ } __packed wmi = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 1,
-+ .len = sizeof(wmi.wmi)
-+ + sizeof(wmi.cmd),
-+ },
-+ .wmi = {
-+ .id = WMI_NOTIFY_REQ_CMDID,
-+ .info1 = 0,
-+ },
-+ .cmd = {
-+ .cid = 0,
-+ .interval_usec = 0,
-+ },
-+ };
-+
-+#if 0
-+ wil_info(wil, "%s(%pM)\n", __func__, mac);
-+#endif
-+ if (memcmp(mac, wil->dst_addr[0], ETH_ALEN))
-+ return -ENOENT;
-+ rc = wmi_call(wil, &wmi, WMI_NOTIFY_REQ_DONE_EVENTID, NULL, 0, 20);
-+ if (rc)
-+ return rc;
-+
-+ sinfo->filled |= STATION_INFO_TX_BITRATE;
-+ sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
-+ sinfo->txrate.mcs = wil->stats.bf_mcs;
-+ sinfo->filled |= STATION_INFO_RX_BITRATE;
-+ sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
-+ sinfo->rxrate.mcs = wil->stats.last_mcs_rx;
-+
-+ if (test_bit(wil_status_fwconnected, &wil->status)) {
-+ sinfo->filled |= STATION_INFO_SIGNAL;
-+ sinfo->signal = 12; /* TODO: provide real number */
-+ }
-+
-+ return 0;
-+}
-+
-+static int wil_cfg80211_change_iface(struct wiphy *wiphy,
-+ struct net_device *ndev,
-+ enum nl80211_iftype type, u32 *flags,
-+ struct vif_params *params)
-+{
-+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-+ struct wireless_dev *wdev = wil->wdev;
-+ wil_info(wil, "%s()\n", __func__);
-+
-+ switch (type) {
-+ case NL80211_IFTYPE_STATION:
-+ wil_info(wil, "type: STATION\n");
-+ break;
-+ case NL80211_IFTYPE_AP:
-+ wil_info(wil, "type: AP\n");
-+ break;
-+ case NL80211_IFTYPE_P2P_CLIENT:
-+ wil_info(wil, "type: P2P_CLIENT\n");
-+ break;
-+ case NL80211_IFTYPE_P2P_GO:
-+ wil_info(wil, "type: P2P_GO\n");
-+ break;
-+ case NL80211_IFTYPE_MONITOR:
-+ wil_info(wil, "type: Monitor\n");
-+ if (flags) {
-+ wil_info(wil, "Monitor flags: 0x%08x\n", *flags);
-+ wil->monitor_flags = *flags;
-+ } else {
-+ wil->monitor_flags = 0;
-+ }
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+ wdev->iftype = type;
-+ return 0;
-+}
-+
-+static int wil_cfg80211_scan(struct wiphy *wiphy,
-+ struct cfg80211_scan_request *request)
-+{
-+#if 0
-+ int rc;
-+#endif
-+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-+ struct wireless_dev *wdev = wil->wdev;
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_START_SCAN_CMD scan;
-+ u16 channels[4];
-+ } __packed wmi_scan = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 0,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi)
-+ + sizeof(struct WMI_START_SCAN_CMD),
-+ },
-+ .wmi = {
-+ .id = WMI_START_SCAN_CMDID,
-+ .info1 = 0,
-+ },
-+ .scan = {
-+ },
-+ };
-+#if 0
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_SET_BSS_FILTER_CMD filter;
-+ } __packed wmi_bss_filter = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 0,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi)
-+ + sizeof(struct WMI_SET_BSS_FILTER_CMD),
-+ },
-+ .wmi = {
-+ .id = WMI_SET_BSS_FILTER_CMDID,
-+ .info1 = 0,
-+ },
-+ .filter = {
-+ .bssFilter = ALL_BSS_FILTER,
-+ },
-+ };
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_SET_SCAN_PARAMS_CMD params;
-+ } __packed wmi_scan_params = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 0,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi)
-+ + sizeof(struct WMI_SET_BSS_FILTER_CMD),
-+ },
-+ .wmi = {
-+ .id = WMI_SET_SCAN_PARAMS_CMDID,
-+ .info1 = 0,
-+ },
-+ .params = {
-+ .fg_start_period = 0, /* seconds */
-+ .fg_end_period = 0, /* seconds */
-+ .bg_period = 0, /* seconds */
-+ .maxact_chdwell_time = 0, /* msec */
-+ .pas_chdwell_time = 0, /* msec */
-+ .shortScanRatio = 0, /* how many short scans */
-+ /* for one long */
-+ .scanCtrlFlags = DEFAULT_SCAN_CTRL_FLAGS,
-+ .minact_chdwell_time = 0, /* msec */
-+ .maxact_scan_per_ssid = 0, /* max active scans */
-+ /* per ssid */
-+ .max_dfsch_act_time = 0, /* msecs */
-+ },
-+ };
-+#endif
-+ int i, n;
-+ wil_info(wil, "%s()\n", __func__);
-+ if (wil->scan_request) {
-+ wil_err(wil, "Already scanning\n");
-+ return -EAGAIN;
-+ }
-+ /* check we are client side */
-+ switch (wdev->iftype) {
-+ case NL80211_IFTYPE_STATION:
-+ case NL80211_IFTYPE_P2P_CLIENT:
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+
-+ }
-+ /**
-+ * FW don't support scan after connection attempt
-+ */
-+ if (test_bit(wil_status_dontscan, &wil->status)) {
-+ wil_err(wil, "Scan after connect attempt not supported\n");
-+ return -EBUSY;
-+ }
-+
-+ wil->scan_request = request;
-+ wmi_scan.scan.forceFgScan = 0;
-+ wmi_scan.scan.isLegacy = 0;
-+ wmi_scan.scan.homeDwellTime = 0;
-+ wmi_scan.scan.forceScanInterval = 0;
-+ wmi_scan.scan.scanType = 0;
-+ wmi_scan.scan.numChannels = 0;
-+ n = min(request->n_channels, 4U);
-+ for (i = 0; i < n; i++) {
-+ int ch = ieee80211_frequency_to_channel(
-+ request->channels[i]->center_freq);
-+ if (ch == 0) {
-+ wil_err(wil,
-+ "Scan requested for unknown frequency %dMhz\n",
-+ request->channels[i]->center_freq);
-+ continue;
-+ }
-+ /* 0-based index */
-+ /* TODO convert CPU to LE */
-+ wmi_scan.scan.channelList[wmi_scan.scan.numChannels++] = ch-1;
-+ wil_info(wil, "Scan for ch %d : %d MHz\n", ch,
-+ request->channels[i]->center_freq);
-+ }
-+ wmi_scan.hdr.len += wmi_scan.scan.numChannels *
-+ sizeof(wmi_scan.scan.channelList[0]);
-+#if 0
-+ rc = wmi_send_cmd(wil, &wmi_bss_filter);
-+ if (rc)
-+ return rc;
-+ rc = wmi_send_cmd(wil, &wmi_scan_params);
-+ if (rc)
-+ return rc;
-+#endif
-+ return wmi_send_cmd(wil, &wmi_scan);
-+}
-+
-+static int wil_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
-+ struct cfg80211_connect_params *sme)
-+{
-+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-+ struct wireless_dev *wdev = wil->wdev;
-+ struct cfg80211_bss *bss;
-+ const u8 *ssid_eid;
-+ int rc = 0;
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_CONNECT_CMD conn;
-+ } __packed wmi_conn = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 0,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi)
-+ + sizeof(struct WMI_CONNECT_CMD),
-+ },
-+ .wmi = {
-+ .id = WMI_CONNECT_CMDID,
-+ .info1 = 0,
-+ },
-+ .conn = {
-+ },
-+ };
-+ wil_info(wil, "%s()\n", __func__);
-+ if (sme->channel)
-+ wil_info(wil, "Channel : %d MHz\n",
-+ sme->channel->center_freq);
-+ if (sme->bssid)
-+ wil_info(wil, "BSSID : %pM\n", sme->bssid);
-+ if (sme->ssid && sme->ssid_len)
-+ print_hex_dump(KERN_INFO, "SSID : ", DUMP_PREFIX_NONE, 16, 1,
-+ sme->ssid, sme->ssid_len, true);
-+ bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
-+ sme->ssid, sme->ssid_len,
-+ WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
-+ if (!bss) {
-+ wil_err(wil, "Unable to find BSS\n");
-+ return -ENOENT;
-+ }
-+ ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
-+ if (!ssid_eid) {
-+ wil_err(wil, "No SSID\n");
-+ rc = -ENOENT;
-+ goto out;
-+ }
-+ wmi_conn.conn.networkType = iftype_nl2wmi(wdev->iftype);
-+ /* FIXME Firmware works now in PBSS mode(ToDS=0, FromDS=0) */
-+ wmi_conn.conn.networkType = iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
-+ wmi_conn.conn.dot11AuthMode = OPEN_AUTH; /* TODO: crypto flow */
-+ wmi_conn.conn.authMode = NONE_AUTH; /* TODO: crypto flow */
-+ /* wmi_conn.conn.pairwiseCryptoType; */
-+ /* wmi_conn.conn.pairwiseCryptoLen; */
-+ wmi_conn.conn.groupCryptoType = NONE_CRYPT; /* TODO: crypto flow */
-+ /* wmi_conn.conn.groupCryptoLen; */
-+ wmi_conn.conn.ssidLength = min_t(u8, ssid_eid[1], 32);
-+ memcpy(wmi_conn.conn.ssid, ssid_eid+2, wmi_conn.conn.ssidLength);
-+ {
-+ int ch = ieee80211_frequency_to_channel(
-+ bss->channel->center_freq);
-+ if (ch == 0) {
-+ wil_err(wil, "BSS at unknown frequency %dMhz\n",
-+ bss->channel->center_freq);
-+ rc = -EOPNOTSUPP;
-+ goto out;
-+ }
-+ wmi_conn.conn.channel = ch - 1;
-+ }
-+ memcpy(wmi_conn.conn.bssid, bss->bssid, 6);
-+ wmi_conn.conn.ctrl_flags = 0; /* TODO: set real value */
-+ memcpy(wmi_conn.conn.destMacAddr, bss->bssid, 6);
-+ /**
-+ * FW don't support scan after connection attempt
-+ */
-+ set_bit(wil_status_dontscan, &wil->status);
-+ rc = wmi_send_cmd(wil, &wmi_conn);
-+ if (rc == 0) {
-+ /* Connect can take lots of time */
-+ mod_timer(&wil->connect_timer,
-+ jiffies + msecs_to_jiffies(2000));
-+ }
-+ out:
-+ cfg80211_put_bss(bss);
-+ return rc;
-+}
-+
-+static int wil_cfg80211_disconnect(struct wiphy *wiphy,
-+ struct net_device *ndev,
-+ u16 reason_code)
-+{
-+ int rc;
-+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ } __packed wmi_conn = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 0,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi),
-+ },
-+ .wmi = {
-+ .id = WMI_DISCONNECT_CMDID,
-+ .info1 = 0,
-+ },
-+ };
-+ wil_info(wil, "%s()\n", __func__);
-+ rc = wmi_send_cmd(wil, &wmi_conn);
-+ return rc;
-+}
-+
-+static int wil_cfg80211_set_txpower(struct wiphy *wiphy,
-+ enum nl80211_tx_power_setting type, int mbm)
-+{
-+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-+ wil_info(wil, "%s()\n", __func__);
-+ return 0;
-+}
-+
-+static int wil_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
-+{
-+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-+ wil_info(wil, "%s()\n", __func__);
-+
-+ *dbm = 43;
-+
-+ return 0;
-+}
-+
-+static int wil_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
-+ struct ieee80211_channel *chan, bool offchan,
-+ enum nl80211_channel_type channel_type,
-+ bool channel_type_valid, unsigned int wait,
-+ const u8 *buf, size_t len, bool no_cck,
-+ bool dont_wait_for_ack,
-+ u64 *cookie)
-+{
-+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-+ wil_info(wil, "%s()\n", __func__);
-+ print_hex_dump(KERN_INFO, "mgmt_tx ", DUMP_PREFIX_OFFSET, 16, 1,
-+ buf, len, true);
-+ return 0;
-+}
-+
-+static void wil_mgmt_frame_register(struct wiphy *wiphy,
-+ struct wireless_dev *wdev, u16 frame_type, bool reg)
-+{
-+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-+ wil_info(wil, "%s()\n", __func__);
-+ wil_info(wil, "frame_type = 0x%04x, reg = %d\n", frame_type, reg);
-+}
-+
-+static int wil_set_monitor_channel(struct wiphy *wiphy,
-+#if defined(OLD_SET_CHANNEL_API)
-+ struct net_device *dev,
-+#endif
-+ struct ieee80211_channel *chan,
-+ enum nl80211_channel_type channel_type)
-+{
-+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-+ wil_info(wil, "%s()\n", __func__);
-+ wil_info(wil, "freq = %d\n", chan->center_freq);
-+ wil->monitor_chan = chan;
-+ return 0;
-+}
-+
-+static struct cfg80211_ops wil_cfg80211_ops = {
-+ .scan = wil_cfg80211_scan,
-+ .connect = wil_cfg80211_connect,
-+ .disconnect = wil_cfg80211_disconnect,
-+ .set_tx_power = wil_cfg80211_set_txpower,
-+ .get_tx_power = wil_cfg80211_get_txpower,
-+ .change_virtual_intf = wil_cfg80211_change_iface,
-+ .get_station = wil_cfg80211_get_station,
-+ .mgmt_tx = wil_mgmt_tx,
-+ .mgmt_frame_register = wil_mgmt_frame_register,
-+#if defined(OLD_SET_CHANNEL_API)
-+ .set_channel = wil_set_monitor_channel,
-+#else
-+ .set_monitor_channel = wil_set_monitor_channel,
-+#endif /* defined(NEW_SET_CHANNEL_API) */
-+};
-+
-+static const u32 cipher_suites[] = {
-+ WLAN_CIPHER_SUITE_CCMP, /* keep for debug, TODO: remove */
-+ WLAN_CIPHER_SUITE_GCMP,
-+};
-+
-+static void wil_wiphy_init(struct wiphy *wiphy)
-+{
-+ /* TODO: figure this out */
-+ wiphy->max_scan_ssids = 10;
-+#if 0
-+ wiphy->max_num_pmkids = UMAC_MAX_NUM_PMKIDS;
-+#endif
-+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-+ BIT(NL80211_IFTYPE_AP) |
-+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
-+ BIT(NL80211_IFTYPE_P2P_GO) |
-+ BIT(NL80211_IFTYPE_MONITOR);
-+
-+ wiphy->bands[IEEE80211_BAND_60GHZ] = &wil_band_60ghz;
-+
-+ /* TODO: figure this out */
-+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-+
-+ wiphy->cipher_suites = cipher_suites;
-+ wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-+ wiphy->mgmt_stypes = wil_mgmt_stypes;
-+}
-+
-+struct wireless_dev *wil_cfg80211_init(struct device *dev)
-+{
-+ int r = 0;
-+ struct wireless_dev *wdev;
-+
-+ wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
-+ if (!wdev)
-+ return ERR_PTR(-ENOMEM);
-+
-+ wdev->wiphy = wiphy_new(&wil_cfg80211_ops,
-+ sizeof(struct wil6210_priv));
-+ if (!wdev->wiphy) {
-+ r = -ENOMEM;
-+ goto out;
-+ }
-+
-+ set_wiphy_dev(wdev->wiphy, dev);
-+ wil_wiphy_init(wdev->wiphy);
-+ r = wiphy_register(wdev->wiphy);
-+
-+ if (r < 0)
-+ goto out_failed_reg;
-+
-+ return wdev;
-+
-+out_failed_reg:
-+ wiphy_free(wdev->wiphy);
-+out:
-+ kfree(wdev);
-+ return ERR_PTR(r);
-+}
-+
-+void wil_wdev_free(struct wil6210_priv *wil)
-+{
-+ struct wireless_dev *wdev = wil_to_wdev(wil);
-+ struct device *dev = wil_to_dev(wil);
-+ dev_info(dev, "%s()\n", __func__);
-+
-+ if (!wdev)
-+ return;
-+
-+ wiphy_unregister(wdev->wiphy);
-+ wiphy_free(wdev->wiphy);
-+ kfree(wdev);
-+}
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/cfg80211.h
-@@ -0,0 +1,23 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef __wil_CFG80211_H__
-+#define __wil_CFG80211_H__
-+
-+struct wireless_dev *wil_cfg80211_init(struct device *dev);
-+void wil_wdev_free(struct wil6210_priv *wil);
-+
-+#endif /* __wil_CFG80211_H__ */
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/debug.c
-@@ -0,0 +1,42 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include "wil6210.h"
-+#include "wmi.h"
-+
-+static struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ u32 val;
-+} __packed wmi_echo = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 1,
-+ .len = 8 + 4,
-+ },
-+ .wmi = {
-+ .id = WMI_ECHO_CMDID,
-+ .info1 = 0,
-+ },
-+ .val = 0x12345678,
-+};
-+
-+void send_echo(struct wil6210_priv *wil)
-+{
-+ wmi_call(wil, &wmi_echo, WMI_ECHO_RSP_EVENTID, NULL, 0, 20);
-+}
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
-@@ -0,0 +1,458 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/debugfs.h>
-+#include <linux/seq_file.h>
-+#include <linux/pci.h>
-+#include <linux/rtnetlink.h>
-+
-+#include "wil6210.h"
-+#include "wil6210_rgf.h"
-+#include "txrx.h"
-+
-+static void print_vring(struct seq_file *s, struct wil6210_priv *wil,
-+ const char *name, struct vring *vring)
-+{
-+ void __iomem *x = wmi_addr(wil, vring->hwtail);
-+ seq_printf(s, "VRING %s = {\n", name);
-+ seq_printf(s, " pa = 0x%016llx\n", (unsigned long long)vring->pa);
-+ seq_printf(s, " va = 0x%p\n", vring->va);
-+ seq_printf(s, " size = %d\n", vring->size);
-+ seq_printf(s, " swtail = %d\n", vring->swtail);
-+ seq_printf(s, " swhead = %d\n", vring->swhead);
-+ seq_printf(s, " hwtail = [0x%08x] -> ", vring->hwtail);
-+ if (x)
-+ seq_printf(s, "0x%08x\n", ioread32(x));
-+ else
-+ seq_printf(s, "???\n");
-+ if (vring->va && (vring->size < 1025)) {
-+ int i;
-+ for (i = 0; i < vring->size; i++) {
-+ struct vring_tx_desc *d = &vring->va[i].tx;
-+ if ((i % 64) == 0 && (i != 0))
-+ seq_printf(s, "\n");
-+ seq_printf(s, "%s", (d->dma.status & BIT(0)) ?
-+ "S" : (vring->ctx[i] ? "H" : "h"));
-+ }
-+ seq_printf(s, "\n");
-+ }
-+ seq_printf(s, "}\n");
-+}
-+
-+static int vring_debugfs_show(struct seq_file *s, void *data)
-+{
-+ int i;
-+ struct wil6210_priv *wil = s->private;
-+ print_vring(s, wil, "rx", &wil->vring_rx);
-+ for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
-+ struct vring *vring = &(wil->vring_tx[i]);
-+ if (vring->va) {
-+ char name[10];
-+ snprintf(name, sizeof(name), "tx_%2d", i);
-+ print_vring(s, wil, name, vring);
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int vring_seq_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, vring_debugfs_show, inode->i_private);
-+}
-+
-+static const struct file_operations fops_vring = {
-+ .open = vring_seq_open,
-+ .release = single_release,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+};
-+
-+static void print_ring(struct seq_file *s, const char *prefix
-+ , void __iomem *off)
-+{
-+ struct wil6210_priv *wil = s->private;
-+ struct wil6210_mbox_ring r;
-+ int rsize;
-+ int i;
-+ memcpy_fromio_32(&r, off, sizeof(r));
-+ /*
-+ * we just read memory block from NIC. This memory may be
-+ * garbage. Check validity before using it.
-+ */
-+ rsize = r.size / sizeof(struct wil6210_mbox_ring_desc);
-+ seq_printf(s, "ring %s = {\n", prefix);
-+ seq_printf(s, " base = 0x%08x\n", r.base);
-+ seq_printf(s, " size = 0x%04x bytes -> %d entries\n", r.size, rsize);
-+ seq_printf(s, " tail = 0x%08x\n", r.tail);
-+ seq_printf(s, " head = 0x%08x\n", r.head);
-+ if (r.size % sizeof(struct wil6210_mbox_ring_desc)) {
-+ seq_printf(s, " ??? size is not multiple of %zd, garbage?\n",
-+ sizeof(struct wil6210_mbox_ring_desc));
-+ goto out;
-+ }
-+ if (!wmi_addr(wil, r.base) ||
-+ !wmi_addr(wil, r.tail) ||
-+ !wmi_addr(wil, r.head)) {
-+ seq_printf(s, " ??? pointers are garbage?\n");
-+ goto out;
-+ }
-+ for (i = 0; i < rsize; i++) {
-+ struct wil6210_mbox_ring_desc d;
-+ struct wil6210_mbox_hdr hdr;
-+ size_t delta = i * sizeof(d);
-+ void __iomem *x = wil->csr + HOSTADDR(r.base)
-+ + delta;
-+ memcpy_fromio_32(&d, x, sizeof(d));
-+ seq_printf(s, " [%2x] %s %s%s 0x%08x", i,
-+ d.sync ? "F" : "E",
-+ (r.tail - r.base == delta) ? "t" : " ",
-+ (r.head - r.base == delta) ? "h" : " ",
-+ d.addr);
-+ if (0 == wmi_read_hdr(wil, d.addr, &hdr)) {
-+ seq_printf(s, " -> %04x %04x %04x %02x %02x\n",
-+ hdr.seq, hdr.ctx, hdr.type, hdr.flags, hdr.len);
-+ if (hdr.len <= MAX_MBOXITEM_SIZE) {
-+ int n = 0;
-+ unsigned char printbuf[16 * 3 + 2];
-+ unsigned char databuf[MAX_MBOXITEM_SIZE];
-+ void __iomem *src = wmi_buffer(wil, d.addr)
-+ + sizeof(struct wil6210_mbox_hdr);
-+ /*
-+ * No need to check @src for validity -
-+ * we already validated @d.addr while
-+ * reading header
-+ */
-+ memcpy_fromio_32(databuf, src, hdr.len);
-+ while (n < hdr.len) {
-+ int l = min(hdr.len - n, 16);
-+ hex_dump_to_buffer(databuf + n, l,
-+ 16, 1, printbuf,
-+ sizeof(printbuf),
-+ false);
-+ seq_printf(s, " : %s\n", printbuf);
-+ n += l;
-+ }
-+ }
-+ } else
-+ seq_printf(s, "\n");
-+ }
-+ out:
-+ seq_printf(s, "}\n");
-+}
-+
-+static int mbox_debugfs_show(struct seq_file *s, void *data)
-+{
-+ struct wil6210_priv *wil = s->private;
-+ print_ring(s, "tx", wil->csr + HOST_MBOX
-+ + offsetof(struct wil6210_mbox_ctl, tx));
-+ print_ring(s, "rx", wil->csr + HOST_MBOX
-+ + offsetof(struct wil6210_mbox_ctl, rx));
-+ return 0;
-+}
-+
-+static int mbox_seq_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, mbox_debugfs_show, inode->i_private);
-+}
-+
-+static const struct file_operations fops_mbox = {
-+ .open = mbox_seq_open,
-+ .release = single_release,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+};
-+
-+static int debugfs_iomem_x32_set(void *data, u64 val)
-+{
-+ iowrite32(val, (void __iomem *)data);
-+ wmb();
-+ return 0;
-+}
-+
-+static int debugfs_iomem_x32_get(void *data, u64 *val)
-+{
-+ *val = ioread32((void __iomem *)data);
-+ return 0;
-+}
-+
-+DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, debugfs_iomem_x32_get,
-+ debugfs_iomem_x32_set, "0x%08llx\n");
-+
-+static struct dentry *debugfs_create_iomem_x32(const char *name, mode_t mode,
-+ struct dentry *parent, void __iomem *value)
-+{
-+ return debugfs_create_file(name, mode, parent,
-+ (void * __force)value, &fops_iomem_x32);
-+}
-+
-+static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil,
-+ const char *name, struct dentry *parent, u32 off) {
-+ struct dentry *d = debugfs_create_dir(name, parent);
-+ if (IS_ERR_OR_NULL(d))
-+ return -ENODEV;
-+ debugfs_create_iomem_x32("ICC", S_IRUGO | S_IWUGO, d,
-+ wil->csr + off);
-+ debugfs_create_iomem_x32("ICR", S_IRUGO | S_IWUGO, d,
-+ wil->csr + off + 4);
-+ debugfs_create_iomem_x32("ICM", S_IRUGO | S_IWUGO, d,
-+ wil->csr + off + 8);
-+ debugfs_create_iomem_x32("ICS", S_IWUGO, d,
-+ wil->csr + off + 12);
-+ debugfs_create_iomem_x32("IMV", S_IRUGO | S_IWUGO, d,
-+ wil->csr + off + 16);
-+ debugfs_create_iomem_x32("IMS", S_IWUGO, d,
-+ wil->csr + off + 20);
-+ debugfs_create_iomem_x32("IMC", S_IWUGO, d,
-+ wil->csr + off + 24);
-+ return 0;
-+}
-+
-+static u32 mem_addr;
-+
-+static int memread_debugfs_show(struct seq_file *s, void *data)
-+{
-+ struct wil6210_priv *wil = s->private;
-+ void __iomem *a = wmi_buffer(wil, mem_addr);
-+ if (a)
-+ seq_printf(s, "[0x%08x] = 0x%08x\n", mem_addr, ioread32(a));
-+ else
-+ seq_printf(s, "[0x%08x] = INVALID\n", mem_addr);
-+ return 0;
-+}
-+
-+static int memread_seq_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, memread_debugfs_show, inode->i_private);
-+}
-+
-+static const struct file_operations fops_memread = {
-+ .open = memread_seq_open,
-+ .release = single_release,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+};
-+
-+static int default_open(struct inode *inode, struct file *file)
-+{
-+ if (inode->i_private)
-+ file->private_data = inode->i_private;
-+
-+ return 0;
-+}
-+
-+static ssize_t read_file_ioblob(struct file *file, char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ enum { max_count = 4096 };
-+ struct debugfs_blob_wrapper *blob = file->private_data;
-+ loff_t pos = *ppos;
-+ size_t available = blob->size;
-+ void *buf;
-+ size_t ret;
-+ if (pos < 0)
-+ return -EINVAL;
-+ if (pos >= available || !count)
-+ return 0;
-+ if (count > available - pos)
-+ count = available - pos;
-+ if (count > max_count)
-+ count = max_count;
-+ buf = kmalloc(count, GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+ memcpy_fromio_32(buf, (const volatile void __iomem *)blob->data + pos,
-+ count);
-+ ret = copy_to_user(user_buf, buf, count);
-+ kfree(buf);
-+ if (ret == count)
-+ return -EFAULT;
-+ count -= ret;
-+ *ppos = pos + count;
-+ return count;
-+}
-+
-+static const struct file_operations fops_ioblob = {
-+ .read = read_file_ioblob,
-+ .open = default_open,
-+ .llseek = default_llseek,
-+};
-+
-+static struct dentry *debugfs_create_ioblob(const char *name, mode_t mode,
-+ struct dentry *parent,
-+ struct debugfs_blob_wrapper *blob)
-+{
-+ return debugfs_create_file(name, mode, parent, blob, &fops_ioblob);
-+}
-+/*---reset---*/
-+static ssize_t write_file_reset(struct file *file, const char __user *buf,
-+ size_t len, loff_t *ppos)
-+{
-+ struct wil6210_priv *wil = file->private_data;
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ /**
-+ * BUG:
-+ * this code does NOT sync device state with the rest of system
-+ * use with care, debug only!!!
-+ */
-+ rtnl_lock();
-+ dev_close(ndev);
-+ ndev->flags &= ~IFF_UP;
-+ rtnl_unlock();
-+ wil_reset(wil);
-+ return len;
-+}
-+
-+static const struct file_operations fops_reset = {
-+ .write = write_file_reset,
-+ .open = default_open,
-+};
-+/*---------Tx descriptor------------*/
-+
-+static u32 dbg_txdesc_index; /* = 0; */
-+
-+static int txdesc_debugfs_show(struct seq_file *s, void *data)
-+{
-+ struct wil6210_priv *wil = s->private;
-+ struct vring *vring = &(wil->vring_tx[0]);
-+ if (!vring->va) {
-+ seq_printf(s, "No Tx VRING\n");
-+ return 0;
-+ }
-+ if (dbg_txdesc_index < vring->size) {
-+ struct vring_tx_desc *d = &(vring->va[dbg_txdesc_index].tx);
-+ u32 *u = (u32 *)d;
-+ struct sk_buff *skb = vring->ctx[dbg_txdesc_index];
-+ seq_printf(s, "Tx[%3d] = {\n", dbg_txdesc_index);
-+ seq_printf(s, " MAC = 0x%08x 0x%08x 0x%08x 0x%08x\n",
-+ u[0], u[1], u[2], u[3]);
-+ seq_printf(s, " DMA = 0x%08x 0x%08x 0x%08x 0x%08x\n",
-+ u[4], u[5], u[6], u[7]);
-+ seq_printf(s, " SKB = %p\n", skb);
-+ if (skb) {
-+ unsigned char printbuf[16 * 3 + 2];
-+ int i = 0;
-+ int len = skb_headlen(skb);
-+ void *p = skb->data;
-+ seq_printf(s, " len = %d\n", len);
-+ while (i < len) {
-+ int l = min(len - i, 16);
-+ hex_dump_to_buffer(p + i, l, 16, 1
-+ , printbuf, sizeof(printbuf)
-+ , false);
-+ seq_printf(s, " : %s\n", printbuf);
-+ i += l;
-+ }
-+ }
-+ seq_printf(s, "}\n");
-+ } else {
-+ seq_printf(s, "TxDesc index (%d) >= size (%d)\n",
-+ dbg_txdesc_index, vring->size);
-+ }
-+ return 0;
-+}
-+
-+static int txdesc_seq_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, txdesc_debugfs_show, inode->i_private);
-+}
-+
-+static const struct file_operations fops_txdesc = {
-+ .open = txdesc_seq_open,
-+ .release = single_release,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+};
-+/*----------------*/
-+int wil6210_debugfs_init(struct wil6210_priv *wil)
-+{
-+ struct dentry *pseudo;
-+ struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME,
-+ wil_to_wiphy(wil)->debugfsdir);
-+
-+ if (IS_ERR_OR_NULL(dbg))
-+ return -ENODEV;
-+ debugfs_create_file("mbox", S_IRUGO, dbg, wil, &fops_mbox);
-+ debugfs_create_file("vrings", S_IRUGO, dbg, wil, &fops_vring);
-+ debugfs_create_file("txdesc", S_IRUGO, dbg, wil, &fops_txdesc);
-+ debugfs_create_u32("txdesc_index", S_IRUGO | S_IWUGO, dbg,
-+ &dbg_txdesc_index);
-+ wil6210_debugfs_create_ISR(wil, "USER_ICR", dbg
-+ , HOSTADDR(RGF_USER_USER_ICR));
-+ wil6210_debugfs_create_ISR(wil, "DMA_EP_TX_ICR", dbg
-+ , HOSTADDR(RGF_DMA_EP_TX_ICR));
-+ wil6210_debugfs_create_ISR(wil, "DMA_EP_RX_ICR", dbg
-+ , HOSTADDR(RGF_DMA_EP_RX_ICR));
-+ wil6210_debugfs_create_ISR(wil, "DMA_EP_MISC_ICR", dbg
-+ , HOSTADDR(RGF_DMA_EP_MISC_ICR));
-+ pseudo = debugfs_create_dir("PSEUDO_ISR", dbg);
-+ if (!IS_ERR_OR_NULL(pseudo)) {
-+ debugfs_create_iomem_x32("CAUSE", S_IRUGO, pseudo,
-+ wil->csr + HOSTADDR(RGF_DMA_PSEUDO_CAUSE));
-+ debugfs_create_iomem_x32("MASK_SW", S_IRUGO, pseudo,
-+ wil->csr + HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW));
-+ debugfs_create_iomem_x32("MASK_FW", S_IRUGO, pseudo,
-+ wil->csr + HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_FW));
-+ }
-+ {
-+ struct dentry *rst = debugfs_create_dir("Reset", dbg);
-+ if (!IS_ERR_OR_NULL(rst)) {
-+ debugfs_create_iomem_x32("vec0", S_IRUGO | S_IWUGO, rst,
-+ wil->csr + HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_0));
-+ debugfs_create_iomem_x32("vec1", S_IRUGO | S_IWUGO, rst,
-+ wil->csr + HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_1));
-+ debugfs_create_iomem_x32("vec2", S_IRUGO | S_IWUGO, rst,
-+ wil->csr + HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_2));
-+ debugfs_create_iomem_x32("vec3", S_IRUGO | S_IWUGO, rst,
-+ wil->csr + HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_3));
-+ }
-+ }
-+ debugfs_create_u32("mem_addr", S_IRUGO | S_IWUGO, dbg, &mem_addr);
-+ debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread);
-+ debugfs_create_file("reset", S_IWUGO, dbg, wil, &fops_reset);
-+
-+ wil->rgf_blob.data = (void * __force)wil->csr + 0;
-+ wil->rgf_blob.size = 0xa000;
-+ debugfs_create_ioblob("blob_rgf", S_IRUGO, dbg, &wil->rgf_blob);
-+ wil->fw_code_blob.data = (void * __force)wil->csr + 0x40000;
-+ wil->fw_code_blob.size = 0x40000;
-+ debugfs_create_ioblob("blob_fw_code", S_IRUGO, dbg,
-+ &wil->fw_code_blob);
-+ wil->fw_data_blob.data = (void * __force)wil->csr + 0x80000;
-+ wil->fw_data_blob.size = 0x8000;
-+ debugfs_create_ioblob("blob_fw_data", S_IRUGO, dbg,
-+ &wil->fw_data_blob);
-+ wil->fw_peri_blob.data = (void * __force)wil->csr + 0x88000;
-+ wil->fw_peri_blob.size = 0x18000;
-+ debugfs_create_ioblob("blob_fw_peri", S_IRUGO, dbg,
-+ &wil->fw_peri_blob);
-+ wil->uc_code_blob.data = (void * __force)wil->csr + 0xa0000;
-+ wil->uc_code_blob.size = 0x8000;
-+ debugfs_create_ioblob("blob_uc_code", S_IRUGO, dbg,
-+ &wil->uc_code_blob);
-+ wil->uc_data_blob.data = (void * __force)wil->csr + 0xa8000;
-+ wil->uc_data_blob.size = 0x2000;
-+ debugfs_create_ioblob("blob_uc_data", S_IRUGO, dbg,
-+ &wil->uc_data_blob);
-+
-+ return 0;
-+}
-+
-+void wil6210_debugfs_remove(struct wil6210_priv *wil)
-+{
-+ debugfs_remove_recursive(wil->debug);
-+ wil->debug = NULL;
-+}
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/ifc.sh
-@@ -0,0 +1,20 @@
-+#!/bin/bash
-+
-+#
-+# Print and set $WLAN to the name of the
-+# network interface for the 'wil6210' driver
-+#
-+
-+DRV="wil6210"
-+
-+for f in /sys/class/net/*; do {
-+ drv=`readlink $f/device/driver`;
-+ drv=${drv##.*/}
-+ if [[ $drv == $DRV ]]; then {
-+ ifc=${f#/sys/class/net/}
-+ echo $ifc
-+ export WLAN=$ifc
-+ break
-+ } ; fi
-+} ; done
-+
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
-@@ -0,0 +1,324 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/interrupt.h>
-+
-+#include "wil6210.h"
-+#include "wil6210_rgf.h"
-+
-+/**
-+ * Theory of operation:
-+ *
-+ * There is ISR pseudo-cause register,
-+ * dma_rgf->DMA_RGF.PSEUDO_CAUSE.PSEUDO_CAUSE
-+ * Its bits represents OR'ed bits from 3 real ISR registers:
-+ * TX, RX, and MISC.
-+ *
-+ * Registers may be configured to either "write 1 to clear" or
-+ * "clear on read" mode
-+ *
-+ * When handling interrupt, one have to mask/unmask interrupts for the
-+ * real ISR registers, or hardware may malfunction.
-+ *
-+ */
-+
-+#define WIL6210_IRQ_DISABLE (0xFFFFFFFFUL)
-+#define WIL6210_IMC_RX BIT_DMA_EP_RX_ICR_RX_DONE
-+#define WIL6210_IMC_TX (BIT_DMA_EP_TX_ICR_TX_DONE | \
-+ BIT_DMA_EP_TX_ICR_TX_DONE_N(0))
-+#define WIL6210_IMC_MISC (ISR_MISC_FW_READY | ISR_MISC_MBOX_EVT)
-+
-+static inline u32 ioread32_and_clear(void __iomem *addr)
-+{
-+ u32 x = ioread32(addr);
-+#if !defined(WIL6210_ISR_COR)
-+ iowrite32(x, addr);
-+#endif
-+ return x;
-+}
-+
-+static void wil6210_mask_irq(struct wil6210_priv *wil)
-+{
-+#if 0
-+ wil_info(wil, "%s()\n", __func__);
-+#endif
-+ clear_bit(wil_status_irqen, &wil->status);
-+ iowrite32(WIL6210_IRQ_DISABLE, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
-+ offsetof(struct RGF_ICR, IMS));
-+ iowrite32(WIL6210_IRQ_DISABLE, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
-+ offsetof(struct RGF_ICR, IMS));
-+ iowrite32(WIL6210_IRQ_DISABLE, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
-+ offsetof(struct RGF_ICR, IMS));
-+}
-+
-+static void wil6210_unmask_irq(struct wil6210_priv *wil)
-+{
-+ iowrite32(WIL6210_IMC_RX, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
-+ offsetof(struct RGF_ICR, IMC));
-+ iowrite32(WIL6210_IMC_TX, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
-+ offsetof(struct RGF_ICR, IMC));
-+ iowrite32(WIL6210_IMC_MISC, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
-+ offsetof(struct RGF_ICR, IMC));
-+ set_bit(wil_status_irqen, &wil->status);
-+}
-+
-+void wil6210_disable_irq(struct wil6210_priv *wil)
-+{
-+ wil6210_mask_irq(wil);
-+}
-+
-+void wil6210_enable_irq(struct wil6210_priv *wil)
-+{
-+#if 0
-+ wil_info(wil, "%s()\n", __func__);
-+#endif
-+#if defined(WIL6210_ISR_COR)
-+ /* configure to Clear-On-Read */
-+ iowrite32(0xFFFFFFFFUL, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
-+ offsetof(struct RGF_ICR, ICC));
-+ iowrite32(0xFFFFFFFFUL, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
-+ offsetof(struct RGF_ICR, ICC));
-+ iowrite32(0xFFFFFFFFUL, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
-+ offsetof(struct RGF_ICR, ICC));
-+#else
-+ iowrite32(0, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
-+ offsetof(struct RGF_ICR, ICC));
-+ iowrite32(0, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
-+ offsetof(struct RGF_ICR, ICC));
-+ iowrite32(0, wil->csr +
-+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
-+ offsetof(struct RGF_ICR, ICC));
-+#endif
-+
-+ wil6210_unmask_irq(wil);
-+}
-+
-+static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
-+{
-+ struct wil6210_priv *wil = cookie;
-+ u32 isr = wil->isr_rx;
-+#if 0
-+ wil_info(wil, "ISR RX 0x%08x\n", isr);
-+#endif
-+ if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) {
-+#if 0
-+ wil_info(wil, "RX done\n");
-+#endif
-+ isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE;
-+ rx_handle(wil);
-+ }
-+ if (isr)
-+ wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr);
-+ return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
-+{
-+ struct wil6210_priv *wil = cookie;
-+ u32 isr = wil->isr_tx;
-+#if 0
-+ wil_info(wil, "ISR TX 0x%08x\n", isr);
-+#endif
-+ if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) {
-+ int i;
-+#if 0
-+ wil_info(wil, "TX done\n");
-+#endif
-+ isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
-+ for (i = 0; i < 24; i++) {
-+ u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i);
-+ if (isr & mask) {
-+ isr &= ~mask;
-+#if 0
-+ wil_info(wil, "TX done(%i)\n", i);
-+#endif
-+ tx_complete(wil, i);
-+ }
-+ }
-+ }
-+ if (isr)
-+ wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr);
-+ return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
-+{
-+ struct wil6210_priv *wil = cookie;
-+ u32 isr = wil->isr_misc;
-+#if 0
-+ wil_info(wil, "ISR MISC 0x%08x\n", isr);
-+#endif
-+ if (isr & ISR_MISC_FW_READY) {
-+ wil_info(wil, "IRQ: FW ready\n");
-+ /**
-+ * Actual FW ready indicated by the
-+ * WMI_FW_READY_EVENTID
-+ */
-+ isr &= ~ISR_MISC_FW_READY;
-+ }
-+ if (isr & ISR_MISC_MBOX_EVT) {
-+#if 0
-+ wil_info(wil, "MBOX event\n");
-+#endif
-+ wmi_recv_cmd(wil);
-+ isr &= ~ISR_MISC_MBOX_EVT;
-+ }
-+ if (isr)
-+ wil_err(wil, "un-handled MISC ISR bits 0x%08x\n", isr);
-+ return IRQ_HANDLED;
-+}
-+
-+/**
-+ * thread IRQ handler
-+ */
-+static irqreturn_t wil6210_thread_irq(int irq, void *cookie)
-+{
-+ struct wil6210_priv *wil = cookie;
-+#if 0
-+ wil_info(wil, "Thread IRQ\n");
-+#endif
-+ /* Discover real IRQ cause */
-+ if (wil->isr_misc) {
-+ wil6210_irq_misc(irq, cookie);
-+ wil->isr_misc = 0;
-+ }
-+ wil6210_unmask_irq(wil);
-+ return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t wil6210_hardirq(int irq, void *cookie)
-+{
-+ irqreturn_t rc = IRQ_HANDLED;
-+ struct wil6210_priv *wil = cookie;
-+ u32 pseudo_cause = ioread32(wil->csr +
-+ HOSTADDR(RGF_DMA_PSEUDO_CAUSE));
-+ /**
-+ * pseudo_cause is Clear-On-Read, no need to ACK
-+ */
-+ if ((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff))
-+ return IRQ_NONE;
-+ /* FIXME: IRQ mask debug */
-+ if (!test_bit(wil_status_irqen, &wil->status)) {
-+ u32 icm_rx = ioread32_and_clear(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
-+ offsetof(struct RGF_ICR, ICM));
-+ u32 icr_rx = ioread32_and_clear(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
-+ offsetof(struct RGF_ICR, ICR));
-+ u32 imv_rx = ioread32(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
-+ offsetof(struct RGF_ICR, IMV));
-+ u32 icm_tx = ioread32_and_clear(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
-+ offsetof(struct RGF_ICR, ICM));
-+ u32 icr_tx = ioread32_and_clear(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
-+ offsetof(struct RGF_ICR, ICR));
-+ u32 imv_tx = ioread32(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
-+ offsetof(struct RGF_ICR, IMV));
-+ u32 icm_misc = ioread32_and_clear(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
-+ offsetof(struct RGF_ICR, ICM));
-+ u32 icr_misc = ioread32_and_clear(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
-+ offsetof(struct RGF_ICR, ICR));
-+ u32 imv_misc = ioread32(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
-+ offsetof(struct RGF_ICR, IMV));
-+ wil_err(wil, "IRQ when it should be masked: pseudo 0x%08x\n"
-+ "Rx icm:icr:imv 0x%08x 0x%08x 0x%08x\n"
-+ "Tx icm:icr:imv 0x%08x 0x%08x 0x%08x\n"
-+ "Misc icm:icr:imv 0x%08x 0x%08x 0x%08x\n",
-+ pseudo_cause,
-+ icm_rx, icr_rx, imv_rx,
-+ icm_tx, icr_tx, imv_tx,
-+ icm_misc, icr_misc, imv_misc);
-+ return IRQ_NONE;
-+ }
-+ wil6210_mask_irq(wil);
-+ /* Discover real IRQ cause */
-+ /* All ISR regs configured Clear-On-Read, no need to ACK */
-+ if (pseudo_cause & BIT_DMA_PSEUDO_CAUSE_RX) {
-+ wil->isr_rx = ioread32_and_clear(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_RX_ICR) +
-+ offsetof(struct RGF_ICR, ICR));
-+ }
-+ if (pseudo_cause & BIT_DMA_PSEUDO_CAUSE_TX) {
-+ wil->isr_tx = ioread32_and_clear(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_TX_ICR) +
-+ offsetof(struct RGF_ICR, ICR));
-+ }
-+ if (pseudo_cause & BIT_DMA_PSEUDO_CAUSE_MISC) {
-+ wil->isr_misc = ioread32_and_clear(wil->csr +
-+ HOSTADDR(RGF_DMA_EP_MISC_ICR) +
-+ offsetof(struct RGF_ICR, ICR));
-+ rc = IRQ_WAKE_THREAD;
-+ }
-+ /* process what to be done right in hard IRQ */
-+ if (wil->isr_rx) {
-+ if (wil6210_irq_rx(irq, cookie) == IRQ_WAKE_THREAD)
-+ rc = IRQ_WAKE_THREAD;
-+ else
-+ wil->isr_rx = 0;
-+ }
-+ if (wil->isr_tx) {
-+ if (wil6210_irq_tx(irq, cookie) == IRQ_WAKE_THREAD)
-+ rc = IRQ_WAKE_THREAD;
-+ else
-+ wil->isr_tx = 0;
-+ }
-+ /* if thread is requested, it will unmask IRQ */
-+ if (rc != IRQ_WAKE_THREAD)
-+ wil6210_unmask_irq(wil);
-+#if 0
-+ wil_info(wil, "Hard IRQ 0x%08x\n", pseudo_cause);
-+#endif
-+ return rc;
-+}
-+
-+int wil6210_init_irq(struct wil6210_priv *wil, int irq)
-+{
-+ int rc;
-+ wil_info(wil, "%s()\n", __func__);
-+ /* TODO: handle multiple MSI */
-+ rc = request_threaded_irq(irq,
-+ wil6210_hardirq, wil6210_thread_irq,
-+ wil->n_msi ? 0 : IRQF_SHARED,
-+ WIL_NAME, wil);
-+ if (rc)
-+ return rc;
-+ wil6210_enable_irq(wil);
-+ return 0;
-+}
-+
-+void wil6210_fini_irq(struct wil6210_priv *wil, int irq)
-+{
-+ wil_info(wil, "%s()\n", __func__);
-+ wil6210_disable_irq(wil);
-+ free_irq(irq, wil);
-+}
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/main.c
-@@ -0,0 +1,336 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/sched.h>
-+#include <linux/ieee80211.h>
-+#include <linux/wireless.h>
-+#include <linux/slab.h>
-+#include <linux/moduleparam.h>
-+#include <linux/if_arp.h>
-+
-+#include "wil6210.h"
-+#include "wil6210_rgf.h"
-+
-+/**
-+ * We have to read/write to/from NIC in 32-bit chunks;
-+ * otherwise it is not work on 64-bit platform
-+ */
-+void memcpy_fromio_32(void *dst, const volatile void __iomem *src, size_t count)
-+{
-+ u32 *d = dst;
-+ const volatile u32 __iomem *s = src;
-+ /* size_t is unsigned, if (count%4 != 0) it will wrap */
-+ for (count += 4; count > 4; count -= 4)
-+ *d++ = readl(s++);
-+}
-+
-+void memcpy_toio_32(volatile void __iomem *dst, const void *src, size_t count)
-+{
-+ volatile u32 __iomem *d = dst;
-+ const u32 *s = src;
-+ for (count += 4; count > 4; count -= 4)
-+ writel(*s++, d++);
-+}
-+
-+/* debug */
-+void send_echo(struct wil6210_priv *wil);
-+
-+static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
-+{
-+ int i;
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ struct wireless_dev *wdev = wil->wdev;
-+ wil_info(wil, "%s()\n", __func__);
-+ wil_link_off(wil);
-+ clear_bit(wil_status_fwconnected, &wil->status);
-+ switch (wdev->sme_state) {
-+ case CFG80211_SME_CONNECTED:
-+ cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE,
-+ NULL, 0, GFP_KERNEL);
-+ break;
-+ case CFG80211_SME_CONNECTING:
-+ cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
-+ WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL);
-+ break;
-+ default:
-+ ;
-+ }
-+ for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++)
-+ vring_fini_tx(wil, i);
-+}
-+
-+static void connect_timer_fn(unsigned long x)
-+{
-+ struct wil6210_priv *wil = (void *)x;
-+ wil_info(wil, "Connect timeout\n");
-+ _wil6210_disconnect(wil, NULL);
-+}
-+
-+int wil_priv_init(struct wil6210_priv *wil)
-+{
-+ wil_info(wil, "%s()\n", __func__);
-+
-+ mutex_init(&wil->mutex);
-+ mutex_init(&wil->wmi_mutex);
-+ init_completion(&wil->wmi_ready);
-+ wil->pending_connect_cid = -1;
-+ setup_timer(&wil->connect_timer, connect_timer_fn,
-+ (unsigned long)wil);
-+ INIT_WORK(&wil->wmi_connect_worker, wmi_connect_worker);
-+ INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
-+ INIT_LIST_HEAD(&wil->pending_wmi_ev);
-+ spin_lock_init(&wil->wmi_ev_lock);
-+ wil->wmi_wq = create_singlethread_workqueue(WIL_NAME"_wmi");
-+ if (!wil->wmi_wq)
-+ return -EAGAIN;
-+ wil->wmi_wq_conn = create_singlethread_workqueue(WIL_NAME"_connect");
-+ if (!wil->wmi_wq_conn) {
-+ destroy_workqueue(wil->wmi_wq);
-+ return -EAGAIN;
-+ }
-+ /* make shadow copy of registers that should not change on run time */
-+ memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
-+ sizeof(struct wil6210_mbox_ctl));
-+ return 0;
-+}
-+
-+void wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
-+{
-+ del_timer_sync(&wil->connect_timer);
-+ _wil6210_disconnect(wil, bssid);
-+}
-+
-+void wil_priv_deinit(struct wil6210_priv *wil)
-+{
-+ wil6210_disconnect(wil, NULL);
-+ wmi_event_flush(wil);
-+ destroy_workqueue(wil->wmi_wq_conn);
-+ destroy_workqueue(wil->wmi_wq);
-+}
-+
-+static void wil_target_reset(struct wil6210_priv *wil)
-+{
-+ u32 x;
-+ u32 off;
-+ wil_info(wil, "Resetting...\n");
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_MASK_0);
-+ x = ioread32(wil->csr + off);
-+ x |= BIT(6); /* hpal_perst_from_pad_src_n_mask */
-+ iowrite32(x, wil->csr + off);
-+ x |= BIT(7); /* car_perst_rst_src_n_mask */
-+ iowrite32(x, wil->csr + off);
-+
-+ off = HOSTADDR(RGF_USER_MAC_CPU_0);
-+ iowrite32(BIT(1), wil->csr + off); /* mac_cpu_man_rst */
-+
-+ off = HOSTADDR(RGF_USER_USER_CPU_0);
-+ iowrite32(BIT(1), wil->csr + off); /* user_cpu_man_rst */
-+
-+ msleep(100);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_2);
-+ iowrite32(0xFE000000, wil->csr + off);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_1);
-+ iowrite32(0x0000003F, wil->csr + off);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_3);
-+ iowrite32(0x00000170, wil->csr + off);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_0);
-+ iowrite32(0xFFE7FC00, wil->csr + off);
-+
-+ msleep(100);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_3);
-+ iowrite32(0, wil->csr + off);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_2);
-+ iowrite32(0, wil->csr + off);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_1);
-+ iowrite32(0, wil->csr + off);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_0);
-+ iowrite32(0, wil->csr + off);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_3);
-+ iowrite32(0x00000001, wil->csr + off);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_2);
-+ iowrite32(0x00000080, wil->csr + off);
-+
-+ off = HOSTADDR(RGF_USER_CLKS_CTL_SW_RST_VEC_0);
-+ iowrite32(0, wil->csr + off);
-+
-+ msleep(2000);
-+
-+ off = HOSTADDR(RGF_USER_USER_CPU_0);
-+ iowrite32(BIT(0), wil->csr + off); /* user_cpu_man_de_rst */
-+
-+ msleep(2000);
-+ wil_info(wil, "Reset completed\n");
-+}
-+
-+/*
-+ * We reset all the structures, and we reset the UMAC.
-+ * After calling this routine, you're expected to reload
-+ * the firmware.
-+ */
-+int wil_reset(struct wil6210_priv *wil)
-+{
-+ wil_info(wil, "%s()\n", __func__);
-+ wil6210_disconnect(wil, NULL);
-+ wmi_event_flush(wil);
-+ flush_workqueue(wil->wmi_wq);
-+ flush_workqueue(wil->wmi_wq_conn);
-+ wil6210_disable_irq(wil);
-+ wil->status = 0;
-+ /* TODO: put MAC in reset */
-+ wil_target_reset(wil);
-+ /* init after reset */
-+ wil->pending_connect_cid = -1;
-+ INIT_COMPLETION(wil->wmi_ready);
-+ /* make shadow copy of registers that should not change on run time */
-+ memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
-+ sizeof(struct wil6210_mbox_ctl));
-+ /* TODO: release MAC reset */
-+ wil6210_enable_irq(wil);
-+ /* we just started MAC, wait for FW ready */
-+ {
-+ unsigned long to = msecs_to_jiffies(1000);
-+ unsigned long left = wait_for_completion_timeout(
-+ &wil->wmi_ready, to);
-+ if (0 == left) {
-+ wil_err(wil, "Firmware not ready\n");
-+ return -ETIME;
-+ } else {
-+ wil_info(wil, "FW ready after %d ms\n",
-+ jiffies_to_msecs(to-left));
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+void wil_link_on(struct wil6210_priv *wil)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ wil_info(wil, "%s()\n", __func__);
-+ netif_carrier_on(ndev);
-+ netif_tx_wake_all_queues(ndev);
-+}
-+
-+void wil_link_off(struct wil6210_priv *wil)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ wil_info(wil, "%s()\n", __func__);
-+ netif_tx_stop_all_queues(ndev);
-+ netif_carrier_off(ndev);
-+}
-+
-+static int __wil_up(struct wil6210_priv *wil)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ struct wireless_dev *wdev = wil->wdev;
-+ int rc = wil_reset(wil);
-+ if (rc)
-+ return rc;
-+ /* Apply profile in the following order: */
-+ /* MAC address - pre-requisite for other commands */
-+ wil6210_set_mac_address(wil, ndev->dev_addr);
-+ /* Interface type. Set up beaconing if required. After MAC */
-+ {
-+ u16 wmi_nettype = iftype_nl2wmi(wdev->iftype);
-+ int bi;
-+ /* FIXME Firmware works now in PBSS mode(ToDS=0, FromDS=0) */
-+ wmi_nettype = iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
-+ switch (wdev->iftype) {
-+ case NL80211_IFTYPE_STATION:
-+ wil_info(wil, "type: STATION\n");
-+ bi = 0;
-+ ndev->type = ARPHRD_ETHER;
-+ break;
-+ case NL80211_IFTYPE_AP:
-+ wil_info(wil, "type: AP\n");
-+ bi = 100;
-+ ndev->type = ARPHRD_ETHER;
-+ break;
-+ case NL80211_IFTYPE_P2P_CLIENT:
-+ wil_info(wil, "type: P2P_CLIENT\n");
-+ bi = 0;
-+ ndev->type = ARPHRD_ETHER;
-+ break;
-+ case NL80211_IFTYPE_P2P_GO:
-+ wil_info(wil, "type: P2P_GO\n");
-+ bi = 100;
-+ ndev->type = ARPHRD_ETHER;
-+ break;
-+ case NL80211_IFTYPE_MONITOR:
-+ wil_info(wil, "type: Monitor\n");
-+ bi = 0;
-+ ndev->type = ARPHRD_IEEE80211_RADIOTAP;
-+ /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+ rc = wil6210_set_bcon(wil, bi, wmi_nettype);
-+ if (rc)
-+ return rc;
-+ }
-+ /* Rx VRING. After MAC and beacon */
-+ rx_init(wil);
-+ return 0;
-+}
-+
-+int wil_up(struct wil6210_priv *wil)
-+{
-+ int ret;
-+ wil_info(wil, "%s()\n", __func__);
-+
-+ mutex_lock(&wil->mutex);
-+ ret = __wil_up(wil);
-+ mutex_unlock(&wil->mutex);
-+
-+ return ret;
-+}
-+
-+static int __wil_down(struct wil6210_priv *wil)
-+{
-+ if (wil->scan_request) {
-+ cfg80211_scan_done(wil->scan_request, true);
-+ wil->scan_request = NULL;
-+ }
-+ wil6210_disconnect(wil, NULL);
-+ rx_fini(wil);
-+ return 0;
-+}
-+
-+int wil_down(struct wil6210_priv *wil)
-+{
-+ int ret;
-+ wil_info(wil, "%s()\n", __func__);
-+
-+ mutex_lock(&wil->mutex);
-+ ret = __wil_down(wil);
-+ mutex_unlock(&wil->mutex);
-+
-+ return ret;
-+}
-+
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/memdump.sh
-@@ -0,0 +1,9 @@
-+#!/bin/bash
-+### parameter - memdump prefix
-+P=$1
-+### where is wil6210 debugfs?
-+D=$(find /sys/kernel/debug/ieee80211/ -name wil6210)
-+
-+for f in fw_data fw_peri uc_data; do {
-+ cat $D/blob_${f} > ${P}${f}
-+} done
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/netdev.c
-@@ -0,0 +1,166 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/slab.h>
-+
-+#include "wil6210.h"
-+#include "cfg80211.h"
-+
-+static int wil_open(struct net_device *ndev)
-+{
-+ struct wil6210_priv *wil = ndev_to_wil(ndev);
-+ wil_info(wil, "%s()\n", __func__);
-+
-+ return wil_up(wil);
-+}
-+
-+static int wil_stop(struct net_device *ndev)
-+{
-+ struct wil6210_priv *wil = ndev_to_wil(ndev);
-+ wil_info(wil, "%s()\n", __func__);
-+
-+ return wil_down(wil);
-+}
-+
-+/*
-+ * AC to queue mapping
-+ *
-+ * AC_VO -> queue 3
-+ * AC_VI -> queue 2
-+ * AC_BE -> queue 1
-+ * AC_BK -> queue 0
-+ */
-+static const u16 wil_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
-+#if 0
-+static int wil_tid_to_queue(u16 tid)
-+{
-+ if (tid >= ARRAY_SIZE(wil_1d_to_queue))
-+ return -EINVAL;
-+
-+ return wil_1d_to_queue[tid];
-+}
-+#endif
-+static u16 wil_select_queue(struct net_device *ndev, struct sk_buff *skb)
-+{
-+#ifdef WIL_DEBUG_TXRX
-+ struct wil6210_priv *wil = ndev_to_wil(ndev);
-+#endif
-+ u16 ret;
-+ skb->priority = cfg80211_classify8021d(skb);
-+
-+ ret = wil_1d_to_queue[skb->priority];
-+#ifdef WIL_DEBUG_TXRX
-+ wil_info(wil, "%s() %d -> %d\n", __func__,
-+ (int)skb->priority, (int)ret);
-+#endif
-+ return ret;
-+}
-+
-+static const struct net_device_ops wil_netdev_ops = {
-+ .ndo_open = wil_open,
-+ .ndo_stop = wil_stop,
-+ .ndo_start_xmit = wil_start_xmit,
-+ .ndo_select_queue = wil_select_queue,
-+ .ndo_set_mac_address = eth_mac_addr,
-+ .ndo_validate_addr = eth_validate_addr,
-+};
-+
-+void *wil_if_alloc(struct device *dev, void __iomem *csr)
-+{
-+ struct net_device *ndev;
-+ struct wireless_dev *wdev;
-+ struct wil6210_priv *wil;
-+ int ret = 0;
-+ wdev = wil_cfg80211_init(dev);
-+ if (IS_ERR(wdev)) {
-+ dev_err(dev, "wil_cfg80211_init failed\n");
-+ return wdev;
-+ }
-+
-+ wil = wdev_to_wil(wdev);
-+ wil->csr = csr;
-+ wil->wdev = wdev;
-+
-+ ret = wil_priv_init(wil);
-+ if (ret) {
-+ dev_err(dev, "wil_priv_init failed\n");
-+ goto out_wdev;
-+ }
-+
-+ wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */
-+ /* default monitor channel */
-+ wil->monitor_chan = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels;
-+
-+ ndev = alloc_netdev_mqs(0, "wlan%d", ether_setup, WIL6210_TX_QUEUES, 1);
-+ if (!ndev) {
-+ dev_err(dev, "alloc_netdev_mqs failed\n");
-+ ret = -ENOMEM;
-+ goto out_priv;
-+ }
-+
-+ ndev->netdev_ops = &wil_netdev_ops;
-+ ndev->ieee80211_ptr = wdev;
-+ SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
-+ wdev->netdev = ndev;
-+
-+ wil_link_off(wil);
-+ return wil;
-+
-+/*out_profile:*/
-+ free_netdev(ndev);
-+
-+ out_priv:
-+ wil_priv_deinit(wil);
-+
-+ out_wdev:
-+ wil_wdev_free(wil);
-+ return ERR_PTR(ret);
-+}
-+
-+void wil_if_free(struct wil6210_priv *wil)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ if (!ndev)
-+ return;
-+
-+ free_netdev(ndev);
-+ wil_priv_deinit(wil);
-+ wil_wdev_free(wil);
-+}
-+
-+int wil_if_add(struct wil6210_priv *wil)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ int ret;
-+
-+ ret = register_netdev(ndev);
-+ if (ret < 0) {
-+ dev_err(&ndev->dev, "Failed to register netdev: %d\n", ret);
-+ return ret;
-+ }
-+ wil_link_off(wil);
-+
-+ return 0;
-+}
-+
-+void wil_if_remove(struct wil6210_priv *wil)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ unregister_netdev(ndev);
-+}
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
-@@ -0,0 +1,239 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/netdevice.h>
-+#include <linux/debugfs.h>
-+#include <linux/pci.h>
-+#include <linux/moduleparam.h>
-+
-+#include "wil6210.h"
-+
-+static int use_msi; /* TODO: set default to 1 or 3 when hardware fixed */
-+module_param(use_msi, int, S_IRUGO);
-+MODULE_PARM_DESC(use_msi,
-+ " Use MSI interrupt: 0 - (default) - don't, 1 - single, or 3");
-+
-+/* debug */
-+void send_echo(struct wil6210_priv *wil);
-+
-+/* Bus ops */
-+static int if_pcie_enable(struct wil6210_priv *wil)
-+{
-+ struct pci_dev *pdev = wil->pdev;
-+ int rc;
-+ wil_info(wil, "%s()\n", __func__);
-+ /*
-+ * how many MSI interrupts to request?
-+ */
-+ wil->n_msi = use_msi;
-+ /* TODO: how to deal with 3 MSI? */
-+ if (wil->n_msi) {
-+ wil_info(wil, "Setup %d MSI interrupts\n", use_msi);
-+ rc = pci_enable_msi_block(pdev, wil->n_msi);
-+ if (rc) {
-+ wil_err(wil, "pci_enable_msi failed, use INTx\n");
-+ wil->n_msi = 0;
-+ }
-+ } else {
-+ wil_info(wil, "MSI interrupts disabled, use INTx\n");
-+ }
-+ rc = wil6210_init_irq(wil, pdev->irq);
-+ if (rc)
-+ return rc;
-+ /* need reset here to obtain MAC */
-+ rc = wil_reset(wil);
-+ if (rc)
-+ goto release_irq;
-+ pci_set_master(pdev);
-+
-+ return 0;
-+ release_irq:
-+ wil6210_fini_irq(wil, pdev->irq);
-+ /* safe to call if no MSI */
-+ pci_disable_msi(pdev);
-+ return rc;
-+}
-+
-+static int if_pcie_disable(struct wil6210_priv *wil)
-+{
-+ struct pci_dev *pdev = wil->pdev;
-+ struct device *dev = wil_to_dev(wil);
-+ dev_info(dev, "%s()\n", __func__);
-+
-+ pci_clear_master(pdev);
-+ /* disable IRQ */
-+ /* release IRQ */
-+ wil6210_fini_irq(wil, pdev->irq);
-+ /* safe to call if no MSI */
-+ pci_disable_msi(pdev);
-+ /* disable HW */
-+#if 0
-+ wil_reset(wil);
-+#endif
-+ return 0;
-+}
-+
-+static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-+{
-+ struct wil6210_priv *wil;
-+ struct device *dev = &pdev->dev;
-+ void __iomem *csr;
-+ int rc;
-+ dev_info(dev, "%s()\n", __func__);
-+
-+ /* check HW */
-+ dev_info(&pdev->dev, WIL_NAME " device found [%04x:%04x] (rev %x)\n",
-+ (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
-+ if (pci_resource_len(pdev, 0) != WIL6210_MEM_SIZE) {
-+ dev_err(&pdev->dev, "Not " WIL_NAME "? "
-+ "BAR0 size is %lu while expecting %lu\n",
-+ (unsigned long)pci_resource_len(pdev, 0),
-+ WIL6210_MEM_SIZE);
-+ return -ENODEV;
-+ }
-+ rc = pci_enable_device(pdev);
-+ if (rc) {
-+ dev_err(&pdev->dev, "pci_enable_device failed\n");
-+ return -ENODEV;
-+ }
-+ /* rollback to err_disable_pdev */
-+
-+ rc = pci_request_region(pdev, 0, WIL_NAME);
-+ if (rc) {
-+ dev_err(&pdev->dev, "pci_request_region failed\n");
-+ goto err_disable_pdev;
-+ }
-+ /* rollback to err_release_reg */
-+ csr = pci_ioremap_bar(pdev, 0);
-+ if (!csr) {
-+ dev_err(&pdev->dev, "pci_ioremap_bar failed\n");
-+ rc = -ENODEV;
-+ goto err_release_reg;
-+ }
-+ /* rollback to err_iounmap */
-+ dev_info(&pdev->dev, "CSR at %pR -> %p\n", &pdev->resource[0],
-+ csr);
-+
-+ wil = wil_if_alloc(dev, csr);
-+ if (IS_ERR(wil)) {
-+ rc = (int)PTR_ERR(wil);
-+ dev_err(dev, "wil_if_alloc failed: %d\n", rc);
-+ goto err_iounmap;
-+ }
-+ /* rollback to if_free */
-+
-+ pci_set_drvdata(pdev, wil);
-+ wil->pdev = pdev;
-+
-+ /* FW should raise IRQ when ready */
-+ rc = if_pcie_enable(wil);
-+ if (rc) {
-+ wil_err(wil, "Enable device failed\n");
-+ goto if_free;
-+ }
-+ /* rollback to bus_disable */
-+
-+ rc = wil_if_add(wil);
-+ if (rc) {
-+ wil_err(wil, "wil_if_add failed: %d\n", rc);
-+ goto bus_disable;
-+ }
-+ wil6210_debugfs_init(wil);
-+ /* rollback to debugfs_exit */
-+
-+ { /* print various info */
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ const char *pdev_name = pci_name(pdev);
-+ const char *wiphydev_name = dev_name(wil_to_dev(wil));
-+ const char *ndev_name = netdev_name(ndev);
-+ const char *ifc_name = ndev->name;
-+ struct pci_driver *drv = pci_dev_driver(pdev);
-+ const char *drv_name = drv ? drv->name : "(no drv)";
-+ pr_info("Driver : <%s>\n", drv_name ?: "(null)");
-+ pr_info("PCI dev : <%s>\n", pdev_name ?: "(null)");
-+ pr_info("Net dev : <%s>\n", ndev_name ?: "(null)");
-+ pr_info("Net ifc : <%s>\n", ifc_name ?: "(null)");
-+ pr_info("Wiphy : <%s>\n", wiphydev_name ?: "(null)");
-+
-+ }
-+ send_echo(wil);
-+ return 0;
-+#if 0
-+ debugfs_exit:
-+ wil6210_debugfs_remove(wil);
-+#endif
-+ bus_disable:
-+ if_pcie_disable(wil);
-+ if_free:
-+ wil_if_free(wil);
-+ err_iounmap:
-+ pci_iounmap(pdev, csr);
-+ err_release_reg:
-+ pci_release_region(pdev, 0);
-+ err_disable_pdev:
-+ pci_disable_device(pdev);
-+ return rc;
-+}
-+
-+static void wil_pcie_remove(struct pci_dev *pdev)
-+{
-+ struct wil6210_priv *wil = pci_get_drvdata(pdev);
-+ wil_info(wil, "%s()\n", __func__);
-+
-+ wil6210_debugfs_remove(wil);
-+ if_pcie_disable(wil);
-+ wil_if_remove(wil);
-+ wil_if_free(wil);
-+ pci_iounmap(pdev, wil->csr);
-+ pci_release_region(pdev, 0);
-+ pci_disable_device(pdev);
-+ pci_set_drvdata(pdev, NULL);
-+}
-+
-+static DEFINE_PCI_DEVICE_TABLE(wil6210_pcie_ids) = {
-+ { PCI_DEVICE(PCI_VENDOR_ID_WIL6210, PCI_DEVICE_ID_WIL6210),
-+ /*.driver_data = (kernel_ulong_t)0,*/},
-+ { /* end: all zeroes */ },
-+};
-+MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids);
-+
-+static struct pci_driver wil_driver = {
-+ .probe = wil_pcie_probe,
-+ .remove = __devexit_p(wil_pcie_remove),
-+ .id_table = wil6210_pcie_ids,
-+ .name = WIL_NAME,
-+};
-+
-+
-+static int __init wil_init_module(void)
-+{
-+ return pci_register_driver(&wil_driver);
-+}
-+
-+static void __exit wil_exit_module(void)
-+{
-+ pci_unregister_driver(&wil_driver);
-+}
-+
-+module_init(wil_init_module);
-+module_exit(wil_exit_module);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-+MODULE_AUTHOR("Qualcomm Atheros <wil6210@qualcomm.com>");
-+MODULE_DESCRIPTION("Driver for 60g WiFi WIL6210 card");
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/read_dw.sh
-@@ -0,0 +1,7 @@
-+#!/bin/bash
-+### parameter - FW address to read
-+A=$1
-+### where is wil6210 debugfs?
-+D=$(find /sys/kernel/debug/ieee80211/ -name wil6210)
-+echo $A > $D/mem_addr
-+cat $D/mem_val
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/tools/Makefile
-@@ -0,0 +1,4 @@
-+hostprogs-y := trace
-+
-+always := $(hostprogs-y)
-+
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/tools/trace.c
-@@ -0,0 +1,190 @@
-+#include <stdio.h>
-+#include <stdint.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+
-+/*
-+ * Dumps firmware trace.
-+ *
-+ * Uses binary representation of 'strings' file,
-+ * it should be named fw_strings.bin and be in the current directory
-+ * Periodically reads peripheral memory like in blob_fw_peri on the debugfs
-+ * Name of peripheral memory file passed as parameter
-+ */
-+
-+typedef uint32_t u32;
-+typedef unsigned int uint;
-+
-+struct module_level_enable { /* Little Endian */
-+ uint error_level_enable:1;
-+ uint warn_level_enable:1;
-+ uint info_level_enable:1;
-+ uint verbose_level_enable:1;
-+ uint reserved0:4;
-+} __attribute__((packed));
-+
-+struct log_trace_header { /* Little Endian */
-+ uint strring_offset:20; /* the offset of the trace string in the strings sections */
-+ uint module:4; /* module that outputs the trace */
-+ uint level:2; /* 0 - Error
-+ 1- WARN
-+ 2 - INFO
-+ 3 - VERBOSE */
-+ uint parameters_num:2; /* [0..3] */
-+ uint is_string:1; /* this bit was timestamp_present:1; and changed to indicate if the printf uses %s */
-+ uint signature:3; /* should be 5 (2'101) in valid header */
-+} __attribute__((packed));
-+
-+union log_event {
-+ struct log_trace_header hdr;
-+ u32 param;
-+} __attribute__((packed));
-+
-+struct log_table_header {
-+ u32 write_ptr; /* incremented by trace producer every write */
-+ struct module_level_enable module_level_enable[16];
-+ union log_event evt[0];
-+} __attribute__((packed));
-+
-+static size_t read_all(int f, void *buf, size_t n)
-+{
-+ size_t actual = 0, r;
-+ do {
-+ r = read(f, buf + actual, n - actual);
-+ actual += r;
-+ } while ((r > 0) && (actual < n));
-+ return actual;
-+}
-+
-+static void *read_file(const char *name, size_t *size)
-+{
-+ int f = open(name, O_RDONLY);
-+ size_t sz = *size;
-+ size_t r;
-+ void *buf;
-+ if (f < 0)
-+ return NULL;
-+
-+ if (!sz) {
-+ sz = lseek(f, 0, SEEK_END);
-+ lseek(f, 0, SEEK_SET);
-+ }
-+ buf = malloc(sz);
-+ if (!buf) {
-+ close(f);
-+ return NULL;
-+ }
-+ r = read_all(f, buf, sz);
-+ close(f);
-+ if (r != sz) {
-+ printf("Error: from %s read %zd bytes out of %zd\n",
-+ name, r, sz);
-+ free(buf);
-+ return NULL;
-+ }
-+ *size = sz;
-+ return buf;
-+}
-+
-+static char *strings_bin = "fw_strings.bin";
-+static char *peri = "peri.dump";
-+enum {
-+ log_buf_sizedw = 0x1000/4,
-+ str_mask = 0xFFFF,
-+};
-+
-+static void *peri_buf;
-+static void *str_buf;
-+static size_t str_sz;
-+static u32 rptr = 0;
-+static const char* levels[] = {
-+ "E",
-+ "W",
-+ "I",
-+ "V",
-+};
-+
-+static const char *modules[16];
-+
-+static void do_parse(void)
-+{
-+ struct log_table_header *h = peri_buf;
-+ u32 wptr = h->write_ptr;
-+ if ((wptr - rptr) >= log_buf_sizedw) {
-+ /* overflow; try to parse last wrap */
-+ rptr = wptr - log_buf_sizedw;
-+ }
-+ for (;(long)(wptr - rptr) > 0; rptr++) {
-+ int i;
-+ u32 p[3] = {0};
-+ union log_event *evt = &h->evt[rptr % log_buf_sizedw];
-+ const char *fmt;
-+ if (evt->hdr.signature != 5)
-+ continue;
-+ if (evt->hdr.strring_offset > str_sz)
-+ continue;
-+ if (evt->hdr.parameters_num > 3)
-+ continue;
-+ fmt = str_buf + evt->hdr.strring_offset;
-+ for (i = 0; i < evt->hdr.parameters_num; i++) {
-+ p[i] = h->evt[(rptr + i + 1) % log_buf_sizedw].param;
-+ }
-+ printf("[%6d] %9s %s :", rptr, modules[evt->hdr.module],
-+ levels[evt->hdr.level]);
-+ if (evt->hdr.is_string) {
-+ printf(fmt, str_buf + (p[0] & str_mask),
-+ str_buf + (p[1] & str_mask),
-+ str_buf + (p[2] & str_mask));
-+ } else {
-+ printf(fmt, p[0], p[1], p[2]);
-+ }
-+ printf("\n");
-+ rptr += evt->hdr.parameters_num;
-+ }
-+ fflush(stdout);
-+}
-+
-+int main(int argc, char* argv[])
-+{
-+ if (argc > 1)
-+ peri = argv[1];
-+ const char *mod;
-+ size_t peri_sz = 8*1024;
-+ int i;
-+ str_buf = read_file(strings_bin, &str_sz);
-+ mod = str_buf;
-+ peri_buf = read_file(peri, &peri_sz);
-+ if (!str_buf || !peri_buf)
-+ return -1;
-+ struct log_table_header *h = peri_buf;
-+ u32 wptr = h->write_ptr;
-+ if ((wptr - rptr) >= log_buf_sizedw) {
-+ /* overflow; try to parse last wrap */
-+ rptr = wptr - log_buf_sizedw;
-+ }
-+ printf(" wptr = %d rptr = %d\n", wptr, rptr);
-+ for (i = 0; i < 16; i++) {
-+ modules[i] = mod;
-+ struct module_level_enable *m = &h->module_level_enable[i];
-+ printf(" %s[%2d] : %s%s%s%s\n", modules[i], i,
-+ m->error_level_enable ? "E" : " ",
-+ m->warn_level_enable ? "W" : " ",
-+ m->info_level_enable ? "I" : " ",
-+ m->verbose_level_enable ? "V" : " ");
-+ mod = strchr(mod, '\0') + 1;
-+ }
-+ for(;;) {
-+ do_parse();
-+ sleep(1);
-+ int f = open(peri, O_RDONLY);
-+ size_t r = read_all(f, peri_buf, peri_sz);
-+ close(f);
-+ if (r != peri_sz)
-+ break;
-+ }
-+ return 0;
-+}
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/tools/vhex2bin.py
-@@ -0,0 +1,17 @@
-+#!/usr/bin/python
-+
-+'''
-+Convert .vhex file into binary representation
-+'''
-+
-+import sys
-+import fileinput
-+import re
-+import struct
-+
-+for line in fileinput.input():
-+ if not re.match("[0-9a-f]+", line):
-+ continue
-+ x = int(line,16)
-+ s = struct.pack("<I", x)
-+ sys.stdout.write(s)
-\ No newline at end of file
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/trace.sh
-@@ -0,0 +1,4 @@
-+#!/bin/bash
-+### where is wil6210 debugfs?
-+D=$(find /sys/kernel/debug/ieee80211/ -name wil6210)
-+exec tools/trace $D/blob_fw_peri
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/txdesc.sh
-@@ -0,0 +1,8 @@
-+#!/bin/bash
-+# Display Tx descriptor content
-+# Descriptor index
-+I=$1
-+### where is wil6210 debugfs?
-+D=$(find /sys/kernel/debug/ieee80211/ -name wil6210)
-+echo $I > $D/txdesc_index
-+cat $D/txdesc
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/txrx.c
-@@ -0,0 +1,871 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/hardirq.h>
-+#include <net/ieee80211_radiotap.h>
-+#include <linux/if_arp.h>
-+#include <linux/moduleparam.h>
-+
-+#include "wil6210.h"
-+#include "wmi.h"
-+#include "txrx.h"
-+#include "wil6210_rgf.h"
-+
-+static bool rtap_include_phy_info;
-+module_param(rtap_include_phy_info, bool, S_IRUGO);
-+MODULE_PARM_DESC(rtap_include_phy_info,
-+ " Include PHY info in the radiotap header, default - no");
-+
-+static inline int vring_is_empty(struct vring *vring)
-+{
-+ return vring->swhead == vring->swtail;
-+}
-+
-+static inline u32 vring_next_tail(struct vring *vring)
-+{
-+ return (vring->swtail+1)%vring->size;
-+}
-+
-+static inline void vring_advance_head(struct vring *vring)
-+{
-+ vring->swhead = (vring->swhead+1)%vring->size;
-+}
-+
-+static inline int vring_is_full(struct vring *vring)
-+{
-+ return vring_next_tail(vring) == vring->swhead;
-+}
-+
-+static int vring_alloc(struct wil6210_priv *wil, struct vring *vring)
-+{
-+ struct device *dev = wil_to_dev(wil);
-+ size_t sz = vring->size * sizeof(vring->va[0]);
-+ int i;
-+ BUILD_BUG_ON(sizeof(vring->va[0]) != 32);
-+ wil_info(wil, "%s()\n", __func__);
-+ vring->swhead = 0;
-+ vring->swtail = 0;
-+ vring->ctx = kzalloc(vring->size * sizeof(vring->ctx[0]), GFP_KERNEL);
-+ if (!vring->ctx) {
-+ wil_err(wil, "vring_alloc [%d] failed to alloc ctx mem\n",
-+ vring->size);
-+ vring->va = NULL;
-+ return -ENOMEM;
-+ }
-+ vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL);
-+ if (!vring->va) {
-+ wil_err(wil, "vring_alloc [%d] failed to alloc DMA mem\n",
-+ vring->size);
-+ kfree(vring->ctx);
-+ vring->ctx = NULL;
-+ return -ENOMEM;
-+ }
-+ /* initially, all descriptors are SW owned
-+ * For Tx and Rx, ownership bit is at the same location, thus
-+ * we can use any
-+ */
-+ for (i = 0; i < vring->size; i++) {
-+ struct vring_tx_desc *d = &(vring->va[i].tx);
-+ d->dma.status = TX_DMA_STATUS_DU;
-+ }
-+ wil_info(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,
-+ vring->va, (unsigned long long)vring->pa, vring->ctx);
-+ return 0;
-+}
-+
-+static void vring_free(struct wil6210_priv *wil, struct vring *vring, int tx)
-+{
-+ struct device *dev = wil_to_dev(wil);
-+ size_t sz = vring->size * sizeof(vring->va[0]);
-+ wil_info(wil, "%s()\n", __func__);
-+ while (!vring_is_empty(vring)) {
-+ if (tx) {
-+ struct vring_tx_desc *d = &vring->va[vring->swtail].tx;
-+ dma_addr_t pa = d->dma.addr_low |
-+ ((u64)d->dma.addr_high << 32);
-+ struct sk_buff *skb = vring->ctx[vring->swtail];
-+ if (skb) {
-+ dma_unmap_single(dev, pa, d->dma.length,
-+ DMA_TO_DEVICE);
-+ dev_kfree_skb_any(skb);
-+ vring->ctx[vring->swtail] = NULL;
-+ } else {
-+ dma_unmap_page(dev, pa, d->dma.length,
-+ DMA_TO_DEVICE);
-+ }
-+ vring->swtail = vring_next_tail(vring);
-+ } else { /* rx */
-+ struct vring_rx_desc *d = &vring->va[vring->swtail].rx;
-+ dma_addr_t pa = d->dma.addr_low |
-+ ((u64)d->dma.addr_high << 32);
-+ struct sk_buff *skb = vring->ctx[vring->swhead];
-+ dma_unmap_single(dev, pa, d->dma.length,
-+ DMA_FROM_DEVICE);
-+ kfree_skb(skb);
-+ vring_advance_head(vring);
-+ }
-+ }
-+ dma_free_coherent(dev, sz, vring->va, vring->pa);
-+ kfree(vring->ctx);
-+ vring->pa = 0;
-+ vring->va = NULL;
-+ vring->ctx = NULL;
-+}
-+
-+/**
-+ * Allocate one skb for Rx VRING
-+ *
-+ * Safe to call from IRQ
-+ */
-+static int vring_alloc_skb(struct wil6210_priv *wil,
-+ struct vring *vring, u32 i, int headroom)
-+{
-+ struct device *dev = wil_to_dev(wil);
-+ unsigned int sz = RX_BUF_LEN;
-+ struct vring_rx_desc *d = &(vring->va[i].rx);
-+ dma_addr_t pa;
-+ /* TODO align */
-+ struct sk_buff *skb = dev_alloc_skb(sz + headroom);
-+ if (unlikely(!skb))
-+ return -ENOMEM;
-+ skb_reserve(skb, headroom);
-+ skb_put(skb, sz);
-+ pa = dma_map_single(dev, skb->data, skb->len, DMA_FROM_DEVICE);
-+ if (unlikely(dma_mapping_error(dev, pa))) {
-+ kfree_skb(skb);
-+ return -ENOMEM;
-+ }
-+ d->dma.d0 = BIT(9) | RX_DMA_D0_CMD_DMA_IT;
-+ d->dma.addr_low = lower_32_bits(pa);
-+ d->dma.addr_high = (u16)upper_32_bits(pa);
-+ /* ip_length don't care */
-+ /* b11 don't care */
-+ /* error don't care */
-+ d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
-+ d->dma.length = sz;
-+ vring->ctx[i] = skb;
-+ return 0;
-+}
-+
-+/**
-+ * Adds radiotap header
-+ *
-+ * Any error indicated as "Bad FCS"
-+ *
-+ * Vendor data for 04:ce:14-1 (Wilocity-1) consists of:
-+ * - Rx descriptor: 32 bytes
-+ * - Phy info
-+ */
-+static void rx_add_radiotap_header(struct wil6210_priv *wil,
-+ struct sk_buff *skb,
-+ struct vring_rx_desc *d)
-+{
-+ struct wil6210_rtap {
-+ struct ieee80211_radiotap_header rthdr;
-+ /* fields should be in the order of bits in rthdr.it_present */
-+ /* flags */
-+ u8 flags;
-+ /* channel */
-+ __le16 chnl_freq __aligned(2);
-+ __le16 chnl_flags;
-+ /* MCS */
-+ u8 mcs_present;
-+ u8 mcs_flags;
-+ u8 mcs_index;
-+ } __packed;
-+ struct wil6210_rtap_vendor {
-+ struct wil6210_rtap rtap;
-+ /* vendor */
-+ u8 vendor_oui[3] __aligned(2);
-+ u8 vendor_ns;
-+ __le16 vendor_skip;
-+ u8 vendor_data[0];
-+ } __packed;
-+ struct wil6210_rtap_vendor *rtap_vendor;
-+ int rtap_len = sizeof(struct wil6210_rtap);
-+ int phy_length = 0; /* phy info header size, bytes */
-+ static char phy_data[128];
-+ if (rtap_include_phy_info) {
-+ rtap_len = sizeof(*rtap_vendor) + sizeof(*d);
-+ /* calculate additional length */
-+ if (d->dma.status & RX_DMA_STATUS_PHY_INFO) {
-+ /**
-+ * PHY info starts from 8-byte boundary
-+ * there are 8-byte lines, last line may be partially
-+ * written (HW bug), thus FW configures for last line
-+ * to be excessive. Driver skips this last line.
-+ */
-+ int len = min_t(int, 8 + sizeof(phy_data),
-+ rxdesc_phy_length(d));
-+ if (len > 8) {
-+ void *p = skb_tail_pointer(skb);
-+ void *pa = PTR_ALIGN(p, 8);
-+ if (skb_tailroom(skb) >= len + (pa - p)) {
-+ phy_length = len - 8;
-+ memcpy(phy_data, pa, phy_length);
-+ }
-+ }
-+ }
-+ rtap_len += phy_length;
-+ }
-+
-+ if (skb_headroom(skb) < rtap_len &&
-+ pskb_expand_head(skb, rtap_len, 0, GFP_ATOMIC)) {
-+ wil_err(wil, "Unable to expand headrom to %d\n", rtap_len);
-+ return;
-+ }
-+
-+ rtap_vendor = (void *)skb_push(skb, rtap_len);
-+ memset(rtap_vendor, 0, rtap_len);
-+
-+ rtap_vendor->rtap.rthdr.it_version = PKTHDR_RADIOTAP_VERSION;
-+ rtap_vendor->rtap.rthdr.it_len = cpu_to_le16(rtap_len);
-+ rtap_vendor->rtap.rthdr.it_present = cpu_to_le32(
-+ (1 << IEEE80211_RADIOTAP_FLAGS) |
-+ (1 << IEEE80211_RADIOTAP_CHANNEL) |
-+ (1 << IEEE80211_RADIOTAP_MCS));
-+ if (d->dma.status & RX_DMA_STATUS_ERROR)
-+ rtap_vendor->rtap.flags |= IEEE80211_RADIOTAP_F_BADFCS;
-+
-+ rtap_vendor->rtap.chnl_freq = cpu_to_le16(wil->monitor_chan ?
-+ wil->monitor_chan->center_freq : 58320);
-+ rtap_vendor->rtap.chnl_flags = cpu_to_le16(0);
-+
-+ rtap_vendor->rtap.mcs_present = IEEE80211_RADIOTAP_MCS_HAVE_MCS;
-+ rtap_vendor->rtap.mcs_flags = 0;
-+ rtap_vendor->rtap.mcs_index = rxdesc_mcs(d);
-+
-+ if (rtap_include_phy_info) {
-+ rtap_vendor->rtap.rthdr.it_present |= cpu_to_le32(1 <<
-+ IEEE80211_RADIOTAP_VENDOR_NAMESPACE);
-+ /* OUI for Wilocity 04:ce:14 */
-+ rtap_vendor->vendor_oui[0] = 0x04;
-+ rtap_vendor->vendor_oui[1] = 0xce;
-+ rtap_vendor->vendor_oui[2] = 0x14;
-+ rtap_vendor->vendor_ns = 1;
-+ /* Rx descriptor + PHY data */
-+ rtap_vendor->vendor_skip = cpu_to_le16(sizeof(*d) +
-+ phy_length);
-+ memcpy(rtap_vendor->vendor_data, d, sizeof(*d));
-+ memcpy(rtap_vendor->vendor_data + sizeof(*d), phy_data,
-+ phy_length);
-+ }
-+}
-+
-+/**
-+ * reap 1 frame from @swhead
-+ *
-+ * Safe to call from IRQ
-+ */
-+static struct sk_buff *vring_reap_rx(struct wil6210_priv *wil,
-+ struct vring *vring)
-+{
-+ struct device *dev = wil_to_dev(wil);
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ struct vring_rx_desc *d;
-+ struct sk_buff *skb;
-+ dma_addr_t pa;
-+ unsigned int sz = RX_BUF_LEN;
-+ if (vring_is_empty(vring))
-+ return NULL;
-+ d = &(vring->va[vring->swhead].rx);
-+ if (!(d->dma.status & RX_DMA_STATUS_DU)) {
-+ /* it is not error, we just reached end of Rx done area */
-+ return NULL;
-+ }
-+ pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
-+ skb = vring->ctx[vring->swhead];
-+ dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE);
-+ skb_trim(skb, d->dma.length);
-+ wil->stats.last_mcs_rx = rxdesc_mcs(d);
-+ /* use radiotap header only if required */
-+ if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
-+ rx_add_radiotap_header(wil, skb, d);
-+#ifdef WIL_DEBUG_TXRX
-+ wil_info(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
-+ print_hex_dump(KERN_INFO, "Rx ", DUMP_PREFIX_NONE, 32, 4, d
-+ , sizeof(*d), false);
-+#endif
-+ vring_advance_head(vring);
-+ return skb;
-+}
-+
-+/**
-+ * allocate and fill up to @count buffers in rx ring
-+ * buffers posted at @swtail
-+ */
-+static int rx_refill(struct wil6210_priv *wil, int count)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ struct vring *v = &wil->vring_rx;
-+ u32 next_tail;
-+ int rc = 0;
-+ int headroom = ndev->type == ARPHRD_IEEE80211_RADIOTAP ?
-+ WIL6210_RTAP_SIZE : 0;
-+ for (; next_tail = vring_next_tail(v),
-+ (next_tail != v->swhead) && (count-- > 0);
-+ v->swtail = next_tail) {
-+ rc = vring_alloc_skb(wil, v, v->swtail, headroom);
-+ if (rc) {
-+ wil_err(wil, "Error %d in rx_refill[%d]\n",
-+ rc, v->swtail);
-+ break;
-+ }
-+ }
-+ iowrite32(v->swtail, wil->csr + HOSTADDR(v->hwtail));
-+ return rc;
-+}
-+
-+static int netif_rx_any(struct sk_buff *skb)
-+{
-+ if (in_interrupt())
-+ return netif_rx(skb);
-+ else
-+ return netif_rx_ni(skb);
-+}
-+
-+/**
-+ * Proceed all completed skb's from Rx VRING
-+ *
-+ * Safe to call from IRQ
-+ */
-+void rx_handle(struct wil6210_priv *wil)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ struct vring *v = &wil->vring_rx;
-+ struct sk_buff *skb;
-+ if (!v->va) {
-+ wil_err(wil, "Rx IRQ while Rx not yet initialized\n");
-+ return;
-+ }
-+#ifdef WIL_DEBUG_TXRX
-+ wil_info(wil, "%s()\n", __func__);
-+#endif
-+ while (NULL != (skb = vring_reap_rx(wil, v))) {
-+#ifdef WIL_DEBUG_TXRX
-+ print_hex_dump(KERN_INFO, "Rx ", DUMP_PREFIX_OFFSET, 16, 1,
-+ skb->data, skb_headlen(skb), false);
-+#endif
-+ skb_orphan(skb);
-+ if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
-+ skb->dev = ndev;
-+ skb_reset_mac_header(skb);
-+ skb->ip_summed = CHECKSUM_UNNECESSARY;
-+ skb->pkt_type = PACKET_OTHERHOST;
-+ skb->protocol = htons(ETH_P_802_2);
-+
-+ } else {
-+ skb->protocol = eth_type_trans(skb, ndev);
-+ }
-+ if (likely(netif_rx_any(skb) == NET_RX_SUCCESS)) {
-+ ndev->stats.rx_packets++;
-+ ndev->stats.rx_bytes += skb->len;
-+
-+ } else {
-+ ndev->stats.rx_dropped++;
-+ }
-+ }
-+ rx_refill(wil, v->size);
-+}
-+
-+int rx_init(struct wil6210_priv *wil)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ struct wireless_dev *wdev = wil->wdev;
-+ struct vring *vring = &wil->vring_rx;
-+ int rc;
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_CFG_RX_CHAIN_CMD cfg;
-+ } __packed wmi_rx_cfg = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 1,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi)
-+ + sizeof(struct WMI_CFG_RX_CHAIN_CMD),
-+ },
-+ .wmi = {
-+ .id = WMI_CFG_RX_CHAIN_CMDID,
-+ .info1 = 0,
-+ },
-+ .cfg = {
-+ .action = ADD_RX_CHAIN,
-+ .sw_ring = {
-+ .max_mpdu_size = RX_BUF_LEN,
-+ },
-+ .mid = 0, /* TODO - what is it? */
-+ .decap_trans_type = DECAP_TYPE_802_3,
-+ },
-+ };
-+ struct {
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_CFG_RX_CHAIN_DONE_EVENT cfg;
-+ } __packed wmi_rx_cfg_reply;
-+ wil_info(wil, "%s()\n", __func__);
-+ vring->size = WIL6210_RX_RING_SIZE;
-+ rc = vring_alloc(wil, vring);
-+ if (rc)
-+ return rc;
-+ wmi_rx_cfg.cfg.sw_ring.ring_mem_base = vring->pa;
-+ wmi_rx_cfg.cfg.sw_ring.ring_size = vring->size;
-+ if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
-+ wmi_rx_cfg.cfg.sniffer_mode = 1;
-+ if (wil->monitor_chan)
-+ wmi_rx_cfg.cfg.sniffer_channel =
-+ wil->monitor_chan->hw_value - 1;
-+ wmi_rx_cfg.cfg.sniffer_phy_info =
-+ (ndev->type == ARPHRD_IEEE80211_RADIOTAP);
-+ /* 0 - CP, 1 - DP */
-+ wmi_rx_cfg.cfg.sniffer_phy =
-+ (wil->monitor_flags & MONITOR_FLAG_CONTROL) ?
-+ 0 : 1;
-+ }
-+ rc = wmi_call(wil, &wmi_rx_cfg, WMI_CFG_RX_CHAIN_DONE_EVENTID,
-+ &wmi_rx_cfg_reply, sizeof(wmi_rx_cfg_reply), 200);
-+ if (rc)
-+ goto err_free;
-+ vring->hwtail = wmi_rx_cfg_reply.cfg.rx_ring_tail_ptr;
-+ wil_info(wil, "Rx init: status %d tail 0x%08x\n",
-+ wmi_rx_cfg_reply.cfg.status, vring->hwtail);
-+ rc = rx_refill(wil, vring->size);
-+ if (rc)
-+ goto err_free;
-+ return 0;
-+ err_free:
-+ vring_free(wil, vring, 0);
-+ return rc;
-+}
-+
-+void rx_fini(struct wil6210_priv *wil)
-+{
-+ struct vring *vring = &wil->vring_rx;
-+ wil_info(wil, "%s()\n", __func__);
-+ if (vring->va) {
-+ int rc;
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_CFG_RX_CHAIN_CMD cfg;
-+ } __packed wmi_rx_cfg = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 1,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi)
-+ + sizeof(struct WMI_CFG_RX_CHAIN_CMD),
-+ },
-+ .wmi = {
-+ .id = WMI_CFG_RX_CHAIN_CMDID,
-+ .info1 = 0,
-+ },
-+ .cfg = {
-+ .action = DELETE_RX_CHAIN,
-+ .sw_ring = {
-+ .max_mpdu_size = RX_BUF_LEN,
-+ },
-+ },
-+ };
-+ struct {
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_CFG_RX_CHAIN_DONE_EVENT cfg;
-+ } __packed wmi_rx_cfg_reply;
-+ rc = wmi_call(wil, &wmi_rx_cfg, WMI_CFG_RX_CHAIN_DONE_EVENTID,
-+ &wmi_rx_cfg_reply, sizeof(wmi_rx_cfg_reply),
-+ 100);
-+ vring_free(wil, vring, 0);
-+ }
-+}
-+
-+int vring_init_tx(struct wil6210_priv *wil, int id, int size,
-+ int cid, int tid)
-+{
-+ struct wireless_dev *wdev = wil->wdev;
-+ int rc;
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_VRING_CFG_CMD cfg;
-+ } __packed wmi_tx_cfg = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 1,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi)
-+ + sizeof(struct WMI_VRING_CFG_CMD),
-+ },
-+ .wmi = {
-+ .id = WMI_VRING_CFG_CMDID,
-+ .info1 = 0,
-+ },
-+ .cfg = {
-+ .action = ADD_VRING,
-+ .sw_ring = {
-+ .max_mpdu_size = TX_BUF_LEN,
-+ },
-+ .ringid = id,
-+ .cidxtid = (cid & 0xf) | ((tid & 0xf) << 4),
-+ .encap_trans_type = ENC_TYPE_802_3,
-+ .mac_ctrl = 0,
-+ .to_resolution = 0,
-+ .agg_max_wsize = 0,
-+ .priority = 0,
-+ .timeslot_us = 0xfff,
-+ },
-+ };
-+ struct {
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_VRING_CFG_DONE_EVENT cfg;
-+ } __packed reply;
-+ struct vring *vring = &wil->vring_tx[id];
-+ wil_info(wil, "%s(%d)\n", __func__, id);
-+ if (vring->va) {
-+ wil_err(wil, "Tx ring [%d] already allocated\n", id);
-+ rc = -EINVAL;
-+ goto out;
-+ }
-+ vring->size = size;
-+ rc = vring_alloc(wil, vring);
-+ if (rc)
-+ goto out;
-+ wmi_tx_cfg.cfg.sw_ring.ring_mem_base = vring->pa;
-+ wmi_tx_cfg.cfg.sw_ring.ring_size = vring->size;
-+ /* FIXME Firmware works now in PBSS mode(ToDS=0, FromDS=0) */
-+ switch (wdev->iftype) {
-+ case NL80211_IFTYPE_STATION:
-+#if 0
-+ wmi_tx_cfg.cfg.ds_cfg = STATION_MODE;
-+#else
-+ wmi_tx_cfg.cfg.ds_cfg = PBSS_MODE;
-+#endif
-+ break;
-+ case NL80211_IFTYPE_AP:
-+#if 0
-+ wmi_tx_cfg.cfg.ds_cfg = AP_MODE;
-+#else
-+ wmi_tx_cfg.cfg.ds_cfg = PBSS_MODE;
-+#endif
-+ break;
-+ case NL80211_IFTYPE_P2P_CLIENT:
-+ wmi_tx_cfg.cfg.ds_cfg = STATION_MODE;
-+ break;
-+ case NL80211_IFTYPE_P2P_GO:
-+ wmi_tx_cfg.cfg.ds_cfg = AP_MODE;
-+ break;
-+ default:
-+ rc = -EOPNOTSUPP;
-+ goto out_free;
-+
-+ }
-+ rc = wmi_call(wil, &wmi_tx_cfg, WMI_VRING_CFG_DONE_EVENTID,
-+ &reply, sizeof(reply), 100);
-+ if (rc)
-+ goto out_free;
-+ if (reply.cfg.status != VRING_CFG_SUCCESS) {
-+ wil_err(wil, "Tx config failed, status 0x%02x\n",
-+ reply.cfg.status);
-+ goto out_free;
-+ }
-+ vring->hwtail = reply.cfg.tx_vring_tail_ptr;
-+ return 0;
-+ out_free:
-+ vring_free(wil, vring, 1);
-+ out:
-+ return rc;
-+}
-+
-+void vring_fini_tx(struct wil6210_priv *wil, int id)
-+{
-+#if 0
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_VRING_CFG_CMD cfg;
-+ } __packed wmi_tx_cfg = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 1,
-+ .type = 0,
-+ .flags = 1,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi)
-+ + sizeof(struct WMI_VRING_CFG_CMD),
-+ },
-+ .wmi = {
-+ .id = WMI_VRING_CFG_CMDID,
-+ .info1 = 0,
-+ },
-+ .cfg = {
-+ .action = DELETE_VRING,
-+ .sw_ring = {
-+ },
-+ .ringid = id,
-+ },
-+ };
-+ struct {
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_VRING_CFG_DONE_EVENT cfg;
-+ } __packed reply;
-+#endif
-+ struct vring *vring = &wil->vring_tx[id];
-+ if (!vring->va)
-+ return;
-+ wil_info(wil, "%s(%d)\n", __func__, id);
-+#if 0
-+ wmi_call(wil, &wmi_tx_cfg, WMI_VRING_CFG_DONE_EVENTID,
-+ &reply, sizeof(reply), 100);
-+#endif
-+ vring_free(wil, vring, 1);
-+}
-+
-+static struct vring *find_tx_vring(struct wil6210_priv *wil,
-+ struct sk_buff *skb)
-+{
-+ struct vring *v = &wil->vring_tx[0];
-+ if (v->va)
-+ return v;
-+ return NULL;
-+}
-+
-+static int tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len)
-+{
-+ d->dma.addr_low = lower_32_bits(pa);
-+ d->dma.addr_high = (u16)upper_32_bits(pa);
-+ d->dma.ip_length = 0;
-+ /* 0..6: mac_length; 7:ip_version 0-IP6 1-IP4*/
-+ d->dma.b11 = 0/*14 | BIT(7)*/;
-+ d->dma.error = 0;
-+ d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
-+ d->dma.length = len;
-+ d->dma.d0 = 0;
-+ d->mac.d[0] = 0;
-+ d->mac.d[1] = 0;
-+ d->mac.d[2] = 0;
-+ d->mac.ucode_cmd = 0;
-+#if 0
-+ /* use MCS 1 */
-+ d->mac.d[0] |= BIT(MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_MCS_EN_POS) |
-+ (1 << MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_MCS_INDEX_POS);
-+#endif
-+#if 1
-+ /* use dst index 0 */
-+ d->mac.d[1] |= BIT(MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_DST_INDEX_EN_POS) |
-+ (0 << MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_DST_INDEX_POS);
-+#endif
-+#if 0
-+ d->mac.d[0] |= BIT(MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_STATUS_EN_POS);
-+ d->mac.d[0] |= BIT(MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_INTERRUP_EN_POS);
-+#endif
-+ /* translation type: 0 - bypass; 1 - 802.3; 2 - native wifi */
-+ d->mac.d[2] = BIT(MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_SNAP_HDR_INSERTION_EN_POS) |
-+ (1 << MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_L2_TRANSLATION_TYPE_POS);
-+ return 0;
-+}
-+
-+static int tx_vring(struct wil6210_priv *wil, struct vring *vring,
-+ struct sk_buff *skb)
-+{
-+ struct device *dev = wil_to_dev(wil);
-+ struct vring_tx_desc *d;
-+ u32 swhead = vring->swhead;
-+ u32 swtail = vring->swtail;
-+ int used = (vring->size + swhead - swtail) % vring->size;
-+ int avail = vring->size - used - 1;
-+ int nr_frags = skb_shinfo(skb)->nr_frags;
-+ int f;
-+ int vring_index = vring - wil->vring_tx;
-+ int i = swhead;
-+ dma_addr_t pa;
-+#ifdef WIL_DEBUG_TXRX
-+ wil_info(wil, "%s()\n", __func__);
-+#endif
-+ if (avail < vring->size/8)
-+ netif_tx_stop_all_queues(wil_to_ndev(wil));
-+ if (avail < 1 + nr_frags) {
-+ wil_err(wil, "Tx ring full. No space for %d fragments\n",
-+ 1 + nr_frags);
-+ return -ENOMEM;
-+ }
-+ d = &(vring->va[i].tx);
-+
-+ /* FIXME FW can accept only unicast frames for the peer */
-+ memcpy(skb->data, wil->dst_addr[vring_index], ETH_ALEN);
-+
-+ pa = dma_map_single(dev, skb->data,
-+ skb_headlen(skb), DMA_TO_DEVICE);
-+#ifdef WIL_DEBUG_TXRX
-+ wil_info(wil, "Tx skb %d bytes %p -> %#08llx\n",
-+ skb_headlen(skb), skb->data, (unsigned long long)pa);
-+ print_hex_dump(KERN_INFO, "Tx ", DUMP_PREFIX_OFFSET, 16, 1, skb->data
-+ , skb_headlen(skb), false);
-+#endif
-+ if (unlikely(dma_mapping_error(dev, pa)))
-+ return -EINVAL;
-+ /* 1-st segment */
-+ tx_desc_map(d, pa, skb_headlen(skb));
-+ d->mac.d[2] |= ((nr_frags + 1) <<
-+ MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_NUM_OF_DESCRIPTORS_POS);
-+ vring->ctx[i] = skb;
-+ /* middle segments */
-+ for (f = 0; f < nr_frags; f++) {
-+ const struct skb_frag_struct *frag =
-+ &skb_shinfo(skb)->frags[f];
-+ int len = skb_frag_size(frag);
-+ i = (swhead + f + 1) % vring->size;
-+ d = &(vring->va[i].tx);
-+ pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag),
-+ DMA_TO_DEVICE);
-+ if (unlikely(dma_mapping_error(dev, pa)))
-+ goto dma_error;
-+ tx_desc_map(d, pa, len);
-+ vring->ctx[i] = NULL;
-+ }
-+ /* for the last seg only */
-+ d->dma.d0 |= BIT(DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_CMD_EOP_POS);
-+ d->dma.d0 |= BIT(9);
-+ d->dma.d0 |= BIT(DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_CMD_DMA_IT_POS);
-+ d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_QID_POS);
-+#ifdef WIL_DEBUG_TXRX
-+ print_hex_dump(KERN_INFO, "Tx ", DUMP_PREFIX_NONE, 32, 4, d
-+ , sizeof(*d), false);
-+#endif
-+ /* advance swhead */
-+ vring->swhead = (swhead + nr_frags + 1) % vring->size;
-+#ifdef WIL_DEBUG_TXRX
-+ wil_info(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
-+#endif
-+ iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
-+ return 0;
-+ dma_error:
-+ /* unmap what we have mapped */
-+ for (; f > -1; f--) {
-+ i = (swhead + f + 1) % vring->size;
-+ d = &(vring->va[i].tx);
-+ d->dma.status = TX_DMA_STATUS_DU;
-+ pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
-+ if (vring->ctx[i])
-+ dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE);
-+ else
-+ dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE);
-+ }
-+ return -EINVAL;
-+}
-+
-+
-+netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
-+{
-+ struct wil6210_priv *wil = ndev_to_wil(ndev);
-+ struct vring *vring;
-+#ifdef WIL_DEBUG_TXRX
-+ wil_info(wil, "%s()\n", __func__);
-+#endif
-+ if (!test_bit(wil_status_fwready, &wil->status)) {
-+ wil_err(wil, "FW not ready\n");
-+ goto drop;
-+ }
-+ if (!test_bit(wil_status_fwconnected, &wil->status)) {
-+ wil_err(wil, "FW not connected\n");
-+ goto drop;
-+ }
-+ if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
-+ wil_err(wil, "Xmit in monitor mode not supported\n");
-+ goto drop;
-+ }
-+ /* find vring */
-+ vring = find_tx_vring(wil, skb);
-+ if (!vring) {
-+ wil_err(wil, "No Tx VRING available\n");
-+ goto drop;
-+ }
-+ /* set up vring entry */
-+ switch (tx_vring(wil, vring, skb)) {
-+ case 0:
-+ ndev->stats.tx_packets++;
-+ ndev->stats.tx_bytes += skb->len;
-+ return NETDEV_TX_OK;
-+ break;
-+ case -ENOMEM:
-+ return NETDEV_TX_BUSY;
-+ default:
-+ ; /* goto drop; */
-+ break;
-+ }
-+ drop:
-+ netif_tx_stop_all_queues(ndev);
-+ ndev->stats.tx_dropped++;
-+ dev_kfree_skb_any(skb);
-+ return NET_XMIT_DROP;
-+}
-+
-+/**
-+ * Clean up transmitted skb's from the Tx VRING
-+ *
-+ * Safe to call from IRQ
-+ */
-+void tx_complete(struct wil6210_priv *wil, int ringid)
-+{
-+ struct device *dev = wil_to_dev(wil);
-+ struct vring *vring = &wil->vring_tx[ringid];
-+ if (!vring->va) {
-+ wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid);
-+ return;
-+ }
-+#ifdef WIL_DEBUG_TXRX
-+ wil_info(wil, "%s(%d)\n", __func__, ringid);
-+#endif
-+ while (!vring_is_empty(vring)) {
-+ struct vring_tx_desc *d = &vring->va[vring->swtail].tx;
-+ dma_addr_t pa;
-+ struct sk_buff *skb;
-+ if (!(d->dma.status & TX_DMA_STATUS_DU))
-+ break;
-+#ifdef WIL_DEBUG_TXRX
-+ wil_info(wil, "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n",
-+ vring->swtail, d->dma.length, d->dma.status,
-+ d->dma.error);
-+ print_hex_dump(KERN_INFO, "TxC ", DUMP_PREFIX_NONE, 32, 4, d
-+ , sizeof(*d), false);
-+#endif
-+ pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
-+ skb = vring->ctx[vring->swtail];
-+ if (skb) {
-+ dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE);
-+ dev_kfree_skb_any(skb);
-+ vring->ctx[vring->swtail] = NULL;
-+ } else {
-+ dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE);
-+ }
-+ d->dma.addr_low = 0;
-+ d->dma.addr_high = 0;
-+ d->dma.length = 0;
-+ d->dma.status = TX_DMA_STATUS_DU;
-+ vring->swtail = (vring->swtail + 1) % vring->size;
-+ }
-+ {
-+ u32 swhead = vring->swhead;
-+ u32 swtail = vring->swtail;
-+ int used = (vring->size + swhead - swtail) % vring->size;
-+ int avail = vring->size - used - 1;
-+ if (avail > vring->size/4)
-+ netif_tx_wake_all_queues(wil_to_ndev(wil));
-+ }
-+}
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/txrx.h
-@@ -0,0 +1,352 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef WIL6210_TXRX_H
-+#define WIL6210_TXRX_H
-+
-+#define BUF_SW_OWNED (1)
-+#define BUF_HW_OWNED (0)
-+
-+/* size of max. Rx packet */
-+#define RX_BUF_LEN (2048)
-+#define TX_BUF_LEN (2048)
-+/* how many bytes to reserve for rtap header? */
-+#define WIL6210_RTAP_SIZE (128)
-+
-+/* Tx/Rx path */
-+/*
-+ * Tx descriptor - MAC part
-+ * [dword 0]
-+ * bit 0.. 9 : lifetime_expiry_value:10
-+ * bit 10 : interrup_en:1
-+ * bit 11 : status_en:1
-+ * bit 12..13 : txss_override:2
-+ * bit 14 : timestamp_insertion:1
-+ * bit 15 : duration_preserve:1
-+ * bit 16..21 : reserved0:6
-+ * bit 22..26 : mcs_index:5
-+ * bit 27 : mcs_en:1
-+ * bit 28..29 : reserved1:2
-+ * bit 30 : reserved2:1
-+ * bit 31 : sn_preserved:1
-+ * [dword 1]
-+ * bit 0.. 3 : pkt_mode:4
-+ * bit 4 : pkt_mode_en:1
-+ * bit 5.. 7 : reserved0:3
-+ * bit 8..13 : reserved1:6
-+ * bit 14 : reserved2:1
-+ * bit 15 : ack_policy_en:1
-+ * bit 16..19 : dst_index:4
-+ * bit 20 : dst_index_en:1
-+ * bit 21..22 : ack_policy:2
-+ * bit 23 : lifetime_en:1
-+ * bit 24..30 : max_retry:7
-+ * bit 31 : max_retry_en:1
-+ * [dword 2]
-+ * bit 0.. 7 : num_of_descriptors:8
-+ * bit 8..17 : reserved:10
-+ * bit 18..19 : l2_translation_type:2
-+ * bit 20 : snap_hdr_insertion_en:1
-+ * bit 21 : vlan_removal_en:1
-+ * bit 22..31 : reserved0:10
-+ * [dword 3]
-+ * bit 0.. 31: ucode_cmd:32
-+ */
-+struct vring_tx_mac {
-+ u32 d[3];
-+ u32 ucode_cmd;
-+} __packed;
-+
-+/* TX MAC Dword 0 */
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_LIFETIME_EXPIRY_VALUE_POS 0
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_LIFETIME_EXPIRY_VALUE_LEN 10
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_LIFETIME_EXPIRY_VALUE_MSK 0x3FF
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_INTERRUP_EN_POS 10
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_INTERRUP_EN_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_INTERRUP_EN_MSK 0x400
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_STATUS_EN_POS 11
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_STATUS_EN_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_STATUS_EN_MSK 0x800
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_TXSS_OVERRIDE_POS 12
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_TXSS_OVERRIDE_LEN 2
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_TXSS_OVERRIDE_MSK 0x3000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_TIMESTAMP_INSERTION_POS 14
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_TIMESTAMP_INSERTION_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_TIMESTAMP_INSERTION_MSK 0x4000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_DURATION_PRESERVE_POS 15
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_DURATION_PRESERVE_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_DURATION_PRESERVE_MSK 0x8000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_MCS_INDEX_POS 22
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_MCS_INDEX_LEN 5
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_MCS_INDEX_MSK 0x7C00000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_MCS_EN_POS 27
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_MCS_EN_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_MCS_EN_MSK 0x8000000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_SN_PRESERVED_POS 31
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_SN_PRESERVED_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_0_SN_PRESERVED_MSK 0x80000000
-+
-+/* TX MAC Dword 1 */
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_PKT_MODE_POS 0
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_PKT_MODE_LEN 4
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_PKT_MODE_MSK 0xF
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_PKT_MODE_EN_POS 4
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_PKT_MODE_EN_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_PKT_MODE_EN_MSK 0x10
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_ACK_POLICY_EN_POS 15
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_ACK_POLICY_EN_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_ACK_POLICY_EN_MSK 0x8000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_DST_INDEX_POS 16
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_DST_INDEX_LEN 4
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_DST_INDEX_MSK 0xF0000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_DST_INDEX_EN_POS 20
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_DST_INDEX_EN_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_DST_INDEX_EN_MSK 0x100000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_ACK_POLICY_POS 21
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_ACK_POLICY_LEN 2
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_ACK_POLICY_MSK 0x600000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_LIFETIME_EN_POS 23
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_LIFETIME_EN_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_LIFETIME_EN_MSK 0x800000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_MAX_RETRY_POS 24
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_MAX_RETRY_LEN 7
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_MAX_RETRY_MSK 0x7F000000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_MAX_RETRY_EN_POS 31
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_MAX_RETRY_EN_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_1_MAX_RETRY_EN_MSK 0x80000000
-+
-+/* TX MAC Dword 2 */
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_NUM_OF_DESCRIPTORS_POS 0
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_NUM_OF_DESCRIPTORS_LEN 8
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_NUM_OF_DESCRIPTORS_MSK 0xFF
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_RESERVED_POS 8
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_RESERVED_LEN 10
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_RESERVED_MSK 0x3FF00
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_L2_TRANSLATION_TYPE_POS 18
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_L2_TRANSLATION_TYPE_LEN 2
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_L2_TRANSLATION_TYPE_MSK 0xC0000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_SNAP_HDR_INSERTION_EN_POS 20
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_SNAP_HDR_INSERTION_EN_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_SNAP_HDR_INSERTION_EN_MSK 0x100000
-+
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_VLAN_REMOVAL_EN_POS 21
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_VLAN_REMOVAL_EN_LEN 1
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_2_VLAN_REMOVAL_EN_MSK 0x200000
-+
-+/* TX MAC Dword 3 */
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_3_UCODE_CMD_POS 0
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_3_UCODE_CMD_LEN 32
-+#define MAC_CFG_DESC_TX_DESCRIPTOR_MAC_3_UCODE_CMD_MSK 0xFFFFFFFF
-+
-+/* TX DMA Dword 0 */
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_L4_LENGTH_POS 0
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_L4_LENGTH_LEN 8
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_L4_LENGTH_MSK 0xFF
-+
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_CMD_EOP_POS 8
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_CMD_EOP_LEN 1
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_CMD_EOP_MSK 0x100
-+
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_CMD_DMA_IT_POS 10
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_CMD_DMA_IT_LEN 1
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_CMD_DMA_IT_MSK 0x400
-+
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_SEGMENT_BUF_DETAILS_POS 11
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_SEGMENT_BUF_DETAILS_LEN 2
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_SEGMENT_BUF_DETAILS_MSK 0x1800
-+
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_TCP_SEG_EN_POS 13
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_TCP_SEG_EN_LEN 1
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_TCP_SEG_EN_MSK 0x2000
-+
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_IPV4_CHECKSUM_EN_POS 14
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_IPV4_CHECKSUM_EN_LEN 1
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_IPV4_CHECKSUM_EN_MSK 0x4000
-+
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_TCP_UDP_CHECKSUM_EN_POS 15
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_TCP_UDP_CHECKSUM_EN_LEN 1
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_TCP_UDP_CHECKSUM_EN_MSK 0x8000
-+
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_QID_POS 16
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_QID_LEN 5
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_QID_MSK 0x1F0000
-+
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_PSEUDO_HEADER_CALC_EN_POS 21
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_PSEUDO_HEADER_CALC_EN_LEN 1
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_PSEUDO_HEADER_CALC_EN_MSK 0x200000
-+
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_L4_TYPE_POS 30
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_L4_TYPE_LEN 2
-+#define DMA_CFG_DESC_TX_DESCRIPTOR_DMA_0_L4_TYPE_MSK 0xC0000000
-+
-+
-+#define TX_DMA_STATUS_DU BIT(0)
-+
-+struct vring_tx_dma {
-+ u32 d0;
-+ u32 addr_low;
-+ u16 addr_high;
-+ u8 ip_length;
-+ u8 b11; /* 0..6: mac_length; 7:ip_version */
-+ u8 error; /* 0..2: err; 3..7: reserved; */
-+ u8 status; /* 0: used; 1..7; reserved */
-+ u16 length;
-+} __packed;
-+
-+/*
-+ * Rx descriptor - MAC part
-+ * [dword 0]
-+ * bit 0.. 3 : tid:4 The QoS (b3-0) TID Field
-+ * bit 4.. 6 : connection_id:3 :The Source index that was found during
-+ * Parsing the TA. This field is used to define the source of the packet
-+ * bit 7 : reserved:1
-+ * bit 8.. 9 : mac_id:2 : The MAC virtual Ring number (always zero)
-+ * bit 10..11 : frame_type:2 : The FC Control (b3-2) - MPDU Type
-+ * (management, data, control and extension)
-+ * bit 12..15 : frame_subtype:4 : The FC Control (b7-4) - Frame Subtype
-+ * bit 16..27 : seq_number:12 The received Sequence number field
-+ * bit 28..31 : extended:4 extended subtype
-+ * [dword 1]
-+ * bit 0.. 3 : reserved
-+ * bit 4.. 5 : key_id:2
-+ * bit 6 : decrypt_bypass:1
-+ * bit 7 : security:1
-+ * bit 8.. 9 : ds_bits:2
-+ * bit 10 : a_msdu_present:1 from qos header
-+ * bit 11 : a_msdu_type:1 from qos header
-+ * bit 12 : a_mpdu:1 part of AMPDU aggregation
-+ * bit 13 : broadcast:1
-+ * bit 14 : mutlicast:1
-+ * bit 15 : reserved:1
-+ * bit 16..20 : rx_mac_qid:5 The Queue Identifier that the packet
-+ * is received from
-+ * bit 21..24 : mcs:4
-+ * bit 25..28 : mic_icr:4
-+ * bit 29..31 : reserved:3
-+ * [dword 2]
-+ * bit 0.. 2 : time_slot:3 The timeslot that the MPDU is received
-+ * bit 3 : fc_protocol_ver:1 The FC Control (b0) - Protocol Version
-+ * bit 4 : fc_order:1 The FC Control (b15) -Order
-+ * bit 5.. 7 : qos_ack_policy:3 The QoS (b6-5) ack policy Field
-+ * bit 8 : esop:1 The QoS (b4) ESOP field
-+ * bit 9 : qos_rdg_more_ppdu:1 The QoS (b9) RDG field
-+ * bit 10..14 : qos_reserved:5 The QoS (b14-10) Reserved field
-+ * bit 15 : qos_ac_constraint:1
-+ * bit 16..31 : pn_15_0:16 low 2 bytes of PN
-+ * [dword 3]
-+ * bit 0..31 : pn_47_16:32 high 4 bytes of PN
-+ */
-+struct vring_rx_mac {
-+ u32 d0;
-+ u32 d1;
-+ u16 w4;
-+ u16 pn_15_0;
-+ u32 pn_47_16;
-+} __packed;
-+
-+/*
-+ * Rx descriptor - DMA part
-+ * [dword 0]
-+ * bit 0.. 7 : l4_length:8 layer 4 length
-+ * bit 8.. 9 : reserved:2
-+ * bit 10 : cmd_dma_it:1
-+ * bit 11..15 : reserved:5
-+ * bit 16..29 : phy_info_length:14
-+ * bit 30..31 : l4_type:2 valid if the L4I bit is set in the status field
-+ * [dword 1]
-+ * bit 0..31 : addr_low:32 The payload buffer low address
-+ * [dword 2]
-+ * bit 0..15 : addr_high:16 The payload buffer high address
-+ * bit 16..23 : ip_length:8
-+ * bit 24..30 : mac_length:7
-+ * bit 31 : ip_version:1
-+ * [dword 3]
-+ * [byte 12] error
-+ * [byte 13] status
-+ * bit 0 : du:1
-+ * bit 1 : eop:1
-+ * bit 2 : error:1
-+ * bit 3 : mi:1
-+ * bit 4 : l3_identified:1
-+ * bit 5 : l4_identified:1
-+ * bit 6 : phy_info_included:1
-+ * bit 7 : reserved:1
-+ * [word 7] length
-+ *
-+ */
-+
-+#define RX_DMA_D0_CMD_DMA_IT BIT(10)
-+
-+#define RX_DMA_STATUS_DU BIT(0)
-+#define RX_DMA_STATUS_ERROR BIT(2)
-+#define RX_DMA_STATUS_PHY_INFO BIT(6)
-+
-+struct vring_rx_dma {
-+ u32 d0;
-+ u32 addr_low;
-+ u16 addr_high;
-+ u8 ip_length;
-+ u8 b11;
-+ u8 error;
-+ u8 status;
-+ u16 length;
-+} __packed;
-+
-+struct vring_tx_desc {
-+ struct vring_tx_mac mac;
-+ struct vring_tx_dma dma;
-+} __packed;
-+
-+struct vring_rx_desc {
-+ struct vring_rx_mac mac;
-+ struct vring_rx_dma dma;
-+} __packed;
-+
-+union vring_desc {
-+ struct vring_tx_desc tx;
-+ struct vring_rx_desc rx;
-+} __packed;
-+
-+static inline int rxdesc_phy_length(struct vring_rx_desc *d)
-+{
-+ return GET_BITS(d->dma.d0, 16, 29);
-+}
-+
-+static inline int rxdesc_mcs(struct vring_rx_desc *d)
-+{
-+ return GET_BITS(d->mac.d1, 21, 24);
-+}
-+
-+#endif /* WIL6210_TXRX_H */
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/vrwatch.sh
-@@ -0,0 +1,6 @@
-+#!/bin/bash
-+# Watch VRING's
-+### where is wil6210 debugfs?
-+D=$(find /sys/kernel/debug/ieee80211/ -name wil6210)
-+exec watch -n 0.2 -d cat $D/vrings
-+
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
-@@ -0,0 +1,234 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef __WIL6210_H__
-+#define __WIL6210_H__
-+
-+#include <linux/netdevice.h>
-+#include <linux/wireless.h>
-+#include <net/cfg80211.h>
-+
-+#define WIL_NAME "wil6210"
-+#define PCI_VENDOR_ID_WIL6210 (0x1ae9)
-+#define PCI_DEVICE_ID_WIL6210 (0x0301)
-+
-+/**
-+ * extract bits [@b0:@b1] (inclusive) from the value @x
-+ * it should be @b0 <= @b1, or result is incorrect
-+ */
-+static inline u32 GET_BITS(u32 x, int b0, int b1)
-+{
-+ return (x >> b0) & ((1 << (b1 - b0 + 1)) - 1);
-+}
-+
-+#define WIL6210_MEM_SIZE (2*1024*1024UL)
-+
-+#define WIL6210_TX_QUEUES (4)
-+
-+#define WIL6210_RX_RING_SIZE (128)
-+#define WIL6210_TX_RING_SIZE (128)
-+#define WIL6210_MAX_TX_RINGS (24)
-+
-+struct wil6210_mbox_ring {
-+ u32 base;
-+ u16 unused;
-+ u16 size;
-+ u32 tail;
-+ u32 head;
-+} __packed;
-+
-+struct wil6210_mbox_ring_desc {
-+ u32 sync;
-+ u32 addr;
-+} __packed;
-+
-+/* at HOST_OFF_WIL6210_MBOX_CTL */
-+struct wil6210_mbox_ctl {
-+ struct wil6210_mbox_ring tx;
-+ struct wil6210_mbox_ring rx;
-+} __packed;
-+
-+struct wil6210_mbox_hdr {
-+ u16 seq;
-+ u16 ctx;
-+ u16 type;
-+ u8 flags;
-+ u8 len; /* payload, bytes after this header */
-+} __packed;
-+
-+/* max. value for wil6210_mbox_hdr.len */
-+#define MAX_MBOXITEM_SIZE (120)
-+
-+struct wil6210_mbox_hdr_wmi {
-+ u16 reserved0;
-+ u16 id;
-+ u16 info1;
-+ u16 reserved1;
-+} __packed;
-+
-+struct pending_wmi_event {
-+ struct list_head list;
-+ struct {
-+ struct wil6210_mbox_hdr mbox_hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ u8 data[0];
-+ } __packed event;
-+};
-+
-+union vring_desc;
-+
-+struct vring {
-+ dma_addr_t pa;
-+ union vring_desc *va; /* vring_desc[size] */
-+ u16 size; /* number of vring_desc elements */
-+ u32 swtail;
-+ u32 swhead;
-+ u32 hwtail; /* write here to inform hw */
-+ void **ctx; /* void *ctx[size] - software context */
-+};
-+
-+enum { /* for wil6210_priv.status */
-+ wil_status_fwready = 0,
-+ wil_status_fwconnected,
-+ wil_status_dontscan,
-+ wil_status_irqen, /* FIXME: interrupts enabled - for debug */
-+};
-+
-+struct pci_dev;
-+
-+struct wil6210_stats {
-+ u16 last_mcs_rx;
-+ u16 bf_mcs; /* last BF, used for Tx */
-+};
-+
-+struct wil6210_priv {
-+ struct pci_dev *pdev;
-+ int n_msi;
-+ struct wireless_dev *wdev;
-+ void __iomem *csr;
-+ unsigned long status;
-+ /* profile */
-+ u32 monitor_flags;
-+ struct ieee80211_channel *monitor_chan;
-+ /* cached ISR registers */
-+ u32 isr_rx;
-+ u32 isr_tx;
-+ u32 isr_misc;
-+ /* mailbox related */
-+ struct mutex wmi_mutex;
-+ struct wil6210_mbox_ctl mbox_ctl;
-+ struct completion wmi_ready;
-+ u16 wmi_seq;
-+ u16 reply_id; /**< wait for this WMI event */
-+ void *reply_buf;
-+ u8 reply_size;
-+ struct workqueue_struct *wmi_wq; /* for deferred calls */
-+ struct work_struct wmi_event_worker;
-+ struct workqueue_struct *wmi_wq_conn; /* for connect worker */
-+ struct work_struct wmi_connect_worker;
-+ struct timer_list connect_timer;
-+ int pending_connect_cid;
-+ struct list_head pending_wmi_ev;
-+ spinlock_t wmi_ev_lock;
-+
-+ /* DMA related */
-+ struct vring vring_rx;
-+ struct vring vring_tx[WIL6210_MAX_TX_RINGS];
-+ u8 dst_addr[WIL6210_MAX_TX_RINGS][ETH_ALEN];
-+ /* scan */
-+ struct cfg80211_scan_request *scan_request;
-+
-+ struct mutex mutex;
-+ /* statistics */
-+ struct wil6210_stats stats;
-+ /* debugfs */
-+ struct dentry *debug;
-+ struct debugfs_blob_wrapper fw_code_blob;
-+ struct debugfs_blob_wrapper fw_data_blob;
-+ struct debugfs_blob_wrapper fw_peri_blob;
-+ struct debugfs_blob_wrapper uc_code_blob;
-+ struct debugfs_blob_wrapper uc_data_blob;
-+ struct debugfs_blob_wrapper rgf_blob;
-+};
-+
-+#define wil_to_wiphy(i) (i->wdev->wiphy)
-+#define wil_to_dev(i) (wiphy_dev(wil_to_wiphy(i)))
-+#define wiphy_to_wil(w) (struct wil6210_priv *)(wiphy_priv(w))
-+#define wil_to_wdev(i) (i->wdev)
-+#define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w))
-+#define wil_to_ndev(i) (wil_to_wdev(i)->netdev)
-+#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr))
-+
-+#define wil_info(wil, fmt, arg...) netdev_info(wil_to_ndev(wil), fmt, ##arg)
-+#define wil_err(wil, fmt, arg...) netdev_err(wil_to_ndev(wil), fmt, ##arg)
-+
-+void memcpy_fromio_32(void *dst, const volatile void __iomem *src,
-+ size_t count);
-+void memcpy_toio_32(volatile void __iomem *dst, const void *src, size_t count);
-+
-+void *wil_if_alloc(struct device *dev, void __iomem *csr);
-+void wil_if_free(struct wil6210_priv *wil);
-+int wil_if_add(struct wil6210_priv *wil);
-+void wil_if_remove(struct wil6210_priv *wil);
-+int wil_priv_init(struct wil6210_priv *wil);
-+void wil_priv_deinit(struct wil6210_priv *wil);
-+int wil_reset(struct wil6210_priv *wil);
-+void wil_link_on(struct wil6210_priv *wil);
-+void wil_link_off(struct wil6210_priv *wil);
-+int wil_up(struct wil6210_priv *wil);
-+int wil_down(struct wil6210_priv *wil);
-+
-+void __iomem *wmi_buffer(struct wil6210_priv *wil, u32 ptr);
-+void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr);
-+int wmi_read_hdr(struct wil6210_priv *wil, u32 ptr,
-+ struct wil6210_mbox_hdr *hdr);
-+int wmi_send_cmd(struct wil6210_priv *wil, void *buf);
-+void wmi_recv_cmd(struct wil6210_priv *wil);
-+int wmi_call(struct wil6210_priv *wil, void *buf,
-+ u16 reply_id, void *reply, u8 reply_size, int to_msec);
-+void wmi_connect_worker(struct work_struct *work);
-+void wmi_event_worker(struct work_struct *work);
-+void wmi_event_flush(struct wil6210_priv *wil);
-+
-+int wil6210_init_irq(struct wil6210_priv *wil, int irq);
-+void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
-+void wil6210_disable_irq(struct wil6210_priv *wil);
-+void wil6210_enable_irq(struct wil6210_priv *wil);
-+
-+int wil6210_debugfs_init(struct wil6210_priv *wil);
-+void wil6210_debugfs_remove(struct wil6210_priv *wil);
-+
-+int wil6210_set_mac_address(struct wil6210_priv *wil, void *addr);
-+int wil6210_set_bcon(struct wil6210_priv *wil, int bi, u16 wmi_nettype);
-+void wil6210_disconnect(struct wil6210_priv *wil, void *bssid);
-+
-+int rx_init(struct wil6210_priv *wil);
-+void rx_fini(struct wil6210_priv *wil);
-+
-+/* TX API */
-+int vring_init_tx(struct wil6210_priv *wil, int id,
-+ int size, int cid, int tid);
-+void vring_fini_tx(struct wil6210_priv *wil, int id);
-+
-+netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
-+void tx_complete(struct wil6210_priv *wil, int ringid);
-+
-+/* RX API */
-+void rx_handle(struct wil6210_priv *wil);
-+
-+int iftype_nl2wmi(enum nl80211_iftype type);
-+
-+#endif /* __WIL6210_H__ */
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/wil6210_rgf.h
-@@ -0,0 +1,93 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef WIL6210_RGF_H
-+#define WIL6210_RGF_H
-+
-+/**
-+ * Hardware registers map
-+ *
-+ */
-+
-+/**
-+ * Mapping
-+ * RGF File | Host addr | FW addr
-+ * | |
-+ * user_rgf | 0x000000 | 0x880000
-+ * dma_rgf | 0x001000 | 0x881000
-+ * pcie_rgf | 0x002000 | 0x882000
-+ * | |
-+ */
-+
-+/* Where various structures placed in host address space */
-+#define WIL6210_FW_HOST_OFF (0x880000UL)
-+
-+#define HOSTADDR(fwaddr) (fwaddr - WIL6210_FW_HOST_OFF)
-+
-+/**
-+ * Interrupt control registers block
-+ *
-+ * each interrupt controlled by the same bit in all registers
-+ */
-+struct RGF_ICR {
-+ u32 ICC; /* Cause Control, RW: 0 - W1C, 1 - COR */
-+ u32 ICR; /* Cause, W1C/COR depending on ICC */
-+ u32 ICM; /* Cause masked (ICR & ~IMV), W1C/COR depending on ICC */
-+ u32 ICS; /* Cause Set, WO */
-+ u32 IMV; /* Mask, RW+S/C */
-+ u32 IMS; /* Mask Set, write 1 to set */
-+ u32 IMC; /* Mask Clear, write 1 to clear */
-+} __packed;
-+
-+/* registers - FW addresses */
-+#define RGF_USER_USER_SCRATCH_PAD (0x8802bc)
-+#define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */
-+ #define BIT_USER_USER_ICR_SW_INT_2 BIT(18)
-+#define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14)
-+#define RGF_USER_MAC_CPU_0 (0x8801fc)
-+#define RGF_USER_USER_CPU_0 (0x8801e0)
-+#define RGF_USER_CLKS_CTL_SW_RST_VEC_0 (0x880b04)
-+#define RGF_USER_CLKS_CTL_SW_RST_VEC_1 (0x880b08)
-+#define RGF_USER_CLKS_CTL_SW_RST_VEC_2 (0x880b0c)
-+#define RGF_USER_CLKS_CTL_SW_RST_VEC_3 (0x880b10)
-+
-+#define RGF_DMA_PSEUDO_CAUSE (0x881c68)
-+#define RGF_DMA_PSEUDO_CAUSE_MASK_SW (0x881c6c)
-+#define RGF_DMA_PSEUDO_CAUSE_MASK_FW (0x881c70)
-+ #define BIT_DMA_PSEUDO_CAUSE_RX BIT(0)
-+ #define BIT_DMA_PSEUDO_CAUSE_TX BIT(1)
-+ #define BIT_DMA_PSEUDO_CAUSE_MISC BIT(2)
-+
-+#define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */
-+ #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0)
-+ #define BIT_DMA_EP_TX_ICR_TX_DONE_N(n) BIT(n+1) /* n = [0..23] */
-+#define RGF_DMA_EP_RX_ICR (0x881bd0) /* struct RGF_ICR */
-+ #define BIT_DMA_EP_RX_ICR_RX_DONE BIT(0)
-+#define RGF_DMA_EP_MISC_ICR (0x881bec) /* struct RGF_ICR */
-+ #define BIT_DMA_EP_MISC_ICR_FW_INT0 BIT(28)
-+ #define BIT_DMA_EP_MISC_ICR_FW_INT1 BIT(29)
-+
-+/* popular locations */
-+#define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD)
-+#define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \
-+ offsetof(struct RGF_ICR, ICS))
-+#define SW_INT_MBOX BIT_USER_USER_ICR_SW_INT_2
-+
-+/* ISR register bits */
-+#define ISR_MISC_FW_READY BIT_DMA_EP_MISC_ICR_FW_INT0
-+#define ISR_MISC_MBOX_EVT BIT_DMA_EP_MISC_ICR_FW_INT1
-+
-+#endif /* WIL6210_RGF_H */
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/wmi.c
-@@ -0,0 +1,710 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/pci.h>
-+#include <linux/io.h>
-+#include <linux/list.h>
-+#include <linux/etherdevice.h>
-+
-+#include "wil6210.h"
-+#include "wil6210_rgf.h"
-+#include "wmi.h"
-+
-+/**
-+ * WMI event receiving - theory of operations
-+ *
-+ * When firmware about to report WMI event, it fills memory area
-+ * in the mailbox and raises misc. IRQ. Thread interrupt handler invoked for
-+ * the misc IRQ, function @wmi_recv_cmd called by thread IRQ handler.
-+ *
-+ * @wmi_recv_cmd reads event, allocates memory chunk and attaches it to the
-+ * event list @wil->pending_wmi_ev. Then, work queue @wil->wmi_wq wakes up
-+ * and handles events within the @wmi_event_worker. Every event get detached
-+ * from list, processed and deleted.
-+ *
-+ * Purpose for this mechanism is to release IRQ thread; otherwise,
-+ * if WMI event handling involves another WMI command flow, this 2-nd flow
-+ * won't be completed because of blocked IRQ thread.
-+ */
-+
-+/**
-+ * Addressing - theory of operations
-+ *
-+ * There are several buses present on the WIL6210 card.
-+ * Same memory areas are visible at different address on
-+ * the different busses. There are 3 main bus masters:
-+ * - MAC CPU (ucode)
-+ * - User CPU (firmware)
-+ * - AHB (host)
-+ *
-+ * On the PCI bus, there is one BAR (BAR0) of 2Mb size, exposing
-+ * AHB addresses starting from 0x880000
-+ *
-+ * Internally, firmware uses addresses that allows faster access but
-+ * are invisible from the host. To read from these addresses, alternative
-+ * AHB address must be used.
-+ *
-+ * Memory mapping
-+ * Linker address PCI/Host address
-+ * 0x880000 .. 0xa80000 2Mb BAR0
-+ * 0x800000 .. 0x807000 0x900000 .. 0x907000 28k DCCM
-+ * 0x840000 .. 0x857000 0x908000 .. 0x91f000 92k PERIPH
-+ */
-+
-+/**
-+ * @fw_mapping provides memory remapping table
-+ */
-+static const struct {
-+ u32 from; /* linker address - from, inclusive */
-+ u32 to; /* linker address - to, exclusive */
-+ u32 host; /* PCI/Host address */
-+} fw_mapping[] = {
-+ {0x000000, 0x040000, 0x8c0000}, /* FW code RAM 256k */
-+ {0x800000, 0x808000, 0x900000}, /* FW data RAM 32k */
-+ {0x840000, 0x860000, 0x908000}, /* peripheral data RAM 128k/96k used */
-+ {0x880000, 0x88a000, 0x880000}, /* various RGF */
-+ {0x8c0000, 0x92a000, 0x8c0000}, /* trivial mapping for upper area */
-+ /*
-+ * 920000..928000 ucode code RAM
-+ * 928000..92a000 ucode data RAM
-+ */
-+};
-+
-+/**
-+ * return AHB address for given firmware/ucode internal (linker) address
-+ * @x - internal address
-+ * If address have no valid AHB mapping, return 0
-+ */
-+static u32 wmi_addr_remap(u32 x)
-+{
-+ int i;
-+ for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
-+ if ((x >= fw_mapping[i].from) && (x < fw_mapping[i].to))
-+ return x + fw_mapping[i].host - fw_mapping[i].from;
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * Check address validity for WMI buffer; remap if needed
-+ * @ptr - internal (linker) fw/ucode address
-+ *
-+ * Valid buffer should be DWORD aligned
-+ *
-+ * return address for accessing buffer from the host;
-+ * if buffer is not valid, return NULL.
-+ */
-+void __iomem *wmi_buffer(struct wil6210_priv *wil, u32 ptr)
-+{
-+ u32 off;
-+ if (ptr % 4)
-+ return NULL;
-+ ptr = wmi_addr_remap(ptr);
-+ if (ptr < WIL6210_FW_HOST_OFF)
-+ return NULL;
-+ off = HOSTADDR(ptr);
-+ if (off > WIL6210_MEM_SIZE - 4)
-+ return NULL;
-+ return wil->csr + off;
-+}
-+
-+/**
-+ * Check address validity
-+ */
-+void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr)
-+{
-+ u32 off;
-+ if (ptr % 4)
-+ return NULL;
-+ if (ptr < WIL6210_FW_HOST_OFF)
-+ return NULL;
-+ off = HOSTADDR(ptr);
-+ if (off > WIL6210_MEM_SIZE - 4)
-+ return NULL;
-+ return wil->csr + off;
-+}
-+
-+int wmi_read_hdr(struct wil6210_priv *wil, u32 ptr,
-+ struct wil6210_mbox_hdr *hdr)
-+{
-+ void __iomem *src = wmi_buffer(wil, ptr);
-+ if (!src)
-+ return -EINVAL;
-+ memcpy_fromio_32(hdr, src, sizeof(*hdr));
-+ return 0;
-+}
-+
-+static int __wmi_send_cmd(struct wil6210_priv *wil, void *buf)
-+{
-+ struct wil6210_mbox_hdr *hdr = buf;
-+ struct wil6210_mbox_ring *r = &wil->mbox_ctl.tx;
-+ struct wil6210_mbox_ring_desc d_head;
-+ u32 next_head;
-+ void __iomem *dst;
-+ void __iomem *head = wmi_addr(wil, r->head);
-+ int retry;
-+ wil_info(wil, "%s()\n", __func__);
-+ might_sleep();
-+ if (!test_bit(wil_status_fwready, &wil->status)) {
-+ wil_err(wil, "FW not ready\n");
-+ return -EAGAIN;
-+ }
-+ if (!head) {
-+ wil_err(wil, "WMI head is garbage: 0x%08x\n", r->head);
-+ return -EINVAL;
-+ }
-+ /* read Tx head */
-+ memcpy_fromio_32(&d_head, head
-+ , sizeof(struct wil6210_mbox_ring_desc));
-+ if (d_head.sync != 0) {
-+ wil_err(wil, "WMI head busy\n");
-+ return -EBUSY;
-+ }
-+ /* next head */
-+ next_head = r->base + ((r->head - r->base
-+ + sizeof(struct wil6210_mbox_ring_desc)) % r->size);
-+ wil_info(wil, "Head 0x%08x -> 0x%08x\n"
-+ , r->head, next_head);
-+ /* wait till FW finish with previous command */
-+ for (retry = 5; retry > 0; retry--) {
-+ r->tail = ioread32(wil->csr + HOST_MBOX
-+ + offsetof(struct wil6210_mbox_ctl, tx.tail));
-+ if (next_head != r->tail)
-+ break;
-+ msleep(20);
-+ }
-+ if (next_head == r->tail) {
-+ wil_err(wil, "WMI ring full\n");
-+ return -EBUSY;
-+ }
-+ dst = wmi_buffer(wil, d_head.addr);
-+ if (!dst) {
-+ wil_err(wil, "invalid WMI buffer: 0x%08x\n", d_head.addr);
-+ return -EINVAL;
-+ }
-+ hdr->seq = ++wil->wmi_seq;
-+ /* set command */
-+ if ((hdr->type == 0) && /* TODO: define */
-+ (hdr->len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
-+ struct wil6210_mbox_hdr_wmi *wmi = (void *)(&hdr[1]);
-+ wil_info(wil, "WMI command 0x%04x\n", wmi->id);
-+ }
-+ print_hex_dump(KERN_INFO, "cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf
-+ , sizeof(*hdr) + hdr->len, true);
-+ memcpy_toio_32(dst, buf, sizeof(*hdr) + hdr->len);
-+ /* mark entry as full */
-+ iowrite32(1, wil->csr + HOSTADDR(r->head)
-+ + offsetof(struct wil6210_mbox_ring_desc, sync));
-+ /* advance next ptr */
-+ iowrite32(r->head = next_head, wil->csr + HOST_MBOX
-+ + offsetof(struct wil6210_mbox_ctl, tx.head));
-+
-+ /* interrupt to FW */
-+ iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT);
-+
-+ return 0;
-+}
-+
-+int wmi_send_cmd(struct wil6210_priv *wil, void *buf)
-+{
-+ int rc;
-+ mutex_lock(&wil->wmi_mutex);
-+ rc = __wmi_send_cmd(wil, buf);
-+ mutex_unlock(&wil->wmi_mutex);
-+ return rc;
-+}
-+
-+/*=== Event handlers ===*/
-+static void wmi_evt_ready(struct wil6210_priv *wil, int id,
-+ void *d, int len)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ struct wireless_dev *wdev = wil->wdev;
-+ struct WMI_READY_EVENT *evt = d;
-+ wil_info(wil, "FW ver. %d; MAC %pM\n",
-+ evt->sw_version, evt->macaddr);
-+ if (!is_valid_ether_addr(ndev->dev_addr)) {
-+ memcpy(ndev->dev_addr, evt->macaddr, ETH_ALEN);
-+ memcpy(ndev->perm_addr, evt->macaddr, ETH_ALEN);
-+ }
-+ snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version),
-+ "%d", evt->sw_version);
-+}
-+
-+static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id,
-+ void *d, int len)
-+{
-+ wil_info(wil, "WMI: FW ready\n");
-+ set_bit(wil_status_fwready, &wil->status);
-+ /* reuse wmi_ready for the firmware ready indication */
-+ complete(&wil->wmi_ready);
-+}
-+
-+static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id,
-+ void *d, int len)
-+{
-+ struct WMI_RX_MGMT_PACKET_EVENT *data = d;
-+ struct wiphy *wiphy = wil_to_wiphy(wil);
-+ struct ieee80211_mgmt *rx_mgmt_frame =
-+ (struct ieee80211_mgmt *)data->payload;
-+ int ch_no = data->channel+1;
-+ u32 freq = ieee80211_channel_to_frequency(ch_no,
-+ IEEE80211_BAND_60GHZ);
-+ struct ieee80211_channel *channel = ieee80211_get_channel(wiphy, freq);
-+ /* TODO convert LE to CPU */
-+ s32 signal = data->rssi; /* TODO */
-+ __le16 fc = rx_mgmt_frame->frame_control;
-+ wil_info(wil, "MGMT: channel %d MCS %d RSSI %d\n",
-+ data->channel, data->mcs, data->rssi);
-+ wil_info(wil, "status 0x%08x len %d\n",
-+ data->status, data->length);
-+ wil_info(wil, "qid %d mid %d cid %d\n",
-+ data->qid, data->mid, data->cid);
-+ if (!channel) {
-+ wil_err(wil, "Frame on unsupported channel\n");
-+ return;
-+ }
-+ if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) {
-+ struct cfg80211_bss *bss;
-+ u64 tsf = rx_mgmt_frame->u.beacon.timestamp;
-+ u16 cap = rx_mgmt_frame->u.beacon.capab_info;
-+ u16 bi = rx_mgmt_frame->u.beacon.beacon_int;
-+ const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable;
-+ size_t ie_len = data->length -
-+ offsetof(struct ieee80211_mgmt,
-+ u.beacon.variable);
-+ /* Hack to work around wrong cap. info TODO: remove when fixed*/
-+ if (!(cap & WLAN_CAPABILITY_ESS)) {
-+ wil_info(wil, "No ESS bit in capabitity. Set it.\n");
-+ cap |= WLAN_CAPABILITY_ESS;
-+ }
-+ if (cap & WLAN_CAPABILITY_IBSS) {
-+ wil_info(wil, "IBSS bit in capabitity. Clear it.\n");
-+ cap &= ~WLAN_CAPABILITY_IBSS;
-+ }
-+ bss = cfg80211_inform_bss(wiphy, channel, rx_mgmt_frame->bssid,
-+ tsf, cap, bi, ie_buf, ie_len,
-+ signal, GFP_KERNEL);
-+ if (bss) {
-+ wil_info(wil, "Added BSS %pM\n",
-+ rx_mgmt_frame->bssid);
-+ cfg80211_put_bss(bss);
-+ } else {
-+ wil_err(wil, "cfg80211_inform_bss() failed\n");
-+ }
-+ }
-+}
-+
-+static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
-+ void *d, int len)
-+{
-+ if (wil->scan_request) {
-+ struct WMI_SCAN_COMPLETE_EVENT *data = d;
-+ bool aborted = (data->status != 0);
-+ wil_info(wil, "SCAN_COMPLETE(0x%08x)\n",
-+ data->status);
-+ cfg80211_scan_done(wil->scan_request, aborted);
-+ wil->scan_request = NULL;
-+ } else {
-+ wil_err(wil, "SCAN_COMPLETE while not scanning\n");
-+ }
-+}
-+
-+static void wmi_evt_connect(struct wil6210_priv *wil, int id,
-+ void *d, int len)
-+{
-+ struct net_device *ndev = wil_to_ndev(wil);
-+ struct wireless_dev *wdev = wil->wdev;
-+ struct WMI_CONNECT_EVENT *evt = d;
-+
-+ if (len < sizeof(*evt)) {
-+ wil_err(wil, "Connect event too short : %d bytes\n", len);
-+ return;
-+ }
-+ if (len != sizeof(*evt) + evt->beaconIeLen + evt->assocReqLen
-+ + evt->assocRespLen) {
-+ wil_err(wil,
-+ "Connect event corrupted : %d != %d + %d + %d + %d\n",
-+ len, (int)sizeof(*evt), evt->beaconIeLen,
-+ evt->assocReqLen, evt->assocRespLen);
-+ return;
-+ }
-+ wil_info(wil, "Connect %pM channel [%d] cid %d\n",
-+ evt->bssid, evt->channel, evt->cid);
-+ print_hex_dump(KERN_INFO, "connect AI : ", DUMP_PREFIX_OFFSET, 16, 1,
-+ evt->assocInfo, len - sizeof(*evt), true);
-+ if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
-+ (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
-+ /* capinfo + listen interval */
-+ u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
-+ /* capinfo + status code + associd */
-+ u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) +
-+ sizeof(u16);
-+ u8 *assoc_req_ie = &evt->assocInfo[evt->beaconIeLen
-+ + assoc_req_ie_offset];
-+ u8 *assoc_resp_ie = &evt->assocInfo[evt->beaconIeLen
-+ + evt->assocReqLen + assoc_resp_ie_offset];
-+
-+ u8 assoc_req_ielen = evt->assocReqLen - assoc_req_ie_offset;
-+ u8 assoc_resp_ielen = evt->assocRespLen - assoc_resp_ie_offset;
-+ if (wdev->sme_state != CFG80211_SME_CONNECTING) {
-+ wil_err(wil, "Not in connecting state\n");
-+ return;
-+ }
-+ if (evt->assocReqLen < assoc_req_ie_offset) {
-+ wil_info(wil, "No Assoc. Req. info\n");
-+ assoc_req_ie = NULL;
-+ assoc_req_ielen = 0;
-+ }
-+ if (evt->assocRespLen < assoc_resp_ie_offset) {
-+ wil_info(wil, "No Assoc. Resp. info\n");
-+ assoc_resp_ie = NULL;
-+ assoc_resp_ielen = 0;
-+ }
-+ del_timer_sync(&wil->connect_timer);
-+ cfg80211_connect_result(ndev, evt->bssid,
-+ assoc_req_ie, assoc_req_ielen,
-+ assoc_resp_ie, assoc_resp_ielen,
-+ WLAN_STATUS_SUCCESS, GFP_KERNEL);
-+
-+ }
-+ set_bit(wil_status_fwconnected, &wil->status);
-+
-+ /* FIXME FW can transmit only ucast frames to peer */
-+ /* FIXME real ring_id instead of hard coded 0 */
-+ memcpy(wil->dst_addr[0], evt->bssid, ETH_ALEN);
-+
-+ wil->pending_connect_cid = evt->cid;
-+ queue_work(wil->wmi_wq_conn, &wil->wmi_connect_worker);
-+}
-+
-+static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
-+ void *d, int len)
-+{
-+ struct WMI_DISCONNECT_EVENT *evt = d;
-+ wil_info(wil, "Disconnect %pM reason %d proto %d wmi\n",
-+ evt->bssid,
-+ evt->protocolReasonStatus, evt->disconnectReason);
-+ wil6210_disconnect(wil, evt->bssid);
-+ clear_bit(wil_status_dontscan, &wil->status);
-+}
-+
-+static void wmi_evt_notify(struct wil6210_priv *wil, int id,
-+ void *d, int len)
-+{
-+ struct WMI_NOTIFY_REQ_DONE_EVENT *evt = d;
-+ union {
-+ u64 tsf;
-+ u32 tsf_part[2];
-+ } tsf;
-+ if (len < sizeof(*evt)) {
-+ wil_err(wil, "Short NOTIFY event\n");
-+ return;
-+ }
-+ tsf.tsf_part[0] = evt->tsf_lo;
-+ tsf.tsf_part[1] = evt->tsf_hi;
-+
-+ wil_info(wil, "Link status, MCS %d TSF 0x%016llx\n"
-+ "BF status 0x%08x metric 0x%08x\n"
-+ "Tx Tpt %d goodput %d Rx goodput %d\n"
-+ "Sectors(rx:tx) my %d:%d peer %d:%d\n",
-+ evt->bf_mcs, tsf.tsf,
-+ evt->bf_status, evt->bf_metric,
-+ evt->tx_tpt, evt->tx_gput, evt->rx_gput,
-+ evt->my_rx_sector, evt->my_tx_sector,
-+ evt->peer_rx_sector, evt->peer_tx_sector);
-+ wil->stats.bf_mcs = evt->bf_mcs;
-+}
-+
-+static const struct {
-+ int eventid;
-+ void (*handler)(struct wil6210_priv *wil, int eventid,
-+ void *data, int data_len);
-+} wmi_evt_handlers[] = {
-+ {WMI_READY_EVENTID, wmi_evt_ready},
-+ {WMI_FW_READY_EVENTID, wmi_evt_fw_ready},
-+ {WMI_RX_MGMT_PACKET_EVENTID, wmi_evt_rx_mgmt},
-+ {WMI_SCAN_COMPLETE_EVENTID, wmi_evt_scan_complete},
-+ {WMI_CONNECT_EVENTID, wmi_evt_connect},
-+ {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect},
-+ {WMI_NOTIFY_REQ_DONE_EVENTID, wmi_evt_notify},
-+};
-+
-+void wmi_recv_cmd(struct wil6210_priv *wil)
-+{
-+ struct wil6210_mbox_ring_desc d_tail;
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_ring *r = &wil->mbox_ctl.rx;
-+ struct pending_wmi_event *evt;
-+ u8 *cmd;
-+ void __iomem *src;
-+ unsigned long flags;
-+ wil_info(wil, "%s()\n", __func__);
-+ for (;;) {
-+ r->head = ioread32(wil->csr + HOST_MBOX
-+ + offsetof(struct wil6210_mbox_ctl, rx.head));
-+ if (r->tail == r->head)
-+ return;
-+ /* read cmd from tail */
-+ memcpy_fromio_32(&d_tail,
-+ wil->csr + HOSTADDR(r->tail),
-+ sizeof(struct wil6210_mbox_ring_desc));
-+ if (d_tail.sync == 0) {
-+ wil_err(wil, "Mbox evt not owned by FW?\n");
-+ return;
-+ }
-+ if (0 != wmi_read_hdr(wil, d_tail.addr, &hdr)) {
-+ wil_err(wil, "Mbox evt at 0x%08x?\n",
-+ d_tail.addr);
-+ return;
-+ }
-+ src = wmi_buffer(wil, d_tail.addr)
-+ + sizeof(struct wil6210_mbox_hdr);
-+ evt = kmalloc(ALIGN(offsetof(struct pending_wmi_event,
-+ event.wmi) + hdr.len, 4), GFP_KERNEL);
-+ if (!evt) {
-+ wil_err(wil, "kmalloc for WMI event (%d) failed\n",
-+ hdr.len);
-+ return;
-+ }
-+ evt->event.mbox_hdr = hdr;
-+ cmd = (void *)&evt->event.wmi;
-+ memcpy_fromio_32(cmd, src, hdr.len);
-+ /* mark entry as empty */
-+ iowrite32(0, wil->csr + HOSTADDR(r->tail)
-+ + offsetof(struct wil6210_mbox_ring_desc, sync));
-+ /* indicate */
-+ wil_info(wil, "Mbox evt %04x %04x %04x %02x %02x\n",
-+ hdr.seq, hdr.ctx, hdr.type, hdr.flags, hdr.len);
-+ if ((hdr.type == 0) && /* TODO: define */
-+ (hdr.len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
-+ wil_info(wil, "WMI event 0x%04x\n",
-+ evt->event.wmi.id);
-+ }
-+ print_hex_dump(KERN_INFO, "evt ", DUMP_PREFIX_OFFSET, 16, 1,
-+ &evt->event.mbox_hdr, sizeof(hdr) + hdr.len,
-+ true);
-+ /* advance tail */
-+ r->tail = r->base + ((r->tail - r->base
-+ + sizeof(struct wil6210_mbox_ring_desc)) % r->size);
-+ iowrite32(r->tail, wil->csr + HOST_MBOX
-+ + offsetof(struct wil6210_mbox_ctl, rx.tail));
-+ /* add to the pending list */
-+ spin_lock_irqsave(&wil->wmi_ev_lock, flags);
-+ list_add_tail(&evt->list, &wil->pending_wmi_ev);
-+ spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
-+ {
-+ int q = queue_work(wil->wmi_wq,
-+ &wil->wmi_event_worker);
-+ wil_info(wil, "queue_work -> %d\n", q);
-+ }
-+ }
-+}
-+
-+int wmi_call(struct wil6210_priv *wil, void *buf,
-+ u16 reply_id, void *reply, u8 reply_size, int to_msec)
-+{
-+ int rc;
-+ int remain;
-+ struct wil6210_mbox_wmi {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ } __packed * wmi = buf;
-+ mutex_lock(&wil->wmi_mutex);
-+ rc = __wmi_send_cmd(wil, buf);
-+ if (rc)
-+ goto out;
-+ wil->reply_id = reply_id;
-+ wil->reply_buf = reply;
-+ wil->reply_size = reply_size;
-+ remain = wait_for_completion_timeout(&wil->wmi_ready,
-+ msecs_to_jiffies(to_msec));
-+ if (0 == remain) {
-+ wil_err(wil, "wmi_call(0x%04x->0x%04x) timeout %d msec\n",
-+ wmi->wmi.id, reply_id, to_msec);
-+ rc = -ETIME;
-+ } else {
-+ wil_info(wil,
-+ "wmi_call(0x%04x->0x%04x) completed in %d msec\n",
-+ wmi->wmi.id, reply_id,
-+ to_msec - jiffies_to_msecs(remain));
-+ }
-+ wil->reply_id = 0;
-+ wil->reply_buf = NULL;
-+ wil->reply_size = 0;
-+ out:
-+ mutex_unlock(&wil->wmi_mutex);
-+ return rc;
-+}
-+
-+int wil6210_set_mac_address(struct wil6210_priv *wil, void *addr)
-+{
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_SET_MAC_ADDRESS_CMD mac;
-+ } __packed cmd = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 0,
-+ .type = 0,
-+ .flags = 0,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi)
-+ + sizeof(struct WMI_SET_MAC_ADDRESS_CMD),
-+ },
-+ .wmi = {
-+ .id = WMI_SET_MAC_ADDRESS_CMDID,
-+ .info1 = 0,
-+ },
-+ .mac = {
-+ },
-+ };
-+ memcpy(cmd.mac.macaddr, addr, ETH_ALEN);
-+ wil_info(wil, "Set MAC %pM\n", addr);
-+ return wmi_send_cmd(wil, &cmd);
-+}
-+
-+int wil6210_set_bcon(struct wil6210_priv *wil, int bi, u16 wmi_nettype)
-+{
-+ struct {
-+ struct wil6210_mbox_hdr hdr;
-+ struct wil6210_mbox_hdr_wmi wmi;
-+ struct WMI_SET_BEACON_INT_CMD bcon;
-+ } __packed cmd = {
-+ .hdr = {
-+ .seq = 1,
-+ .ctx = 0,
-+ .type = 0,
-+ .flags = 0,
-+ .len = sizeof(struct wil6210_mbox_hdr_wmi)
-+ + sizeof(struct WMI_SET_BEACON_INT_CMD),
-+ },
-+ .wmi = {
-+ .id = WMI_SET_BEACON_INT_CMDID,
-+ .info1 = 0,
-+ },
-+ .bcon = {
-+ .bcon_interval = bi,
-+ .network_type = wmi_nettype,
-+ },
-+ };
-+ return wmi_send_cmd(wil, &cmd);
-+}
-+
-+void wmi_event_flush(struct wil6210_priv *wil)
-+{
-+ struct pending_wmi_event *evt, *t;
-+ wil_info(wil, "%s()\n", __func__);
-+ list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) {
-+ list_del(&evt->list);
-+ kfree(evt);
-+ }
-+}
-+
-+static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id,
-+ void *d, int len)
-+{
-+ int i;
-+ for (i = 0; i < ARRAY_SIZE(wmi_evt_handlers); i++) {
-+ if (wmi_evt_handlers[i].eventid == id) {
-+ wmi_evt_handlers[i].handler(wil, id, d, len);
-+ return true;
-+ }
-+ }
-+ return false;
-+}
-+
-+static void wmi_event_handle(struct wil6210_priv *wil,
-+ struct wil6210_mbox_hdr *hdr)
-+{
-+ wil_info(wil, "%s()\n", __func__);
-+ if ((hdr->type == 0) && /* TODO: define */
-+ (hdr->len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
-+ struct wil6210_mbox_hdr_wmi *wmi = (void *)(&hdr[1]);
-+ void *evt_data = (void *)(&wmi[1]);
-+ /* check if someone waits for this event */
-+ if (wil->reply_id && wil->reply_id == wmi->id) {
-+ if (wil->reply_buf) {
-+ memcpy(wil->reply_buf, wmi,
-+ min(hdr->len, wil->reply_size));
-+ } else {
-+ wmi_evt_call_handler(wil, wmi->id, evt_data,
-+ hdr->len - sizeof(*wmi));
-+ }
-+ wil_info(wil, "Complete WMI 0x%04x\n",
-+ wmi->id);
-+ complete(&wil->wmi_ready);
-+ return;
-+ }
-+ /* unsolicited event */
-+ /* search for handler */
-+ if (!wmi_evt_call_handler(wil, wmi->id, evt_data,
-+ hdr->len - sizeof(*wmi))) {
-+ wil_err(wil, "Unhandled event 0x%04x\n",
-+ wmi->id);
-+ }
-+ } else {
-+ wil_err(wil, "Unknown event type\n");
-+ print_hex_dump(KERN_INFO, "evt?? ", DUMP_PREFIX_OFFSET, 16, 1,
-+ hdr, sizeof(*hdr) + hdr->len, true);
-+ }
-+}
-+
-+static struct list_head *next_wmi_ev(struct wil6210_priv *wil)
-+{
-+ unsigned long flags;
-+ struct list_head *ret = NULL;
-+ spin_lock_irqsave(&wil->wmi_ev_lock, flags);
-+ if (!list_empty(&wil->pending_wmi_ev)) {
-+ ret = wil->pending_wmi_ev.next;
-+ list_del(ret);
-+ }
-+ spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
-+ return ret;
-+}
-+
-+void wmi_event_worker(struct work_struct *work)
-+{
-+ struct wil6210_priv *wil = container_of(work,
-+ struct wil6210_priv, wmi_event_worker);
-+ struct pending_wmi_event *evt;
-+ struct list_head *lh;
-+ wil_info(wil, "%s()\n", __func__);
-+ while ((lh = next_wmi_ev(wil)) != NULL) {
-+ evt = list_entry(lh, struct pending_wmi_event, list);
-+ wmi_event_handle(wil, &evt->event.mbox_hdr);
-+ kfree(evt);
-+ }
-+ wil_info(wil, "%s() done\n", __func__);
-+}
-+
-+void wmi_connect_worker(struct work_struct *work)
-+{
-+ int rc;
-+ struct wil6210_priv *wil = container_of(work,
-+ struct wil6210_priv, wmi_connect_worker);
-+ if (wil->pending_connect_cid < 0) {
-+ wil_err(wil, "No connection pending\n");
-+ return;
-+ }
-+ wil_info(wil, "Configure for connection CID %d\n",
-+ wil->pending_connect_cid);
-+ rc = vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE,
-+ wil->pending_connect_cid, 0);
-+ wil->pending_connect_cid = -1;
-+ if (rc == 0)
-+ wil_link_on(wil);
-+}
---- /dev/null
-+++ b/drivers/net/wireless/ath/wil6210/wmi.h
-@@ -0,0 +1,837 @@
-+/*
-+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef __WMI_H__
-+#define __WMI_H__
-+/* WMI API */
-+
-+/*
-+ * List of Commnands
-+ */
-+enum WMI_COMMAND_ID {
-+ WMI_CONNECT_CMDID = 0x0001,
-+ WMI_RECONNECT_CMDID,
-+ WMI_DISCONNECT_CMDID,
-+ WMI_SYNCHRONIZE_CMDID,
-+ WMI_CREATE_PSTREAM_CMDID,
-+ WMI_DELETE_PSTREAM_CMDID,
-+ WMI_START_SCAN_CMDID,
-+ WMI_SET_SCAN_PARAMS_CMDID,
-+ WMI_SET_BSS_FILTER_CMDID,
-+ WMI_SET_PROBED_SSID_CMDID, /* 10 */
-+ WMI_SET_LISTEN_INT_CMDID,
-+ WMI_SET_BMISS_TIME_CMDID,
-+ WMI_SET_DISC_TIMEOUT_CMDID,
-+ WMI_GET_CHANNEL_LIST_CMDID,
-+ WMI_SET_BEACON_INT_CMDID,
-+ WMI_GET_STATISTICS_CMDID,
-+ WMI_SET_CHANNEL_PARAMS_CMDID,
-+ WMI_SET_POWER_MODE_CMDID,
-+ WMI_SET_IBSS_PM_CAPS_CMDID,
-+ WMI_SET_POWER_PARAMS_CMDID, /* 20 */
-+ WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
-+ WMI_ADD_CIPHER_KEY_CMDID,
-+ WMI_DELETE_CIPHER_KEY_CMDID,
-+ WMI_ADD_KRK_CMDID,
-+ WMI_DELETE_KRK_CMDID,
-+ WMI_SET_PMKID_CMDID,
-+ WMI_SET_TX_PWR_CMDID,
-+ WMI_GET_TX_PWR_CMDID,
-+ WMI_SET_ASSOC_INFO_CMDID,
-+ WMI_ADD_BAD_AP_CMDID, /* 30 */
-+ WMI_DELETE_BAD_AP_CMDID,
-+ WMI_SET_TKIP_COUNTERMEASURES_CMDID,
-+ WMI_RSSI_THRESHOLD_PARAMS_CMDID,
-+ WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
-+ WMI_SET_ACCESS_PARAMS_CMDID,
-+ WMI_SET_RETRY_LIMITS_CMDID,
-+ WMI_SET_OPT_MODE_CMDID,
-+ WMI_OPT_TX_FRAME_CMDID,
-+ WMI_SET_VOICE_PKT_SIZE_CMDID,
-+ WMI_SET_MAX_SP_LEN_CMDID, /* 40 */
-+ WMI_SET_ROAM_CTRL_CMDID,
-+ WMI_GET_ROAM_TBL_CMDID,
-+ WMI_GET_ROAM_DATA_CMDID,
-+ WMI_ENABLE_RM_CMDID,
-+ WMI_SET_MAX_OFFHOME_DURATION_CMDID,
-+ WMI_EXTENSION_CMDID, /* Non-wireless extensions */
-+ WMI_SNR_THRESHOLD_PARAMS_CMDID,
-+ WMI_LQ_THRESHOLD_PARAMS_CMDID,
-+ WMI_SET_LPREAMBLE_CMDID,
-+ WMI_SET_RTS_CMDID, /* 50 */
-+ WMI_CLR_RSSI_SNR_CMDID,
-+ WMI_SET_FIXRATES_CMDID,
-+ WMI_GET_FIXRATES_CMDID,
-+ WMI_SET_AUTH_MODE_CMDID,
-+ WMI_SET_REASSOC_MODE_CMDID,
-+ WMI_SET_WMM_CMDID,
-+ WMI_SET_WMM_TXOP_CMDID,
-+ WMI_TEST_CMDID,
-+ /* COEX AR6002 only*/
-+ WMI_SET_BT_STATUS_CMDID,
-+ WMI_SET_BT_PARAMS_CMDID, /* 60 */
-+
-+ WMI_SET_KEEPALIVE_CMDID,
-+ WMI_GET_KEEPALIVE_CMDID,
-+ WMI_SET_APPIE_CMDID,
-+ WMI_GET_APPIE_CMDID,
-+ WMI_SET_WSC_STATUS_CMDID,
-+
-+ /* Wake on Wireless */
-+ WMI_SET_HOST_SLEEP_MODE_CMDID,
-+ WMI_SET_WOW_MODE_CMDID,
-+ WMI_GET_WOW_LIST_CMDID,
-+ WMI_ADD_WOW_PATTERN_CMDID,
-+ WMI_DEL_WOW_PATTERN_CMDID, /* 70 */
-+
-+ WMI_SET_FRAMERATES_CMDID,
-+ WMI_SET_AP_PS_CMDID,
-+ WMI_SET_QOS_SUPP_CMDID,
-+
-+ /* WILOCITY types */
-+ WMI_MEM_READ_CMDID = 0x0800, /* WILOCITY types */
-+ WMI_MEM_WR_CMDID = 0x0801,
-+ WMI_FAST_MEM_ACC_MODE_CMDID = 0x0300,
-+ WMI_ECHO_CMDID = 0x0803,
-+ WMI_DEEP_ECHO_CMDID = 0x0804,
-+ WMI_CONFIG_MAC_CMDID = 0x0805,
-+ WMI_CONFIG_PHY_DEBUG_CMDID = 0x0806,
-+ WMI_ADD_STATION_CMDID = 0x0807,
-+ WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x0808,
-+ WMI_PHY_GET_STATISTICS_CMDID = 0x0809,
-+ WMI_FS_TUNE_CMDID = 0x080A,
-+ WMI_CORR_MEASURE_CMDID = 0x080B,
-+ WMI_TEMP_SENSE_CMDID = 0x080E,
-+ WMI_DC_CALIB_CMDID = 0x080F,
-+ WMI_SEND_TONE_CMDID = 0x0810,
-+ WMI_IQ_TX_CALIB_CMDID = 0x0811,
-+ WMI_IQ_RX_CALIB_CMDID = 0x0812,
-+ WMI_SET_UCODE_IDLE_CMDID = 0x0813,
-+ WMI_SET_CHANNEL_IND_CMDID = 0x0814,
-+ WMI_SET_WORK_MODE_CMDID = 0x0815,
-+ WMI_LO_LEAKAGE_CALIB_CMDID = 0x0816,
-+ WMI_WIL6210_R_ACTIVATE_CMDID = 0x0817,
-+ WMI_WIL6210_R_READ_CMDID = 0x0818,
-+ WMI_WIL6210_R_WRITE_CMDID = 0x0819,
-+ WMI_WIL6210_R_TXRX_SEL_CMDID = 0x081A,
-+ MAC_IO_STATIC_PARAMS_CMD = 0x081B,
-+ MAC_IO_DYNAMIC_PARAMS_CMD = 0x081C,
-+ WMI_SILENT_RSSI_CALIB_CMDID = 0x081D,
-+
-+ WMI_CFG_RX_CHAIN_CMDID = 0x0820,
-+ WMI_VRING_CFG_CMDID = 0x0821,
-+ WMI_RN_ON_CMDID = 0x0822,
-+ WMI_VRING_BA_EN_CMDID = 0x0823,
-+ WMI_VRING_BA_DIS_CMDID = 0x0824,
-+ WMI_RCP_ADDBA_RESP_CMDID = 0x0825,
-+ WMI_RCP_DELBA_CMDID = 0x0826,
-+
-+ WMI_READ_MAC_RXQ_CMDID = 0x0830,
-+ WMI_READ_MAC_TXQ_CMDID = 0x0831,
-+ WMI_WRITE_MAC_RXQ_CMDID = 0x0832,
-+ WMI_WRITE_MAC_TXQ_CMDID = 0x0833,
-+ WMI_WRITE_MAC_XQ_FIELD_CMDID = 0x0834,
-+
-+ WMI_MLME_PUSH_CMDID = 0x0835,
-+ WMI_BF_START_TXSS_CMDID = 0x0836,
-+ WMI_BF_TXSS_MGMT_CMDID = 0x0837,
-+ WMI_BF_SM_MGMT_CMDID = 0x0838,
-+ WMI_BF_RXSS_MGMT_CMDID = 0x0839,
-+ WMI_RS_MGMT_CMDID = 0x0852,
-+
-+ WMI_LINK_START_CMDID = 0x0850,
-+ WMI_LINK_STOP_CMDID = 0x0851,
-+
-+ /* Performance monitoring commands */
-+ WMI_BF_CTRL_CMDID = 0x0862,
-+ WMI_NOTIFY_REQ_CMDID = 0x0863,
-+
-+ WMI_UNIT_TEST_CMD_ID = 0x0900,
-+ WMI_HICCUP_CMD_ID = 0x0901,
-+
-+#if 0
-+ WMI_TXRX_SEND_CMDID = 0x0810,
-+#endif
-+ /* WMI_THIN_RESERVED_... mark the start and end
-+ * values for WMI_THIN_RESERVED command IDs. These
-+ * command IDs can be found in wmi_thin.h */
-+ WMI_THIN_RESERVED_START = 0x8000,
-+ WMI_THIN_RESERVED_END = 0x8fff,
-+ /*
-+ * Developer commands starts at 0xF000
-+ */
-+ WMI_SET_BITRATE_CMDID = 0xF000,
-+ WMI_GET_BITRATE_CMDID,
-+ WMI_SET_WHALPARAM_CMDID,
-+
-+ /*Should add the new command to the tail for compatible with
-+ * etna.
-+ */
-+ WMI_SET_MAC_ADDRESS_CMDID,
-+ WMI_SET_AKMP_PARAMS_CMDID,
-+ WMI_SET_PMKID_LIST_CMDID,
-+ WMI_GET_PMKID_LIST_CMDID,
-+ WMI_ABORT_SCAN_CMDID,
-+ WMI_SET_TARGET_EVENT_REPORT_CMDID,
-+
-+ /* Unused */
-+ WMI_UNUSED1,
-+ WMI_UNUSED2,
-+
-+ /*
-+ * AP mode commands
-+ */
-+ WMI_AP_HIDDEN_SSID_CMDID, /* F00B */
-+ WMI_AP_SET_NUM_STA_CMDID,
-+ WMI_AP_ACL_POLICY_CMDID,
-+ WMI_AP_ACL_MAC_LIST_CMDID,
-+ WMI_AP_CONFIG_COMMIT_CMDID,
-+ WMI_AP_SET_MLME_CMDID, /* F010 */
-+ WMI_AP_SET_PVB_CMDID,
-+ WMI_AP_CONN_INACT_CMDID,
-+ WMI_AP_PROT_SCAN_TIME_CMDID,
-+ WMI_AP_SET_COUNTRY_CMDID,
-+ WMI_AP_SET_DTIM_CMDID,
-+ WMI_AP_MODE_STAT_CMDID,
-+
-+ WMI_SET_IP_CMDID, /* F017 */
-+ WMI_SET_PARAMS_CMDID,
-+ WMI_SET_MCAST_FILTER_CMDID,
-+ WMI_DEL_MCAST_FILTER_CMDID,
-+
-+ WMI_ALLOW_AGGR_CMDID, /* F01B */
-+ WMI_ADDBA_REQ_CMDID,
-+ WMI_DELBA_REQ_CMDID,
-+ WMI_SET_HT_CAP_CMDID,
-+ WMI_SET_HT_OP_CMDID,
-+ WMI_SET_TX_SELECT_RATES_CMDID,
-+ WMI_SET_TX_SGI_PARAM_CMDID,
-+ WMI_SET_RATE_POLICY_CMDID,
-+
-+ WMI_HCI_CMD_CMDID, /* F023 */
-+ WMI_RX_FRAME_FORMAT_CMDID,
-+ WMI_SET_THIN_MODE_CMDID,
-+ WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
-+
-+ WMI_AP_SET_11BG_RATESET_CMDID, /* F027 */
-+ WMI_SET_PMK_CMDID,
-+ WMI_MCAST_FILTER_CMDID,
-+ /* COEX CMDID AR6003*/
-+ WMI_SET_BTCOEX_FE_ANT_CMDID, /* F02A */
-+ WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
-+ WMI_SET_BTCOEX_SCO_CONFIG_CMDID,
-+ WMI_SET_BTCOEX_A2DP_CONFIG_CMDID,
-+ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID,
-+ WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
-+ WMI_SET_BTCOEX_DEBUG_CMDID,
-+ WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
-+ WMI_GET_BTCOEX_STATS_CMDID,
-+ WMI_GET_BTCOEX_CONFIG_CMDID,
-+
-+ WMI_SET_DFS_ENABLE_CMDID, /* F034 */
-+ WMI_SET_DFS_MINRSSITHRESH_CMDID,
-+ WMI_SET_DFS_MAXPULSEDUR_CMDID,
-+ WMI_DFS_RADAR_DETECTED_CMDID,
-+
-+ /* P2P CMDS */
-+ WMI_P2P_SET_CONFIG_CMDID, /* F038 */
-+ WMI_WPS_SET_CONFIG_CMDID,
-+ WMI_SET_REQ_DEV_ATTR_CMDID,
-+ WMI_P2P_FIND_CMDID,
-+ WMI_P2P_STOP_FIND_CMDID,
-+ WMI_P2P_GO_NEG_START_CMDID,
-+ WMI_P2P_LISTEN_CMDID,
-+
-+ WMI_CONFIG_TX_MAC_RULES_CMDID, /* F040 */
-+ WMI_SET_PROMISCUOUS_MODE_CMDID,
-+ WMI_RX_FRAME_FILTER_CMDID,
-+ WMI_SET_CHANNEL_CMDID,
-+
-+ /* WAC commands */
-+ WMI_ENABLE_WAC_CMDID,
-+ WMI_WAC_SCAN_REPLY_CMDID,
-+ WMI_WAC_CTRL_REQ_CMDID,
-+ WMI_SET_DIV_PARAMS_CMDID,
-+
-+ WMI_GET_PMK_CMDID,
-+ WMI_SET_PASSPHRASE_CMDID,
-+ WMI_SEND_ASSOC_RES_CMDID,
-+ WMI_SET_ASSOC_REQ_RELAY_CMDID,
-+};
-+
-+/*
-+ * List of Events (target to host)
-+ */
-+enum WMI_EVENT_ID {
-+ WMI_READY_EVENTID = 0x1001,
-+ WMI_CONNECT_EVENTID,
-+ WMI_DISCONNECT_EVENTID,
-+ WMI_BSSINFO_EVENTID,
-+ WMI_CMDERROR_EVENTID,
-+ WMI_REGDOMAIN_EVENTID,
-+ WMI_PSTREAM_TIMEOUT_EVENTID,
-+ WMI_NEIGHBOR_REPORT_EVENTID,
-+ WMI_TKIP_MICERR_EVENTID,
-+ WMI_SCAN_COMPLETE_EVENTID, /* 0x100a */
-+ WMI_REPORT_STATISTICS_EVENTID,
-+ WMI_RSSI_THRESHOLD_EVENTID,
-+ WMI_ERROR_REPORT_EVENTID,
-+ WMI_OPT_RX_FRAME_EVENTID,
-+ WMI_REPORT_ROAM_TBL_EVENTID,
-+ WMI_EXTENSION_EVENTID,
-+ WMI_CAC_EVENTID,
-+ WMI_SNR_THRESHOLD_EVENTID,
-+ WMI_LQ_THRESHOLD_EVENTID,
-+ WMI_TX_RETRY_ERR_EVENTID, /* 0x1014 */
-+ WMI_REPORT_ROAM_DATA_EVENTID,
-+ WMI_TEST_EVENTID,
-+ WMI_APLIST_EVENTID,
-+ WMI_GET_WOW_LIST_EVENTID,
-+ WMI_GET_PMKID_LIST_EVENTID,
-+ WMI_CHANNEL_CHANGE_EVENTID,
-+ WMI_PEER_NODE_EVENTID,
-+ WMI_PSPOLL_EVENTID,
-+ WMI_DTIMEXPIRY_EVENTID,
-+ WMI_WLAN_VERSION_EVENTID,
-+ WMI_SET_PARAMS_REPLY_EVENTID,
-+ WMI_ADDBA_REQ_EVENTID, /*0x1020 */
-+ WMI_ADDBA_RESP_EVENTID,
-+ WMI_DELBA_REQ_EVENTID,
-+ WMI_TX_COMPLETE_EVENTID,
-+ WMI_HCI_EVENT_EVENTID,
-+ WMI_ACL_DATA_EVENTID,
-+ WMI_REPORT_SLEEP_STATE_EVENTID,
-+ WMI_REPORT_BTCOEX_STATS_EVENTID,
-+ WMI_REPORT_BTCOEX_CONFIG_EVENTID,
-+ WMI_GET_PMK_EVENTID,
-+
-+ /* DFS Events */
-+ WMI_DFS_HOST_ATTACH_EVENTID,
-+ WMI_DFS_HOST_INIT_EVENTID,
-+ WMI_DFS_RESET_DELAYLINES_EVENTID,
-+ WMI_DFS_RESET_RADARQ_EVENTID,
-+ WMI_DFS_RESET_AR_EVENTID,
-+ WMI_DFS_RESET_ARQ_EVENTID,
-+ WMI_DFS_SET_DUR_MULTIPLIER_EVENTID,
-+ WMI_DFS_SET_BANGRADAR_EVENTID,
-+ WMI_DFS_SET_DEBUGLEVEL_EVENTID,
-+ WMI_DFS_PHYERR_EVENTID,
-+ /* CCX Evants */
-+ WMI_CCX_RM_STATUS_EVENTID,
-+
-+ /* P2P Events */
-+ WMI_P2P_GO_NEG_RESULT_EVENTID,
-+
-+ WMI_WAC_SCAN_DONE_EVENTID,
-+ WMI_WAC_REPORT_BSS_EVENTID,
-+ WMI_WAC_START_WPS_EVENTID,
-+ WMI_WAC_CTRL_REQ_REPLY_EVENTID,
-+ WMI_REPORT_WMM_PARAMS_EVENTID,
-+
-+ /* WILOCITY types */
-+ WMI_IMM_RSP_EVENTID = 0x0000,
-+ WMI_RD_MEM_RSP_EVENTID = 0x1800,
-+ WMI_FW_READY_EVENTID = 0x1801,
-+ WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x0200,
-+ WMI_ECHO_RSP_EVENTID = 0x1803,
-+ WMI_CONFIG_MAC_DONE_EVENTID = 0x1805,
-+ WMI_CONFIG_PHY_DEBUG_DONE_EVENTID = 0x1806,
-+ WMI_ADD_STATION_DONE_EVENTID = 0x1807,
-+ WMI_ADD_DEBUG_TX_PCKT_DONE_EVENTID = 0x1808,
-+ WMI_PHY_GET_STATISTICS_EVENTID = 0x1809,
-+ WMI_FS_TUNE_DONE_EVENTID = 0x180A,
-+ WMI_CORR_MEASURE_DONE_EVENTID = 0x180B,
-+ WMI_TEMP_SENSE_DONE_EVENTID = 0x180E,
-+ WMI_DC_CALIB_DONE_EVENTID = 0x180F,
-+ WMI_IQ_TX_CALIB_DONE_EVENTID = 0x1811,
-+ WMI_IQ_RX_CALIB_DONE_EVENTID = 0x1812,
-+ WMI_SET_CHANNEL_DONE_EVENTID = 0x1814,
-+ WMI_SET_WORK_MODE_DONE_EVENTID = 0x1815,
-+ WMI_LO_LEAKAGE_CALIB_DONE_EVENTID = 0x1816,
-+ WMI_WIL6210_R_ACTIVATE_DONE_EVENTID = 0x1817,
-+ WMI_WIL6210_R_READ_DONE_EVENTID = 0x1818,
-+ WMI_WIL6210_R_WRITE_DONE_EVENTID = 0x1819,
-+ WMI_WIL6210_R_TXRX_SEL_DONE_EVENTID = 0x181A,
-+ WMI_SILENT_RSSI_CALIB_DONE_EVENTID = 0x181D,
-+
-+ WMI_CFG_RX_CHAIN_DONE_EVENTID = 0x1820,
-+ WMI_VRING_CFG_DONE_EVENTID = 0x1821,
-+ WMI_RX_ON_EVENTID = 0x1822,
-+ WMI_BA_STATUS_EVENTID = 0x1823,
-+ WMI_RCP_ADDBA_REQ_EVENTID = 0x1824,
-+ WMI_ADDBA_RESP_SENT_EVENTID = 0x1825,
-+ WMI_DELBA_EVENTID = 0x1826,
-+
-+ WMI_READ_MAC_RXQ_EVENTID = 0x1830,
-+ WMI_READ_MAC_TXQ_EVENTID = 0x1831,
-+ WMI_WRITE_MAC_RXQ_EVENTID = 0x1832,
-+ WMI_WRITE_MAC_TXQ_EVENTID = 0x1833,
-+ WMI_WRITE_MAC_XQ_FIELD_EVENTID = 0x1834,
-+
-+ WMI_BF_START_TXSS_DONE_EVENTID = 0x1836,
-+ WMI_BF_TXSS_MGMT_DONE_EVENTID = 0x1837,
-+ WMI_BF_RXSS_MGMT_DONE_EVENTID = 0x1839,
-+ WMI_RS_MGMT_DONE_EVENTID = 0x1852,
-+ WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838,
-+ WMI_RX_MGMT_PACKET_EVENTID = 0x1840,
-+ WMI_LINK_START_DONE_EVENTID = 0x1850,
-+ WMI_LINK_STOP_DONE_EVENTID = 0x1851,
-+
-+ /* Performance monitoring events */
-+ WMI_WBE_LINKUP_EVENTID = 0x1860,
-+ WMI_WBE_LINKDOWN_EVENTID = 0x1861,
-+
-+ WMI_BF_CTRL_DONE_EVENTID = 0x1862,
-+ WMI_NOTIFY_REQ_DONE_EVENTID = 0x1863,
-+
-+ WMI_UNIT_TEST_EVENTID = 0x1900,
-+
-+ WMI_THIN_RESERVED_START_EVENTID = 0x8000,
-+ /* Events in this range are reserved for thinmode
-+ * See wmi_thin.h for actual definitions */
-+ WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
-+
-+ WMI_SET_CHANNEL_EVENTID,
-+ WMI_ASSOC_REQ_EVENTID
-+};
-+
-+/*
-+ * WMI_READY_EVENTID
-+ */
-+struct WMI_READY_EVENT {
-+ u32 sw_version;
-+ u32 abi_version;
-+ u8 macaddr[ETH_ALEN];
-+ u8 phyCapability; /* WMI_PHY_CAPABILITY */
-+} __packed;
-+
-+enum WMI_NETWORK_TYPE {
-+ INFRA_NETWORK = 0x01,
-+ ADHOC_NETWORK = 0x02,
-+ ADHOC_CREATOR = 0x04,
-+ AP_NETWORK = 0x10,
-+ P2P_NETWORK = 0x20,
-+ WBE_NETWORK = 0x40,
-+};
-+
-+enum DOT11_AUTH_MODE {
-+ OPEN_AUTH = 0x01,
-+ SHARED_AUTH = 0x02,
-+ LEAP_AUTH = 0x04, /* different from IEEE_AUTH_MODE definitions */
-+};
-+
-+enum AUTH_MODE {
-+ NONE_AUTH = 0x01,
-+ WPA_AUTH = 0x02,
-+ WPA2_AUTH = 0x04,
-+ WPA_PSK_AUTH = 0x08,
-+ WPA2_PSK_AUTH = 0x10,
-+ WPA_AUTH_CCKM = 0x20,
-+ WPA2_AUTH_CCKM = 0x40,
-+};
-+
-+enum CRYPTO_TYPE {
-+ NONE_CRYPT = 0x01,
-+ WEP_CRYPT = 0x02,
-+ TKIP_CRYPT = 0x04,
-+ AES_CRYPT = 0x08,
-+#ifdef WAPI_ENABLE
-+ WAPI_CRYPT = 0x10,
-+#endif /*WAPI_ENABLE*/
-+};
-+
-+#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT
-+#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1)
-+
-+#ifdef WAPI_ENABLE
-+#undef WMI_MAX_CRYPTO_TYPE
-+#define WMI_MAX_CRYPTO_TYPE (WAPI_CRYPT + 1)
-+#endif /* WAPI_ENABLE */
-+
-+#ifdef WAPI_ENABLE
-+#define IW_ENCODE_ALG_SM4 0x20
-+#define IW_AUTH_WAPI_ENABLED 0x20
-+#endif
-+
-+#define WMI_MIN_KEY_INDEX 0
-+#define WMI_MAX_KEY_INDEX 3
-+
-+#ifdef WAPI_ENABLE
-+#undef WMI_MAX_KEY_INDEX
-+#define WMI_MAX_KEY_INDEX 7 /* wapi grpKey 0-3, prwKey 4-7 */
-+#endif /* WAPI_ENABLE */
-+
-+enum WMI_CONNECT_CTRL_FLAGS_BITS {
-+ CONNECT_ASSOC_POLICY_USER = 0x0001,
-+ CONNECT_SEND_REASSOC = 0x0002,
-+ CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
-+ CONNECT_PROFILE_MATCH_DONE = 0x0008,
-+ CONNECT_IGNORE_AAC_BEACON = 0x0010,
-+ CONNECT_CSA_FOLLOW_BSS = 0x0020,
-+ CONNECT_DO_WPA_OFFLOAD = 0x0040,
-+ CONNECT_DO_NOT_DEAUTH = 0x0080,
-+};
-+#define DEFAULT_CONNECT_CTRL_FLAGS (CONNECT_CSA_FOLLOW_BSS)
-+
-+/*
-+ * WMI_CONNECT_CMDID
-+ */
-+struct WMI_CONNECT_CMD {
-+ u8 networkType;
-+ u8 dot11AuthMode;
-+ u8 authMode;
-+ u8 pairwiseCryptoType;
-+ u8 pairwiseCryptoLen;
-+ u8 groupCryptoType;
-+ u8 groupCryptoLen;
-+ u8 ssidLength;
-+ u8 ssid[32];
-+ u16 channel;
-+ u8 bssid[ETH_ALEN];
-+ u32 ctrl_flags;
-+ u8 destMacAddr[ETH_ALEN];
-+ u16 reserved;
-+} __packed;
-+
-+/*
-+ * WMI_CONNECT_EVENTID
-+ */
-+struct WMI_CONNECT_EVENT {
-+ u16 channel;
-+ u8 bssid[ETH_ALEN];
-+ u16 listenInterval;
-+ u16 beaconInterval;
-+ u32 networkType;
-+ u8 beaconIeLen;
-+ u8 assocReqLen;
-+ u8 assocRespLen;
-+ u8 cid;
-+ u8 reserved0;
-+ u16 reserved1;
-+ u8 assocInfo[0];
-+} __packed;
-+
-+/*
-+ * WMI_DISCONNECT_EVENTID
-+ */
-+enum WMI_DISCONNECT_REASON {
-+ NO_NETWORK_AVAIL = 0x01,
-+ LOST_LINK = 0x02, /* bmiss */
-+ DISCONNECT_CMD = 0x03,
-+ BSS_DISCONNECTED = 0x04,
-+ AUTH_FAILED = 0x05,
-+ ASSOC_FAILED = 0x06,
-+ NO_RESOURCES_AVAIL = 0x07,
-+ CSERV_DISCONNECT = 0x08,
-+ INVALID_PROFILE = 0x0a,
-+ DOT11H_CHANNEL_SWITCH = 0x0b,
-+ PROFILE_MISMATCH = 0x0c,
-+ CONNECTION_EVICTED = 0x0d,
-+ IBSS_MERGE = 0xe,
-+};
-+
-+struct WMI_DISCONNECT_EVENT {
-+ u16 protocolReasonStatus; /* reason code, see 802.11 spec. */
-+ u8 bssid[ETH_ALEN]; /* set if known */
-+ u8 disconnectReason; /* see WMI_DISCONNECT_REASON */
-+ u8 assocRespLen;
-+ u8 assocInfo[0];
-+} __packed;
-+
-+/*
-+ * WMI_START_SCAN_CMDID
-+ */
-+enum WMI_SCAN_TYPE {
-+ WMI_LONG_SCAN = 0, WMI_SHORT_SCAN = 1,
-+};
-+
-+struct WMI_START_SCAN_CMD {
-+ u32 forceFgScan;
-+ u32 isLegacy; /* For Legacy Cisco AP compatibility */
-+ u32 homeDwellTime; /* Maximum duration in the home channel(msec) */
-+ u32 forceScanInterval; /* Time interval between scans (milliseconds)*/
-+ u8 scanType; /* WMI_SCAN_TYPE */
-+ u8 numChannels; /* how many channels follow */
-+ u16 channelList[0]; /* channels in Mhz */
-+} __packed;
-+
-+/*
-+ * WMI_SET_SCAN_PARAMS_CMDID
-+ */
-+#define WMI_SHORTSCANRATIO_DEFAULT 3
-+/*
-+ * Warning: ScanCtrlFlag value of 0xFF is used
-+ * to disable all flags in WMI_SCAN_PARAMS_CMD
-+ * Do not add any more flags to WMI_SCAN_CTRL_FLAG_BITS
-+ */
-+enum WMI_SCAN_CTRL_FLAGS_BITS {
-+ CONNECT_SCAN_CTRL_FLAGS = 0x01, /* set if can scan in the Connect cmd */
-+ SCAN_CONNECTED_CTRL_FLAGS = 0x02, /* set if scan for the SSID it is */
-+ /* already connected to */
-+ ACTIVE_SCAN_CTRL_FLAGS = 0x04, /* set if enable active scan */
-+ ROAM_SCAN_CTRL_FLAGS = 0x08, /* set if enable roam scan */
-+ /* when bmiss and lowrssi */
-+ REPORT_BSSINFO_CTRL_FLAGS = 0x10, /* set if follows customer */
-+ /* BSSINFO reporting rule */
-+ ENABLE_AUTO_CTRL_FLAGS = 0x20, /* if disabled, target doesn't */
-+ /* scan after a disconnect event */
-+ ENABLE_SCAN_ABORT_EVENT = 0x40, /* Scan complete event with canceled */
-+ /* status will be generated */
-+ /* when a scan is prempted */
-+ /* before it gets completed */
-+};
-+
-+#define CAN_SCAN_IN_CONNECT(flags) (flags & CONNECT_SCAN_CTRL_FLAGS)
-+#define CAN_SCAN_CONNECTED(flags) (flags & SCAN_CONNECTED_CTRL_FLAGS)
-+#define ENABLE_ACTIVE_SCAN(flags) (flags & ACTIVE_SCAN_CTRL_FLAGS)
-+#define ENABLE_ROAM_SCAN(flags) (flags & ROAM_SCAN_CTRL_FLAGS)
-+#define CONFIG_REPORT_BSSINFO(flags) (flags & REPORT_BSSINFO_CTRL_FLAGS)
-+#define IS_AUTO_SCAN_ENABLED(flags) (flags & ENABLE_AUTO_CTRL_FLAGS)
-+#define SCAN_ABORT_EVENT_ENABLED(flags) (flags & ENABLE_SCAN_ABORT_EVENT)
-+
-+#define DEFAULT_SCAN_CTRL_FLAGS (CONNECT_SCAN_CTRL_FLAGS | \
-+ SCAN_CONNECTED_CTRL_FLAGS | ACTIVE_SCAN_CTRL_FLAGS | \
-+ ROAM_SCAN_CTRL_FLAGS | ENABLE_AUTO_CTRL_FLAGS)
-+
-+struct WMI_SET_SCAN_PARAMS_CMD {
-+ u16 fg_start_period; /* seconds */
-+ u16 fg_end_period; /* seconds */
-+ u16 bg_period; /* seconds */
-+ u16 maxact_chdwell_time; /* msec */
-+ u16 pas_chdwell_time; /* msec */
-+ u8 shortScanRatio; /* how many shorts scan for one long */
-+ u8 scanCtrlFlags;
-+ u16 minact_chdwell_time; /* msec */
-+ u16 maxact_scan_per_ssid; /* max active scans per ssid */
-+ u32 max_dfsch_act_time; /* msecs */
-+} __packed;
-+
-+/*
-+ * WMI_SET_BSS_FILTER_CMDID
-+ */
-+enum WMI_BSS_FILTER {
-+ NONE_BSS_FILTER = 0x0, /* no beacons forwarded */
-+ ALL_BSS_FILTER, /* all beacons forwarded */
-+ PROFILE_FILTER, /* only beacons matching profile */
-+ ALL_BUT_PROFILE_FILTER, /* all but beacons matching profile */
-+ CURRENT_BSS_FILTER, /* only beacons matching current BSS */
-+ ALL_BUT_BSS_FILTER, /* all but beacons matching BSS */
-+ PROBED_SSID_FILTER, /* beacons matching probed ssid */
-+ LAST_BSS_FILTER, /* marker only */
-+};
-+
-+struct WMI_SET_BSS_FILTER_CMD {
-+ u8 bssFilter; /* see WMI_BSS_FILTER */
-+ u8 reserved1; /* For alignment */
-+ u16 reserved2; /* For alignment */
-+ u32 ieMask;
-+} __packed;
-+
-+/*
-+ * WMI_SCAN_COMPLETE_EVENTID - status parameter
-+ */
-+struct WMI_SCAN_COMPLETE_EVENT {
-+ u32 status;
-+} __packed;
-+
-+/*
-+ * WMI_RX_MGMT_PACKET_EVENTID
-+ */
-+struct WMI_RX_MGMT_PACKET_EVENT {
-+ u16 mcs;
-+ u16 rssi;
-+ u32 status;
-+ u32 length;
-+ u8 qid; /* Not resolved when == 0xFFFFFFFF ==> Broadcast to all MIDS */
-+ u8 mid; /* Not resolved when == 0xFFFFFFFF ==> Broadcast to all MIDS */
-+ u8 cid;
-+ u8 channel; /* From Radio MNGR */
-+ u8 payload[0]; /* struct ieee80211_mgmt */
-+} __packed;
-+
-+/* DMA rings */
-+
-+struct wmi_sw_ring_cfg {
-+ u64 ring_mem_base; /* 48 bit; upper 16 bits reserved */
-+ u16 ring_size;
-+ u16 max_mpdu_size;
-+} __packed;
-+
-+enum wmi_cfg_rx_chain_cmd_action {
-+ ADD_RX_CHAIN = 0x0, DELETE_RX_CHAIN = 0x1,
-+};
-+
-+enum wmi_cfg_rx_chain_cmd_decap_trans_type {
-+ DECAP_TYPE_802_3 = 0x0, DECAP_TYPE_NATIVE_WIFI = 0x1,
-+};
-+
-+enum wmi_cfg_rx_chain_cmd_nwifi_ds_trans_type {
-+ NWIFI_RX_NO_TRANS_MODE = 0x0,
-+ NWIFI_RX_PBSS2AP_TRANS_MODE = 0x1,
-+ NWIFI_RX_PBSS2STA_TRANS_MODE = 0x2,
-+};
-+
-+/*
-+ * WMI_CFG_RX_CHAIN_CMDID
-+ */
-+struct WMI_CFG_RX_CHAIN_CMD {
-+ u32 action; /* enum wmi_cfg_rx_chain_cmd_action */
-+ struct wmi_sw_ring_cfg sw_ring;
-+ u8 mid;
-+ u8 decap_trans_type; /* enum wmi_cfg_rx_chain_cmd_decap_trans_type */
-+ u8 l2_802_3_offload_ctrl;
-+ u8 l2_nwifi_offload_ctrl;
-+ u8 vlan_id;
-+ u8 nwifi_ds_trans_type;
-+ /* enum wmi_cfg_rx_chain_cmd_nwifi_ds_trans_type */
-+ u8 l3_l4_ctrl;
-+ u8 ring_ctrl;
-+ u16 prefetch_thrsh;
-+ u16 wb_thrsh;
-+ u32 itr_value;
-+ u16 host_thrsh;
-+ u16 reserved;
-+ /* added for sniffer mode */
-+ u32 sniffer_mode; /* 0/1, other sniffer fields ignored if 0 */
-+ u32 sniffer_phy_info; /* 0/1, should phy_info be included? */
-+ u32 sniffer_phy; /* 0 - CP; 1 - DP */
-+ u32 sniffer_channel; /* channel index 0..2 */
-+} __packed;
-+
-+enum wmi_cfg_rx_chain_done_event_status {
-+ CFG_RX_CHAIN_SUCCESS = 0x1,
-+};
-+
-+/*
-+ * WMI_CFG_RX_CHAIN_DONE_EVENTID
-+ */
-+struct WMI_CFG_RX_CHAIN_DONE_EVENT {
-+ u32 rx_ring_tail_ptr; /* Rx V-Ring Tail pointer */
-+ u32 status; /* enum wmi_cfg_rx_chain_done_event_status */
-+} __packed;
-+
-+/*
-+ * WMI_VRING_CFG_CMDID
-+ */
-+enum wmi_vring_cfg_cmd_action {
-+ ADD_VRING = 0x0,
-+ MODIFY_VRING = 0x1,
-+ DELETE_VRING = 0x2,
-+};
-+
-+enum wmi_vring_cfg_encap_trans_type {
-+ ENC_TYPE_802_3 = 0x0,
-+ ENC_TYPE_NATIVE_WIFI = 0x1,
-+};
-+
-+enum wmi_vring_cfg_ds_cfg {
-+ PBSS_MODE = 0x0,
-+ STATION_MODE = 0x1,
-+ AP_MODE = 0x2,
-+ ADDR4_MODE = 0x3,
-+};
-+
-+enum wmi_vring_cfg_nwifi_ds_trans_type {
-+ NWIFI_TX_NO_TRANS_MODE = 0x0,
-+ NWIFI_TX_AP2PBSS_TRANS_MODE = 0x1,
-+ NWIFI_TX_STA2PBSS_TRANS_MODE = 0x2,
-+};
-+
-+enum wmi_vring_cfg_schd_params_priority {
-+ REGULAR = 0x0,
-+ HIGH = 0x1,
-+};
-+
-+struct WMI_VRING_CFG_CMD {
-+ u32 action; /* enum wmi_vring_cfg_cmd_action */
-+ struct wmi_sw_ring_cfg sw_ring;
-+ u8 ringid; /* 0-23 */
-+ u8 cidxtid; /* 0..3: cid; 4..7: tid */
-+ u8 encap_trans_type; /* enum wmi_vring_cfg_encap_trans_type */
-+ u8 ds_cfg; /* enum wmi_vring_cfg_ds_cfg - 802.3 DS cfg */
-+ u8 nwifi_ds_trans_type; /* enum wmi_vring_cfg_nwifi_ds_trans_type */
-+ u8 mac_ctrl; /* 0: lifetime_en; 1: aggr_en */
-+#define VRING_CFG_MAC_CTRL_LIFETIME_EN BIT(0)
-+#define VRING_CFG_MAC_CTRL_AGGR_EN BIT(1)
-+ u8 to_resolution; /* 0..5: value; 6..7: reserved */
-+ u8 agg_max_wsize;
-+ /* schd_params */
-+ u16 priority; /* enum wmi_vring_cfg_schd_params_priority */
-+ u16 timeslot_us;
-+} __packed;
-+
-+/*
-+ * WMI_VRING_CFG_DONE_EVENTID
-+ */
-+enum wmi_vring_cfg_done_event_status {
-+ VRING_CFG_SUCCESS = 0x0, VRING_CFG_FAILURE = 0x1,
-+};
-+
-+struct WMI_VRING_CFG_DONE_EVENT {
-+ u8 ringid;
-+ u8 status;
-+ u16 reserved;
-+ u32 tx_vring_tail_ptr; /* Tx vring tail pointer */
-+} __packed;
-+
-+/*
-+ * WMI_SET_MAC_ADDRESS_CMDID
-+ */
-+struct WMI_SET_MAC_ADDRESS_CMD {
-+ u8 macaddr[ETH_ALEN];
-+ u16 reserved;
-+} __packed;
-+
-+/*
-+ * WMI_SET_BEACON_INT_CMDID
-+ */
-+struct WMI_SET_BEACON_INT_CMD {
-+ u16 bcon_interval;
-+ u16 frag_num;
-+ u32 ss_mask_low;
-+ u32 ss_mask_high;
-+ u16 network_type;
-+ u16 reserved;
-+} __packed;
-+
-+/*
-+ * WMI_NOTIFY_REQ_CMDID
-+ */
-+struct WMI_NOTIFY_REQ_CMD {
-+ u32 cid;
-+ u32 interval_usec;
-+} __packed;
-+
-+/*
-+ * WMI_NOTIFY_REQ_DONE_EVENTID
-+ */
-+struct WMI_NOTIFY_REQ_DONE_EVENT {
-+ u32 bf_status;
-+ u32 tsf_hi;
-+ u32 tsf_lo;
-+ u32 bf_metric;
-+ u32 tx_tpt;
-+ u32 tx_gput;
-+ u32 rx_gput;
-+ u16 bf_mcs;
-+ u16 my_rx_sector;
-+ u16 my_tx_sector;
-+ u16 peer_rx_sector;
-+ u16 peer_tx_sector;
-+ u16 reserved;
-+} __packed;
-+
-+#endif /* __WMI_H__ */
---- a/drivers/net/wireless/ath/Makefile
-+++ b/drivers/net/wireless/ath/Makefile
-@@ -2,6 +2,7 @@ obj-$(CONFIG_ATH5K) += ath5k/
- obj-$(CONFIG_ATH9K_HW) += ath9k/
- obj-$(CONFIG_CARL9170) += carl9170/
- obj-$(CONFIG_ATH6KL) += ath6kl/
-+obj-$(CONFIG_WIL6210) += wil6210/
-
- obj-$(CONFIG_ATH_COMMON) += ath.o
-