DPDK patches and discussions
 help / color / mirror / Atom feed
* Re: [dpdk-dev] [PATCH] net/fm10k: support switch function with local linux kernel driver
       [not found] <1574664677-6357-1-git-send-email-xiaojun.liu@silicom.co.il>
@ 2019-11-28  6:34 ` Wang, Xiao W
  0 siblings, 0 replies; only message in thread
From: Wang, Xiao W @ 2019-11-28  6:34 UTC (permalink / raw)
  To: Xiaojun Liu, Zhang, Qi Z, Kwan, Ngai-mint, Fornal, Jakub, Keller,
	Jacob E
  Cc: dev, Zhang, Helin, Lee, Gary M

Hi,

+Kwan, Jakub and Jacob to help on the review, especially on the switch management part.

Thanks,
Xiao

> -----Original Message-----
> From: Xiaojun Liu <xiaojun.liu@silicom.co.il>
> Sent: Monday, November 25, 2019 2:52 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wang, Xiao W
> <xiao.w.wang@intel.com>
> Cc: dev@dpdk.org; Xiaojun Liu <xiaojun.liu@silicom.co.il>
> Subject: [PATCH] net/fm10k: support switch function with local linux kernel
> driver
> 
> To avoid configuration for both kernel driver
> and userspace SDK outside DPDK, we add switch
> management in FM10K DPDK PMD driver.
> It will initialize the switch and configure
> the forwarding rules. We also add a mapping
> between hardware port and DPDK port,
> and change the port initialization steps.
> 
> With the new switch management and port mapping,
> FM10k can be configured as a standard NIC,
> And also can be configured other forwarding rules.
> FM10K can be easily used with them.
> 
> To enable the management, you need add
> CONFIG_RTE_FM10K_MANAGEMENT=y in
> config/common_linux when building.
> 
> Signed-off-by: Xiaojun Liu <xiaojun.liu@silicom.co.il>
> ---
>  drivers/net/fm10k/Makefile                  |   28 +
>  drivers/net/fm10k/base/fm10k_type.h         |   28 +
>  drivers/net/fm10k/fm10k_ethdev.c            |  529 ++++-
>  drivers/net/fm10k/fm10k_flow.c              |  847 ++++++++
>  drivers/net/fm10k/switch/fm10k_config.c     |  693 +++++++
>  drivers/net/fm10k/switch/fm10k_config.h     |  170 ++
>  drivers/net/fm10k/switch/fm10k_debug.h      |   32 +
>  drivers/net/fm10k/switch/fm10k_ext_port.c   |  952 +++++++++
>  drivers/net/fm10k/switch/fm10k_ext_port.h   |  145 ++
>  drivers/net/fm10k/switch/fm10k_ffu.c        | 1031 ++++++++++
>  drivers/net/fm10k/switch/fm10k_ffu.h        |   42 +
>  drivers/net/fm10k/switch/fm10k_i2c.c        |  334 +++
>  drivers/net/fm10k/switch/fm10k_i2c.h        |   68 +
>  drivers/net/fm10k/switch/fm10k_regs.h       | 1944 +++++++++++++++++
>  drivers/net/fm10k/switch/fm10k_sbus.c       |  294 +++
>  drivers/net/fm10k/switch/fm10k_sbus.h       |   55 +
>  drivers/net/fm10k/switch/fm10k_serdes.c     | 1898 +++++++++++++++++
>  drivers/net/fm10k/switch/fm10k_serdes.h     |   41 +
>  drivers/net/fm10k/switch/fm10k_sm.c         |  195 ++
>  drivers/net/fm10k/switch/fm10k_sm.h         |  120 ++
>  drivers/net/fm10k/switch/fm10k_spico_code.c | 2977
> +++++++++++++++++++++++++++
>  drivers/net/fm10k/switch/fm10k_spico_code.h |   34 +
>  drivers/net/fm10k/switch/fm10k_stats.c      |  911 ++++++++
>  drivers/net/fm10k/switch/fm10k_stats.h      |  270 +++
>  drivers/net/fm10k/switch/fm10k_switch.c     | 2422 ++++++++++++++++++++++
>  drivers/net/fm10k/switch/fm10k_switch.h     |  341 +++
>  26 files changed, 16370 insertions(+), 31 deletions(-)
>  create mode 100644 drivers/net/fm10k/fm10k_flow.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_config.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_config.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_debug.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_ext_port.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_ext_port.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_ffu.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_ffu.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_i2c.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_i2c.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_regs.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_sbus.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_sbus.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_serdes.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_serdes.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_sm.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_sm.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_spico_code.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_spico_code.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_stats.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_stats.h
>  create mode 100644 drivers/net/fm10k/switch/fm10k_switch.c
>  create mode 100644 drivers/net/fm10k/switch/fm10k_switch.h
> 
> diff --git a/drivers/net/fm10k/Makefile b/drivers/net/fm10k/Makefile
> index 55e9cd5..c19e6d9 100644
> --- a/drivers/net/fm10k/Makefile
> +++ b/drivers/net/fm10k/Makefile
> @@ -8,9 +8,16 @@ include $(RTE_SDK)/mk/rte.vars.mk
>  #
>  LIB = librte_pmd_fm10k.a
> 
> +ifeq ($(CONFIG_RTE_FM10K_MANAGEMENT),y)
> +LDLIBS += -lpthread
> +endif
> +
>  CFLAGS += -O3
>  CFLAGS += $(WERROR_FLAGS)
>  CFLAGS += -DALLOW_EXPERIMENTAL_API
> +ifeq ($(CONFIG_RTE_FM10K_MANAGEMENT),y)
> +CFLAGS += -DENABLE_FM10K_MANAGEMENT
> +endif
> 
>  EXPORT_MAP := rte_pmd_fm10k_version.map
> 
> @@ -62,12 +69,19 @@ $(foreach obj, $(BASE_DRIVER_OBJS), $(eval
> CFLAGS_$(obj)+=$(CFLAGS_BASE_DRIVER))
> 
>  VPATH += $(SRCDIR)/base
> 
> +ifeq ($(CONFIG_RTE_FM10K_MANAGEMENT),y)
> +VPATH += $(SRCDIR)/switch
> +endif
> +
>  #
>  # all source are stored in SRCS-y
>  # base driver is based on the package of cid-fm10k.2017.01.24.tar.gz
>  #
>  SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_ethdev.c
>  SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_rxtx.c
> +ifeq ($(CONFIG_RTE_FM10K_MANAGEMENT),y)
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_flow.c
> +endif
> 
>  SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_pf.c
>  SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_tlv.c
> @@ -75,6 +89,20 @@ SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=
> fm10k_common.c
>  SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_mbx.c
>  SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_vf.c
>  SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_api.c
> +
> +ifeq ($(CONFIG_RTE_FM10K_MANAGEMENT),y)
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_ext_port.c
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_i2c.c
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_sbus.c
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_serdes.c
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_sm.c
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_spico_code.c
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_stats.c
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_ffu.c
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_config.c
> +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_switch.c
> +endif
> +
>  SRCS-$(CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR) += fm10k_rxtx_vec.c
> 
>  include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/drivers/net/fm10k/base/fm10k_type.h
> b/drivers/net/fm10k/base/fm10k_type.h
> index 84781ba..107e3e1 100644
> --- a/drivers/net/fm10k/base/fm10k_type.h
> +++ b/drivers/net/fm10k/base/fm10k_type.h
> @@ -5,6 +5,14 @@
>  #ifndef _FM10K_TYPE_H_
>  #define _FM10K_TYPE_H_
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +#include <rte_time.h>
> +#include <rte_kvargs.h>
> +#include <rte_hash.h>
> +#include <rte_flow.h>
> +#include <rte_flow_driver.h>
> +#include <rte_tm_driver.h>
> +#endif
>  /* forward declaration */
>  struct fm10k_hw;
> 
> @@ -701,10 +709,26 @@ struct fm10k_iov_info {
>  	u16 num_pools;
>  };
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +/*
> + * Struct to store flow created.
> + */
> +struct rte_flow {
> +	TAILQ_ENTRY(rte_flow) node;
> +	enum rte_filter_type filter_type;
> +	void *rule;
> +};
> +
> +TAILQ_HEAD(fm10k_flow_list, rte_flow);
> +#endif
> +
>  struct fm10k_hw {
>  	u32 *hw_addr;
>  	u32 *sw_addr;
>  	void *back;
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	void *rte_dev;
> +#endif
>  	struct fm10k_mac_info mac;
>  	struct fm10k_bus_info bus;
>  	struct fm10k_bus_info bus_caps;
> @@ -717,6 +741,10 @@ struct fm10k_hw {
>  	u16 subsystem_vendor_id;
>  	u8 revision_id;
>  	u32 flags;
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	u32 switch_id;
> +	struct fm10k_flow_list flow_list;
> +#endif
>  #define FM10K_HW_FLAG_CLOCK_OWNER	BIT(0)
>  };
> 
> diff --git a/drivers/net/fm10k/fm10k_ethdev.c
> b/drivers/net/fm10k/fm10k_ethdev.c
> index 99c4366..ac04e0e 100644
> --- a/drivers/net/fm10k/fm10k_ethdev.c
> +++ b/drivers/net/fm10k/fm10k_ethdev.c
> @@ -13,6 +13,10 @@
> 
>  #include "fm10k.h"
>  #include "base/fm10k_api.h"
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +#include "switch/fm10k_regs.h"
> +#include "switch/fm10k_switch.h"
> +#endif
> 
>  /* Default delay to acquire mailbox lock */
>  #define FM10K_MBXLOCK_DELAY_US 20
> @@ -39,6 +43,12 @@
>  #define GLORT_PF_MASK    0xFFC0
>  #define GLORT_FD_MASK    GLORT_PF_MASK
>  #define GLORT_FD_INDEX   GLORT_FD_Q_BASE
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +/* Flow operations */
> +extern const struct rte_flow_ops fm10k_flow_ops;
> +/* When the switch is ready, the status will be changed */
> +static int fm10k_switch_ready = 0;
> +#endif
> 
>  int fm10k_logtype_init;
>  int fm10k_logtype_driver;
> @@ -509,6 +519,15 @@ struct fm10k_xstats_name_off {
>  	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
>  	uint32_t mrqc, *key, i, reta, j;
>  	uint64_t hf;
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	uint16_t nb_rx_queues = dev->data->nb_rx_queues;
> +	int mapped_num;
> +	struct fm10k_hw *mapped_hws[2];
> +
> +	mapped_num = fm10k_switch_dpdk_mapped_hw_get(hw,
> mapped_hws);
> +	if(mapped_num == 2)
> +		nb_rx_queues /= 2;
> +#endif
> 
>  #define RSS_KEY_SIZE 40
>  	static uint8_t rss_intel_key[RSS_KEY_SIZE] = {
> @@ -638,27 +657,42 @@ struct fm10k_xstats_name_off {
>  static int
>  fm10k_dev_tx_init(struct rte_eth_dev *dev)
>  {
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +#else
> +	struct fm10k_hw *hw;
> +	struct fm10k_hw *unmap_hw = FM10K_DEV_PRIVATE_TO_HW(dev-
> >data->dev_private);
> +	uint32_t data;
> +#endif
>  	int i, ret;
> +	uint16_t hw_queue_id;
>  	struct fm10k_tx_queue *txq;
>  	uint64_t base_addr;
>  	uint32_t size;
> 
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	/* Disable TXINT to avoid possible interrupt */
>  	for (i = 0; i < hw->mac.max_queues; i++)
>  		FM10K_WRITE_REG(hw, FM10K_TXINT(i),
>  				3 << FM10K_TXINT_TIMER_SHIFT);
> +#else
> +	fm10k_switch_dpdk_tx_queue_num_set(unmap_hw, dev->data-
> >nb_tx_queues);
> +#endif
> 
>  	/* Setup TX queue */
>  	for (i = 0; i < dev->data->nb_tx_queues; ++i) {
> +		hw_queue_id = i;
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +		fm10k_switch_dpdk_hw_queue_map(unmap_hw, i, dev->data-
> >nb_tx_queues, &hw, &hw_queue_id);
> +#endif
>  		txq = dev->data->tx_queues[i];
>  		base_addr = txq->hw_ring_phys_addr;
>  		size = txq->nb_desc * sizeof(struct fm10k_tx_desc);
> 
>  		/* disable queue to avoid issues while updating state */
> -		ret = tx_queue_disable(hw, i);
> +		ret = tx_queue_disable(hw, hw_queue_id);
>  		if (ret) {
> -			PMD_INIT_LOG(ERR, "failed to disable queue %d", i);
> +			PMD_INIT_LOG(ERR, "failed to disable queue %d",
> hw_queue_id);
>  			return -1;
>  		}
>  		/* Enable use of FTAG bit in TX descriptor, PFVTCTL
> @@ -666,7 +700,7 @@ struct fm10k_xstats_name_off {
>  		 */
>  		if (fm10k_check_ftag(dev->device->devargs)) {
>  			if (hw->mac.type == fm10k_mac_pf) {
> -				FM10K_WRITE_REG(hw, FM10K_PFVTCTL(i),
> +				FM10K_WRITE_REG(hw,
> FM10K_PFVTCTL(hw_queue_id),
> 
> 	FM10K_PFVTCTL_FTAG_DESC_ENABLE);
>  				PMD_INIT_LOG(DEBUG, "FTAG mode is
> enabled");
>  			} else {
> @@ -676,15 +710,22 @@ struct fm10k_xstats_name_off {
>  		}
> 
>  		/* set location and size for descriptor ring */
> -		FM10K_WRITE_REG(hw, FM10K_TDBAL(i),
> +		FM10K_WRITE_REG(hw, FM10K_TDBAL(hw_queue_id),
>  				base_addr & UINT64_LOWER_32BITS_MASK);
> -		FM10K_WRITE_REG(hw, FM10K_TDBAH(i),
> +		FM10K_WRITE_REG(hw, FM10K_TDBAH(hw_queue_id),
>  				base_addr >> (CHAR_BIT * sizeof(uint32_t)));
> -		FM10K_WRITE_REG(hw, FM10K_TDLEN(i), size);
> +		FM10K_WRITE_REG(hw, FM10K_TDLEN(hw_queue_id), size);
> 
>  		/* assign default SGLORT for each TX queue by PF */
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  		if (hw->mac.type == fm10k_mac_pf)
> -			FM10K_WRITE_REG(hw, FM10K_TX_SGLORT(i), hw-
> >mac.dglort_map);
> +			FM10K_WRITE_REG(hw,
> FM10K_TX_SGLORT(hw_queue_id), hw->mac.dglort_map);
> +#else
> +		if (hw->mac.type == fm10k_mac_pf) {
> +			data =
> FM10K_SW_MAKE_REG_FIELD(TX_SGLORT_SGLORT, hw->mac.dglort_map);
> +			FM10K_WRITE_REG(hw,
> FM10K_TX_SGLORT(hw_queue_id), data);
> +		}
> +#endif
>  	}
> 
>  	/* set up vector or scalar TX function as appropriate */
> @@ -696,19 +737,26 @@ struct fm10k_xstats_name_off {
>  static int
>  fm10k_dev_rx_init(struct rte_eth_dev *dev)
>  {
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
>  	struct fm10k_macvlan_filter_info *macvlan;
>  	struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
>  	struct rte_intr_handle *intr_handle = &pdev->intr_handle;
> +	uint32_t logic_port = hw->mac.dglort_map;
> +	uint16_t queue_stride = 0;
> +#else
> +	struct fm10k_hw *hw;
> +	struct fm10k_hw *unmap_hw = FM10K_DEV_PRIVATE_TO_HW(dev-
> >data->dev_private);
> +#endif
>  	int i, ret;
> +	uint16_t hw_queue_id;
>  	struct fm10k_rx_queue *rxq;
>  	uint64_t base_addr;
>  	uint32_t size;
>  	uint32_t rxdctl = FM10K_RXDCTL_WRITE_BACK_MIN_DELAY;
> -	uint32_t logic_port = hw->mac.dglort_map;
>  	uint16_t buf_size;
> -	uint16_t queue_stride = 0;
> 
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	/* enable RXINT for interrupt mode */
>  	i = 0;
>  	if (rte_intr_dp_is_en(intr_handle)) {
> @@ -728,26 +776,33 @@ struct fm10k_xstats_name_off {
>  	for (; i < hw->mac.max_queues; i++)
>  		FM10K_WRITE_REG(hw, FM10K_RXINT(i),
>  			3 << FM10K_RXINT_TIMER_SHIFT);
> +#else
> +	fm10k_switch_dpdk_rx_queue_num_set(unmap_hw, dev->data-
> >nb_rx_queues);
> +#endif
> 
>  	/* Setup RX queues */
>  	for (i = 0; i < dev->data->nb_rx_queues; ++i) {
> +		hw_queue_id = i;
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +		fm10k_switch_dpdk_hw_queue_map(unmap_hw, i, dev->data-
> >nb_rx_queues, &hw, &hw_queue_id);
> +#endif
>  		rxq = dev->data->rx_queues[i];
>  		base_addr = rxq->hw_ring_phys_addr;
>  		size = rxq->nb_desc * sizeof(union fm10k_rx_desc);
> 
>  		/* disable queue to avoid issues while updating state */
> -		ret = rx_queue_disable(hw, i);
> +		ret = rx_queue_disable(hw, hw_queue_id);
>  		if (ret) {
> -			PMD_INIT_LOG(ERR, "failed to disable queue %d", i);
> +			PMD_INIT_LOG(ERR, "failed to disable queue %d",
> hw_queue_id);
>  			return -1;
>  		}
> 
>  		/* Setup the Base and Length of the Rx Descriptor Ring */
> -		FM10K_WRITE_REG(hw, FM10K_RDBAL(i),
> +		FM10K_WRITE_REG(hw, FM10K_RDBAL(hw_queue_id),
>  				base_addr & UINT64_LOWER_32BITS_MASK);
> -		FM10K_WRITE_REG(hw, FM10K_RDBAH(i),
> +		FM10K_WRITE_REG(hw, FM10K_RDBAH(hw_queue_id),
>  				base_addr >> (CHAR_BIT * sizeof(uint32_t)));
> -		FM10K_WRITE_REG(hw, FM10K_RDLEN(i), size);
> +		FM10K_WRITE_REG(hw, FM10K_RDLEN(hw_queue_id), size);
> 
>  		/* Configure the Rx buffer size for one buff without split */
>  		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) -
> @@ -761,7 +816,7 @@ struct fm10k_xstats_name_off {
>  		 */
>  		buf_size -= FM10K_RX_DATABUF_ALIGN;
> 
> -		FM10K_WRITE_REG(hw, FM10K_SRRCTL(i),
> +		FM10K_WRITE_REG(hw, FM10K_SRRCTL(hw_queue_id),
>  				(buf_size >> FM10K_SRRCTL_BSIZEPKT_SHIFT) |
>  				FM10K_SRRCTL_LOOPBACK_SUPPRESS);
> 
> @@ -771,9 +826,9 @@ struct fm10k_xstats_name_off {
>  			rxq->offloads & DEV_RX_OFFLOAD_SCATTER) {
>  			uint32_t reg;
>  			dev->data->scattered_rx = 1;
> -			reg = FM10K_READ_REG(hw, FM10K_SRRCTL(i));
> +			reg = FM10K_READ_REG(hw,
> FM10K_SRRCTL(hw_queue_id));
>  			reg |= FM10K_SRRCTL_BUFFER_CHAINING_EN;
> -			FM10K_WRITE_REG(hw, FM10K_SRRCTL(i), reg);
> +			FM10K_WRITE_REG(hw, FM10K_SRRCTL(hw_queue_id),
> reg);
>  		}
> 
>  		/* Enable drop on empty, it's RO for VF */
> @@ -793,6 +848,7 @@ struct fm10k_xstats_name_off {
>  	/* update RX_SGLORT for loopback suppress*/
>  	if (hw->mac.type != fm10k_mac_pf)
>  		return 0;
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	macvlan = FM10K_DEV_PRIVATE_TO_MACVLAN(dev->data-
> >dev_private);
>  	if (macvlan->nb_queue_pools)
>  		queue_stride = dev->data->nb_rx_queues / macvlan-
> >nb_queue_pools;
> @@ -801,6 +857,7 @@ struct fm10k_xstats_name_off {
>  			logic_port++;
>  		FM10K_WRITE_REG(hw, FM10K_RX_SGLORT(i), logic_port);
>  	}
> +#endif
> 
>  	return 0;
>  }
> @@ -808,13 +865,29 @@ struct fm10k_xstats_name_off {
>  static int
>  fm10k_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
>  {
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +#else
> +	struct fm10k_hw *hw;
> +	struct fm10k_hw *unmap_hw = FM10K_DEV_PRIVATE_TO_HW(dev-
> >data->dev_private);
> +	int ret;
> +#endif
>  	int err;
>  	uint32_t reg;
>  	struct fm10k_rx_queue *rxq;
> +	uint16_t hw_queue_id = rx_queue_id;
> 
>  	PMD_INIT_FUNC_TRACE();
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	ret = fm10k_switch_dpdk_hw_queue_map(unmap_hw,
> +			rx_queue_id, dev->data->nb_rx_queues, &hw,
> &hw_queue_id);
> +	if (ret < 0)
> +		return -EIO;
> +	else if (ret != 1)	/* reference port's queue don't need start */
> +		return 0;
> +#endif
> +
>  	rxq = dev->data->rx_queues[rx_queue_id];
>  	err = rx_queue_reset(rxq);
>  	if (err == -ENOMEM) {
> @@ -833,23 +906,23 @@ struct fm10k_xstats_name_off {
>  	 * this comment and the following two register writes when the
>  	 * emulation platform is no longer being used.
>  	 */
> -	FM10K_WRITE_REG(hw, FM10K_RDH(rx_queue_id), 0);
> -	FM10K_WRITE_REG(hw, FM10K_RDT(rx_queue_id), rxq->nb_desc - 1);
> +	FM10K_WRITE_REG(hw, FM10K_RDH(hw_queue_id), 0);
> +	FM10K_WRITE_REG(hw, FM10K_RDT(hw_queue_id), rxq->nb_desc - 1);
> 
>  	/* Set PF ownership flag for PF devices */
> -	reg = FM10K_READ_REG(hw, FM10K_RXQCTL(rx_queue_id));
> +	reg = FM10K_READ_REG(hw, FM10K_RXQCTL(hw_queue_id));
>  	if (hw->mac.type == fm10k_mac_pf)
>  		reg |= FM10K_RXQCTL_PF;
>  	reg |= FM10K_RXQCTL_ENABLE;
>  	/* enable RX queue */
> -	FM10K_WRITE_REG(hw, FM10K_RXQCTL(rx_queue_id), reg);
> +	FM10K_WRITE_REG(hw, FM10K_RXQCTL(hw_queue_id), reg);
>  	FM10K_WRITE_FLUSH(hw);
> 
>  	/* Setup the HW Rx Head and Tail Descriptor Pointers
>  	 * Note: this must be done AFTER the queue is enabled
>  	 */
> -	FM10K_WRITE_REG(hw, FM10K_RDH(rx_queue_id), 0);
> -	FM10K_WRITE_REG(hw, FM10K_RDT(rx_queue_id), rxq->nb_desc - 1);
> +	FM10K_WRITE_REG(hw, FM10K_RDH(hw_queue_id), 0);
> +	FM10K_WRITE_REG(hw, FM10K_RDT(hw_queue_id), rxq->nb_desc - 1);
>  	dev->data->rx_queue_state[rx_queue_id] =
> RTE_ETH_QUEUE_STATE_STARTED;
> 
>  	return 0;
> @@ -875,22 +948,38 @@ struct fm10k_xstats_name_off {
>  static int
>  fm10k_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
>  {
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +#else
> +	struct fm10k_hw *hw;
> +	struct fm10k_hw *unmap_hw = FM10K_DEV_PRIVATE_TO_HW(dev-
> >data->dev_private);
> +	int ret;
> +#endif
>  	/** @todo - this should be defined in the shared code */
>  #define FM10K_TXDCTL_WRITE_BACK_MIN_DELAY	0x00010000
>  	uint32_t txdctl = FM10K_TXDCTL_WRITE_BACK_MIN_DELAY;
>  	struct fm10k_tx_queue *q = dev->data->tx_queues[tx_queue_id];
> +	uint16_t hw_queue_id = tx_queue_id;
> 
>  	PMD_INIT_FUNC_TRACE();
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	ret = fm10k_switch_dpdk_hw_queue_map(unmap_hw,
> +		tx_queue_id, dev->data->nb_tx_queues, &hw, &hw_queue_id);
> +	if (ret < 0)
> +		return -EIO;
> +	else if (ret != 1)
> +		return 0;
> +#endif
> +
>  	q->ops->reset(q);
> 
>  	/* reset head and tail pointers */
> -	FM10K_WRITE_REG(hw, FM10K_TDH(tx_queue_id), 0);
> -	FM10K_WRITE_REG(hw, FM10K_TDT(tx_queue_id), 0);
> +	FM10K_WRITE_REG(hw, FM10K_TDH(hw_queue_id), 0);
> +	FM10K_WRITE_REG(hw, FM10K_TDT(hw_queue_id), 0);
> 
>  	/* enable TX queue */
> -	FM10K_WRITE_REG(hw, FM10K_TXDCTL(tx_queue_id),
> +	FM10K_WRITE_REG(hw, FM10K_TXDCTL(hw_queue_id),
>  				FM10K_TXDCTL_ENABLE | txdctl);
>  	FM10K_WRITE_FLUSH(hw);
>  	dev->data->tx_queue_state[tx_queue_id] =
> RTE_ETH_QUEUE_STATE_STARTED;
> @@ -1081,9 +1170,22 @@ static inline int fm10k_glort_valid(struct fm10k_hw
> *hw)
>  {
>  	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
>  	int i, diag;
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	struct fm10k_hw *mapped_hws[2];
> +	int j, mapped_num;
> +	uint32_t data;
> +#endif
> 
>  	PMD_INIT_FUNC_TRACE();
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	mapped_num = fm10k_switch_dpdk_mapped_hw_get(hw,
> mapped_hws);
> +	if (mapped_num < 0 || mapped_num > 2)
> +		return -EIO;
> +#endif
> +
> +
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	/* stop, init, then start the hw */
>  	diag = fm10k_stop_hw(hw);
>  	if (diag != FM10K_SUCCESS) {
> @@ -1102,6 +1204,57 @@ static inline int fm10k_glort_valid(struct fm10k_hw
> *hw)
>  		PMD_INIT_LOG(ERR, "Hardware start failed: %d", diag);
>  		return -EIO;
>  	}
> +#else
> +	for (j = 0; j < mapped_num; j++) {
> +		struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI((struct
> rte_eth_dev *)(mapped_hws[j]->rte_dev));
> +		struct rte_intr_handle *intr_handle = &pdev->intr_handle;
> +
> +		/* stop, init, then start the hw */
> +		diag = fm10k_stop_hw(mapped_hws[j]);
> +		if (diag != FM10K_SUCCESS) {
> +			PMD_INIT_LOG(ERR, "Hardware stop failed: %d", diag);
> +			return -EIO;
> +		}
> +
> +		diag = fm10k_init_hw(mapped_hws[j]);
> +		if (diag != FM10K_SUCCESS) {
> +			PMD_INIT_LOG(ERR, "Hardware init failed: %d", diag);
> +			return -EIO;
> +		}
> +
> +		diag = fm10k_start_hw(mapped_hws[j]);
> +		if (diag != FM10K_SUCCESS) {
> +			PMD_INIT_LOG(ERR, "Hardware start failed: %d", diag);
> +			return -EIO;
> +		}
> +
> +		/* Disable TXINT to avoid possible interrupt */
> +		for (i = 0; i < hw->mac.max_queues; i++)
> +			FM10K_WRITE_REG(mapped_hws[j], FM10K_TXINT(i),
> +					3 << FM10K_TXINT_TIMER_SHIFT);
> +
> +		/* enable RXINT for interrupt mode */
> +		i = 0;
> +		if (rte_intr_dp_is_en(intr_handle)) {
> +			for (; i < dev->data->nb_rx_queues; i++) {
> +				FM10K_WRITE_REG(mapped_hws[j],
> FM10K_RXINT(i), Q2V(pdev, i));
> +				if (mapped_hws[j]->mac.type ==
> fm10k_mac_pf)
> +					FM10K_WRITE_REG(mapped_hws[j],
> FM10K_ITR(Q2V(pdev, i)),
> +						FM10K_ITR_AUTOMASK |
> +						FM10K_ITR_MASK_CLEAR);
> +				else
> +					FM10K_WRITE_REG(mapped_hws[j],
> FM10K_VFITR(Q2V(pdev, i)),
> +						FM10K_ITR_AUTOMASK |
> +						FM10K_ITR_MASK_CLEAR);
> +			}
> +		}
> +
> +		/* Disable other RXINT to avoid possible interrupt */
> +		for (; i < hw->mac.max_queues; i++)
> +			FM10K_WRITE_REG(mapped_hws[j], FM10K_RXINT(i),
> +				3 << FM10K_RXINT_TIMER_SHIFT);
> +	}
> +#endif
> 
>  	diag = fm10k_dev_tx_init(dev);
>  	if (diag) {
> @@ -1153,12 +1306,28 @@ static inline int fm10k_glort_valid(struct fm10k_hw
> *hw)
>  		}
>  	}
> 
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	/* Update default vlan when not in VMDQ mode */
>  	if (!(dev->data->dev_conf.rxmode.mq_mode &
> ETH_MQ_RX_VMDQ_FLAG))
>  		fm10k_vlan_filter_set(dev, hw->mac.default_vid, true);
> +#endif
> 
>  	fm10k_link_update(dev, 0);
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	/* Admit all VLANs */
> +	for (j = 0; j <= 64; j++) {
> +		for (i = 0; i < FM10K_SW_VLAN_TABLE_ENTRIES; i++)
> +			FM10K_WRITE_REG(hw,
> FM10K_SW_VLAN_TABLE_ENTRY(j, i), 0xffffffff);
> +	}
> +
> +	/* Disable PEP 1loopback */
> +	/* XXX Does this need to be done by the master PEP while the switch is
> in reset? */
> +	data = FM10K_READ_REG(hw, FM10K_CTRL_EXT);
> +	data &= ~FM10K_SW_CTRL_EXT_SWITCH_LOOPBACK;
> +	FM10K_WRITE_REG(hw, FM10K_CTRL_EXT, data);
> +#endif
> +
>  	return 0;
>  }
> 
> @@ -1319,17 +1488,40 @@ static int fm10k_xstats_get_names(__rte_unused
> struct rte_eth_dev *dev,
>  fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
>  {
>  	uint64_t ipackets, opackets, ibytes, obytes, imissed;
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	struct fm10k_hw *hw =
>  		FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +#else
> +	struct fm10k_hw *hw;
> +	struct fm10k_hw *unmap_hw =
> +		FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +	struct fm10k_hw *mapped_hws[2];
> +	int mapped_num;
> +	uint16_t hw_queue_id;
> +#endif
>  	struct fm10k_hw_stats *hw_stats =
>  		FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
>  	int i;
> 
>  	PMD_INIT_FUNC_TRACE();
> 
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	fm10k_update_hw_stats(hw, hw_stats);
> +#else
> +	mapped_num = fm10k_switch_dpdk_mapped_hw_get(unmap_hw,
> mapped_hws);
> +	if (mapped_num < 0 || mapped_num > 2)
> +		return -EIO;
> +
> +	for (i = 0; i < mapped_num; i++) {
> +		struct rte_eth_dev *mydev = mapped_hws[i]->rte_dev;
> +		hw_stats = FM10K_DEV_PRIVATE_TO_STATS(mydev->data-
> >dev_private);
> +		fm10k_update_hw_stats(mapped_hws[i], hw_stats);
> +	}
> +#endif
> 
>  	ipackets = opackets = ibytes = obytes = imissed = 0;
> +
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	for (i = 0; (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) &&
>  		(i < hw->mac.max_queues); ++i) {
>  		stats->q_ipackets[i] = hw_stats->q[i].rx_packets.count;
> @@ -1343,6 +1535,28 @@ static int fm10k_xstats_get_names(__rte_unused
> struct rte_eth_dev *dev,
>  		obytes   += stats->q_obytes[i];
>  		imissed  += stats->q_errors[i];
>  	}
> +#else
> +	if (mapped_num)	{
> +		for (i = 0; (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) &&
> +			(i < unmap_hw->mac.max_queues); ++i) {
> +			hw_queue_id = i;
> +			fm10k_switch_dpdk_hw_queue_map(unmap_hw, i,
> unmap_hw->mac.max_queues, &hw, &hw_queue_id);
> +			if (mapped_hws[1]) {
> +				struct rte_eth_dev *mydev;
> +				mydev = hw->rte_dev;
> +				hw_stats =
> FM10K_DEV_PRIVATE_TO_STATS(mydev->data->dev_private);
> +			}
> +			stats->q_ipackets[i] = hw_stats-
> >q[hw_queue_id].rx_packets.count;
> +			stats->q_opackets[i] = hw_stats-
> >q[hw_queue_id].tx_packets.count;
> +			stats->q_ibytes[i]   = hw_stats-
> >q[hw_queue_id].rx_bytes.count;
> +			stats->q_obytes[i]   = hw_stats-
> >q[hw_queue_id].tx_bytes.count;
> +			ipackets += stats->q_ipackets[i];
> +			opackets += stats->q_opackets[i];
> +			ibytes   += stats->q_ibytes[i];
> +			obytes   += stats->q_obytes[i];
> +		}
> +	}
> +#endif
>  	stats->ipackets = ipackets;
>  	stats->opackets = opackets;
>  	stats->ibytes = ibytes;
> @@ -1813,15 +2027,27 @@ static uint64_t
> fm10k_get_rx_port_offloads_capa(struct rte_eth_dev *dev)
>  	uint16_t nb_desc, unsigned int socket_id,
>  	const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
>  {
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +#else
> +	struct fm10k_hw *hw;
> +	struct fm10k_hw *unmap_hw = FM10K_DEV_PRIVATE_TO_HW(dev-
> >data->dev_private);
> +#endif
>  	struct fm10k_dev_info *dev_info =
>  		FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
>  	struct fm10k_rx_queue *q;
>  	const struct rte_memzone *mz;
>  	uint64_t offloads;
> +	uint16_t hw_queue_id = queue_id;
> 
>  	PMD_INIT_FUNC_TRACE();
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	if (fm10k_switch_dpdk_hw_queue_map(unmap_hw,
> +			queue_id, dev->data->nb_rx_queues, &hw,
> &hw_queue_id) < 0)
> +		return -EIO;
> +#endif
> +
>  	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
> 
>  	/* make sure the mempool element size can account for alignment. */
> @@ -1867,7 +2093,7 @@ static uint64_t
> fm10k_get_rx_port_offloads_capa(struct rte_eth_dev *dev)
>  	q->port_id = dev->data->port_id;
>  	q->queue_id = queue_id;
>  	q->tail_ptr = (volatile uint32_t *)
> -		&((uint32_t *)hw->hw_addr)[FM10K_RDT(queue_id)];
> +		&((uint32_t *)hw->hw_addr)[FM10K_RDT(hw_queue_id)];
>  	q->offloads = offloads;
>  	if (handle_rxconf(q, conf))
>  		return -EINVAL;
> @@ -2002,13 +2228,25 @@ static uint64_t
> fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
>  	uint16_t nb_desc, unsigned int socket_id,
>  	const struct rte_eth_txconf *conf)
>  {
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +#else
> +	struct fm10k_hw *hw;
> +	struct fm10k_hw *unmap_hw = FM10K_DEV_PRIVATE_TO_HW(dev-
> >data->dev_private);
> +#endif
>  	struct fm10k_tx_queue *q;
>  	const struct rte_memzone *mz;
>  	uint64_t offloads;
> +	uint16_t hw_queue_id = queue_id;
> 
>  	PMD_INIT_FUNC_TRACE();
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	if (fm10k_switch_dpdk_hw_queue_map(unmap_hw,
> +			queue_id, dev->data->nb_tx_queues, &hw,
> &hw_queue_id) < 0)
> +		return -EIO;
> +#endif
> +
>  	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
> 
>  	/* make sure a valid number of descriptors have been requested */
> @@ -2050,7 +2288,7 @@ static uint64_t
> fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
>  	q->offloads = offloads;
>  	q->ops = &def_txq_ops;
>  	q->tail_ptr = (volatile uint32_t *)
> -		&((uint32_t *)hw->hw_addr)[FM10K_TDT(queue_id)];
> +		&((uint32_t *)hw->hw_addr)[FM10K_TDT(hw_queue_id)];
>  	if (handle_txconf(q, conf))
>  		return -EINVAL;
> 
> @@ -2280,6 +2518,74 @@ static uint64_t
> fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
>  	return 0;
>  }
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +static int
> +fm10k_mirror_rule_set(struct rte_eth_dev *dev,
> +			struct rte_eth_mirror_conf *mirror_conf,
> +			uint8_t sw_id, uint8_t on)
> +{
> +	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +
> +	PMD_INIT_LOG(DEBUG, "Mirror set, switch %d to port %d attach
> vlan %d on %d",
> +			sw_id, mirror_conf->dst_pool, mirror_conf-
> >vlan.vlan_id[0], on);
> +
> +	if (on)	{
> +		if (fm10k_switch_mirror_set(hw,
> +				mirror_conf->dst_pool, mirror_conf-
> >vlan.vlan_id[0]) < 0) {
> +			PMD_INIT_LOG(ERR, "Input wrong port!!!");
> +			return -1;
> +		}
> +	} else {
> +		if (fm10k_switch_mirror_reset(hw) < 0) {
> +			PMD_INIT_LOG(ERR, "Input wrong port!!!");
> +			return -1;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +
> +static int
> +fm10k_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t sw_id)
> +{
> +	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +
> +	PMD_INIT_LOG(DEBUG, "Mirror reset, switch %d", sw_id);
> +
> +	fm10k_switch_mirror_reset(hw);
> +
> +	return 0;
> +}
> +
> +static int
> +fm10k_dev_filter_ctrl(struct rte_eth_dev *dev,
> +		     enum rte_filter_type filter_type,
> +		     enum rte_filter_op filter_op,
> +		     void *arg)
> +{
> +	int ret = 0;
> +
> +	if (dev == NULL)
> +		return -EINVAL;
> +
> +	switch (filter_type) {
> +	case RTE_ETH_FILTER_GENERIC:
> +		if (filter_op != RTE_ETH_FILTER_GET)
> +			return -EINVAL;
> +		*(const void **)arg = &fm10k_flow_ops;
> +		break;
> +	default:
> +		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
> +							filter_type);
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +#endif
> +
>  static void
>  fm10k_dev_enable_intr_pf(struct rte_eth_dev *dev)
>  {
> @@ -2588,6 +2894,9 @@ static uint64_t
> fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
>  		FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
>  	int status_mbx;
>  	s32 err;
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	uint32_t writeback = 0;
> +#endif
> 
>  	if (hw->mac.type != fm10k_mac_pf)
>  		return;
> @@ -2601,11 +2910,20 @@ static uint64_t
> fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
>  	}
> 
>  	/* Handle switch up/down */
> -	if (cause & FM10K_EICR_SWITCHNOTREADY)
> -		PMD_INIT_LOG(ERR, "INT: Switch is not ready");
> +	if (cause & FM10K_EICR_SWITCHNOTREADY) {
> +		PMD_INIT_LOG(INFO, "INT: Switch is not ready");
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +		fm10k_switch_ready = 0;
> +		writeback |= FM10K_EICR_SWITCHNOTREADY;
> +#endif
> +	}
> 
>  	if (cause & FM10K_EICR_SWITCHREADY) {
>  		PMD_INIT_LOG(INFO, "INT: Switch is ready");
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +		fm10k_switch_ready = 1;
> +		writeback |= FM10K_EICR_SWITCHREADY;
> +#endif
>  		if (dev_info->sm_down == 1) {
>  			fm10k_mbx_lock(hw);
> 
> @@ -2656,6 +2974,7 @@ static uint64_t
> fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
>  	}
> 
>  	/* Handle mailbox message */
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	fm10k_mbx_lock(hw);
>  	err = hw->mbx.ops.process(hw, &hw->mbx);
>  	fm10k_mbx_unlock(hw);
> @@ -2667,6 +2986,25 @@ static uint64_t
> fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
>  				NULL);
>  	}
> 
> +#else
> +	if (cause & FM10K_EICR_MAILBOX)	{
> +		fm10k_mbx_lock(hw);
> +		err = hw->mbx.ops.process(hw, &hw->mbx);
> +		fm10k_mbx_unlock(hw);
> +		writeback |= FM10K_EICR_MAILBOX;
> +		if (err == FM10K_ERR_RESET_REQUESTED) {
> +			PMD_INIT_LOG(INFO, "INT: Switch is down");
> +			dev_info->sm_down = 1;
> +			_rte_eth_dev_callback_process(dev,
> RTE_ETH_EVENT_INTR_LSC,
> +					NULL);
> +		}
> +	}
> +
> +	/* Handle switch interrupt */
> +	if (cause & FM10K_SW_EICR_SWITCH_INT)
> +		fm10k_switch_intr(hw);
> +#endif
> +
>  	/* Handle SRAM error */
>  	if (cause & FM10K_EICR_SRAMERROR) {
>  		PMD_INIT_LOG(ERR, "INT: SRAM error on PEP");
> @@ -2678,15 +3016,26 @@ static uint64_t
> fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
>  		/* Todo: print out error message after shared code  updates */
>  	}
> 
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	/* Clear these 3 events if having any */
>  	cause &= FM10K_EICR_SWITCHNOTREADY | FM10K_EICR_MAILBOX |
>  		 FM10K_EICR_SWITCHREADY;
>  	if (cause)
>  		FM10K_WRITE_REG(hw, FM10K_EICR, cause);
> +#else
> +	if (writeback)
> +		FM10K_WRITE_REG(hw, FM10K_EICR, writeback);
> +#endif
> 
>  	/* Re-enable interrupt from device side */
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	FM10K_WRITE_REG(hw, FM10K_ITR(0), FM10K_ITR_AUTOMASK |
>  					FM10K_ITR_MASK_CLEAR);
> +#else
> +	FM10K_WRITE_REG(hw, FM10K_ITR(0),
> + 	    FM10K_SW_ITR_AUTO_MASK |
> +	    FM10K_SW_MAKE_REG_FIELD(ITR_MASK,
> FM10K_SW_ITR_MASK_W_ENABLE));
> +#endif
>  	/* Re-enable interrupt from host side */
>  	rte_intr_ack(dev->intr_handle);
>  }
> @@ -2893,6 +3242,11 @@ static uint64_t
> fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
>  	.reta_query		= fm10k_reta_query,
>  	.rss_hash_update	= fm10k_rss_hash_update,
>  	.rss_hash_conf_get	= fm10k_rss_hash_conf_get,
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	.mirror_rule_set 	= fm10k_mirror_rule_set,
> +	.mirror_rule_reset 	= fm10k_mirror_rule_reset,
> +	.filter_ctrl        	= fm10k_dev_filter_ctrl,
> +#endif
>  };
> 
>  static int ftag_check_handler(__rte_unused const char *key,
> @@ -3071,13 +3425,87 @@ static void __attribute__((cold))
>  	info->sm_down = false;
>  }
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +static int eth_fm10k_dev_init_hook(struct fm10k_hw *hw)
> +{
> +	int i, switch_ready;
> +	struct rte_eth_dev *dev = (struct rte_eth_dev*)hw->rte_dev;
> +
> +	/* Make sure Switch Manager is ready before going forward. */
> +	if (hw->mac.type == fm10k_mac_pf) {
> +		switch_ready = 0;
> +
> +		for (i = 0; i < MAX_QUERY_SWITCH_STATE_TIMES; i++) {
> +			fm10k_mbx_lock(hw);
> +			switch_ready = fm10k_switch_ready;
> +			fm10k_mbx_unlock(hw);
> +			if (switch_ready)
> +				break;
> +			/* Delay some time to acquire async LPORT_MAP info.
> */
> +			rte_delay_us(WAIT_SWITCH_MSG_US);
> +		}
> +
> +		if (switch_ready == 0) {
> +			PMD_INIT_LOG(ERR, "switch is not ready");
> +			return -1;
> +		}
> +	}
> +
> +	/*
> +	 * Below function will trigger operations on mailbox, acquire lock to
> +	 * avoid race condition from interrupt handler. Operations on mailbox
> +	 * FIFO will trigger interrupt to PF/SM, in which interrupt handler
> +	 * will handle and generate an interrupt to our side. Then,  FIFO in
> +	 * mailbox will be touched.
> +	 */
> +	if (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE)	{
> +		PMD_INIT_LOG(ERR, "dglort_map is not ready");
> +		return -1;
> +	}
> +
> +	fm10k_mbx_lock(hw);
> +	/* Enable port first */
> +	hw->mac.ops.update_lport_state(hw, hw->mac.dglort_map,
> +					MAX_LPORT_NUM, 1);
> +	/* Set unicast mode by default. App can change to other mode in other
> +	 * API func.
> +	 */
> +	hw->mac.ops.update_xcast_mode(hw, hw->mac.dglort_map,
> +					FM10K_XCAST_MODE_NONE);
> +	fm10k_mbx_unlock(hw);
> +
> +	/* Make sure default VID is ready before going forward. */
> +	if (hw->mac.type == fm10k_mac_pf) {
> +		for (i = 0; i < MAX_QUERY_SWITCH_STATE_TIMES; i++) {
> +			if (hw->mac.default_vid)
> +				break;
> +			/* Delay some time to acquire async port VLAN info. */
> +			rte_delay_us(WAIT_SWITCH_MSG_US);
> +		}
> +
> +		if (hw->mac.default_vid == 0) {
> +			hw->mac.default_vid = 1;
> +		}
> +	}
> +
> +	/* Add default mac address */
> +	fm10k_MAC_filter_set(dev, hw->mac.addr, true,
> +		MAIN_VSI_POOL_NUMBER);
> +
> +	return 0;
> +}
> +#endif
> +
>  static int
>  eth_fm10k_dev_init(struct rte_eth_dev *dev)
>  {
>  	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
>  	struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
>  	struct rte_intr_handle *intr_handle = &pdev->intr_handle;
> -	int diag, i;
> +	int diag;
> +#ifndef ENABLE_FM10K_MANAGEMENT
> +	int i;
> +#endif
>  	struct fm10k_macvlan_filter_info *macvlan;
> 
>  	PMD_INIT_FUNC_TRACE();
> @@ -3114,7 +3542,11 @@ static void __attribute__((cold))
>  			" Try to blacklist unused devices.");
>  		return -EIO;
>  	}
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	hw->sw_addr = (void *)pdev->mem_resource[4].addr;
> 
> +	TAILQ_INIT(&hw->flow_list);
> +#endif
>  	/* Store fm10k_adapter pointer */
>  	hw->back = dev->data->dev_private;
> 
> @@ -3125,6 +3557,26 @@ static void __attribute__((cold))
>  		return -EIO;
>  	}
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	if (hw->mac.type == fm10k_mac_pf) {
> +		if (hw->hw_addr == NULL || hw->sw_addr == NULL) {
> +			PMD_INIT_LOG(ERR, "Bad mem resource."
> +	                                  " Try to blacklist unused devices.");
> +			return -EIO;
> +		}
> +	} else {
> +		if (hw->hw_addr == NULL) {
> +			PMD_INIT_LOG(ERR, "Bad mem resource."
> +	                                    " Try to blacklist unused devices.");
> +			return -EIO;
> +		}
> +	}
> +
> +	/* Store fm10k_adapter pointer */
> +	hw->back = dev->data->dev_private;
> +	hw->rte_dev = dev;
> +#endif
> +
>  	/* Initialize parameters */
>  	fm10k_params_init(dev);
> 
> @@ -3205,6 +3657,7 @@ static void __attribute__((cold))
>  	hw->mac.ops.update_int_moderator(hw);
> 
>  	/* Make sure Switch Manager is ready before going forward. */
> +#ifndef ENABLE_FM10K_MANAGEMENT
>  	if (hw->mac.type == fm10k_mac_pf) {
>  		int switch_ready = 0;
> 
> @@ -3264,11 +3717,21 @@ static void __attribute__((cold))
>  		MAIN_VSI_POOL_NUMBER);
> 
>  	return 0;
> +#else
> +	if (hw->mac.type == fm10k_mac_pf) {
> +		bool master = FM10K_READ_REG(hw,
> FM10K_CTRL)&FM10K_CTRL_BAR4_ALLOWED;
> +		return fm10k_switch_dpdk_port_start(hw, 1, master,
> eth_fm10k_dev_init_hook);
> +	} else	/* It may not work for VF */
> +		return fm10k_switch_dpdk_port_start(hw, 0, false,
> eth_fm10k_dev_init_hook);
> +#endif
>  }
> 
>  static int
>  eth_fm10k_dev_uninit(struct rte_eth_dev *dev)
>  {
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +#endif
>  	PMD_INIT_FUNC_TRACE();
> 
>  	/* only uninitialize in the primary process */
> @@ -3278,6 +3741,10 @@ static void __attribute__((cold))
>  	/* safe to close dev here */
>  	fm10k_dev_close(dev);
> 
> +#ifdef ENABLE_FM10K_MANAGEMENT
> +	fm10k_switch_dpdk_port_stop(hw);
> +#endif
> +
>  	return 0;
>  }
> 
> diff --git a/drivers/net/fm10k/fm10k_flow.c b/drivers/net/fm10k/fm10k_flow.c
> new file mode 100644
> index 0000000..b367def
> --- /dev/null
> +++ b/drivers/net/fm10k/fm10k_flow.c
> @@ -0,0 +1,847 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +
> +#include <sys/queue.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <stdint.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <stdarg.h>
> +
> +#include <rte_ether.h>
> +#include <rte_ethdev.h>
> +#include <rte_log.h>
> +#include <rte_malloc.h>
> +#include <rte_eth_ctrl.h>
> +#include <rte_tailq.h>
> +#include <rte_flow_driver.h>
> +
> +#include "fm10k.h"
> +#include "base/fm10k_api.h"
> +#include "base/fm10k_type.h"
> +#include "switch/fm10k_switch.h"
> +#include "switch/fm10k_ffu.h"
> +#include "switch/fm10k_config.h"
> +
> +
> +static int fm10k_flow_validate(struct rte_eth_dev *dev,
> +			      const struct rte_flow_attr *attr,
> +			      const struct rte_flow_item pattern[],
> +			      const struct rte_flow_action actions[],
> +			      struct rte_flow_error *error);
> +static struct rte_flow *fm10k_flow_create(struct rte_eth_dev *dev,
> +					 const struct rte_flow_attr *attr,
> +					 const struct rte_flow_item pattern[],
> +					 const struct rte_flow_action actions[],
> +					 struct rte_flow_error *error);
> +static int fm10k_flow_destroy(struct rte_eth_dev *dev,
> +			     struct rte_flow *flow,
> +			     struct rte_flow_error *error);
> +static int fm10k_flow_flush(struct rte_eth_dev *dev,
> +			   struct rte_flow_error *error);
> +static int fm10k_flow_parse_attr(const struct rte_flow_attr *attr,
> +				struct rte_flow_error *error);
> +
> +const struct rte_flow_ops fm10k_flow_ops = {
> +	.validate = fm10k_flow_validate,
> +	.create = fm10k_flow_create,
> +	.destroy = fm10k_flow_destroy,
> +	.flush = fm10k_flow_flush,
> +};
> +
> +union fm10k_filter_t cons_filter;
> +enum rte_filter_type fm10k_cons_filter_type = RTE_ETH_FILTER_NONE;
> +
> +/**
> + * MPLS filter configuration.
> + */
> +enum fm10k_mpls_type {
> +	FM10K_MPLS_TYPE_UNI,
> +	FM10K_MPLS_TYPE_MULTI,
> +};
> +
> +enum fm10k_mpls_action {
> +	FM10K_MPLS_ACTION_DROP,
> +	FM10K_MPLS_ACTION_QUEUE,
> +};
> +
> +struct fm10k_mpls_filter_conf {
> +	enum fm10k_mpls_type mpls_type; /**< mandatory for MPLS */
> +	uint32_t mpls_header;     /**< MPLS header */
> +	uint32_t mpls_header_mask;      /**< MPLS header mask */
> +	enum fm10k_mpls_action mpls_action;
> +	uint16_t queue;
> +	uint8_t ffu_id;
> +	uint8_t ffu_prio;
> +};
> +
> +/**
> + * VLAN filter configuration.
> + */
> +struct fm10k_vlan_filter_conf {
> +	int ffu_id;
> +	uint8_t ffu_prio;
> +	uint8_t is_ingress;
> +	uint8_t port;
> +	uint8_t in_ext_port;
> +	uint8_t out_ext_port;
> +	uint16_t in_vlan;
> +	uint16_t out_vlan;
> +};
> +
> +
> +union fm10k_filter_t {
> +	struct fm10k_mpls_filter_conf mpls_filter;
> +	struct fm10k_vlan_filter_conf vlan_filter;
> +};
> +
> +typedef int (*parse_filter_t)(struct rte_eth_dev *dev,
> +			      const struct rte_flow_attr *attr,
> +			      const struct rte_flow_item pattern[],
> +			      const struct rte_flow_action actions[],
> +			      struct rte_flow_error *error,
> +			      union fm10k_filter_t *filter);
> +
> +struct fm10k_valid_pattern {
> +	enum rte_flow_item_type *items;
> +	parse_filter_t parse_filter;
> +};
> +
> +static enum rte_flow_item_type pattern_mpls_1[] = {
> +	RTE_FLOW_ITEM_TYPE_ETH,
> +	RTE_FLOW_ITEM_TYPE_MPLS,
> +	RTE_FLOW_ITEM_TYPE_END,
> +};
> +
> +static enum rte_flow_item_type pattern_vlan_1[] = {
> +	RTE_FLOW_ITEM_TYPE_VLAN,
> +	RTE_FLOW_ITEM_TYPE_PHY_PORT,
> +	RTE_FLOW_ITEM_TYPE_END,
> +};
> +
> +static enum rte_flow_item_type pattern_vlan_2[] = {
> +	RTE_FLOW_ITEM_TYPE_VLAN,
> +	RTE_FLOW_ITEM_TYPE_PHY_PORT,
> +	RTE_FLOW_ITEM_TYPE_PHY_PORT,
> +	RTE_FLOW_ITEM_TYPE_END,
> +};
> +
> +static int fm10k_flow_parse_mpls_filter(struct rte_eth_dev *dev,
> +				    const struct rte_flow_attr *attr,
> +				    const struct rte_flow_item pattern[],
> +				    const struct rte_flow_action actions[],
> +				    struct rte_flow_error *error,
> +				    union fm10k_filter_t *filter);
> +static int
> +fm10k_flow_parse_vlan_filter(struct rte_eth_dev *dev,
> +			    const struct rte_flow_attr *attr,
> +			    const struct rte_flow_item pattern[],
> +			    const struct rte_flow_action actions[],
> +			    struct rte_flow_error *error,
> +			    union fm10k_filter_t *filter);
> +
> +static struct fm10k_valid_pattern fm10k_supported_patterns[] = {
> +	/* MPLS */
> +	{ pattern_mpls_1, fm10k_flow_parse_mpls_filter },
> +	/* VLAN */
> +	{ pattern_vlan_1, fm10k_flow_parse_vlan_filter },
> +	/* VLAN */
> +	{ pattern_vlan_2, fm10k_flow_parse_vlan_filter },
> +};
> +
> +#define NEXT_ITEM_OF_ACTION(act, actions, index)
> 	\
> +	do {
> 						\
> +		act = actions + index;
> 				\
> +		while (act->type == RTE_FLOW_ACTION_TYPE_VOID) {
> 	\
> +			index++;
> 						\
> +			act = actions + index;
> 				\
> +		}
> 							\
> +	} while (0)
> +
> +/* Find the first VOID or non-VOID item pointer */
> +static const struct rte_flow_item *
> +fm10k_find_first_item(const struct rte_flow_item *item, bool is_void)
> +{
> +	bool is_find;
> +
> +	while (item->type != RTE_FLOW_ITEM_TYPE_END) {
> +		if (is_void)
> +			is_find = item->type == RTE_FLOW_ITEM_TYPE_VOID;
> +		else
> +			is_find = item->type != RTE_FLOW_ITEM_TYPE_VOID;
> +		if (is_find)
> +			break;
> +		item++;
> +	}
> +	return item;
> +}
> +
> +/* Skip all VOID items of the pattern */
> +static void
> +fm10k_pattern_skip_void_item(struct rte_flow_item *items,
> +			    const struct rte_flow_item *pattern)
> +{
> +	uint32_t cpy_count = 0;
> +	const struct rte_flow_item *pb = pattern, *pe = pattern;
> +
> +	for (;;) {
> +		/* Find a non-void item first */
> +		pb = fm10k_find_first_item(pb, false);
> +		if (pb->type == RTE_FLOW_ITEM_TYPE_END) {
> +			pe = pb;
> +			break;
> +		}
> +
> +		/* Find a void item */
> +		pe = fm10k_find_first_item(pb + 1, true);
> +
> +		cpy_count = pe - pb;
> +		rte_memcpy(items, pb, sizeof(struct rte_flow_item) *
> cpy_count);
> +
> +		items += cpy_count;
> +
> +		if (pe->type == RTE_FLOW_ITEM_TYPE_END) {
> +			pb = pe;
> +			break;
> +		}
> +
> +		pb = pe + 1;
> +	}
> +	/* Copy the END item. */
> +	rte_memcpy(items, pe, sizeof(struct rte_flow_item));
> +}
> +
> +/* Check if the pattern matches a supported item type array */
> +static bool
> +fm10k_match_pattern(enum rte_flow_item_type *item_array,
> +		   struct rte_flow_item *pattern)
> +{
> +	struct rte_flow_item *item = pattern;
> +
> +	while ((*item_array == item->type) &&
> +	       (*item_array != RTE_FLOW_ITEM_TYPE_END)) {
> +		item_array++;
> +		item++;
> +	}
> +
> +	return (*item_array == RTE_FLOW_ITEM_TYPE_END &&
> +		item->type == RTE_FLOW_ITEM_TYPE_END);
> +}
> +
> +/* Find if there's parse filter function matched */
> +static parse_filter_t
> +fm10k_find_parse_filter_func(struct rte_flow_item *pattern, uint32_t *idx)
> +{
> +	parse_filter_t parse_filter = NULL;
> +	uint8_t i = *idx;
> +
> +	for (; i < RTE_DIM(fm10k_supported_patterns); i++) {
> +		if (fm10k_match_pattern(fm10k_supported_patterns[i].items,
> +					pattern)) {
> +			parse_filter = fm10k_supported_patterns[i].parse_filter;
> +			break;
> +		}
> +	}
> +
> +	*idx = ++i;
> +
> +	return parse_filter;
> +}
> +
> +/* Parse attributes */
> +static int
> +fm10k_flow_parse_attr(const struct rte_flow_attr *attr,
> +		     struct rte_flow_error *error)
> +{
> +	/* Not supported */
> +	if (attr->group) {
> +		rte_flow_error_set(error, EINVAL,
> +				   RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
> +				   attr, "Not support group.");
> +		return -rte_errno;
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * MPLS
> + */
> +/* 1. Last in item should be NULL as range is not supported.
> + * 2. Supported filter types: MPLS label.
> + * 3. Mask of fields which need to be matched should be
> + *    filled with 1.
> + * 4. Mask of fields which needn't to be matched should be
> + *    filled with 0.
> + */
> +static int
> +fm10k_flow_parse_mpls_pattern(__rte_unused struct rte_eth_dev *dev,
> +			     const struct rte_flow_item *pattern,
> +			     struct rte_flow_error *error,
> +			     struct fm10k_mpls_filter_conf *filter)
> +{
> +	const struct rte_flow_item *item = pattern;
> +	const struct rte_flow_item_mpls *mpls_spec;
> +	const struct rte_flow_item_mpls *mpls_mask;
> +	const struct rte_flow_item_eth *eth_spec;
> +	enum rte_flow_item_type item_type;
> +	const uint8_t label_mask[3] = {0xFF, 0xFF, 0xF0};
> +	uint32_t label_be = 0;
> +	uint32_t be_mask = 0;
> +
> +	for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
> +		if (item->last) {
> +			rte_flow_error_set(error, EINVAL,
> +					   RTE_FLOW_ERROR_TYPE_ITEM,
> +					   item,
> +					   "Not support range");
> +			return -rte_errno;
> +		}
> +		item_type = item->type;
> +		switch (item_type) {
> +		case RTE_FLOW_ITEM_TYPE_ETH:
> +			if (!item->spec || item->mask) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ITEM,
> +						   item,
> +						   "Invalid ETH item");
> +				return -rte_errno;
> +			}
> +			eth_spec =
> +				(const struct rte_flow_item_eth *)item->spec;
> +			printf("%s eth type %#x\n", __func__,
> rte_be_to_cpu_16(eth_spec->type));
> +
> +			if (rte_be_to_cpu_16(eth_spec->type) == 0x8847)
> +				filter->mpls_type = FM10K_MPLS_TYPE_UNI;
> +			else if (rte_be_to_cpu_16(eth_spec->type) == 0x8848)
> +				filter->mpls_type = FM10K_MPLS_TYPE_MULTI;
> +			else {
> +				rte_flow_error_set(error, EINVAL,
> +
> 	   RTE_FLOW_ERROR_TYPE_ITEM,
> +
> 	   item,
> +
> 	   "Invalid ETH item");
> +				return -rte_errno;
> +			}
> +			break;
> +		case RTE_FLOW_ITEM_TYPE_MPLS:
> +			mpls_spec =
> +				(const struct rte_flow_item_mpls *)item->spec;
> +			mpls_mask =
> +				(const struct rte_flow_item_mpls *)item->mask;
> +
> +			if (!mpls_spec || !mpls_mask) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ITEM,
> +						   item,
> +						   "Invalid MPLS item");
> +				return -rte_errno;
> +			}
> +
> +			if (memcmp(mpls_mask->label_tc_s, label_mask, 3)) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ITEM,
> +						   item,
> +						   "Invalid MPLS label mask");
> +				return -rte_errno;
> +			}
> +			rte_memcpy(((uint8_t *)&label_be + 1),
> +				   mpls_spec->label_tc_s, 3);
> +			rte_memcpy(((uint8_t *)&be_mask + 1),
> +							   mpls_mask-
> >label_tc_s, 3);
> +			filter->mpls_header = rte_be_to_cpu_32(label_be) >> 4;
> +			filter->mpls_header_mask =
> rte_be_to_cpu_32(be_mask) >> 4;
> +
> +			fm10k_cons_filter_type = RTE_ETH_FILTER_TUNNEL;
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/* MPLS action only supports QUEUE or DROP. */
> +static int
> +fm10k_flow_parse_mpls_action(const struct rte_flow_action *actions,
> +				 struct rte_flow_error *error,
> +				 struct fm10k_mpls_filter_conf *filter)
> +{
> +	const struct rte_flow_action *act;
> +	const struct rte_flow_action_queue *act_q;
> +	uint32_t index = 0;
> +
> +	/* Check if the first non-void action is QUEUE or DROP. */
> +	NEXT_ITEM_OF_ACTION(act, actions, index);
> +	if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
> +	    act->type != RTE_FLOW_ACTION_TYPE_DROP) {
> +		rte_flow_error_set(error, EINVAL,
> RTE_FLOW_ERROR_TYPE_ACTION,
> +				   act, "Not supported action.");
> +		return -rte_errno;
> +	}
> +
> +	if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
> +		act_q = (const struct rte_flow_action_queue *)act->conf;
> +		filter->mpls_action = FM10K_MPLS_ACTION_QUEUE;
> +		filter->queue = act_q->index;
> +	} else {
> +		filter->mpls_action = FM10K_MPLS_ACTION_DROP;
> +	}
> +
> +	/* Check if the next non-void item is END */
> +	index++;
> +	NEXT_ITEM_OF_ACTION(act, actions, index);
> +	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
> +		rte_flow_error_set(error, EINVAL,
> RTE_FLOW_ERROR_TYPE_ACTION,
> +				   act, "Not supported action.");
> +		return -rte_errno;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +fm10k_flow_parse_mpls_filter(struct rte_eth_dev *dev,
> +			    const struct rte_flow_attr *attr,
> +			    const struct rte_flow_item pattern[],
> +			    const struct rte_flow_action actions[],
> +			    struct rte_flow_error *error,
> +			    union fm10k_filter_t *filter)
> +{
> +	struct fm10k_mpls_filter_conf *mpls_filter =
> +		&filter->mpls_filter;
> +	int ret;
> +
> +	ret = fm10k_flow_parse_mpls_pattern(dev, pattern,
> +					   error, mpls_filter);
> +	if (ret)
> +		return ret;
> +
> +	ret = fm10k_flow_parse_mpls_action(actions, error, mpls_filter);
> +	if (ret)
> +		return ret;
> +
> +	ret = fm10k_flow_parse_attr(attr, error);
> +	return ret;
> +}
> +
> +
> +/*
> + * VLAN
> + */
> +static int
> +fm10k_flow_parse_vlan_pattern(__rte_unused struct rte_eth_dev *dev,
> +			     const struct rte_flow_item *pattern,
> +			     struct rte_flow_error *error,
> +			     struct fm10k_vlan_filter_conf *filter)
> +{
> +	const struct rte_flow_item *item = pattern;
> +	const struct rte_flow_item_vlan *vlan_spec;
> +	const struct rte_flow_item_phy_port *pp_spec;
> +	enum rte_flow_item_type item_type;
> +
> +	PMD_INIT_LOG(DEBUG, "Parse vlan pattern ffu id %d", filter->ffu_id);
> +
> +	for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
> +		if (item->last) {
> +			rte_flow_error_set(error, EINVAL,
> +					   RTE_FLOW_ERROR_TYPE_ITEM,
> +					   item,
> +					   "Not support range");
> +			return -rte_errno;
> +		}
> +		item_type = item->type;
> +		switch (item_type) {
> +		case RTE_FLOW_ITEM_TYPE_VLAN:
> +			vlan_spec =
> +				(const struct rte_flow_item_vlan *)item->spec;
> +
> +			if (!vlan_spec) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ITEM,
> +						   item,
> +						   "Invalid VLAN item");
> +				return -rte_errno;
> +			}
> +			break;
> +
> +		case RTE_FLOW_ITEM_TYPE_PHY_PORT:
> +			pp_spec =
> +				(const struct rte_flow_item_phy_port *)item-
> >spec;
> +			if (!pp_spec) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ITEM,
> +						   item,
> +						   "Invalid PHY PORT item");
> +				return -rte_errno;
> +			}
> +			break;
> +
> +		default:
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +
> +static int
> +fm10k_flow_parse_vlan_action(struct rte_eth_dev *dev,
> +				 const struct rte_flow_action *actions,
> +				 struct rte_flow_error *error,
> +				 struct fm10k_vlan_filter_conf *filter)
> +{
> +	const struct rte_flow_action *act;
> +	uint32_t index = 0;
> +
> +	PMD_INIT_LOG(DEBUG, "Parse vlan action name %s ffu id %d", dev-
> >device->name, filter->ffu_id);
> +
> +	/* Check if the first non-void action is QUEUE or DROP. */
> +	NEXT_ITEM_OF_ACTION(act, actions, index);
> +	if (act->type != RTE_FLOW_ACTION_TYPE_MARK) {
> +		rte_flow_error_set(error, EINVAL,
> RTE_FLOW_ERROR_TYPE_ACTION,
> +				   act, "Not supported action.");
> +		return -rte_errno;
> +	}
> +
> +	index++;
> +	NEXT_ITEM_OF_ACTION(act, actions, index);
> +	if (act->type != RTE_FLOW_ACTION_TYPE_MARK && act->type !=
> RTE_FLOW_ACTION_TYPE_END) {
> +		rte_flow_error_set(error, EINVAL,
> RTE_FLOW_ERROR_TYPE_ACTION,
> +				   act, "Not supported action.");
> +		return -rte_errno;
> +	}
> +	if (act->type == RTE_FLOW_ACTION_TYPE_END)
> +		return 0;
> +
> +	index++;
> +	/* Check if the next non-void item is END */
> +	NEXT_ITEM_OF_ACTION(act, actions, index);
> +	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
> +		rte_flow_error_set(error, EINVAL,
> RTE_FLOW_ERROR_TYPE_ACTION,
> +				   act, "Not supported action.");
> +		return -rte_errno;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +fm10k_flow_parse_vlan_filter(struct rte_eth_dev *dev,
> +			    const struct rte_flow_attr *attr,
> +			    const struct rte_flow_item pattern[],
> +			    const struct rte_flow_action actions[],
> +			    struct rte_flow_error *error,
> +			    union fm10k_filter_t *filter)
> +{
> +	int ret;
> +	struct fm10k_vlan_filter_conf *vlan_filter =
> +		&filter->vlan_filter;
> +
> +	ret = fm10k_flow_parse_vlan_pattern(dev, pattern,
> +					   error, vlan_filter);
> +	if (ret)
> +		return ret;
> +
> +	ret = fm10k_flow_parse_vlan_action(dev, actions, error, vlan_filter);
> +	if (ret)
> +		return ret;
> +
> +	if(attr->ingress)
> +		vlan_filter->is_ingress = 1;
> +	else if(attr->egress)
> +		vlan_filter->is_ingress = 0;
> +	vlan_filter->ffu_prio = attr->priority;
> +
> +	ret = fm10k_flow_parse_attr(attr, error);
> +	return ret;
> +}
> +
> +/*
> + *
> + */
> +static int
> +fm10k_flow_validate(struct rte_eth_dev *dev,
> +		   const struct rte_flow_attr *attr,
> +		   const struct rte_flow_item pattern[],
> +		   const struct rte_flow_action actions[],
> +		   struct rte_flow_error *error)
> +{
> +	struct rte_flow_item *items; /* internal pattern w/o VOID items */
> +	parse_filter_t parse_filter;
> +	uint32_t item_num = 0; /* non-void item number of pattern*/
> +	uint32_t i = 0;
> +	bool flag = false;
> +	int ret = -1;
> +
> +	if (!pattern) {
> +		rte_flow_error_set(error, EINVAL,
> RTE_FLOW_ERROR_TYPE_ITEM_NUM,
> +				   NULL, "NULL pattern.");
> +		return -rte_errno;
> +	}
> +
> +	if (!actions) {
> +		rte_flow_error_set(error, EINVAL,
> +				   RTE_FLOW_ERROR_TYPE_ACTION_NUM,
> +				   NULL, "NULL action.");
> +		return -rte_errno;
> +	}
> +
> +	if (!attr) {
> +		rte_flow_error_set(error, EINVAL,
> +				   RTE_FLOW_ERROR_TYPE_ATTR,
> +				   NULL, "NULL attribute.");
> +		return -rte_errno;
> +	}
> +
> +	/* Get the non-void item number of pattern */
> +	while ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) {
> +		if ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_VOID)
> +			item_num++;
> +		i++;
> +	}
> +	item_num++;
> +
> +	items = rte_zmalloc("fm10k_pattern",
> +			    item_num * sizeof(struct rte_flow_item), 0);
> +	if (!items) {
> +		rte_flow_error_set(error, ENOMEM,
> RTE_FLOW_ERROR_TYPE_ITEM_NUM,
> +				   NULL, "No memory for PMD internal items.");
> +		return -ENOMEM;
> +	}
> +
> +	fm10k_pattern_skip_void_item(items, pattern);
> +
> +	i = 0;
> +	do {
> +		parse_filter = fm10k_find_parse_filter_func(items, &i);
> +		if (!parse_filter && !flag) {
> +			rte_flow_error_set(error, EINVAL,
> +					   RTE_FLOW_ERROR_TYPE_ITEM,
> +					   pattern, "Unsupported pattern");
> +			rte_free(items);
> +			return -rte_errno;
> +		}
> +		if (parse_filter)
> +			ret = parse_filter(dev, attr, items, actions,
> +					   error, &cons_filter);
> +		flag = true;
> +	} while ((ret < 0) && (i < RTE_DIM(fm10k_supported_patterns)));
> +
> +	rte_free(items);
> +
> +	return ret;
> +}
> +
> +static struct fm10k_cfg_flow *
> +fm10k_flow_cfg_transfer(struct rte_eth_dev *dev,
> +		 const struct rte_flow_attr *attr,
> +		 const struct rte_flow_item pattern[],
> +		 const struct rte_flow_action actions[],
> +		 struct rte_flow_error *error)
> +{
> +	int i;
> +	u8 port_id;
> +	int set_port_num = 0, set_vlan_num = 0;
> +	u16 fw_port_id = 0, bp_port_id = 0;
> +	u16 filter_vlan_id = 0, fw_vlan_id = 0, bp_vlan_id = 0;
> +	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +	struct fm10k_cfg_flow *cf;
> +
> +	cf = rte_zmalloc("fm10k_rule", sizeof(struct fm10k_cfg_flow), 0);
> +	if (!cf) {
> +		rte_flow_error_set(error, ENOMEM,
> +				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +				   "Failed to allocate memory");
> +		return NULL;
> +	}
> +	memset(cf, 0, sizeof(struct fm10k_cfg_flow));
> +
> +	port_id = fm10k_switch_dpdk_port_no_get(hw);
> +	for (i=0; i<4; i++)	{
> +		if (pattern[i].type == RTE_FLOW_ITEM_TYPE_VLAN) {
> +			filter_vlan_id = rte_be_to_cpu_16(((const struct
> rte_flow_item_vlan*)pattern[i].spec)->tci);
> +		}
> +		else if (pattern[i].type == RTE_FLOW_ITEM_TYPE_PHY_PORT) {
> +			if(set_port_num)
> +				bp_port_id = ((const struct
> rte_flow_item_phy_port*)pattern[i].spec)->index;
> +			else
> +				fw_port_id = ((const struct
> rte_flow_item_phy_port*)pattern[i].spec)->index;
> +			set_port_num++;
> +		}
> +		else if (pattern[i].type == RTE_FLOW_ITEM_TYPE_END)
> +			break;
> +	}
> +
> +	for (i=0; i<3; i++)	{
> +		if (actions[i].type == RTE_FLOW_ACTION_TYPE_MARK) {
> +			if (set_vlan_num)
> +				bp_vlan_id = ((const struct
> rte_flow_action_mark*)actions[i].conf)->id;
> +			else
> +				fw_vlan_id = ((const struct
> rte_flow_action_mark*)actions[i].conf)->id;
> +			set_vlan_num++;
> +		}
> +		else if (actions[i].type == RTE_FLOW_ACTION_TYPE_END)
> +			break;
> +	}
> +
> +	if (attr->ingress && !attr->egress)	{
> +		/* this port is DPDK port and it is destination port */
> +		cf->src_port.port_type = FM10K_CONFIG_FLOW_EXT_PORT;
> +		cf->src_port.port_no = fw_port_id;
> +		cf->src_port.vlan_id = filter_vlan_id;
> +		cf->fw_port[0].port_type =
> FM10K_CONFIG_FLOW_DPDK_PORT;
> +		cf->fw_port[0].port_no = port_id;
> +		cf->fw_port[0].vlan_id = fw_vlan_id;
> +	} else if (!attr->ingress && attr->egress) {
> +		/* this port is DPDK port and it is source port */
> +		cf->src_port.port_type = FM10K_CONFIG_FLOW_DPDK_PORT;
> +		cf->src_port.port_no = port_id;
> +		cf->src_port.vlan_id = filter_vlan_id;
> +		cf->fw_port[0].port_type = FM10K_CONFIG_FLOW_EXT_PORT;
> +		cf->fw_port[0].port_no = fw_port_id;
> +		cf->fw_port[0].vlan_id = fw_vlan_id;
> +	}
> +	else if (!attr->ingress && !attr->egress) {
> +		/* two ports are external port */
> +		cf->src_port.port_type = FM10K_CONFIG_FLOW_EXT_PORT;
> +		cf->src_port.port_no = port_id;
> +		cf->src_port.vlan_id = filter_vlan_id;
> +		cf->fw_port[0].port_type = FM10K_CONFIG_FLOW_EXT_PORT;
> +		cf->fw_port[0].port_no = fw_port_id;
> +		cf->fw_port[0].vlan_id = fw_vlan_id;
> +	} else {
> +		/* two ports are DPDK port */
> +		cf->src_port.port_type = FM10K_CONFIG_FLOW_DPDK_PORT;
> +		cf->src_port.port_no = port_id;
> +		cf->src_port.vlan_id = filter_vlan_id;
> +		cf->fw_port[0].port_type =
> FM10K_CONFIG_FLOW_DPDK_PORT;
> +		cf->fw_port[0].port_no = fw_port_id;
> +		cf->fw_port[0].vlan_id = fw_vlan_id;
> +	}
> +
> +	if (set_port_num == 2 && set_vlan_num == 2)	{
> +		cf->fw_port[1].port_type = FM10K_CONFIG_FLOW_EXT_PORT;
> +		cf->fw_port[1].port_no = bp_port_id;
> +		cf->fw_port[1].vlan_id = bp_vlan_id;
> +	}
> +
> +	return cf;
> +}
> +
> +
> +static struct rte_flow *
> +fm10k_flow_create(struct rte_eth_dev *dev,
> +		 const struct rte_flow_attr *attr,
> +		 const struct rte_flow_item pattern[],
> +		 const struct rte_flow_action actions[],
> +		 struct rte_flow_error *error)
> +{
> +	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +	struct rte_flow *flow;
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +	struct fm10k_cfg_flow *cf;
> +	int ret;
> +
> +	flow = rte_zmalloc("fm10k_flow", sizeof(struct rte_flow), 0);
> +	if (!flow) {
> +		rte_flow_error_set(error, ENOMEM,
> +				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +				   "Failed to allocate memory");
> +		return flow;
> +	}
> +
> +	ret = fm10k_flow_validate(dev, attr, pattern, actions, error);
> +	if (ret < 0)
> +		return NULL;
> +
> +	cf = fm10k_flow_cfg_transfer(dev, attr, pattern, actions, error);
> +	if (!cf)
> +		goto free_flow;
> +
> +	flow->rule = cf;
> +	fm10k_ffu_flow_enable(sw, cf);
> +	fm10k_config_flow_list_add_tail(fm10k_config_flowset_current_get(),
> cf);
> +
> +	TAILQ_INSERT_TAIL(&hw->flow_list, flow, node);
> +	return flow;
> +
> +free_flow:
> +	rte_flow_error_set(error, -ret,
> +			   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +			   "Failed to create flow.");
> +	rte_free(flow);
> +	return NULL;
> +}
> +
> +static int
> +fm10k_flow_destroy(struct rte_eth_dev *dev,
> +		  struct rte_flow *flow,
> +		  struct rte_flow_error *error)
> +{
> +	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +	int ret = 0;
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	if (flow->rule)	{
> +		fm10k_config_flow_list_delete((struct fm10k_cfg_flow*)flow-
> >rule);
> +		fm10k_ffu_flow_disable(sw, (struct fm10k_cfg_flow*)flow-
> >rule);
> +	}
> +
> +	if (!ret) {
> +		TAILQ_REMOVE(&hw->flow_list, flow, node);
> +		rte_free(flow->rule);
> +		rte_free(flow);
> +	} else
> +		rte_flow_error_set(error, -ret,
> +				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +				   "Failed to destroy flow.");
> +
> +	return ret;
> +}
> +
> +
> +static int
> +fm10k_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
> +{
> +	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> +	struct rte_flow *flow;
> +	void *temp;
> +	int ret = 0;
> +	struct fm10k_cfg_flow *cf;
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	/* Delete flows in flow list. */
> +	TAILQ_FOREACH_SAFE(flow, &hw->flow_list, node, temp) {
> +		cf = flow->rule;
> +		if (cf) {
> +			fm10k_config_flow_list_delete(cf);
> +			fm10k_ffu_flow_disable(sw, cf);
> +		} else {
> +			rte_flow_error_set(error, -ret,
> +					   RTE_FLOW_ERROR_TYPE_HANDLE,
> NULL,
> +					   "No such rule in flow.");
> +		}
> +		TAILQ_REMOVE(&hw->flow_list, flow, node);
> +		rte_free(flow);
> +	}
> +
> +	return ret;
> +}
> diff --git a/drivers/net/fm10k/switch/fm10k_config.c
> b/drivers/net/fm10k/switch/fm10k_config.c
> new file mode 100644
> index 0000000..5cfda59
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_config.c
> @@ -0,0 +1,693 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +
> +#include <unistd.h>
> +
> +#include "../base/fm10k_type.h"
> +#include "../base/fm10k_osdep.h"
> +
> +#include "../fm10k.h"
> +#include "../fm10k_logs.h"
> +#include "fm10k_debug.h"
> +#include "fm10k_regs.h"
> +#include "fm10k_switch.h"
> +#include "fm10k_config.h"
> +
> +#define FM10K_CONFIG_WORD_MAX			10
> +#define FM10K_CONFIG_WORD_LEN			20
> +#define FM10K_CONFIG_STR_MAX			100
> +
> +struct fm10k_cfg_key_item {
> +	const char* key_str[FM10K_CONFIG_WORD_MAX];
> +	uint8_t type;
> +};
> +
> +static const char *fm10k_config_dpdk_conf_file = "/etc/dpdk_fm10k.conf";
> +static struct fm10k_dpdk_cfg fm10k_config_dpdk_cfg;
> +
> +static struct fm10k_cfg_key_item fm10k_config_key_items[] = {
> +		/* debug configuration */
> +		{ {"debug","print","enable"}, FM10K_CONFIG_DEBUG_ENABLE},
> +		{ {"debug","print","config"}, FM10K_CONFIG_DEBUG_CONFIG},
> +		{ {"debug","print","ffu","init"},
> FM10K_CONFIG_DEBUG_FFU_INIT},
> +		{ {"debug","print","ffu","register"},
> FM10K_CONFIG_DEBUG_FFU_REG},
> +		{ {"debug","print","ffu","rule"},
> FM10K_CONFIG_DEBUG_FFU_RULE},
> +		{ {"debug","print","stats","port"},
> FM10K_CONFIG_DEBUG_STATS_PORT},
> +		{ {"debug","print","stats","queue"},
> FM10K_CONFIG_DEBUG_STATS_QUEUE},
> +		{ {"debug","print","stats","rule"},
> FM10K_CONFIG_DEBUG_STATS_FFU},
> +		{ {"debug","print","stats", "detail"},
> FM10K_CONFIG_DEBUG_STATS_MORE},
> +		{ {"debug","print","stats", "interval"},
> FM10K_CONFIG_DEBUG_STATS_INTERVAL},
> +		/* general configuration */
> +		{ {"dpdk","bind","pf","number"},
> FM10K_CONFIG_BIND_PF_NUMBER},
> +		{ {"extern","port","speed"}, FM10K_CONFIG_EXT_PORT_SPEED},
> +		/* internal redirect configuration */
> +		{ {"dpdk","port","*","map","pf"},
> FM10K_CONFIG_DPDK_PORT_MAP_PF},
> +		{ {"extern","port","*","map","pf"},
> FM10K_CONFIG_EXT_PORT_MAP_PF},
> +		/* external redirect configuration */
> +		{ {"flowset","start"}, FM10K_CONFIG_FLOWSET_START},
> +		{ {"flowset","stop"}, FM10K_CONFIG_FLOWSET_STOP},
> +		{ {"flowset","enable"}, FM10K_CONFIG_FLOWSET_ENABLE},
> +		{ {"flow","*","condition","source","extern","port"},
> FM10K_CONFIG_FLOW_COND_SRC_EXT_PORT},
> +		{ {"flow","*","condition","source","dpdk","port"},
> FM10K_CONFIG_FLOW_COND_SRC_DPDK_PORT},
> +		{ {"flow","*","condition","vlan"},
> FM10K_CONFIG_FLOW_COND_VLAN},
> +		{ {"flow","*","action","forward","extern","port"},
> FM10K_CONFIG_FLOW_ACT_FW_EXT_PORT},
> +		{ {"flow","*","action","forward","dpdk","port"},
> FM10K_CONFIG_FLOW_ACT_FW_DPDK_PORT},
> +		{ {"flow","*","action","forward","vlan"},
> FM10K_CONFIG_FLOW_ACT_FW_VALN},
> +};
> +
> +static char default_flowset[10]="default";
> +
> +static struct fm10k_cfg_config_item fm10k_silc_nic_2ext_2pep[] = {
> +		{FM10K_CONFIG_BIND_PF_NUMBER,
> FM10K_CONFIG_VALUE_INT, 0,
> +				"# Tell how many PF ports are bound in DPDK.
> Driver will check the number when initializes.", .val.int64=2},
> +
> +		{FM10K_CONFIG_EXT_PORT_SPEED,
> FM10K_CONFIG_VALUE_INT, 0,
> +				"# Set external port speed, 40 means 40G, 100
> means 100G.", .val.int64=100},
> +
> +		{FM10K_CONFIG_DPDK_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 0,
> +				"# Map 1 or 2 PF ports to one DPDK port. \n"
> +				"# If mapped PF number is 2, traffic will be load
> balance between the 2 PF. \n"
> +				"# And the DPDK port queue number will be
> configured more than 2(each PF need at least 1 DPDK port
> queue).", .val.int64=0},
> +		{FM10K_CONFIG_DPDK_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 1, "", .val.int64=1},
> +
> +		{FM10K_CONFIG_EXT_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 1,
> +				"# Map 1 or 2 PF to one external port. If
> mapped PF number is 2, \n"
> +				"# traffic will be load balance between the 2 PF.
> ", .val.int64=0},
> +		{FM10K_CONFIG_EXT_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 2, "", .val.int64=1},
> +
> +		{FM10K_CONFIG_FLOWSET_START,
> FM10K_CONFIG_VALUE_STR, 0, "# Define flow rule", .val.str=default_flowset},
> +		{FM10K_CONFIG_FLOWSET_STOP,
> FM10K_CONFIG_VALUE_STR, 0, "", .val.str=default_flowset},
> +		{FM10K_CONFIG_FLOWSET_ENABLE,
> FM10K_CONFIG_VALUE_STR, 0, "", .val.str=default_flowset},
> +
> +		{FM10K_CONFIG_TYPE_NULL, 0, 0, "", .val.int64=0},
> +};
> +
> +static struct fm10k_cfg_config_item fm10k_silc_nic_2ext_4pep[] = {
> +		{FM10K_CONFIG_BIND_PF_NUMBER,
> FM10K_CONFIG_VALUE_INT, 0,
> +				"# Tell how many PF ports are bound in DPDK.
> Driver will check the  number when initializes.", .val.int64=4},
> +
> +		{FM10K_CONFIG_EXT_PORT_SPEED,
> FM10K_CONFIG_VALUE_INT, 0,
> +				"# Set external port speed, 40 means 40G, 100
> means 100G.", .val.int64=100},
> +
> +		{FM10K_CONFIG_DPDK_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 0,
> +				"# Map 1 or 2 PF ports to one DPDK port. \n"
> +				"# If mapped PF number is 2, traffic will be load
> balance between the 2 PFs. \n"
> +				"# And the DPDK port queue number will be
> configured more than 2(each PF need at least 1 DPDK port
> queue).", .val.int64=0},
> +		{FM10K_CONFIG_DPDK_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 0, "", .val.int64=2},
> +		{FM10K_CONFIG_DPDK_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 1, "", .val.int64=1},
> +		{FM10K_CONFIG_DPDK_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 1, "", .val.int64=3},
> +
> +		{FM10K_CONFIG_EXT_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 1,
> +				"# Map 1 or 2 PF to one external port. If
> mapped PF number is 2, \n"
> +				"# traffic will be load balance between the 2
> PF.", .val.int64=0},
> +		{FM10K_CONFIG_EXT_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 1, "", .val.int64=2},
> +		{FM10K_CONFIG_EXT_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 2, "", .val.int64=1},
> +		{FM10K_CONFIG_EXT_PORT_MAP_PF,
> FM10K_CONFIG_VALUE_INT, 2, "", .val.int64=3},
> +
> +		{FM10K_CONFIG_FLOWSET_START,
> FM10K_CONFIG_VALUE_STR, 0, "# Define flow rule", .val.str=default_flowset},
> +		{FM10K_CONFIG_FLOWSET_STOP,
> FM10K_CONFIG_VALUE_STR, 0, "", .val.str=default_flowset},
> +		{FM10K_CONFIG_FLOWSET_ENABLE,
> FM10K_CONFIG_VALUE_STR, 0, "", .val.str=default_flowset},
> +
> +		{FM10K_CONFIG_TYPE_NULL, 0, 0, "", .val.int64=0},
> +};
> +
> +
> +static int
> +fm10k_config_conf_line_parser(char* buff, struct fm10k_cfg_config_item*
> item)
> +{
> +	char *p;
> +	char *endptr;
> +	const char *cfg_delims = { " " };
> +	const char *key_delims = { "." };
> +	struct fm10k_cfg_key_item *key;
> +	char cfgs[3][FM10K_CONFIG_STR_MAX];
> +	char
> cmp_keys[FM10K_CONFIG_WORD_MAX][FM10K_CONFIG_WORD_LEN];
> +	long int key_param = 0;
> +	uint16_t i, j;
> +	uint8_t val_type = FM10K_CONFIG_VALUE_NULL;
> +
> +	for (i = 0; i < 3; i++)	{
> +		if (i == 0)
> +			p = strtok(buff, cfg_delims);
> +		else
> +			p = strtok(NULL, cfg_delims);
> +		if (p == NULL)
> +			return -1;
> +		strncpy(cfgs[i], p, FM10K_CONFIG_STR_MAX);
> +	}
> +
> +	p = strtok(NULL, cfg_delims);
> +	if (p)
> +		return -1;
> +
> +	memset(cmp_keys, 0, sizeof(cmp_keys));
> +	for (i = 0; i < FM10K_CONFIG_WORD_MAX; i++)	{
> +		if (i == 0)
> +			p = strtok(cfgs[0], key_delims);
> +		else
> +			p = strtok(NULL, key_delims);
> +		if (p == NULL)
> +			break;
> +		strncpy(cmp_keys[i], p, FM10K_CONFIG_WORD_LEN);
> +	}
> +
> +	if (strcmp(cfgs[1], "int") == 0)
> +		val_type = FM10K_CONFIG_VALUE_INT;
> +	else if (strcmp(cfgs[1], "string") == 0)
> +		val_type = FM10K_CONFIG_VALUE_STR;
> +	else
> +		return -1;
> +
> +	for (i = 0; i < FM10K_SW_NITEMS(fm10k_config_key_items); i++) {
> +		key = &fm10k_config_key_items[i];
> +		for (j = 0; j < FM10K_CONFIG_WORD_MAX; j++)	{
> +			if (key->key_str[j] &&
> +					strlen(cmp_keys[j]) > 0) {
> +				if (strcmp(key->key_str[j], "*") == 0) {
> +					key_param = strtol(cmp_keys[j],
> &endptr, 10);
> +					if ((key_param == 0 && endptr ==
> cmp_keys[j]) ||
> +							(endptr != cmp_keys[j]
> && strlen(endptr) != 0))
> +						break;
> +				}
> +				else if (strcmp(key->key_str[j], cmp_keys[j]) !=
> 0)
> +					break;
> +			}
> +			else if (key->key_str[j] == 0 &&
> +					strlen(cmp_keys[j]) == 0) {
> +				if (val_type == FM10K_CONFIG_VALUE_STR) {
> +					item->val.str = malloc(strlen(cfgs[2]) +
> 1);
> +					if (item->val.str == NULL)
> +						return -1;
> +					strcpy(item->val.str, cfgs[2]);
> +				}
> +				else
> +					item->val.int64 = strtol(cfgs[2], NULL,
> 10);
> +				item->type = key->type;
> +				item->key_param = key_param;
> +				item->val_type = val_type;
> +				return 0;
> +			}
> +		}
> +	}
> +	return -1;
> +}
> +
> +static bool
> +fm10k_config_blank_line_check(char *line)
> +{
> +	uint16_t i;
> +
> +	for (i = 0; i < strlen(line); i++) {
> +		if (line[i] == ' ' ||
> +				line[i] == '\n' ||
> +				line[i] == '\t' || line[i] == 0x0d) /* 0d: CR */
> +			continue;
> +		else
> +			return false;
> +	}
> +	return true;
> +}
> +
> +static int
> +fm10k_config_conf_file_load(void)
> +{
> +	int i = 0;
> +	FILE *fp;
> +	char buff[255];
> +	struct fm10k_cfg_config_item* item;
> +
> +	fp = fopen(fm10k_config_dpdk_conf_file, "r");
> +	if (fp == NULL)
> +		return -1;
> +
> +	fm10k_config_dpdk_cfg.config_list =
> +			malloc(sizeof(struct fm10k_cfg_config_item) *
> FM10K_SW_CONFIG_MAX);
> +	if (fm10k_config_dpdk_cfg.config_list == NULL)
> +		return -1;
> +	memset(fm10k_config_dpdk_cfg.config_list, 0,
> +			sizeof(struct fm10k_cfg_config_item) *
> FM10K_SW_CONFIG_MAX);
> +
> +	while (fgets(buff, sizeof(buff), fp)) {
> +		if (buff[0] == '#' || buff[0] == 0)
> +			continue;
> +
> +		if (fm10k_config_blank_line_check(buff))
> +			continue;
> +
> +		item = &fm10k_config_dpdk_cfg.config_list[i++];
> +		if (fm10k_config_conf_line_parser(buff, item) < 0) {
> +			FM10K_SW_ERR("Unknow configuration: %s", buff);
> +			return -1;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +struct fm10k_hw*
> +fm10k_config_hw_get(int port_no)
> +{
> +	int hw_port;
> +
> +	hw_port =
> fm10k_config_dpdk_cfg.dpdk_port_map[port_no].map_no[0];
> +	return fm10k_config_dpdk_cfg.pf_hw[hw_port];
> +}
> +
> +struct fm10k_cfg_flowset *
> +fm10k_config_flowset_current_get(void)
> +{
> +	return fm10k_config_dpdk_cfg.current;
> +}
> +
> +void
> +fm10k_config_flowset_current_set(struct fm10k_cfg_flowset *new)
> +{
> +	fm10k_config_dpdk_cfg.current = new;
> +}
> +
> +bool
> +fm10k_config_flow_list_end(struct fm10k_cfg_flow *list, struct
> fm10k_cfg_flow *flow)
> +{
> +	return (list == flow);
> +}
> +
> +static void
> +fm10k_config_flow_list_init(struct fm10k_cfg_flow *list)
> +{
> +	list->next = list;
> +	list->prev = list;
> +}
> +
> +static void
> +fm10k_config_flow_list_add(struct fm10k_cfg_flow *new, struct
> fm10k_cfg_flow *list)
> +{
> +	struct fm10k_cfg_flow *next = list->next;
> +	next->prev = new;
> +	new->next = next;
> +	new->prev = list;
> +	list->next = new;
> +}
> +
> +void
> +fm10k_config_flow_list_add_tail(struct fm10k_cfg_flowset* flowset,
> +		struct fm10k_cfg_flow *flow)
> +{
> +	fm10k_config_flow_list_add(flow, flowset->flow_head.prev);
> +}
> +
> +void
> +fm10k_config_flow_list_delete(struct fm10k_cfg_flow * flow)
> +{
> +	flow->prev->next = flow->next;
> +	flow->next->prev = flow->prev;
> +	flow->prev = NULL;
> +	flow->next = NULL;
> +}
> +
> +struct fm10k_cfg_flowset *
> +fm10k_config_flowset_get(const char* name)
> +{
> +	struct fm10k_cfg_flowset *flowset;
> +
> +	flowset = fm10k_config_dpdk_cfg.flowset_head.next;
> +	while (flowset)	{
> +		if (strcmp(flowset->name, name) == 0)
> +			break;
> +		flowset = flowset->next;
> +	}
> +
> +	if (flowset == NULL) {
> +		flowset = malloc(sizeof(struct fm10k_cfg_flowset));
> +		if (flowset == NULL)
> +			return NULL;
> +		strcpy(flowset->name, name);
> +		fm10k_config_flow_list_init(&flowset->flow_head);
> +		flowset->next = fm10k_config_dpdk_cfg.flowset_head.next;
> +		fm10k_config_dpdk_cfg.flowset_head.next = flowset;
> +	}
> +	return flowset;
> +}
> +
> +
> +static int
> +fm10k_cfg_flow_item_set(struct fm10k_cfg_flowset* flowset,
> +		uint8_t flow_no, uint8_t type, int64_t val)
> +{
> +	struct fm10k_cfg_flow *tmp;
> +	struct fm10k_cfg_flow *flow = NULL;
> +
> +	if (flowset == NULL)
> +		return -1;
> +
> +	tmp = flowset->flow_head.next;
> +	while (!fm10k_config_flow_list_end(&flowset->flow_head, tmp)) {
> +		if (tmp->flow_no == flow_no) {
> +			flow = tmp;
> +			break;
> +		}
> +		tmp = tmp->next;
> +	}
> +	if (flow == NULL) {
> +		flow = malloc(sizeof(struct fm10k_cfg_flow));
> +		memset(flow, 0, sizeof(struct fm10k_cfg_flow));
> +		flow->flow_no = flow_no;
> +		fm10k_config_flow_list_add_tail(flowset, flow);
> +	}
> +	if (flow == NULL)
> +		return -1;
> +
> +	switch (type) {
> +	case FM10K_CONFIG_FLOW_COND_SRC_EXT_PORT:
> +		flow->src_port.port_type = FM10K_CONFIG_FLOW_EXT_PORT;
> +		flow->src_port.port_no = val;
> +		break;
> +	case FM10K_CONFIG_FLOW_COND_SRC_DPDK_PORT:
> +		flow->src_port.port_type =
> FM10K_CONFIG_FLOW_DPDK_PORT;
> +		flow->src_port.port_no = val;
> +		break;
> +	case FM10K_CONFIG_FLOW_COND_VLAN:
> +		flow->src_port.vlan_id = val;
> +		break;
> +	case FM10K_CONFIG_FLOW_ACT_FW_EXT_PORT:
> +		if (flow->fw_port[0].port_type ==
> FM10K_CONFIG_FLOW_NONE_PORT) {
> +			flow->fw_port[0].port_type =
> FM10K_CONFIG_FLOW_EXT_PORT;
> +			flow->fw_port[0].port_no = val;
> +		} else {
> +			flow->fw_port[1].port_type =
> FM10K_CONFIG_FLOW_EXT_PORT;
> +			flow->fw_port[1].port_no = val;
> +		}
> +		break;
> +	case FM10K_CONFIG_FLOW_ACT_FW_DPDK_PORT:
> +		if (flow->fw_port[0].port_type ==
> FM10K_CONFIG_FLOW_NONE_PORT) {
> +			flow->fw_port[0].port_type =
> FM10K_CONFIG_FLOW_DPDK_PORT;
> +			flow->fw_port[0].port_no = val;
> +		} else {
> +			flow->fw_port[1].port_type =
> FM10K_CONFIG_FLOW_DPDK_PORT;
> +			flow->fw_port[1].port_no = val;
> +		}
> +		break;
> +	case FM10K_CONFIG_FLOW_ACT_FW_VALN:
> +		if (flow->fw_port[0].vlan_id == 0)
> +			flow->fw_port[0].vlan_id = val;
> +		else
> +			flow->fw_port[1].vlan_id = val;
> +		break;
> +	default:
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +fm10k_config_conf_file_transfer(void)
> +{
> +	int i;
> +	int offset;
> +	uint32_t tmp, data;
> +	struct fm10k_cfg_config_item *item;
> +	struct fm10k_cfg_flowset* flowset = NULL;
> +
> +	for (i = 0; i < FM10K_SW_CONFIG_MAX; i++) {
> +		item = &(fm10k_config_dpdk_cfg.config_list[i]);
> +		if (item->type == FM10K_CONFIG_TYPE_NULL)
> +			break;
> +
> +		switch (item->type)	{
> +		case FM10K_CONFIG_BIND_PF_NUMBER:
> +			fm10k_config_dpdk_cfg.pf_num = item->val.int64;
> +			break;
> +		case FM10K_CONFIG_EXT_PORT_SPEED:
> +			fm10k_config_dpdk_cfg.ext_port_speed = item-
> >val.int64;
> +			break;
> +		case FM10K_CONFIG_DPDK_PORT_MAP_PF:
> +			if (fm10k_config_dpdk_cfg.dpdk_port_map[item-
> >key_param].type
> +					== FM10K_CONFIG_PORT_MAP_PF) {
> +				fm10k_config_dpdk_cfg.dpdk_port_map[item-
> >key_param].type = FM10K_CONFIG_PORT_MAP_PFS;
> +				fm10k_config_dpdk_cfg.dpdk_port_map[item-
> >key_param].map_no[1] = item->val.int64;
> +			} else {
> +				fm10k_config_dpdk_cfg.dpdk_port_map[item-
> >key_param].type = FM10K_CONFIG_PORT_MAP_PF;
> +				fm10k_config_dpdk_cfg.dpdk_port_map[item-
> >key_param].map_no[0] = item->val.int64;
> +			}
> +			break;
> +		case FM10K_CONFIG_EXT_PORT_MAP_PF:
> +			if (fm10k_config_dpdk_cfg.ext_port_map[item-
> >key_param-1].type
> +					== FM10K_CONFIG_PORT_MAP_PF) {
> +				fm10k_config_dpdk_cfg.ext_port_map[item-
> >key_param-1].type = FM10K_CONFIG_PORT_MAP_PFS;
> +				fm10k_config_dpdk_cfg.ext_port_map[item-
> >key_param-1].map_no[1] = item->val.int64;
> +			} else {
> +				fm10k_config_dpdk_cfg.ext_port_map[item-
> >key_param-1].type = FM10K_CONFIG_PORT_MAP_PF;
> +				fm10k_config_dpdk_cfg.ext_port_map[item-
> >key_param-1].map_no[0] = item->val.int64;
> +			}
> +			break;
> +
> +		case FM10K_CONFIG_DEBUG_ENABLE:
> +		case FM10K_CONFIG_DEBUG_CONFIG:
> +		case FM10K_CONFIG_DEBUG_FFU_INIT:
> +		case FM10K_CONFIG_DEBUG_FFU_REG:
> +		case FM10K_CONFIG_DEBUG_FFU_RULE:
> +		case FM10K_CONFIG_DEBUG_STATS_PORT:
> +		case FM10K_CONFIG_DEBUG_STATS_QUEUE:
> +		case FM10K_CONFIG_DEBUG_STATS_FFU:
> +		case FM10K_CONFIG_DEBUG_STATS_MORE:
> +			offset = item->type-FM10K_CONFIG_DEBUG_START;
> +			tmp = fm10k_config_dpdk_cfg.debug_cfg;
> +			data = 1;
> +			if (item->val.int64 != 1)
> +				fm10k_config_dpdk_cfg.debug_cfg = tmp &
> ~(data<<offset);
> +			else
> +				fm10k_config_dpdk_cfg.debug_cfg |=
> (data<<offset);
> +			break;
> +		case FM10K_CONFIG_DEBUG_STATS_INTERVAL:
> +			fm10k_config_dpdk_cfg.stats_interval = item-
> >val.int64;
> +			break;
> +
> +		case FM10K_CONFIG_FLOWSET_START:
> +			item->val.str[strlen(item->val.str) - 2] = 0; /* skip /r/n */
> +			flowset = fm10k_config_flowset_get(item->val.str);
> +			if (flowset == NULL)
> +				return -1;
> +			break;
> +		case FM10K_CONFIG_FLOWSET_STOP:
> +			flowset = NULL;
> +			break;
> +		case FM10K_CONFIG_FLOWSET_ENABLE:
> +			item->val.str[strlen(item->val.str)-2] = 0; /* skip /r/n */
> +			fm10k_config_dpdk_cfg.current =
> fm10k_config_flowset_get(item->val.str);
> +			break;
> +		case FM10K_CONFIG_FLOW_COND_SRC_EXT_PORT:
> +		case FM10K_CONFIG_FLOW_COND_SRC_DPDK_PORT:
> +		case FM10K_CONFIG_FLOW_COND_VLAN:
> +		case FM10K_CONFIG_FLOW_ACT_FW_EXT_PORT:
> +		case FM10K_CONFIG_FLOW_ACT_FW_DPDK_PORT:
> +		case FM10K_CONFIG_FLOW_ACT_FW_VALN:
> +			if (flowset == NULL ||
> +					fm10k_cfg_flow_item_set(flowset,
> item->key_param, item->type, item->val.int64) != 0)
> +				return -1;
> +			break;
> +		default:
> +			return -1;
> +		}
> +	}
> +	return 0;
> +}
> +
> +static bool
> +fm10k_config_conf_file_exist(void)
> +{
> +	if(access(fm10k_config_dpdk_conf_file, 0) == 0)
> +		return true;
> +	return false;
> +}
> +
> +static int
> +fm10k_config_conf_file_create(void)
> +{
> +	uint16_t i, j, k;
> +	struct fm10k_cfg_key_item *key;
> +	struct fm10k_cfg_config_item *item;
> +	FILE *fp;
> +	char buff[255] = "";
> +
> +	fp = fopen(fm10k_config_dpdk_conf_file, "w");
> +	if (fp == NULL)
> +		return -1;
> +
> +	for (i = 0; i < FM10K_SW_CONFIG_MAX; i++) {
> +		item = &(fm10k_config_dpdk_cfg.config_list[i]);
> +		if (item->type == FM10K_CONFIG_TYPE_NULL)
> +			break;
> +		buff[0] = 0;
> +		if (strlen(item->describe) > 0)
> +			sprintf(buff, "\n\n%s\n", item->describe);
> +		for (j = 0; j < FM10K_SW_NITEMS(fm10k_config_key_items); j++)
> {
> +			key = &fm10k_config_key_items[j];
> +			if (item->type == key->type) {
> +				for (k = 0; k < FM10K_CONFIG_WORD_MAX;
> k++) {
> +					if (key->key_str[k] == 0)
> +						break;
> +					if (k == 0)
> +						sprintf(buff+strlen(buff), "%s",
> key->key_str[k]);
> +					else {
> +						if (strcmp(key->key_str[k], "*")
> == 0)
> +
> 	sprintf(buff+strlen(buff), ".%u", item->key_param);
> +						else
> +
> 	sprintf(buff+strlen(buff), ".%s", key->key_str[k]);
> +					}
> +				}
> +				if (item->val_type ==
> FM10K_CONFIG_VALUE_INT)
> +					sprintf(buff+strlen(buff), " int %lld\n",
> (long long int)item->val.int64);
> +				else if (item->val_type ==
> FM10K_CONFIG_VALUE_STR)
> +					sprintf(buff+strlen(buff), " string %s\n",
> item->val.str);
> +				else
> +					return -1;
> +				fwrite(buff, strlen(buff), 1, fp);
> +				FM10K_SW_TRACE("[write] %s", buff);
> +				break;
> +			}
> +		}
> +	}
> +	fclose(fp);
> +	return 0;
> +}
> +
> +void
> +fm10k_config_cfg_flowset_show(void)
> +{
> +	struct fm10k_cfg_flowset* flowset;
> +
> +	printf("  FLOWSET ENABLE: %s\n", fm10k_config_dpdk_cfg.current-
> >name);
> +
> +	flowset = fm10k_config_dpdk_cfg.flowset_head.next;
> +	while (flowset) {
> +		printf("\n  FLOWSET  : %s\n", flowset->name);
> +		struct fm10k_cfg_flow* flow = flowset->flow_head.next;
> +		while (!fm10k_config_flow_list_end(&flowset->flow_head,
> flow)) {
> +			const char *port_type[3] = { "NON", "EXT", "DPDK" };
> +			if (flow->fw_port[1].port_type !=
> FM10K_CONFIG_FLOW_NONE_PORT) {
> +				printf("  FLOW %d : %4s PORT %d VLAN %4d --
> > %4s PORT %d VLAN %4d & %4s PORT %d VLAN %4d \n",
> +					flow->flow_no, port_type[flow-
> >src_port.port_type], flow->src_port.port_no, flow->src_port.vlan_id,
> +					port_type[flow-
> >fw_port[0].port_type], flow->fw_port[0].port_no, flow->fw_port[0].vlan_id,
> +					port_type[flow-
> >fw_port[1].port_type], flow->fw_port[1].port_no, flow->fw_port[1].vlan_id);
> +			} else {
> +				printf("  FLOW %d : %4s PORT %d VLAN %4d --
> > %4s PORT %d VLAN %4d\n",
> +					flow->flow_no, port_type[flow-
> >src_port.port_type], flow->src_port.port_no, flow->src_port.vlan_id,
> +					port_type[flow-
> >fw_port[0].port_type], flow->fw_port[0].port_no, flow->fw_port[0].vlan_id);
> +			}
> +			flow = flow->next;
> +		}
> +		flowset = flowset->next;
> +	}
> +}
> +
> +static void
> +fm10k_config_cfg_describe(struct fm10k_switch *sw, struct
> fm10k_device_info *info)
> +{
> +	uint16_t i;
> +	struct fm10k_cfg_flowset* flowset;
> +
> +	if (!FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_CONFIG))
> +		return;
> +
> +	printf("--- FM10K STATIC CONFIG ---\n");
> +	printf("  Card Type: %s\n", info->desc);
> +	printf("  PF Max   : %d\n", fm10k_config_dpdk_cfg.pf_max);
> +	printf("  PF Bind  : %d\n", fm10k_config_dpdk_cfg.pf_num);
> +	printf("  DEBUG    : %#x\n", fm10k_config_dpdk_cfg.debug_cfg);
> +	printf("  STATS GAP: %d sec\n", fm10k_config_dpdk_cfg.stats_interval);
> +	printf("  EXT PORT speed: %d Gbps\n",
> fm10k_config_dpdk_cfg.ext_port_speed);
> +	printf("  FLOWSET ENABLE: %s\n", fm10k_config_dpdk_cfg.current-
> >name);
> +
> +	for (i = 0; i < fm10k_config_dpdk_cfg.ext_port_num; i++) {
> +		if (fm10k_config_dpdk_cfg.ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_NULL)
> +			continue;
> +		if (fm10k_config_dpdk_cfg.ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PF)
> +			printf("  EXT PORT[%d] MAP: PF%d\n", i+1,
> +
> 	fm10k_config_dpdk_cfg.ext_port_map[i].map_no[0]);
> +		else
> +			printf("  EXT PORT[%d] MAP: PF%d PF%d\n", i+1,
> +
> 	fm10k_config_dpdk_cfg.ext_port_map[i].map_no[0],
> +
> 	fm10k_config_dpdk_cfg.ext_port_map[i].map_no[1]);
> +	}
> +
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		if (fm10k_config_dpdk_cfg.dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_NULL)
> +			continue;
> +		if (fm10k_config_dpdk_cfg.ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PF)
> +			printf("  DPDK PORT[%d] MAP: PF%d\n", i,
> +
> 	fm10k_config_dpdk_cfg.dpdk_port_map[i].map_no[0]);
> +		else
> +			printf("  DPDK PORT[%d] MAP: PF%d PF%d\n", i,
> +
> 	fm10k_config_dpdk_cfg.dpdk_port_map[i].map_no[0],
> +
> 	fm10k_config_dpdk_cfg.dpdk_port_map[i].map_no[1]);
> +	}
> +
> +	flowset = fm10k_config_dpdk_cfg.flowset_head.next;
> +	while (flowset) {
> +		printf("\n  FLOWSET  : %s\n", flowset->name);
> +		struct fm10k_cfg_flow* flow = flowset->flow_head.next;
> +		while (!fm10k_config_flow_list_end(&flowset->flow_head,
> flow)) {
> +			const char *port_type[3] = { "NON", "EXT", "DPDK" };
> +			if (flow->fw_port[1].port_type !=
> FM10K_CONFIG_FLOW_NONE_PORT) {
> +				printf("  FLOW %d : %4s PORT %d VLAN %4d --
> > %4s PORT %d VLAN %4d & %4s PORT %d VLAN %4d \n",
> +					flow->flow_no, port_type[flow-
> >src_port.port_type], flow->src_port.port_no, flow->src_port.vlan_id,
> +					port_type[flow-
> >fw_port[0].port_type], flow->fw_port[0].port_no, flow->fw_port[0].vlan_id,
> +					port_type[flow-
> >fw_port[1].port_type], flow->fw_port[1].port_no, flow->fw_port[1].vlan_id);
> +			} else {
> +				printf("  FLOW %d : %4s PORT %d VLAN %4d --
> > %4s PORT %d VLAN %4d\n",
> +					flow->flow_no, port_type[flow-
> >src_port.port_type], flow->src_port.port_no, flow->src_port.vlan_id,
> +					port_type[flow-
> >fw_port[0].port_type], flow->fw_port[0].port_no, flow->fw_port[0].vlan_id);
> +			}
> +			flow = flow->next;
> +		}
> +		flowset = flowset->next;
> +	}
> +	printf("\n");
> +}
> +
> +int
> +fm10k_config_init(struct fm10k_switch *sw, struct fm10k_hw *hw)
> +{
> +	struct fm10k_device_info *info = fm10k_get_device_info(hw);
> +
> +	fm10k_config_dpdk_cfg.stats_interval = 2;
> +	fm10k_config_dpdk_cfg.pf_max = info->num_peps;
> +	fm10k_config_dpdk_cfg.ext_port_num = info->num_ext_ports;
> +
> +	if (!fm10k_config_conf_file_exist()) {
> +		if (info->num_epls == 2 && info->num_peps == 2)
> +			fm10k_config_dpdk_cfg.config_list =
> fm10k_silc_nic_2ext_2pep;
> +		else if (info->num_epls == 2 && info->num_peps == 4)
> +			fm10k_config_dpdk_cfg.config_list =
> fm10k_silc_nic_2ext_4pep;
> +		else
> +			return -1;
> +
> +		fm10k_config_conf_file_create();
> +	} else {
> +		if (fm10k_config_conf_file_load() < 0)
> +			return -1;
> +	}
> +
> +	if (fm10k_config_conf_file_transfer() < 0)
> +		return -1;
> +	sw->dpdk_cfg = &fm10k_config_dpdk_cfg;
> +
> +	fm10k_config_cfg_describe(sw, info);
> +
> +	return 0;
> +}
> diff --git a/drivers/net/fm10k/switch/fm10k_config.h
> b/drivers/net/fm10k/switch/fm10k_config.h
> new file mode 100644
> index 0000000..b7e060b
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_config.h
> @@ -0,0 +1,170 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_CONFIG_H_
> +#define _FM10K_CONFIG_H_
> +
> +
> +#include <stdint.h>
> +#include "fm10k_switch.h"
> +
> +/* General configuration */
> +#define FM10K_CONFIG_TYPE_NULL				0
> +#define FM10K_CONFIG_BIND_PF_NUMBER			1
> +#define FM10K_CONFIG_EXT_PORT_SPEED			2
> +
> +/* Internal redirect configuration */
> +#define FM10K_CONFIG_DPDK_PORT_MAP_PF		10
> +#define FM10K_CONFIG_EXT_PORT_MAP_PF		11
> +
> +/* Debug configuration */
> +#define FM10K_CONFIG_DEBUG_START			50
> +#define FM10K_CONFIG_DEBUG_ENABLE
> 	(FM10K_CONFIG_DEBUG_START + 0)
> +#define FM10K_CONFIG_DEBUG_CONFIG
> 	(FM10K_CONFIG_DEBUG_START + 1)
> +#define FM10K_CONFIG_DEBUG_FFU_INIT
> 	(FM10K_CONFIG_DEBUG_START + 2)
> +#define FM10K_CONFIG_DEBUG_FFU_REG
> 	(FM10K_CONFIG_DEBUG_START + 3)
> +#define FM10K_CONFIG_DEBUG_FFU_RULE
> 	(FM10K_CONFIG_DEBUG_START + 4)
> +#define FM10K_CONFIG_DEBUG_STATS_PORT
> 	(FM10K_CONFIG_DEBUG_START + 5)
> +#define FM10K_CONFIG_DEBUG_STATS_QUEUE
> 	(FM10K_CONFIG_DEBUG_START + 6)
> +#define FM10K_CONFIG_DEBUG_STATS_FFU
> 	(FM10K_CONFIG_DEBUG_START + 7)
> +#define FM10K_CONFIG_DEBUG_STATS_MORE
> 	(FM10K_CONFIG_DEBUG_START + 8)
> +#define FM10K_CONFIG_DEBUG_STATS_INTERVAL
> 	(FM10K_CONFIG_DEBUG_START + 9)
> +
> +#define FM10K_CONFIG_CHECK_DEBUG(cfg, dbg)	(((cfg)-
> >debug_cfg)&(0x1<<((dbg)-FM10K_CONFIG_DEBUG_START)) && ((cfg)-
> >debug_cfg)&1 )
> +
> +/* external redirect configuration */
> +#define FM10K_CONFIG_FLOWSET_START				80
> +#define FM10K_CONFIG_FLOWSET_STOP				81
> +#define FM10K_CONFIG_FLOWSET_ENABLE				82
> +
> +#define FM10K_CONFIG_FLOW_COND_START			100
> +#define FM10K_CONFIG_FLOW_COND_SRC_EXT_PORT
> 	(FM10K_CONFIG_FLOW_COND_START + 0)
> +#define FM10K_CONFIG_FLOW_COND_SRC_DPDK_PORT
> 	(FM10K_CONFIG_FLOW_COND_START + 1)
> +#define FM10K_CONFIG_FLOW_COND_VLAN
> 	(FM10K_CONFIG_FLOW_COND_START + 2)
> +#define FM10K_CONFIG_FLOW_COND_END
> 	(FM10K_CONFIG_FLOW_COND_START + 2)
> +
> +#define FM10K_CONFIG_FLOW_ACT_START				200
> +#define FM10K_CONFIG_FLOW_ACT_FW_EXT_PORT
> 	(FM10K_CONFIG_FLOW_ACT_START + 0)
> +#define FM10K_CONFIG_FLOW_ACT_FW_DPDK_PORT
> 	(FM10K_CONFIG_FLOW_ACT_START + 1)
> +#define FM10K_CONFIG_FLOW_ACT_FW_VALN
> 	(FM10K_CONFIG_FLOW_ACT_START + 2)
> +#define FM10K_CONFIG_FLOW_ACT_END
> 	(FM10K_CONFIG_FLOW_ACT_START + 2)
> +
> +#define FM10K_CONFIG_FLOW_NONE_PORT		0
> +#define FM10K_CONFIG_FLOW_EXT_PORT		1
> +#define FM10K_CONFIG_FLOW_DPDK_PORT		2
> +
> +#define FM10K_CONFIG_VALUE_NULL			0
> +#define FM10K_CONFIG_VALUE_INT			1
> +#define FM10K_CONFIG_VALUE_STR			2
> +
> +/* SWITCH config */
> +#define FM10K_CONFIG_PORT_MAP_NULL	0
> +#define FM10K_CONFIG_PORT_MAP_PF	1
> +#define FM10K_CONFIG_PORT_MAP_PFS	2
> +#define FM10K_CONFIG_PORT_MAP_PFSS	3
> +
> +struct fm10k_cfg_port_pf_map {
> +	uint8_t type;
> +	uint8_t map_no[2];
> +};
> +
> +/* Configuration read from file */
> +struct fm10k_cfg_config_item {
> +	uint8_t  type;
> +	uint8_t  val_type;
> +	uint16_t key_param;
> +	const char *describe;
> +	union {
> +		int64_t int64;
> +		char* str;
> +	}val;
> +};
> +
> +/* DPDK port */
> +#define	FM10K_CONFIG_DPDK_NULL 		0
> +#define FM10K_CONFIG_DPDK_PF		1
> +#define FM10K_CONFIG_DPDK_VF		2
> +#define FM10K_CONFIG_DPDK_MAX		3
> +
> +struct fm10k_hw;
> +struct fm10k_dpdk_port {
> +	uint8_t type;
> +	struct fm10k_hw* hw;
> +	uint16_t pf_no;
> +	uint8_t tx_queue_num;
> +	uint8_t rx_queue_num;
> +};
> +
> +
> +/* Flow configuraton */
> +struct fm10k_cfg_port {
> +	uint8_t port_type;
> +	uint8_t port_no;
> +	uint16_t vlan_id;
> +};
> +
> +struct fm10k_cfg_flow {
> +	/* set by configuration */
> +	struct fm10k_cfg_flow* prev;
> +	struct fm10k_cfg_flow* next;
> +	uint8_t flow_no; /* only configured flow has this NO. */
> +	struct fm10k_cfg_port src_port;
> +	struct fm10k_cfg_port fw_port[2];
> +	/* set by ffu rule add */
> +	uint16_t rule_id;
> +};
> +
> +#define FM10K_CONFIG_FLOWSET_NAME_MAX	256
> +struct fm10k_cfg_flowset {
> +	char name[FM10K_CONFIG_FLOWSET_NAME_MAX];
> +	struct fm10k_cfg_flow flow_head;
> +	struct fm10k_cfg_flowset *next;
> +};
> +
> +/* Configuration */
> +struct fm10k_dpdk_cfg {
> +	uint8_t pf_num;			/* configure by conf */
> +	uint8_t pf_bind;		/* initialize by dpdk */
> +	uint8_t pf_max;			/* set by card type */
> +	uint8_t ext_port_num;	/* configure by conf */
> +	uint8_t ext_port_speed;	/* configure by conf */
> +	uint32_t debug_cfg;		/* configure by conf */
> +	uint32_t stats_interval;/* configure by conf */
> +
> +	struct fm10k_hw* master_hw;					/*
> initialize by dpdk */
> +	struct fm10k_hw* pf_hw[FM10K_SW_PEPS_MAX];	/* initialize by
> dpdk */
> +
> +	struct fm10k_dpdk_port ports[FM10K_SW_LOGICAL_PORTS_MAX];
> 	/* initialize by dpdk */
> +	struct fm10k_cfg_port_pf_map
> dpdk_port_map[FM10K_SW_LOGICAL_PORTS_MAX];	/* configure by conf or
> default*/
> +	struct fm10k_cfg_port_pf_map
> ext_port_map[FM10K_SW_EXT_PORTS_MAX];		/* configure by conf */
> +	struct fm10k_cfg_config_item* config_list;
> 					/* configure by conf */
> +	struct fm10k_cfg_flowset flowset_head;
> 					/* transfer from conf file */
> +	struct fm10k_cfg_flowset *current;
> +};
> +
> +struct fm10k_cfg_flowset* fm10k_config_flowset_get(const char* name);
> +struct fm10k_cfg_flowset* fm10k_config_flowset_current_get(void);
> +void fm10k_config_flowset_current_set(struct fm10k_cfg_flowset *new);
> +void fm10k_config_flow_list_add_tail(struct fm10k_cfg_flowset* flowset,
> struct fm10k_cfg_flow * flow);
> +void fm10k_config_flow_list_delete(struct fm10k_cfg_flow * flow);
> +bool fm10k_config_flow_list_end(struct fm10k_cfg_flow *list, struct
> fm10k_cfg_flow *flow);
> +
> +void fm10k_config_cfg_flowset_show(void);
> +struct fm10k_hw* fm10k_config_hw_get(int port_no);
> +int fm10k_config_init(struct fm10k_switch *sw, struct fm10k_hw *hw);
> +
> +#endif /* _FM10K_CONFIG_H */
> diff --git a/drivers/net/fm10k/switch/fm10k_debug.h
> b/drivers/net/fm10k/switch/fm10k_debug.h
> new file mode 100644
> index 0000000..6ffde5f
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_debug.h
> @@ -0,0 +1,32 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_DEBUG_H_
> +#define _FM10K_DEBUG_H_
> +
> +
> +#define FM10K_SW_ERR(...)		PMD_INIT_LOG(ERR, __VA_ARGS__)
> +#define FM10K_SW_INFO(...)		PMD_INIT_LOG(INFO, __VA_ARGS__)
> +#define FM10K_SW_TRACE(...)		PMD_INIT_LOG(DEBUG, __VA_ARGS__)
> +
> +#define FM10K_SW_ASSERT(...)	do {}while(0)
> +
> +#define FM10K_SW_STATS_TRACE_ENABLE		1
> +#define FM10K_SW_FFU_CONF_TRACE_ENABLE	0
> +#define FM10K_SW_MIRROR_TRACE_ENABLE	0
> +
> +#endif /* _FM10K_DEBUG_H_ */
> diff --git a/drivers/net/fm10k/switch/fm10k_ext_port.c
> b/drivers/net/fm10k/switch/fm10k_ext_port.c
> new file mode 100644
> index 0000000..0fb35fb
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_ext_port.c
> @@ -0,0 +1,952 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#include <rte_malloc.h>
> +
> +#include "fm10k_debug.h"
> +#include "fm10k_ext_port.h"
> +#include "fm10k_i2c.h"
> +#include "fm10k_regs.h"
> +#include "fm10k_serdes.h"
> +#include "fm10k_sm.h"
> +#include "fm10k_switch.h"
> +
> +
> +#define LANE_EVENT(e_)
> 	FM10K_SW_EXT_PORT_LANE_EVENT_##e_
> +#define LANE_TIMER(t_)
> 	FM10K_SW_EXT_PORT_LANE_TIMER_##t_
> +#define LANE_TIMEOUT(t_)
> 	FM10K_SW_EXT_PORT_LANE_##t_##_TIMEOUT_MS
> +#define LANE_POLL(t_)
> 	FM10K_SW_EXT_PORT_LANE_##t_##_POLL_MS
> +#define LANE_STATE(s_)
> 	FM10K_SW_EXT_PORT_LANE_STATE_##s_
> +#define LANE_FLAG(f_)
> 	FM10K_SW_EXT_PORT_LANE_FLAG_##f_
> +#define LANE_FLAGS(f_)
> 	FM10K_SW_EXT_PORT_LANE_FLAGS_##f_
> +#define LANE_FLAG_SET(l_, f_)	((l_)->flags & LANE_FLAG(f_))
> +#define LANE_FLAGS_SET(l_, f_)	(((l_)->flags & LANE_FLAGS(f_)) ==
> LANE_FLAGS(f_))
> +
> +#define PORT_EVENT(e_)
> 	FM10K_SW_EXT_PORT_EVENT_##e_
> +#define PORT_STATE(s_)
> 	FM10K_SW_EXT_PORT_STATE_##s_
> +
> +static void fm10k_ext_ports_epl_intr(struct fm10k_ext_ports *ports, unsigned
> int eplno);
> +static void fm10k_ext_port_intr(struct fm10k_ext_port *port, uint32_t epl_ip);
> +static void fm10k_ext_port_process_event(struct fm10k_sm *sm, uint16_t
> event);
> +static void fm10k_ext_port_bring_down(struct fm10k_ext_port *port);
> +static void fm10k_ext_port_lane_process_event(struct fm10k_sm *sm,
> uint16_t event);
> +static void fm10k_ext_port_lane_process_timer(struct fm10k_sm *sm,
> uint16_t timer);
> +static void fm10k_ext_port_restart_lane(struct fm10k_ext_port_lane *lane);
> +static void fm10k_ext_port_disable_lane(struct fm10k_ext_port_lane *lane);
> +static void fm10k_ext_port_phy_enable(struct fm10k_ext_port *port);
> +static void fm10k_ext_port_phy_disable(struct fm10k_ext_port *port);
> +
> +#if FM10K_SW_TRACE_ENABLE
> +static const char*fm10k_ext_port_state_name(enum fm10k_ext_port_state
> state);
> +static const char*fm10k_ext_port_event_name(enum fm10k_ext_port_event
> event);
> +static const char*fm10k_ext_port_lane_state_name(enum
> fm10k_ext_port_lane_state state);
> +static const char*fm10k_ext_port_lane_event_name(enum
> fm10k_ext_port_lane_event event);
> +static const char*fm10k_ext_port_lane_timer_name(enum
> fm10k_ext_port_lane_timer timer);
> +#endif
> +
> +struct fm10k_ext_ports *
> +fm10k_ext_ports_attach(struct fm10k_switch *sw)
> +{
> +//	struct fm10k_pep *pep = sw->pep;
> +	struct fm10k_ext_ports *ports;
> +	struct fm10k_ext_port *port;
> +	struct fm10k_ext_port_lane *lane;
> +	struct fm10k_device_info *cfg = sw->info;
> +	unsigned int is_quad, lane_speed;
> +	unsigned int i, j;
> +	unsigned int eplidx, laneno;
> +
> +	FM10K_SW_TRACE("attaching external ports\n");
> +
> +	ports = (struct fm10k_ext_ports *)rte_zmalloc("fm10k_ext_ports",
> sizeof(struct fm10k_ext_ports), 0);
> +	if (ports == NULL) {
> +		FM10K_SW_ERR("failed to allocate external ports\n");
> +		goto fail;
> +	}
> +
> +	ports->ports = (struct fm10k_ext_port
> *)rte_zmalloc("fm10k_ext_port_list", sizeof(struct fm10k_ext_port)*cfg-
> >num_ext_ports, 0);
> +	if (ports->ports == NULL) {
> +		FM10K_SW_ERR("failed to allocate external ports list\n");
> +		goto fail;
> +	}
> +	ports->sw = sw;
> +	ports->num_ports = cfg->num_ext_ports;
> +	ports->ports_per_epl = cfg->num_ext_ports / cfg->num_epls;
> +	ports->epl_mask = 0;
> +
> +	switch (cfg->ext_port_speed) {
> +	default:
> +	case 10:
> +		is_quad = 0;
> +		lane_speed = 10;
> +		break;
> +	case 25:
> +		is_quad = 0;
> +		lane_speed = 25;
> +		break;
> +	case 40:
> +		is_quad = 1;
> +		lane_speed = 10;
> +		break;
> +	case 100:
> +		is_quad = 1;
> +		lane_speed = 25;
> +		break;
> +	}
> +
> +	for (i = 0; i < ports->num_ports; i++) {
> +		port = &ports->ports[i];
> +		port->ports = ports;
> +		fm10k_ext_port_eplidx_lane(ports, i, &eplidx, &laneno);
> +		port->portno = i;
> +		port->eplno = fm10k_switch_eplidx_to_eplno(sw, eplidx);
> +		snprintf(port->name, sizeof(port->name), "EPL[%u][%u]",
> +		    port->eplno, port->first_lane);
> +		port->first_lane = laneno;
> +		port->is_quad = is_quad;
> +		port->num_lanes = port->is_quad ? 4 : 1;
> +		port->lane_speed = lane_speed;
> +		port->sm = fm10k_sm_attach(
> +		    FM10K_SW_EXT_PORT_NUM_EVENTS, 0,
> +		    fm10k_ext_port_process_event, NULL,
> +		    (void*)port);
> +		if (port->sm == NULL)
> +			goto fail;
> +		port->sm->portno = port->portno;
> +		port->sm->laneno = 0;
> +		port->an_im = FM10K_SW_AN_IM_ALL;
> +		port->link_im = FM10K_SW_LINK_IM_ALL;
> +
> +		for (j = port->first_lane;
> +		     j < port->first_lane + port->num_lanes; j++) {
> +			lane = &port->lanes[j];
> +			lane->port = port;
> +			lane->abs_laneno = port->eplno *
> FM10K_SW_EPL_LANES + j;
> +			lane->rel_laneno = j;
> +			lane->im = FM10K_SW_SERDES_IM_ALL;
> +			lane->sm = fm10k_sm_attach(
> +			    FM10K_SW_EXT_PORT_LANE_NUM_EVENTS,
> +			    FM10K_SW_EXT_PORT_LANE_NUM_TIMERS,
> +			    fm10k_ext_port_lane_process_event,
> +			    fm10k_ext_port_lane_process_timer,
> +			    (void*)lane);
> +			if (lane->sm == NULL)
> +				goto fail;
> +			lane->sm->portno = lane->port->portno;
> +			lane->sm->laneno = lane->rel_laneno;
> +		}
> +
> +		ports->epl_mask |= (1 << port->eplno);
> +	}
> +
> +	return (ports);
> +fail:
> +	if (ports)
> +		fm10k_ext_ports_detach(ports);
> +	return (NULL);
> +}
> +
> +void
> +fm10k_ext_ports_detach(struct fm10k_ext_ports *ports)
> +{
> +	struct fm10k_ext_port *port;
> +	struct fm10k_ext_port_lane *lane;
> +	unsigned int i, j;
> +
> +	FM10K_SW_TRACE("detaching external ports\n");
> +
> +	if (ports->ports) {
> +		for (i = 0; i < ports->num_ports; i++) {
> +			port = &ports->ports[i];
> +
> +			if (port->sm)
> +				fm10k_sm_detach(port->sm);
> +			for (j = port->first_lane;
> +			     j < port->first_lane + port->num_lanes; j++) {
> +				lane = &port->lanes[j];
> +				if (lane->sm)
> +					fm10k_sm_detach(lane->sm);
> +			}
> +
> +			fm10k_ext_port_phy_disable(port);
> +		}
> +		rte_free(ports->ports);
> +	}
> +
> +	rte_free(ports);
> +}
> +
> +unsigned int
> +fm10k_ext_ports_epl_intrs(struct fm10k_ext_ports *ports, uint64_t gid)
> +{
> +	unsigned int i;
> +	uint16_t epl_mask;
> +
> +	/*
> +	 * Process EPL interrupts for all EPLs that are in use and have
> +	 * their bit set in global interrupt detect.
> +	 */
> +	epl_mask = ports->epl_mask &
> +	    FM10K_SW_REG_FIELD64(gid, GLOBAL_INTERRUPT_DETECT_EPL);
> +	for (i = 0; i < FM10K_SW_EPLS_MAX; i++)
> +		if (epl_mask & (1 << i))
> +			fm10k_ext_ports_epl_intr(ports, i);
> +
> +	return (ports->epl_mask);
> +}
> +
> +static void
> +fm10k_ext_ports_epl_intr(struct fm10k_ext_ports *ports, unsigned int eplno)
> +{
> +	struct fm10k_switch *sw = ports->sw;
> +	struct fm10k_ext_port *port;
> +	uint64_t gid;
> +	unsigned int i, j;
> +	uint32_t epl_ip;
> +
> +	/*
> +	 * The global interrupt detect architecture makes it somewhat
> +	 * challenging to ensure events are not lost and spurious interrupts
> +	 * are not generated.
> +	 *
> +	 * The EPLs have an internal interrupt hierarchy whose reporting is
> +	 * rooted at EPL_IP.  Whenever an EPL transitions from having no
> +	 * unmasked interrupts pending to at least one unmasked interrupt
> +	 * pending or from having at least one unmasked interrupt pending to
> +	 * no unmasked interrupts pending, it sends a vector to the
> +	 * interrupt controller over a serial bus indicating the
> +	 * at-least-one/none pending state, and the controller updates the
> +	 * bit for that EPL in the global interrupt detect register
> +	 * accordingly.
> +	 *
> +	 * Because of the update-vector-in-flight potential, there is a race
> +	 * between re-enabling the EPL PCIe interrupt mask after servicing
> +	 * the EPL interrupts and the all-clear vector from the EPL reaching
> +	 * the interrupt controller - it's possible for the software to
> +	 * clear all the EPL-internal interrupt sources during servicing and
> +	 * then re-enable the EPL interrupt in the PCIe mask before the
> +	 * all-clear vector reaches the interrupt controller and clears the
> +	 * EPL pending bit in the global interrupt detect register.  This
> +	 * would result in a spurious EPL interrupt, potentially for every
> +	 * necessary EPL interrupt.
> +	 *
> +	 * The approach taken here to avoid spurious interrupts is to first
> +	 * mask off all EPL-internal sources, then poll the EPL bits in the
> +	 * global interrupt detect register until they clear (indicating the
> +	 * update vector from the EPL has reached the interrupt controller).
> +	 * Then software interrupt processing proceeds, and the EPL-internal
> +	 * masks are restored to their desired state at the end.  This
> +	 * ensures that when the EPL PCIe interrupt mask is re-enabled, the
> +	 * EPL pending bits in the global interrupt detect register will
> +	 * only be set if there are new, unprocessed EPL events of interest.
> +	 *
> +	 */
> +	FM10K_SW_SWITCH_LOCK(sw);
> +	/* Grab epl_ip before it is cleared by the masks below */
> +	epl_ip = fm10k_read_switch_reg(sw, FM10K_SW_EPL_IP(eplno));
> +#if 0
> +	/* currently not used, so will default to masked off */
> +	fm10k_write_switch_reg(sw,
> +	    FM10K_SW_EPL_ERROR_IM(eplno),
> FM10K_SW_EPL_ERROR_IM_ALL);
> +#endif
> +	for (i = 0; i < ports->num_ports; i++) {
> +		port = &ports->ports[i];
> +		if (port->eplno != eplno)
> +			continue;
> +
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_AN_IM(eplno, port->first_lane),
> +		    FM10K_SW_AN_IM_ALL);
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_LINK_IM(eplno, port->first_lane),
> +		    FM10K_SW_LINK_IM_ALL);
> +
> +		for (j = port->first_lane;
> +		     j < port->first_lane + port->num_lanes; j++) {
> +			fm10k_write_switch_reg(sw,
> +			    FM10K_SW_SERDES_IM(eplno, j),
> +			    FM10K_SW_SERDES_IM_ALL);
> +		}
> +	}
> +
> +	/*
> +	 * Wait for the all-clear vector to propagate over the internal
> +	 * interrupt serial bus to the global interrupt detect.
> +	 */
> +	do {
> +		gid = fm10k_read_switch_reg64(sw,
> FM10K_SW_GLOBAL_INTERRUPT_DETECT);
> +	} while (gid & FM10K_SW_GLOBAL_INTERRUPT_DETECT_EPL(eplno));
> +	FM10K_SW_SWITCH_UNLOCK(sw);
> +
> +	/*
> +	 * Proceed with interrupt processing per-external-port.
> +	 */
> +	for (i = 0; i < ports->num_ports; i++) {
> +		port = &ports->ports[i];
> +		if (port->eplno != eplno)
> +			continue;
> +		fm10k_ext_port_intr(port, epl_ip);
> +	}
> +}
> +
> +static void
> +fm10k_ext_port_intr(struct fm10k_ext_port *port, uint32_t epl_ip)
> +{
> +	struct fm10k_switch *sw = port->ports->sw;
> +	struct fm10k_ext_port_lane *lane;
> +	unsigned int i;
> +	uint32_t serdes_ip, data = 0;
> +
> +	for (i = port->first_lane;
> +	     i < port->first_lane + port->num_lanes; i++) {
> +		lane = &port->lanes[i];
> +		if (epl_ip & FM10K_SW_EPL_IP_SERDES_INTERRUPT(i)) {
> +			FM10K_SW_SWITCH_LOCK(sw);
> +			serdes_ip = fm10k_read_switch_reg(sw,
> +			    FM10K_SW_SERDES_IP(port->eplno, i));
> +			serdes_ip &= ~lane->im;
> +			fm10k_write_switch_reg(sw,
> +			    FM10K_SW_SERDES_IP(port->eplno, i), serdes_ip);
> +			if (serdes_ip & FM10K_SW_SERDES_IP_RX_SIGNAL_OK)
> +				data = fm10k_read_switch_reg(sw,
> +				    FM10K_SW_LANE_SERDES_STATUS(port-
> >eplno, i));
> +			FM10K_SW_SWITCH_UNLOCK(sw);
> +
> +			if (serdes_ip & FM10K_SW_SERDES_IP_RX_SIGNAL_OK)
> {
> +				fm10k_sm_send_event(lane->sm,
> +				    (data &
> +
> 	FM10K_SW_LANE_SERDES_STATUS_RX_SIGNAL_OK) ?
> +				    LANE_EVENT(SIGNAL_OK) :
> LANE_EVENT(SIGNAL_NOK));
> +			}
> +
> +			if (serdes_ip & FM10K_SW_SERDES_IP_RX_RDY)
> +				fm10k_sm_send_event(lane->sm,
> +				    LANE_EVENT(RX_PLL_LOCK));
> +
> +			if (serdes_ip & FM10K_SW_SERDES_IP_TX_RDY)
> +				fm10k_sm_send_event(lane->sm,
> +				    LANE_EVENT(TX_PLL_LOCK));
> +		}
> +		else
> +			fm10k_sm_send_event(lane->sm,
> +			    LANE_EVENT(RESTORE_IM));
> +
> +	}
> +}
> +
> +void
> +fm10k_ext_port_up(struct fm10k_ext_port *port)
> +{
> +	fm10k_sm_send_event(port->sm, PORT_EVENT(BRING_UP));
> +}
> +
> +void
> +fm10k_ext_port_down(struct fm10k_ext_port *port)
> +{
> +	fm10k_sm_send_event(port->sm, PORT_EVENT(BRING_DOWN));
> +}
> +
> +unsigned int
> +fm10k_ext_port_isup(struct fm10k_ext_port *port)
> +{
> +	/* no locked needed as we are just inspecting the current value of an int
> */
> +	unsigned int port_state = port->sm->state;
> +
> +	return (port_state == FM10K_SW_EXT_PORT_STATE_UP);
> +}
> +
> +static void
> +fm10k_ext_port_process_event(struct fm10k_sm *sm, uint16_t event)
> +{
> +	struct fm10k_ext_port *port = sm->ctx;
> +	struct fm10k_ext_port_lane *lane;
> +	unsigned int i;
> +	unsigned int lanes_up;
> +
> +#if FM10K_SW_TRACE_ENABLE
> +	FM10K_SW_ERR("port %d event %s in state %s", port->portno,
> +	    fm10k_ext_port_event_name(event),
> +	    fm10k_ext_port_state_name(sm->state));
> +#endif
> +
> +	switch (sm->state) {
> +	case PORT_STATE(DOWN):
> +		if (event == PORT_EVENT(BRING_UP)) {
> +			fm10k_ext_port_phy_enable(port);
> +
> +			for (i = port->first_lane;
> +			     i < port->first_lane + port->num_lanes; i++) {
> +				lane = &port->lanes[i];
> +				fm10k_sm_send_event(lane->sm,
> LANE_EVENT(BRING_UP));
> +			}
> +			sm->state = PORT_STATE(WAITING_FOR_LANES);
> +		}
> +		break;
> +
> +	case PORT_STATE(WAITING_FOR_LANES):
> +		if (event == PORT_EVENT(LANE_UP)) {
> +			lanes_up = 0;
> +			for (i = port->first_lane;
> +			     i < port->first_lane + port->num_lanes; i++) {
> +				lane = &port->lanes[i];
> +				if (lane->sm->state != LANE_STATE(UP))
> +					break;
> +				lanes_up++;
> +			}
> +			if (lanes_up == port->num_lanes)
> +			{
> +				sm->state = PORT_STATE(UP);
> +				FM10K_SW_INFO("Port %d is LINK UP", port-
> >portno);
> +			}
> +		} else if (event == PORT_EVENT(BRING_DOWN)) {
> +			fm10k_ext_port_bring_down(port);
> +		}
> +		break;
> +
> +	case PORT_STATE(UP):
> +		if (event == PORT_EVENT(LANE_DOWN)) {
> +			sm->state = PORT_STATE(WAITING_FOR_LANES);
> +			FM10K_SW_INFO("Port %d is LINK DOWN", port-
> >portno);
> +		} else if (event == PORT_EVENT(BRING_DOWN)) {
> +			fm10k_ext_port_bring_down(port);
> +			FM10K_SW_INFO("Port %d is LINK DOWN", port-
> >portno);
> +		}
> +	}
> +}
> +
> +static void
> +fm10k_ext_port_bring_down(struct fm10k_ext_port *port)
> +{
> +	struct fm10k_sm *sm = port->sm;
> +	struct fm10k_ext_port_lane *lane;
> +	unsigned int i;
> +
> +	sm->state = PORT_STATE(DOWN);
> +
> +	fm10k_ext_port_phy_disable(port);
> +
> +	for (i = port->first_lane;
> +	     i < port->first_lane + port->num_lanes; i++) {
> +		lane = &port->lanes[i];
> +		fm10k_sm_send_event(lane->sm,
> LANE_EVENT(BRING_DOWN));
> +	}
> +}
> +
> +static void
> +fm10k_ext_port_lane_process_event(struct fm10k_sm *sm, uint16_t event)
> +{
> +	struct fm10k_ext_port_lane *lane = sm->ctx;
> + 	struct fm10k_ext_port *port = lane->port;
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	int error;
> +
> +#if FM10K_SW_TRACE_ENABLE
> +	FM10K_SW_ERR("port %d lane %d event %s in state %s", lane->port-
> >portno, lane->rel_laneno,
> +	    fm10k_ext_port_lane_event_name(event),
> +	    fm10k_ext_port_lane_state_name(sm->state));
> +#endif
> +
> +	switch (sm->state) {
> +	case LANE_STATE(DOWN):
> +		if (event == LANE_EVENT(BRING_UP)) {
> +			lane->flags &= ~LANE_FLAGS(PLLS_LOCKED);
> +
> +			/*
> +			 * Clear all pending interrupts.
> +			 */
> +			FM10K_SW_SWITCH_LOCK(sw);
> +			fm10k_write_switch_reg(sw,
> +			    FM10K_SW_SERDES_IP(port->eplno, lane-
> >rel_laneno),
> +			    FM10K_SW_SERDES_IP_ALL);
> +			FM10K_SW_SWITCH_UNLOCK(sw);
> +
> +			error = fm10k_epl_serdes_start_bringup(lane);
> +			if (error == 0) {
> +				sm->state = LANE_STATE(WAIT_PLL_LOCK);
> +
> +				/*
> +				 * Enable PLL lock interrupts.
> +				 */
> +				lane->im &=
> ~(FM10K_SW_SERDES_IM_RX_RDY |
> +				    FM10K_SW_SERDES_IM_TX_RDY);
> +			}
> +		}
> +		break;
> +
> +	case LANE_STATE(WAIT_PLL_LOCK):
> +		if ((event == LANE_EVENT(RX_PLL_LOCK)) ||
> +		    (event == LANE_EVENT(TX_PLL_LOCK))) {
> +			if (event == LANE_EVENT(RX_PLL_LOCK))
> +				lane->flags |= LANE_FLAG(RX_LOCKED);
> +			if (event == LANE_EVENT(TX_PLL_LOCK))
> +				lane->flags |= LANE_FLAG(TX_LOCKED);
> +			if (LANE_FLAGS_SET(lane, PLLS_LOCKED)) {
> +				error =
> fm10k_epl_serdes_continue_bringup(lane);
> +				if (error == 0) {
> +					sm->state =
> LANE_STATE(WAIT_SIGNAL_OK);
> +					/* unmask RX signal OK interrupt */
> +					lane->im |=
> (FM10K_SW_SERDES_IM_RX_RDY |
> +					    FM10K_SW_SERDES_IM_TX_RDY);
> +					lane->im &=
> ~FM10K_SW_SERDES_IM_RX_SIGNAL_OK;
> +				}
> +			}
> +		} else if (event == LANE_EVENT(BRING_DOWN)) {
> +			fm10k_ext_port_disable_lane(lane);
> +		}
> +		break;
> +
> +	case LANE_STATE(WAIT_SIGNAL_OK):
> +		if (event == LANE_EVENT(SIGNAL_OK)) {
> +			sm->state = LANE_STATE(WAIT_DFE_ICAL);
> +
> +			fm10k_epl_serdes_configure_for_dfe_tuning(lane);
> +			fm10k_epl_serdes_start_dfe_ical(lane);
> +
> +			lane->dfe_poll_time_ms = 0;
> +			fm10k_sm_timer_start(sm, LANE_TIMER(DFE_TUNING),
> +			    LANE_POLL(DFE_ICAL));
> +		} else if (event == LANE_EVENT(BRING_DOWN)) {
> +			fm10k_ext_port_disable_lane(lane);
> +		}
> +		break;
> +
> +	case LANE_STATE(WAIT_DFE_ICAL):
> +		if (event == LANE_EVENT(DFE_TUNING_COMPLETE)) {
> +			sm->state = LANE_STATE(WAIT_DFE_PCAL);
> +
> +			fm10k_epl_serdes_start_dfe_pcal(lane);
> +
> +			lane->dfe_poll_time_ms = 0;
> +			fm10k_sm_timer_start(sm, LANE_TIMER(DFE_TUNING),
> +			    LANE_POLL(DFE_PCAL));
> +		} else if ((event == LANE_EVENT(DFE_TUNING_FAILED)) ||
> +		    (event == LANE_EVENT(DFE_TUNING_TIMED_OUT))) {
> +			fm10k_ext_port_restart_lane(lane);
> +		}  else if (event == LANE_EVENT(BRING_DOWN)) {
> +			fm10k_ext_port_disable_lane(lane);
> +		}
> +		break;
> +
> +	case LANE_STATE(WAIT_DFE_PCAL):
> +		if (event == LANE_EVENT(DFE_TUNING_COMPLETE)) {
> +			fm10k_epl_serdes_set_signal_detect(lane,
> +			    FM10K_SW_LANE_OVERRIDE_NORMAL);
> +
> +			sm->state = LANE_STATE(UP);
> +			fm10k_sm_send_event(port->sm,
> PORT_EVENT(LANE_UP));
> +		} else if ((event == LANE_EVENT(DFE_TUNING_FAILED)) ||
> +		    (event == LANE_EVENT(DFE_TUNING_TIMED_OUT)) ||
> +		    (event == LANE_EVENT(SIGNAL_NOK))) {
> +			fm10k_ext_port_restart_lane(lane);
> +		}  else if (event == LANE_EVENT(BRING_DOWN)) {
> +			fm10k_ext_port_disable_lane(lane);
> +		}
> +		break;
> +
> +	case LANE_STATE(UP):
> +		if (event == LANE_EVENT(SIGNAL_NOK)) {
> +			fm10k_ext_port_restart_lane(lane);
> +		}  else if (event == LANE_EVENT(BRING_DOWN)) {
> +			fm10k_ext_port_disable_lane(lane);
> +		}
> +		break;
> +	}
> +
> +	/* Always restore the interrupt mask */
> +	FM10K_SW_SWITCH_LOCK(sw);
> +	fm10k_write_switch_reg(sw,
> +	    FM10K_SW_SERDES_IM(port->eplno,
> +		lane->rel_laneno),
> +	    lane->im);
> +	FM10K_SW_SWITCH_UNLOCK(sw);
> +}
> +
> +static void
> +fm10k_ext_port_lane_process_timer(struct fm10k_sm *sm, uint16_t timer)
> +{
> + 	struct fm10k_ext_port_lane *lane = sm->ctx;
> +	uint32_t status;
> +
> +	switch (sm->state) {
> +	case LANE_STATE(WAIT_DFE_ICAL):
> +		if (timer == LANE_TIMER(DFE_TUNING)) {
> +			lane->dfe_poll_time_ms += LANE_POLL(DFE_ICAL);
> +			fm10k_epl_serdes_dfe_ical_status(lane, &status);
> +
> +			if (status ==
> FM10K_SW_SERDES_DFE_ICAL_IN_PROGRESS) {
> +				if (lane->dfe_poll_time_ms <
> +				    LANE_TIMEOUT(DFE_ICAL))
> +					fm10k_sm_timer_start(sm,
> +					    LANE_TIMER(DFE_TUNING),
> +					    LANE_POLL(DFE_ICAL));
> +				else
> +					fm10k_sm_send_event(sm,
> +
> LANE_EVENT(DFE_TUNING_TIMED_OUT));
> +			} else if (status ==
> FM10K_SW_SERDES_DFE_ICAL_CONVERGED)
> +				fm10k_sm_send_event(sm,
> +				    LANE_EVENT(DFE_TUNING_COMPLETE));
> +			else
> +				fm10k_sm_send_event(sm,
> +				    LANE_EVENT(DFE_TUNING_FAILED));
> +		}
> +		break;
> +
> +	case LANE_STATE(WAIT_DFE_PCAL):
> +		if (timer == LANE_TIMER(DFE_TUNING)) {
> +			lane->dfe_poll_time_ms += LANE_POLL(DFE_PCAL);
> +
> +			fm10k_epl_serdes_dfe_pcal_status(lane, &status);
> +			if (status ==
> FM10K_SW_SERDES_DFE_PCAL_IN_PROGRESS) {
> +				if (lane->dfe_poll_time_ms <
> +				    LANE_TIMEOUT(DFE_PCAL))
> +					fm10k_sm_timer_start(sm,
> +					    LANE_TIMER(DFE_TUNING),
> +					    LANE_POLL(DFE_PCAL));
> +				else
> +					fm10k_sm_send_event(sm,
> +
> LANE_EVENT(DFE_TUNING_TIMED_OUT));
> +			} else
> +				fm10k_sm_send_event(sm,
> +				    LANE_EVENT(DFE_TUNING_COMPLETE));
> +		}
> +		break;
> +	}
> +}
> +
> +static void
> +fm10k_ext_port_restart_lane(struct fm10k_ext_port_lane *lane)
> +{
> +	struct fm10k_sm *sm = lane->sm;
> +	struct fm10k_ext_port *port = lane->port;
> +	int error;
> +
> +	error = fm10k_epl_serdes_start_bringup(lane);
> +	if (error == 0) {
> +		sm->state = LANE_STATE(WAIT_PLL_LOCK);
> +
> +		/*
> +		 * Enable PLL lock interrupts.
> +		 */
> +		lane->flags &=
> ~FM10K_SW_EXT_PORT_LANE_FLAGS_PLLS_LOCKED;
> +		lane->im |= FM10K_SW_SERDES_IM_RX_SIGNAL_OK;
> +		lane->im = ~(FM10K_SW_SERDES_IM_RX_RDY |
> +		    FM10K_SW_SERDES_IM_TX_RDY);
> +	}
> +
> +	fm10k_sm_send_event(port->sm, PORT_EVENT(LANE_DOWN));
> +}
> +
> +static void
> +fm10k_ext_port_disable_lane(struct fm10k_ext_port_lane *lane)
> +{
> +	struct fm10k_sm *sm = lane->sm;
> +
> +	fm10k_sm_timer_cancel(sm, LANE_TIMER(DFE_TUNING));
> +	fm10k_epl_serdes_disable(lane);
> +
> +	/*
> +	 * Disable all interrupts.
> +	 */
> +	lane->im = FM10K_SW_SERDES_IM_ALL;
> +
> +	sm->state = LANE_STATE(DOWN);
> +}
> +
> +void
> +fm10k_ext_port_eplidx_lane(struct fm10k_ext_ports *ports,
> +    unsigned int ext_port_idx, unsigned int *eplidx, unsigned int *lane)
> +{
> +	FM10K_SW_ASSERT(ext_port_idx < ports->num_ports,
> +	    ("ext_port_idx out of range"));
> +
> +	*eplidx = ext_port_idx / ports->ports_per_epl;
> +	*lane = ext_port_idx % ports->ports_per_epl;
> +}
> +
> +
> +static void
> +fm10k_ext_port_phy_enable(struct fm10k_ext_port *port)
> +{
> +	struct fm10k_switch *sw = port->ports->sw;
> +	struct fm10k_device_info *cfg = sw->info;
> +
> +	switch (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice)) {
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QS41):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QS41):
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QS43):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QS43):
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QL4):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QL4):
> +		FM10K_SW_I2C_LOCK(sw->i2c);
> +		/*
> +		 * Set up the first PCA9545 mux so we can get at the
> +		 * PCA9505 that the QSFP control lines are connected
> +		 * to.
> +		 */
> +		fm10k_i2c_write8(sw->i2c, 0x70, 0x04);
> +
> +		/*
> +		 * Configure the I/O pins on the PCA9505 that are
> +		 * connected to LpMode and ResetL on the QSFP as
> +		 * outputs, and set LpMode to low to enable high
> +		 * power mode and set ResetL to high to take it out
> +		 * of reset.
> +		 */
> +		if (port->portno == 0) {
> +			fm10k_i2c_write16(sw->i2c, 0x20, 0x18, 0xf6);
> +			fm10k_i2c_write16(sw->i2c, 0x20, 0x08, 0x08);
> +		} else {
> +			fm10k_i2c_write16(sw->i2c, 0x20, 0x19, 0xf6);
> +			fm10k_i2c_write16(sw->i2c, 0x20, 0x09, 0x08);
> +		}
> +		FM10K_SW_I2C_UNLOCK(sw->i2c);
> +		break;
> +
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4_REV_2):
> +			FM10K_SW_I2C_LOCK(sw->i2c);
> +			/*
> +			 * Set up the first PCA9545 mux so we can get at the
> PCA9505
> +			 * that the QSFP control lines are connected to.
> +			 */
> +			fm10k_i2c_write8(sw->i2c, 0x70, 0x01);
> +
> +			/*
> +			 * Configure the I/O pins on the PCA9505 that are
> +			 * connected to LpMode and ResetL on the QSFP as
> +			 * outputs, and set LpMode to low to enable high
> +			 * power mode and set ResetL to high to take it out
> +			 * of reset.
> +			 */
> +			if (port->portno == 0) {
> +				fm10k_i2c_write16(sw->i2c, 0x20, 0x18, 0xf6);
> +				fm10k_i2c_write16(sw->i2c, 0x20, 0x08, 0x08);
> +			} else {
> +				fm10k_i2c_write16(sw->i2c, 0x20, 0x19, 0xf6);
> +				fm10k_i2c_write16(sw->i2c, 0x20, 0x09, 0x08);
> +			}
> +			FM10K_SW_I2C_UNLOCK(sw->i2c);
> +			break;
> +
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRL_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4):
> +		FM10K_SW_I2C_LOCK(sw->i2c);
> +
> +		/*
> +		 * Configure the I/O pins on the PCA9538 that are
> +		 * connected to LpMode and ResetL on the QSFP as
> +		 * outputs, and set LpMode to low to enable high
> +		 * power mode and set ResetL to high to take it out
> +		 * of reset.
> +		 */
> +		if (port->portno == 0) {
> +			fm10k_i2c_write16(sw->i2c, 0x60, 0x03, 0xcf);
> +			fm10k_i2c_write16(sw->i2c, 0x60, 0x01, 0x10);
> +		} else {
> +			fm10k_i2c_write16(sw->i2c, 0x61, 0x03, 0xcf);
> +			fm10k_i2c_write16(sw->i2c, 0x61, 0x01, 0x10);
> +		}
> +		FM10K_SW_I2C_UNLOCK(sw->i2c);
> +		break;
> +
> +	default:
> +		FM10K_SW_ERR(
> +		    "don't know how to enable phy for this card "
> +		    "(subvendor=0x%04x subdevice=0x%04x)\n",
> +		    cfg->subvendor, cfg->subdevice);
> +		break;
> +	}
> +}
> +
> +static void
> +fm10k_ext_port_phy_disable(struct fm10k_ext_port *port)
> +{
> +	struct fm10k_switch *sw = port->ports->sw;
> +	struct fm10k_device_info *cfg = sw->info;
> +
> +	switch (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice)) {
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QS41):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QS41):
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QS43):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QS43):
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QL4):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QL4):
> +		FM10K_SW_I2C_LOCK(sw->i2c);
> +		/*
> +		 * Set up the first PCA9545 mux so we can get at the PCA9505
> +		 * that the QSFP control lines are connected to.
> +		 */
> +		fm10k_i2c_write8(sw->i2c, 0x70, 0x04);
> +
> +		/*
> +		 * Configure the I/O pins on the PCA9505 that are
> +		 * connected to LpMode and ResetL on the QSFP as
> +		 * outputs, and set LpMode to high to disable high
> +		 * power mode and set ResetL to low to put it in
> +		 * reset.
> +		 */
> +		if (port->portno == 0) {
> +			fm10k_i2c_write16(sw->i2c, 0x20, 0x18, 0xf6);
> +			fm10k_i2c_write16(sw->i2c, 0x20, 0x08, 0x01);
> +		} else {
> +			fm10k_i2c_write16(sw->i2c, 0x20, 0x19, 0xf6);
> +			fm10k_i2c_write16(sw->i2c, 0x20, 0x09, 0x01);
> +		}
> +		FM10K_SW_I2C_UNLOCK(sw->i2c);
> +		break;
> +
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4_REV_2):
> +	FM10K_SW_I2C_LOCK(sw->i2c);
> +	/*
> +	 * Set up the first PCA9545 mux so we can get at the PCA9505
> +	 * that the QSFP control lines are connected to.
> +	 */
> +	fm10k_i2c_write8(sw->i2c, 0x70, 0x01);
> +
> +	/*
> +	 * Configure the I/O pins on the PCA9505 that are
> +	 * connected to LpMode and ResetL on the QSFP as
> +	 * outputs, and set LpMode to high to disable high
> +	 * power mode and set ResetL to low to put it in
> +	 * reset.
> +	 */
> +	if (port->portno == 0) {
> +		fm10k_i2c_write16(sw->i2c, 0x20, 0x18, 0xf6);
> +		fm10k_i2c_write16(sw->i2c, 0x20, 0x08, 0x01);
> +	} else {
> +		fm10k_i2c_write16(sw->i2c, 0x20, 0x19, 0xf6);
> +		fm10k_i2c_write16(sw->i2c, 0x20, 0x09, 0x01);
> +	}
> +	FM10K_SW_I2C_UNLOCK(sw->i2c);
> +	break;
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRL_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4):
> +		FM10K_SW_I2C_LOCK(sw->i2c);
> +		/*
> +		 * Configure the I/O pins on the PCA9538 that are
> +		 * connected to LpMode and ResetL on the QSFP as
> +		 * outputs, and set LpMode to high to disable high
> +		 * power mode and set ResetL to low to put it in
> +		 * reset.
> +		 */
> +		if (port->portno == 0) {
> +			fm10k_i2c_write16(sw->i2c, 0x60, 0x03, 0xcf);
> +			fm10k_i2c_write16(sw->i2c, 0x60, 0x01, 0x20);
> +			FM10K_SW_ERR("%s config PCA9538 %#x set LpMode",
> __func__, 0x60);
> +		} else {
> +			fm10k_i2c_write16(sw->i2c, 0x61, 0x03, 0xcf);
> +			fm10k_i2c_write16(sw->i2c, 0x61, 0x01, 0x20);
> +			FM10K_SW_ERR("%s config PCA9538 %#x set LpMode",
> __func__, 0x61);
> +		}
> +		FM10K_SW_I2C_UNLOCK(sw->i2c);
> +		break;
> +
> +	default:
> +		FM10K_SW_ERR(
> +		    "don't know how to disable phy for this card "
> +		    "(subvendor=0x%04x subdevice=0x%04x)\n",
> +		    cfg->subvendor, cfg->subdevice);
> +		break;
> +	}
> +}
> +
> +
> +#if FM10K_SW_TRACE_ENABLE
> +
> +#define RETURN_STRING(val_, str_) \
> +		case val_: return(str_)
> +#define RETURN_PORT_STATE_STR(s_) \
> +		RETURN_STRING(FM10K_SW_EXT_PORT_STATE_##s_, #s_)
> +#define RETURN_PORT_EVENT_STR(e_) \
> +		RETURN_STRING(FM10K_SW_EXT_PORT_EVENT_##e_, #e_)
> +#define RETURN_PORT_LANE_STATE_STR(s_) \
> +		RETURN_STRING(FM10K_SW_EXT_PORT_LANE_STATE_##s_,
> #s_)
> +#define RETURN_PORT_LANE_EVENT_STR(e_) \
> +		RETURN_STRING(FM10K_SW_EXT_PORT_LANE_EVENT_##e_,
> #e_)
> +#define RETURN_PORT_LANE_TIMER_STR(t_) \
> +		RETURN_STRING(FM10K_SW_EXT_PORT_LANE_TIMER_##t_,
> #t_)
> +
> +static const char*
> +fm10k_ext_port_state_name(enum fm10k_ext_port_state state)
> +{
> +	switch (state) {
> +		RETURN_PORT_STATE_STR(DOWN);
> +		RETURN_PORT_STATE_STR(WAITING_FOR_LANES);
> +		RETURN_PORT_STATE_STR(UP);
> +	}
> +	return ("");
> +}
> +
> +static const char*
> +fm10k_ext_port_event_name(enum fm10k_ext_port_event event)
> +{
> +	switch (event) {
> +		RETURN_PORT_EVENT_STR(BRING_UP);
> +		RETURN_PORT_EVENT_STR(BRING_DOWN);
> +		RETURN_PORT_EVENT_STR(LANE_UP);
> +		RETURN_PORT_EVENT_STR(LANE_DOWN);
> +	case FM10K_SW_EXT_PORT_NUM_EVENTS: break;
> +	}
> +	return ("");
> +}
> +
> +static const char*
> +fm10k_ext_port_lane_state_name(enum fm10k_ext_port_lane_state state)
> +{
> +	switch (state) {
> +		RETURN_PORT_LANE_STATE_STR(DOWN);
> +		RETURN_PORT_LANE_STATE_STR(WAIT_PLL_LOCK);
> +		RETURN_PORT_LANE_STATE_STR(WAIT_SIGNAL_OK);
> +		RETURN_PORT_LANE_STATE_STR(WAIT_DFE_ICAL);
> +		RETURN_PORT_LANE_STATE_STR(WAIT_DFE_PCAL);
> +		RETURN_PORT_LANE_STATE_STR(UP);
> +	}
> +	return ("");
> +}
> +
> +static const char*
> +fm10k_ext_port_lane_event_name(enum fm10k_ext_port_lane_event event)
> +{
> +	switch (event) {
> +		RETURN_PORT_LANE_EVENT_STR(BRING_UP);
> +		RETURN_PORT_LANE_EVENT_STR(RX_PLL_LOCK);
> +		RETURN_PORT_LANE_EVENT_STR(TX_PLL_LOCK);
> +		RETURN_PORT_LANE_EVENT_STR(SIGNAL_OK);
> +		RETURN_PORT_LANE_EVENT_STR(SIGNAL_NOK);
> +		RETURN_PORT_LANE_EVENT_STR(DFE_TUNING_COMPLETE);
> +		RETURN_PORT_LANE_EVENT_STR(DFE_TUNING_FAILED);
> +		RETURN_PORT_LANE_EVENT_STR(DFE_TUNING_TIMED_OUT);
> +		RETURN_PORT_LANE_EVENT_STR(RESTORE_IM);
> +		RETURN_PORT_LANE_EVENT_STR(BRING_DOWN);
> +	case FM10K_SW_EXT_PORT_LANE_NUM_EVENTS: break;
> +	}
> +	return ("");
> +}
> +
> +static const char*
> +fm10k_ext_port_lane_timer_name(enum fm10k_ext_port_lane_timer timer)
> +{
> +	switch (timer) {
> +		RETURN_PORT_LANE_TIMER_STR(PLL_LOCK);
> +		RETURN_PORT_LANE_TIMER_STR(SIGNAL_OK);
> +		RETURN_PORT_LANE_TIMER_STR(DFE_TUNING);
> +	case FM10K_SW_EXT_PORT_LANE_NUM_TIMERS: break;
> +	}
> +	return ("");
> +}
> +#endif /* FM10K_SW_TRACE_ENABLE */
> diff --git a/drivers/net/fm10k/switch/fm10k_ext_port.h
> b/drivers/net/fm10k/switch/fm10k_ext_port.h
> new file mode 100644
> index 0000000..91312a2
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_ext_port.h
> @@ -0,0 +1,145 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_SW_EXT_PORT_H_
> +#define _FM10K_SW_EXT_PORT_H_
> +
> +#include "fm10k_regs.h"
> +#include "fm10k_sm.h"
> +#include "fm10k_sbus.h"
> +#include "fm10k_switch.h"
> +
> +
> +struct fm10k_sbus;
> +struct fm10k_switch;
> +
> +#define FM10K_SW_TRACE_ENABLE 0
> +
> +enum fm10k_ext_port_lane_state {
> +	FM10K_SW_EXT_PORT_LANE_STATE_DOWN,
> +	FM10K_SW_EXT_PORT_LANE_STATE_WAIT_PLL_LOCK,
> +	FM10K_SW_EXT_PORT_LANE_STATE_WAIT_SIGNAL_OK,
> +	FM10K_SW_EXT_PORT_LANE_STATE_WAIT_DFE_ICAL,
> +	FM10K_SW_EXT_PORT_LANE_STATE_WAIT_DFE_PCAL,
> +	FM10K_SW_EXT_PORT_LANE_STATE_UP
> +};
> +
> +enum fm10k_ext_port_lane_event {
> +	FM10K_SW_EXT_PORT_LANE_EVENT_BRING_UP,
> +	FM10K_SW_EXT_PORT_LANE_EVENT_RX_PLL_LOCK,
> +	FM10K_SW_EXT_PORT_LANE_EVENT_TX_PLL_LOCK,
> +	FM10K_SW_EXT_PORT_LANE_EVENT_SIGNAL_OK,
> +	FM10K_SW_EXT_PORT_LANE_EVENT_SIGNAL_NOK,
> +	FM10K_SW_EXT_PORT_LANE_EVENT_DFE_TUNING_COMPLETE,
> +	FM10K_SW_EXT_PORT_LANE_EVENT_DFE_TUNING_FAILED,
> +	FM10K_SW_EXT_PORT_LANE_EVENT_DFE_TUNING_TIMED_OUT,
> +	FM10K_SW_EXT_PORT_LANE_EVENT_RESTORE_IM,
> +	FM10K_SW_EXT_PORT_LANE_EVENT_BRING_DOWN,
> +
> +	FM10K_SW_EXT_PORT_LANE_NUM_EVENTS
> +};
> +
> +enum fm10k_ext_port_lane_timer {
> +	FM10K_SW_EXT_PORT_LANE_TIMER_PLL_LOCK,
> +	FM10K_SW_EXT_PORT_LANE_TIMER_SIGNAL_OK,
> +	FM10K_SW_EXT_PORT_LANE_TIMER_DFE_TUNING,
> +
> +	FM10K_SW_EXT_PORT_LANE_NUM_TIMERS
> +};
> +
> +#define FM10K_SW_EXT_PORT_LANE_PLL_LOCK_TIMEOUT_MS		2000
> +#define FM10K_SW_EXT_PORT_LANE_SIGNAL_OK_TIMEOUT_MS
> 	2000
> +#define FM10K_SW_EXT_PORT_LANE_DFE_ICAL_POLL_MS
> 	200
> +#define FM10K_SW_EXT_PORT_LANE_DFE_ICAL_TIMEOUT_MS		3000
> +#define FM10K_SW_EXT_PORT_LANE_DFE_PCAL_POLL_MS
> 	100
> +#define FM10K_SW_EXT_PORT_LANE_DFE_PCAL_TIMEOUT_MS
> 	2000
> +
> +
> +enum fm10k_ext_port_state {
> +	FM10K_SW_EXT_PORT_STATE_DOWN,
> +	FM10K_SW_EXT_PORT_STATE_WAITING_FOR_LANES,
> +	FM10K_SW_EXT_PORT_STATE_UP
> +};
> +
> +enum fm10k_ext_port_event {
> +	FM10K_SW_EXT_PORT_EVENT_BRING_UP,
> +	FM10K_SW_EXT_PORT_EVENT_BRING_DOWN,
> +	FM10K_SW_EXT_PORT_EVENT_LANE_UP,
> +	FM10K_SW_EXT_PORT_EVENT_LANE_DOWN,
> +
> +	FM10K_SW_EXT_PORT_NUM_EVENTS
> +};
> +
> +struct fm10k_ext_port;
> +
> +struct fm10k_ext_port_lane {
> +	struct fm10k_ext_port *port;
> +	struct fm10k_sm *sm;
> +	uint32_t im;
> +	uint16_t dfe_poll_time_ms;
> +	uint8_t abs_laneno;
> +	uint8_t rel_laneno;
> +	uint8_t flags;
> +};
> +
> +#define FM10K_SW_EXT_PORT_LANE_FLAG_RX_LOCKED		0x01
> +#define FM10K_SW_EXT_PORT_LANE_FLAG_TX_LOCKED		0x02
> +
> +#define FM10K_SW_EXT_PORT_LANE_FLAGS_PLLS_LOCKED
> 	(FM10K_SW_EXT_PORT_LANE_FLAG_RX_LOCKED |
> FM10K_SW_EXT_PORT_LANE_FLAG_TX_LOCKED)
> +
> +struct fm10k_ext_ports;
> +
> +struct fm10k_ext_port {
> +	struct fm10k_ext_ports *ports;
> +	struct fm10k_sm *sm;
> +	struct fm10k_ext_port_lane lanes[FM10K_SW_EPL_LANES];
> +	char name[10];
> +	uint8_t portno;
> +	uint8_t eplno;
> +	uint8_t lport; 		/* filled in by switch */
> +	uint8_t first_lane; /* range is [0..3] */
> +	uint8_t num_lanes;
> +	uint8_t is_quad;
> +	uint8_t lane_speed;
> +	uint8_t last_led_flags;
> +	uint32_t an_im;
> +	uint32_t link_im;
> +};
> +
> +#define FM10K_SW_EXT_PORT_LED_FLAG_UP	0x01
> +#define FM10K_SW_EXT_PORT_LED_FLAG_ACTIVE	0x02
> +
> +struct fm10k_ext_ports {
> +	struct fm10k_switch *sw;
> +	struct fm10k_ext_port *ports;
> +	uint16_t epl_mask;
> +	uint8_t num_ports;
> +	uint8_t ports_per_epl;
> +};
> +
> +#define FM10K_SW_EXT_PORTS_EPL_USED(p_, n_)		((p_)-
> >epl_mask & (1 << (n_)))
> +
> +struct fm10k_ext_ports *fm10k_ext_ports_attach(struct fm10k_switch *sw);
> +void fm10k_ext_ports_detach(struct fm10k_ext_ports *ports);
> +unsigned int fm10k_ext_ports_epl_intrs(struct fm10k_ext_ports *ports,
> uint64_t gid);
> +void fm10k_ext_port_up(struct fm10k_ext_port *port);
> +void fm10k_ext_port_down(struct fm10k_ext_port *port);
> +unsigned int fm10k_ext_port_isup(struct fm10k_ext_port *port);
> +void fm10k_ext_port_eplidx_lane(struct fm10k_ext_ports *ports,
> +	    unsigned int ext_port_idx, unsigned int *eplidx, unsigned int *lane);
> +
> +#endif /* _FM10K_SW_EXT_PORT_H_ */
> diff --git a/drivers/net/fm10k/switch/fm10k_ffu.c
> b/drivers/net/fm10k/switch/fm10k_ffu.c
> new file mode 100644
> index 0000000..dde4090
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_ffu.c
> @@ -0,0 +1,1031 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#include "../base/fm10k_type.h"
> +#include "../base/fm10k_osdep.h"
> +
> +#include "../fm10k.h"
> +#include "../fm10k_logs.h"
> +#include "fm10k_debug.h"
> +#include "fm10k_regs.h"
> +#include "fm10k_switch.h"
> +#include "fm10k_config.h"
> +#include "fm10k_ffu.h"
> +#include "fm10k_stats.h"
> +
> +/*
> + * one SLICE for 40bits SEL
> + * SLICE 28   FOR SEL SGLORT(16bits) and VLAN(16bits)
> + *            FOR ACT ROUTE
> + * SLICE 29   FOR SEL ETHER_TYPE(16bits)
> + * 			  FOR ACT MIRROR | SET_VLAN
> + * SLICE 30   FOR SEL MPLS_LABEL0(32bits)
> + * SLICE 31   FOR SEL MPLS_LABEL1(32bits)
> + */
> +#define FM10K_FFU_SLICE_START			28
> +#define FM10K_FFU_SLICE_SGLORT_VID		28
> +#define FM10K_FFU_SLICE_ETYPE_VID2		29
> +#define FM10K_FFU_SLICE_MPLS_LABEL0		30
> +#define FM10K_FFU_SLICE_MPLS_LABEL1		31
> +
> +#define FM10K_FFU_SLICE_SGLORT_VLAN_CFG	    \
> +		(FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_0,
> FM10K_SW_FFU_MUX_SEL_SGLORT) | \
> +	     FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_1,
> FM10K_SW_FFU_MUX_SEL_SGLORT) | \
> +	     FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_2,
> FM10K_SW_FFU_MUX_SEL_VPRI_VID) | \
> +		 FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_3,
> FM10K_SW_FFU_MUX_SEL_VPRI_VID) | \
> +		 FM10K_SW_FFU_SLICE_CFG_START_ACTION |
> FM10K_SW_FFU_SLICE_CFG_START_COMPARE | \
> +	     FM10K_SW_FFU_SLICE_CFG_VALID_LOW)
> +#define FM10K_FFU_SLICE_ETHER_TYPE_CFG	    \
> +		(FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_0,
> FM10K_SW_FFU_MUX_SEL_L2_TYPE) | \
> +	     FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_1,
> FM10K_SW_FFU_MUX_SEL_L2_TYPE) | \
> +	     FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_2,
> FM10K_SW_FFU_MUX_SEL_VPRI2_VID2) | \
> +		 FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_3,
> FM10K_SW_FFU_MUX_SEL_VPRI2_VID2) | \
> +		 FM10K_SW_FFU_SLICE_CFG_VALID_LOW)
> +#define FM10K_FFU_SLICE_MPLS_LABEL0_CFG	    \
> +		(FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_0,
> FM10K_SW_FFU_MUX_SEL_L3_SIP_127_96) | \
> +	     FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_1,
> FM10K_SW_FFU_MUX_SEL_L3_SIP_127_96) | \
> +	     FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_2,
> FM10K_SW_FFU_MUX_SEL_L3_SIP_127_96) | \
> +		 FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_3,
> FM10K_SW_FFU_MUX_SEL_L3_SIP_127_96) | \
> +		 FM10K_SW_FFU_SLICE_CFG_START_COMPARE |
> FM10K_SW_FFU_SLICE_CFG_VALID_LOW)
> +#define FM10K_FFU_SLICE_MPLS_LABEL1_CFG	    \
> +		(FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_0,
> FM10K_SW_FFU_MUX_SEL_L3_SIP_95_64) | \
> +	     FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_1,
> FM10K_SW_FFU_MUX_SEL_L3_SIP_95_64) | \
> +	     FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_2,
> FM10K_SW_FFU_MUX_SEL_L3_SIP_95_64) | \
> +		 FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_3,
> FM10K_SW_FFU_MUX_SEL_L3_SIP_95_64) | \
> +		 FM10K_SW_FFU_SLICE_CFG_START_COMPARE |
> FM10K_SW_FFU_SLICE_CFG_VALID_LOW)
> +
> +static uint64_t fm10k_ffu_slice_cfgs[4] = {
> +		FM10K_FFU_SLICE_SGLORT_VLAN_CFG,
> +		FM10K_FFU_SLICE_ETHER_TYPE_CFG,
> +		FM10K_FFU_SLICE_MPLS_LABEL0_CFG,
> +		FM10K_FFU_SLICE_MPLS_LABEL1_CFG
> +};
> +
> +#define FM10K_FFU_INIT_PRINT(cfg, ...)		do{ \
> +	if(FM10K_CONFIG_CHECK_DEBUG(cfg,
> FM10K_CONFIG_DEBUG_FFU_INIT)) \
> +		printf(__VA_ARGS__); \
> +}while(0)
> +
> +#define FM10K_FFU_RULE_PRINT(cfg, ...)		do{ \
> +	if(FM10K_CONFIG_CHECK_DEBUG(cfg,
> FM10K_CONFIG_DEBUG_FFU_RULE)) \
> +		printf(__VA_ARGS__); \
> +}while(0)
> +
> +#define FM10K_FFU_CNT_INDEX(x)
> 	(FM10K_SW_FFU_CNT_START+x)
> +
> +#define FM10K_FFU_FLOW_START		10
> +#define FM10K_FFU_MIRROR_PROFILE	1
> +
> +#define FM10K_FFU_SGLORT_TYPE_NULL 	0
> +#define FM10K_FFU_SGLORT_TYPE_EPL 	1
> +#define FM10K_FFU_SGLORT_TYPE_PF 	2
> +#define FM10K_FFU_SGLORT_TYPE_PFS 	3
> +#define FM10K_FFU_SGLORT_TYPE_DPDK 	4
> +
> +struct fm10k_ffu_rule_data{
> +	uint16_t sglort_type;
> +	uint16_t cond_sglort;
> +	uint16_t cond_vlan;
> +	uint16_t act_dglort;
> +	uint16_t act_vlan;
> +	uint16_t bypass_dglort;
> +	uint16_t bypass_vlan;
> +};
> +
> +
> +static uint8_t fm10k_ffu_bitmap[FM10K_FFU_RULE_MAX/8];
> +static uint8_t
> +fm10k_ffu_rule_get_bit(int id)
> +{
> +	int num = id/8;
> +	int offset = id%8;
> +
> +	return (fm10k_ffu_bitmap[num]>>offset)&0x1;
> +}
> +
> +static void
> +fm10k_ffu_rule_set_bit(int id, uint8_t bit)
> +{
> +	int num = id/8;
> +	int offset = id%8;
> +	uint8_t tmp = fm10k_ffu_bitmap[num];
> +	uint8_t data = 1;
> +
> +	if (bit == 0)
> +		fm10k_ffu_bitmap[num] = tmp & ~(data<<offset);
> +	else
> +		fm10k_ffu_bitmap[num] |= (data<<offset);
> +}
> +
> +static int
> +fm10k_ffu_rule_alloc(void)
> +{
> +	int i;
> +
> +	for (i = FM10K_FFU_FLOW_START; i < FM10K_FFU_RULE_MAX; i++)
> +	{
> +		if (fm10k_ffu_rule_get_bit(i) != 0)
> +			continue;
> +		fm10k_ffu_rule_set_bit(i, 1);
> +		return i;
> +	}
> +	return -1;
> +}
> +
> +static void
> +fm10k_ffu_rule_free(int id)
> +{
> +	fm10k_ffu_rule_set_bit(id, 0);
> +}
> +
> +static void
> +fm10k_ffu_always_mismatch(struct fm10k_switch *sw, unsigned int slice,
> +    unsigned int idx)
> +{
> +	uint64_t temp64;
> +
> +	temp64 =
> +	    FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY, ~0ULL) |
> +	    FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY_TOP, ~0ULL);
> +	fm10k_write_switch_reg128(sw, FM10K_SW_FFU_SLICE_TCAM(slice,
> idx),
> +	    temp64, temp64);
> +}
> +
> +static void
> +fm10k_ffu_route_dglort(struct fm10k_switch *sw, unsigned int slice,
> +    unsigned int idx, uint16_t sglort, uint16_t dglort)
> +{
> +	uint64_t temp64, temp64_2;
> +
> +	/*
> +	 * Set the key to exact match on the 16 SGLORT bits and
> +	 * always match everywhere else.
> +	 */
> +	temp64 = FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY,
> sglort);
> +	temp64_2 = FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY,
> ~sglort & 0xffff);
> +	fm10k_write_switch_reg128(sw, FM10K_SW_FFU_SLICE_TCAM(slice,
> idx),
> +	    temp64_2, temp64);
> +
> +	/*
> +	 * Set the corresponding SRAM entry to ROUTE_GLORT to the
> +	 * corresponding DGLORT.
> +	 */
> +	temp64 = 0x40;
> +	temp64 = temp64<<32 |
> +
> FM10K_SW_MAKE_REG_FIELD(FFU_SLICE_SRAM_ROUTE_GLORT_DGLORT,
> dglort);
> +	temp64 |= FM10K_SW_MAKE_REG_FIELD64(
> +	    FFU_SLICE_SRAM_COMMAND,
> +	    FM10K_SW_FFU_SLICE_SRAM_COMMAND_ROUTE_GLORT);
> +	/*
> +	 * 11.5.4.2 FFU_SLICE_SRAM[0..31][0..1023]
> +	 */
> +	temp64_2 = FM10K_SW_FFU_CNT_BANK<<(35-23) |
> (FM10K_SW_FFU_CNT_START+idx);
> +	temp64 |= temp64_2<<23;
> +	fm10k_write_switch_reg64(sw, FM10K_SW_FFU_SLICE_SRAM(slice, idx),
> +	    temp64);
> +
> +}
> +
> +
> +static void
> +fm10k_ffu_set_dest_glort_mask(struct fm10k_switch *sw, unsigned int idx,
> uint16_t dglort, uint64_t dport_mask)
> +{
> +	uint64_t temp64;
> +	unsigned int multiple_dports;
> +	unsigned int num_dports;
> +	unsigned int amplification_factor;
> +	unsigned int hashed_entries;
> +	unsigned int i, j;
> +
> +	multiple_dports = (dport_mask & (dport_mask - 1));
> +
> +	FM10K_FFU_INIT_PRINT(sw->dpdk_cfg, "%s set glort %#x to port ",
> __func__, dglort);
> +	/*
> +	 * Create an exact-match key for the given DGLORT in the DGLORT CAM.
> +	 */
> +	fm10k_write_switch_reg(sw, FM10K_SW_GLORT_CAM(idx),
> +	    FM10K_SW_MAKE_REG_FIELD(GLORT_CAM_KEY, dglort) |
> +	    FM10K_SW_MAKE_REG_FIELD(GLORT_CAM_KEY_INVERT, ~dglort));
> +
> +	if (multiple_dports) {
> +		/*
> +		 * Create a pair of entries and use the hash value to select
> +		 * among them.
> +		 */
> +		num_dports = 0;
> +		for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++)
> +			if (dport_mask & (1ULL << i))
> +			{
> +				num_dports++;
> +				FM10K_FFU_INIT_PRINT(sw->dpdk_cfg, " %d",
> i);
> +			}
> +		FM10K_FFU_INIT_PRINT(sw->dpdk_cfg, "\n");
> +
> +		/*
> +		 * Create multiple entries for each dport to increase the
> +		 * hash modulus and capture more hash entropy.  The maximum
> +		 * number of hashed entries is 16.
> +		 */
> +		amplification_factor = 16 / num_dports;
> +		hashed_entries = num_dports * amplification_factor;
> +		temp64 = FM10K_SW_MAKE_REG_FIELD64(
> +		    GLORT_RAM_STRICT,
> +		    FM10K_SW_GLORT_RAM_STRICT_HASHED);
> +		temp64 |=
> FM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_DEST_INDEX, sw-
> >glort_dest_table_idx);
> +		temp64 |=
> FM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_DEST_COUNT, hashed_entries);
> +		fm10k_write_switch_reg64(sw, FM10K_SW_GLORT_RAM(idx),
> temp64);
> +
> +		for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++)
> +			if (dport_mask & (1ULL << i))
> +				for (j = 0; j < amplification_factor; j++) {
> +					fm10k_write_switch_reg64(sw,
> +
> FM10K_SW_GLORT_DEST_TABLE(sw->glort_dest_table_idx),
> +					    FM10K_SW_MAKE_REG_FIELD64(
> +						GLORT_DEST_TABLE_MASK,
> +						(1ULL << i)));
> +					sw->glort_dest_table_idx++;
> +				}
> +	} else {
> +		/*
> +		 * Set the corresponding entry in the DGLORT map RAM to use
> +		 * strict indexing straight into the DEST_TABLE, then write
> +		 * the corresponding destination port in the DEST_TABLE.
> +		 */
> +
> +		temp64 = FM10K_SW_MAKE_REG_FIELD64(
> +		    GLORT_RAM_STRICT,
> +		    FM10K_SW_GLORT_RAM_STRICT_STRICT);
> +		temp64 |=
> FM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_DEST_INDEX, sw-
> >glort_dest_table_idx);
> +		fm10k_write_switch_reg64(sw, FM10K_SW_GLORT_RAM(idx),
> temp64);
> +
> +		fm10k_write_switch_reg64(sw,
> FM10K_SW_GLORT_DEST_TABLE(sw->glort_dest_table_idx),
> +		    FM10K_SW_MAKE_REG_FIELD64(
> +			GLORT_DEST_TABLE_MASK,
> +			dport_mask));
> +		sw->glort_dest_table_idx++;
> +		for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++)
> +			if (dport_mask & (1ULL << i))
> +			{
> +				FM10K_FFU_INIT_PRINT(sw->dpdk_cfg,
> " %d\n", i);
> +			}
> +	}
> +}
> +
> +
> +static uint32_t
> +fm10k_ffu_set_dest_glort_multi_cast(struct fm10k_switch *sw, uint8_t lport1,
> uint8_t lport2, uint16_t vlan1, uint16_t vlan2)
> +{
> +	uint32_t dglort;
> +	bool is_new;
> +	uint32_t idx;
> +	uint64_t temp64;
> +
> +	dglort = fm10k_switch_multi_glort_get(lport1, lport2, vlan1, vlan2,
> &is_new);
> +
> +	if (!is_new)
> +		return dglort;
> +
> +	FM10K_FFU_INIT_PRINT(sw->dpdk_cfg, "%s set glort %#x to (%d:%d)
> (%d:%d)\n", __func__, dglort, lport1, vlan1, lport2, vlan2);
> +	/*
> +	 * Create an exact-match key for the given DGLORT in the DGLORT CAM.
> +	 */
> +	idx = sw->glort_cam_ram_idx++;
> +	fm10k_write_switch_reg(sw, FM10K_SW_GLORT_CAM(idx),
> +	    FM10K_SW_MAKE_REG_FIELD(GLORT_CAM_KEY, dglort) |
> +	    FM10K_SW_MAKE_REG_FIELD(GLORT_CAM_KEY_INVERT, ~dglort));
> +
> +	/*
> +	 * Create multiple entries for each dport to increase the
> +	 * hash modulus and capture more hash entropy.  The maximum
> +	 * number of hashed entries is 16.
> +	 */
> +	temp64 = FM10K_SW_MAKE_REG_FIELD64(
> +	    GLORT_RAM_STRICT,
> +	    FM10K_SW_GLORT_RAM_STRICT_STRICT);
> +	temp64 |= FM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_DEST_INDEX,
> sw->glort_dest_table_idx);
> +	fm10k_write_switch_reg64(sw, FM10K_SW_GLORT_RAM(idx), temp64);
> +
> +	/* GLORT_DEST_TABLE
> +	 * Field Name 		Bit(s) 	Type 	Default Description
> +	 * DestMask 		47:0 	RW 		0x0 	Contains the
> destination port mask (for normal copies, not including logged or
> +	 *
> 			mirrored copies).
> +	 * IP_MulticastIndex59:48 	RW 		0x0 	Selects the IP
> multicast profile.
> +	 *
> 			This value is used as an index into
> SCHED_MCAST_DEST_TABLE[0..4095].
> +	 * Reserved 		63:60 	RSV 	0x0 	Reserved.
> +	 */
> +	temp64 = sw->mcast_dest_table_idx;
> +	temp64 = temp64<<48 | 1<<lport1 | 1<<lport2;
> +	fm10k_write_switch_reg64(sw, FM10K_SW_GLORT_DEST_TABLE(sw-
> >glort_dest_table_idx), temp64);
> +	sw->glort_dest_table_idx++;
> +
> +	/* MCAST_DEST_TABLE
> +	 * Field Name 		Bit(s) 	Type 	Default Description
> +	 * PortMask 		47:0 	RW 		0x0 	Defines which
> ports have a list of destination VLANs specified in
> +	 *
> 			SCHED_MCAST_LEN_TABLE.
> +	 *
> 			If a port does not have a list, and the destination mask
> from the Frame Processing
> +	 *
> 			Pipeline is 1 for that port, a packet is sent to that port
> without a VLAN replication
> +	 *
> 			attached to it.
> +	 * LenTableIdx 		61:48 	RW 		0x0 	Defines the
> base location of the list of VLAN lists in the
> +	 *
> 			SCHED_MCAST_LEN_TABLE.
> +	 * Reserved 		63:62 	RSV 	00b 	Reserved.
> +	 */
> +	temp64 = sw->mcast_len_table_idx;
> +	temp64 = 1<<lport1 | 1<<lport2 | temp64<<48;
> +	fm10k_write_switch_reg64(sw,
> FM10K_SW_SCHED_MCAST_DEST_TABLE(sw->mcast_dest_table_idx++),
> temp64);
> +
> +	/* MCAST_LEN_TABLE
> +	 * Field Name 		Bit(s) 	Type 	Default Description
> +	 * L3_McastIdx 		14:0 	RW 		0x0 	Defines the
> base location of the VLAN list in MOD_MCAST_VLAN_TABLE.
> +	 * L3_Repcnt 		26:15 	RW 		0x0 	Defines the
> number of multicast copies to make.
> +	 *
> 			The number of copies made is one more than the value
> of this field, so that 0
> +	 *
> 			indicates that a single frame is made. Legal values are 0
> through 4093, so that 1 to
> +	 *
> 			4094 copies are made.
> +	 * Reserved 		31:27 	RSV 	0x0 	Reserved.
> +	 */
> +	temp64 = sw->mcast_vlan_table_idx | 1<<15;
> +	fm10k_write_switch_reg64(sw,
> FM10K_SW_SCHED_MCAST_LEN_TABLE(sw->mcast_len_table_idx++), temp64);
> +
> +	/* MCAST_VLAN_TABLE
> +	 * Field Name 		Bit(s) 	Type 	Default	Description
> +	 * VID 				11:0 	RW 		0x0 	The
> new VID to use if update is requested.
> +	 * DGLORT 			27:12 	RW 		0x0 	The
> new DGLORT to use if update is requested.
> +	 * ReplaceVID 		28 		RW 		0b
> 	Indicates if the VID must be updated or not.
> +	 * ReplaceDGLORT 	29 		RW 		0b
> 	Indicates if the DGLORT must be updated or not.
> +	 * Reserved 		31:30	RSV 	00b 	Reserved.
> +	 */
> +	temp64 = vlan1 | fm10k_switch_pf_glort_get(lport1)<<12 | 1<<28 |
> 1<<29;
> +	fm10k_write_switch_reg64(sw,
> FM10K_SW_MOD_MCAST_VLAN_TABLE(sw->mcast_vlan_table_idx++), temp64);
> +	temp64 = vlan2 | fm10k_switch_pf_glort_get(lport2)<<12 | 1<<28 |
> 1<<29;
> +	fm10k_write_switch_reg64(sw,
> FM10K_SW_MOD_MCAST_VLAN_TABLE(sw->mcast_vlan_table_idx++), temp64);
> +
> +	return dglort;
> +}
> +
> +static uint64_t
> +fm10k_data64_field64_get(uint64_t data, int start, int end)
> +{
> +	uint64_t tmp64 = data;
> +
> +	if (start == end)
> +		tmp64 = data>>start & 1;
> +	else {
> +		tmp64 = tmp64<<(64-end);
> +		tmp64 = tmp64>>(64-end+start);
> +	}
> +	return tmp64;
> +}
> +
> +static uint32_t
> +fm10k_data64_field32_get(uint64_t data, int start, int end)
> +{
> +	uint64_t tmp64 = data;
> +	uint32_t tmp32;
> +
> +	if (start == end)
> +		tmp32 = data>>start & 1;
> +	else {
> +		tmp64 = tmp64<<(64-end);
> +		tmp32 = tmp64>>(64-end+start);
> +	}
> +	return tmp32;
> +}
> +
> +static uint32_t
> +fm10k_data32_field_get(uint32_t data, int start, int end)
> +{
> +	uint32_t tmp32 = data;
> +
> +	if (start == end)
> +		tmp32 = data>>start & 1;
> +	else {
> +		tmp32 = tmp32<<(64-end);
> +		tmp32 = tmp32>>(64-end+start);
> +	}
> +	return tmp32;
> +}
> +
> +
> +static void
> +fm10k_glort_register_dump(struct fm10k_switch *sw)
> +{
> +	uint32_t i;
> +	uint64_t data64;
> +	uint32_t data32;
> +	uint32_t tmp32;
> +
> + 	if (!FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_FFU_REG))
> + 		return;
> +
> +	printf("----- GLORT -----\n");
> +
> +	for (i = 0; i < sw->glort_cam_ram_idx; i++)	{
> +		data32 = fm10k_read_switch_reg(sw,
> FM10K_SW_GLORT_CAM(i));
> +		printf("[%02u]GLORT_CAM %#x Key %#x \n", i, data32,
> fm10k_data32_field_get(data32, 0, 15));
> +		data64 = fm10k_read_switch_reg64(sw,
> FM10K_SW_GLORT_RAM(i));
> +		printf("    GLORT_RAM %#llx Strict %u DestIndex %u\n", (long
> long unsigned int)data64,
> +				fm10k_data64_field32_get(data64, 0, 1),
> +				fm10k_data64_field32_get(data64, 2, 13));
> +		tmp32 = fm10k_data64_field32_get(data64, 2, 13);
> +		data64 = fm10k_read_switch_reg64(sw,
> FM10K_SW_GLORT_DEST_TABLE(tmp32));
> +		printf("    GLORT_DEST_TABLE[%u] %#llx
> IP_MulticastIndex %u\n", tmp32, (long long unsigned int)data64,
> +				fm10k_data64_field32_get(data64, 48, 59));
> +		tmp32 = fm10k_data64_field32_get(data64, 48, 59);
> +		if (tmp32 == 0)
> +			continue;
> +		data64 = fm10k_read_switch_reg64(sw,
> FM10K_SW_SCHED_MCAST_DEST_TABLE(tmp32));
> +		printf("    SCHED_MCAST_DEST_TABLE[%u] %#llx
> PortMask %#llx LenTableIdx %u\n", tmp32, (long long unsigned int)data64,
> +				(long long unsigned
> int)fm10k_data64_field64_get(data64, 0, 47),
> +				fm10k_data64_field32_get(data64, 48, 61));
> +		tmp32 = fm10k_data64_field32_get(data64, 48, 61);
> +		data32 = fm10k_read_switch_reg(sw,
> FM10K_SW_SCHED_MCAST_LEN_TABLE(tmp32));
> +		printf("    SCHED_MCAST_LEN_TABLE[%u] %#x L3_McastIdx %u
> L3_Repcnt %u\n", tmp32, data32,
> +				fm10k_data32_field_get(data32, 0, 14),
> +				fm10k_data32_field_get(data32, 15, 26));
> +		tmp32 = fm10k_data32_field_get(data32, 0, 14);
> +		data32 = fm10k_read_switch_reg(sw,
> FM10K_SW_MOD_MCAST_VLAN_TABLE(tmp32));
> +		printf("    MOD_MCAST_VLAN_TABLE[%u] %#x VID %u
> DGLORT %#x ReplaceVID %u ReplaceDGLORT %u\n", tmp32, data32,
> +				fm10k_data32_field_get(data32, 0, 11),
> +				fm10k_data32_field_get(data32, 12, 27),
> +				fm10k_data32_field_get(data32, 28, 28),
> +				fm10k_data32_field_get(data32, 29, 29));
> +		data32 = fm10k_read_switch_reg(sw,
> FM10K_SW_MOD_MCAST_VLAN_TABLE(tmp32+1));
> +		printf("    MOD_MCAST_VLAN_TABLE[%u] %#x VID %u
> DGLORT %#x ReplaceVID %u ReplaceDGLORT %u\n", tmp32+1, data32,
> +				fm10k_data32_field_get(data32, 0, 11),
> +				fm10k_data32_field_get(data32, 12, 27),
> +				fm10k_data32_field_get(data32, 28, 28),
> +				fm10k_data32_field_get(data32, 29, 29));
> +	}
> +}
> +
> +static void
> +fm10k_ffu_register_dump(struct fm10k_switch *sw)
> +{
> + 	int i,j;
> + 	uint32_t data[8];
> + 	uint32_t ffu_valid;
> +
> + 	if (!FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_FFU_REG))
> + 		return;
> +
> + 	printf("--------------- FFU REGISTERS DUMP ------------------\n");
> +
> + 	fm10k_read_switch_array(sw, FM10K_SW_FFU_MASTER_VALID, data,
> 2);
> + 	printf("FFU_MASTER_VALID: %#x %#x\n", data[0], data[1]);
> + 	ffu_valid = data[0];
> +
> + 	for (i = 0; i < 32; i++)
> + 	{
> + 		if ((ffu_valid & 1<<i) == 0)
> + 			continue;
> +
> + 		printf("------ SLICE%d ------\n", i);
> +
> + 		fm10k_read_switch_array(sw, FM10K_SW_FFU_SLICE_VALID(i),
> data, 2);
> + 		if (data[0] != 0 || data[1] != 0)
> + 			printf("FFU_SLICE_VALID[%d]: %#x %#x\n", i, data[0],
> data[1]);
> +
> + 		fm10k_read_switch_array(sw,
> FM10K_SW_FFU_SLICE_CASCADE_ACTION(i), data, 2);
> + 		if (data[0] != 0 || data[1] != 0)
> + 			printf("FFU_SLICE_CASCADE_ACTION[%d]: %#x %#x\n",
> i, data[0], data[1]);
> +
> +		for (j = 0; j < 1; j++)
> +		{
> +			fm10k_read_switch_array(sw,
> FM10K_SW_FFU_SLICE_CFG(i, j), data, 2);
> +			if (data[0] != 0 || data[1] != 0)
> +				printf("FFU_SLICE_CFG[%d][%d]: %#x %#x\n", i,
> j, data[0], data[1]);
> +		}
> + 		for (j = 0; j < 32; j++) {
> + 			fm10k_read_switch_array(sw,
> FM10K_SW_FFU_SLICE_TCAM(i, j), data, 4);
> + 			if ((data[0] != 0 || data[1] != 0 || data[2] != 0 ||
> data[3] != 0))
> +
> 	printf("FFU_SLICE_TCAM[%d][%d]: %#x %#x %#x %#x\n",
> + 					i, j, data[0], data[1], data[2], data[3]);
> +
> + 			fm10k_read_switch_array(sw,
> FM10K_SW_FFU_SLICE_SRAM(i, j), data, 2);
> + 			if (data[0] != 0 || data[1] != 0)
> + 				printf("FFU_SLICE_SRAM[%d][%d]: %#x %#x\n",
> i, j, data[0], data[1]);
> + 		}
> + 	}
> +#if 0
> + 	/* RX_MIRROR_CFG */
> + 	printf("RX_MIRROR_CFG: %#x", fm10k_read_switch_reg(sw, 0xd50000
> + 0xd));
> + 	/* FH_MIRROR_PROFILE_TABLE */
> + 	printf("FH_MIRROR_PROFILE_TABLE[%d]: %#llx",
> + 			FM10K_FFU_MIRROR_PROFILE,
> +			fm10k_read_switch_reg(sw, 0xd50000 +
> 0x1*FM10K_FFU_MIRROR_PROFILE + 0x40));
> + 	/* MOD_MIRROR_PROFILE_TABLE don't work */
> + 	printf("MOD_MIRROR_PROFILE_TABLE[%d]: %#llx",
> + 			FM10K_FFU_MIRROR_PROFILE,
> +			fm10k_read_switch_reg64(sw, 0xe80000 +
> 0x2*FM10K_FFU_MIRROR_PROFILE + 0x24000));
> +#endif
> +}
> +
> +
> +static void
> +fm10k_ffu_mirror_set_action(struct fm10k_switch* sw,
> +		uint16_t ffu_slice,	uint16_t table_idx)
> +{
> +	uint64_t data64;
> +
> +	/* blank the next ffu slice */
> +	fm10k_write_switch_reg128(sw,
> +		FM10K_SW_FFU_SLICE_TCAM(ffu_slice, table_idx), 0xffffffffff,
> 0x1);
> +	/* SET FFU RX_MIRROR */
> +	data64 = 0x60; /* higher than route, not necessary */
> +	data64 = data64<<32 | 0x2<<21 | 1<<(8+4) | 1<<4;
> +	fm10k_write_switch_reg64(sw,
> +			FM10K_SW_FFU_SLICE_SRAM(ffu_slice, table_idx),
> data64);
> +}
> +
> +static void
> +fm10k_ffu_mirror_set_forward(struct fm10k_switch *sw,
> +		int profile,
> +		uint16_t vlan,
> +		uint16_t dest_lport,
> +		uint32_t dest_sglort)
> +{
> +	uint64_t data64;
> +
> +	/* RX_MIRROR_CFG */
> +	fm10k_write_switch_reg(sw, 0xd50000 + 0xd, profile);
> +
> +	/* FH_MIRROR_PROFILE_TABLE */
> +	fm10k_write_switch_reg(sw, 0xd50000 + 0x1*profile + 0x40, dest_lport);
> +
> +	/* MOD_MIRROR_PROFILE_TABLE don't work */
> +	data64 = vlan;
> +	data64 = (dest_sglort & 0xffff) | data64<<17;
> +	fm10k_write_switch_reg64(sw, 0xe80000 + 0x2*profile + 0x24000,
> data64);
> +#if FM10K_SW_FFU_CONF_TRACE_ENABLE
> +	fm10k_switch_dump_ffu(sw);
> +#endif
> +}
> +
> +
> +int
> +fm10k_ffu_mirror_set(struct fm10k_switch *sw,
> +		uint16_t src_ext_port,
> +		uint16_t dest_ext_port,
> +		uint16_t vlan)
> +{
> +	uint16_t table_idx;
> +	uint16_t ffu_slice = FM10K_FFU_SLICE_SGLORT_VID + 1;
> +	uint16_t mirror_profile = FM10K_FFU_MIRROR_PROFILE;
> +
> +	table_idx = FM10K_FFU_EXT_PORT_RULE_INGRESS(src_ext_port-1);
> +	fm10k_ffu_mirror_set_action(sw, ffu_slice, table_idx);
> +
> +	fm10k_ffu_mirror_set_forward(sw, mirror_profile,
> +			vlan, sw->epl_map[dest_ext_port-1].logical_port, sw-
> >epl_map[dest_ext_port-1].glort);
> +	return 0;
> +}
> +
> +int
> +fm10k_ffu_mirror_reset(struct fm10k_switch *sw, int src_ext_port)
> +{
> +	uint16_t table_idx;
> +	uint16_t ffu_slice = FM10K_FFU_SLICE_SGLORT_VID + 1;
> +
> +	table_idx = FM10K_FFU_EXT_PORT_RULE_INGRESS(src_ext_port-1);
> +	fm10k_write_switch_reg64(sw,
> +				FM10K_SW_FFU_SLICE_SRAM(ffu_slice,
> table_idx), 0);
> +	return 0;
> +}
> +
> +static void
> +fm10k_ffu_logical_port_vlan_set(struct fm10k_switch *sw,
> +		uint16_t lport, uint16_t vlan_id)
> +{
> +	uint64_t data;
> +
> +	/* 11.21.3.9 INGRESS_VID_TABLE[0..4095] */
> +	data = fm10k_read_switch_reg64(sw, 0xE80000 + 0x2*vlan_id +
> 0x20000);
> +	data |= 1<<lport;
> +	fm10k_write_switch_reg64(sw, 0xE80000 + 0x2*vlan_id + 0x20000,
> data);
> +
> +	FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, "%s lport:%d, vlan_id:%d,
> reg:%#llx\n",
> +			__func__, lport, vlan_id, (unsigned long long)data);
> +}
> +
> +static void
> +fm10k_ffu_glort_port_vlan_set(struct fm10k_switch *sw,
> +		uint16_t glort, uint16_t vlan_id)
> +{
> +	int i;
> +
> +	for (i = 0; i < FM10K_SW_PEPS_SUPPORTED; i++) {
> +		if (sw->pep_map[i].glort == glort) {
> +			fm10k_ffu_logical_port_vlan_set(sw, sw-
> >pep_map[i].logical_port, vlan_id);
> +			break;
> +		}
> +	}
> +	for (i = 0; i < FM10K_SW_EPLS_SUPPORTED; i++) {
> +		if (sw->epl_map[i].glort == glort) {
> +			fm10k_ffu_logical_port_vlan_set(sw, sw-
> >epl_map[i].logical_port, vlan_id);
> +			break;
> +		}
> +	}
> +}
> +
> +
> +static uint16_t
> +fm10k_ffu_dpdk_port_glort_get(struct fm10k_switch *sw, int port)
> +{
> +	int pf;
> +	uint16_t glort = 0;
> +
> +	if (sw->dpdk_cfg->dpdk_port_map[port].type ==
> FM10K_CONFIG_PORT_MAP_PFS ||
> +			sw->dpdk_cfg->dpdk_port_map[port].type ==
> FM10K_CONFIG_PORT_MAP_PFSS) {
> +		glort = fm10k_switch_pfs_glort_get(sw->dpdk_cfg-
> >dpdk_port_map[port].map_no[0],
> +				sw->dpdk_cfg-
> >dpdk_port_map[port].map_no[1]);
> +	} else if (sw->dpdk_cfg->dpdk_port_map[port].type ==
> FM10K_CONFIG_PORT_MAP_PF) {
> +		pf = sw->dpdk_cfg->dpdk_port_map[port].map_no[0];
> +		glort = fm10k_switch_pf_glort_get(pf);
> +	}
> +	return glort;
> +}
> +
> +static void
> +fm10k_ffu_rule_enable_single_cast(struct fm10k_switch *sw,
> +		int rule_id,
> +		uint16_t sglort,
> +		uint16_t svlan,
> +		uint16_t dglort,
> +		uint16_t dvlan)
> +{
> +	uint64_t temp64;
> +	uint64_t sglort_vid_tcam = 0, sglort_vid_tcam_mask = 0;
> +	uint64_t sram[4] = { 0, 0, 0, 0 };
> +	uint16_t sram_idx = 0, tcam_slice, sram_slice, i;
> +
> +	sglort_vid_tcam |= sglort;
> +	sglort_vid_tcam_mask |= 0xffff;
> +	if (svlan) {
> +		temp64 = svlan;
> +		sglort_vid_tcam |= temp64<<16;
> +		sglort_vid_tcam_mask |= 0xfff0000;
> +		fm10k_ffu_glort_port_vlan_set(sw, sglort, svlan);
> +	}
> +
> +	/* set counter */
> +	sram[sram_idx] |=
> FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_COUNTER_BANK,
> FM10K_SW_FFU_CNT_BANK) |
> +
> 	FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_COUNTER_INDEX,
> FM10K_FFU_CNT_INDEX(rule_id));
> +
> +	sram[sram_idx] |=
> FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_PRECEDENCE, 3) |
> +
> FM10K_SW_MAKE_REG_FIELD(FFU_SLICE_SRAM_ROUTE_GLORT_DGLORT,
> dglort) |
> +
> 	FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_COMMAND,
> FM10K_SW_FFU_SLICE_SRAM_COMMAND_ROUTE_GLORT);
> +	sram_idx++;
> +
> +	if (dvlan) {
> +		temp64 = 3; /* Force updating VLAN tag if present. Add if
> absent. 11.5.3.4 */
> +		sram[sram_idx] = temp64<<16 | dvlan |
> +
> 	FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_PRECEDENCE, 2) |
> +
> 	FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_COMMAND,
> FM10K_SW_FFU_SLICE_SRAM_COMMAND_FIELD_SET);
> +		fm10k_ffu_glort_port_vlan_set(sw, dglort, dvlan);
> +		sram_idx++;
> +	}
> +
> +	if (sglort_vid_tcam) {
> +		tcam_slice = FM10K_FFU_SLICE_SGLORT_VID;
> +		temp64 =
> FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY, ~sglort_vid_tcam &
> sglort_vid_tcam_mask);
> +		fm10k_write_switch_reg128(sw,
> FM10K_SW_FFU_SLICE_TCAM(tcam_slice, rule_id),
> +				temp64, sglort_vid_tcam);
> +		FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, "TCAM slice:%d,
> rule:%d, data0:%#llx, data1:%#llx\n",
> +				tcam_slice, rule_id, (unsigned long
> long)sglort_vid_tcam, (unsigned long long)temp64);
> +	}
> +
> +	/* blank the next SLICE TCAM */
> +	fm10k_ffu_always_mismatch(sw, tcam_slice+1, rule_id);
> +
> +	for (i = 0; i < sram_idx; i++) {
> +		sram_slice = FM10K_FFU_SLICE_START + i;
> +		fm10k_write_switch_reg64(sw,
> FM10K_SW_FFU_SLICE_SRAM(sram_slice, rule_id), sram[i]);
> +		FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, "SRAM slice:%d,
> rule:%d, data:%#llx\n",
> +				sram_slice, rule_id, (unsigned long
> long)sram[i]);
> +	}
> +	/* disable the next SLICE SRAM */
> +	fm10k_write_switch_reg64(sw,
> FM10K_SW_FFU_SLICE_SRAM(sram_slice+1, rule_id), 0);
> +
> +	fm10k_stats_rule_count_reg(rule_id);
> +}
> +
> +static void
> +fm10k_ffu_rule_enable_multi_cast(struct fm10k_switch *sw,
> +		int rule_id,
> +		uint16_t sglort,
> +		uint16_t svlan,
> +		uint8_t lport1,
> +		uint8_t lport2,
> +		uint16_t vlan1,
> +		uint16_t vlan2)
> +{
> +	uint64_t temp64;
> +	uint32_t dglort;
> +	uint64_t sglort_vid_tcam = 0, sglort_vid_tcam_mask = 0;
> +	uint64_t sram[4] = { 0, 0, 0, 0 };
> +	uint16_t sram_idx = 0, tcam_slice, sram_slice, i;
> +
> +	dglort = fm10k_ffu_set_dest_glort_multi_cast(sw, lport1, lport2, vlan1,
> vlan2);
> +
> +	sglort_vid_tcam |= sglort;
> +	sglort_vid_tcam_mask |= 0xffff;
> +	if (svlan) {
> +		temp64 = svlan;
> +		sglort_vid_tcam |= temp64<<16;
> +		sglort_vid_tcam_mask |= 0xfff0000;
> +		fm10k_ffu_glort_port_vlan_set(sw, sglort, svlan);
> +	}
> +
> +	fm10k_ffu_logical_port_vlan_set(sw, lport1, vlan1);
> +	fm10k_ffu_logical_port_vlan_set(sw, lport2, vlan2);
> +
> +	/* set counter */
> +	sram[sram_idx] |=
> FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_COUNTER_BANK,
> FM10K_SW_FFU_CNT_BANK) |
> +
> 	FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_COUNTER_INDEX,
> FM10K_FFU_CNT_INDEX(rule_id));
> +
> +	sram[sram_idx] |=
> FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_PRECEDENCE, 3) |
> +
> FM10K_SW_MAKE_REG_FIELD(FFU_SLICE_SRAM_ROUTE_GLORT_DGLORT,
> dglort) |
> +
> 	FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_COMMAND,
> FM10K_SW_FFU_SLICE_SRAM_COMMAND_ROUTE_GLORT);
> +	sram_idx++;
> +
> +	if (sglort_vid_tcam) {
> +		tcam_slice = FM10K_FFU_SLICE_SGLORT_VID;
> +		temp64 =
> FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY, ~sglort_vid_tcam &
> sglort_vid_tcam_mask);
> +		fm10k_write_switch_reg128(sw,
> FM10K_SW_FFU_SLICE_TCAM(tcam_slice, rule_id),
> +				temp64, sglort_vid_tcam);
> +		FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, "TCAM slice:%d,
> rule:%d, data0:%#llx, data1:%#llx\n",
> +				tcam_slice, rule_id, (unsigned long
> long)sglort_vid_tcam, (unsigned long long)temp64);
> +	}
> +
> +	/* blank the next SLICE TCAM */
> +	fm10k_ffu_always_mismatch(sw, tcam_slice+1, rule_id);
> +
> +	for (i = 0; i < sram_idx; i++)
> +	{
> +		sram_slice = FM10K_FFU_SLICE_START + i;
> +		fm10k_write_switch_reg64(sw,
> FM10K_SW_FFU_SLICE_SRAM(sram_slice, rule_id), sram[i]);
> +		FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, "SRAM slice:%d,
> rule:%d, data:%#llx\n",
> +				sram_slice, rule_id, (unsigned long
> long)sram[i]);
> +	}
> +	/* disable the next SLICE SRAM */
> +	fm10k_write_switch_reg64(sw,
> FM10K_SW_FFU_SLICE_SRAM(sram_slice+1, rule_id), 0);
> +
> +	fm10k_stats_rule_count_reg(rule_id);
> +}
> +
> +
> +void
> +fm10k_ffu_flow_enable(struct fm10k_switch *sw, struct fm10k_cfg_flow*
> flow)
> +{
> +	uint16_t sglort = 0;
> +	uint16_t svlan = 0;
> +	uint16_t dglort = 0;
> +	uint16_t dvlan = 0;
> +	uint16_t lport1 = 0, lport2 = 0;
> +	uint16_t dvlan2 = 0;
> +
> +	switch (flow->src_port.port_type) {
> +	case FM10K_CONFIG_FLOW_EXT_PORT:
> +		sglort = fm10k_switch_epl_glort_get(flow->src_port.port_no -
> 1);
> +		break;
> +	case FM10K_CONFIG_FLOW_DPDK_PORT:
> +		sglort = fm10k_ffu_dpdk_port_glort_get(sw, flow-
> >src_port.port_no);
> +		break;
> +	}
> +	switch (flow->fw_port[0].port_type) {
> +	case FM10K_CONFIG_FLOW_EXT_PORT:
> +		dglort = fm10k_switch_epl_glort_get(flow->fw_port[0].port_no
> - 1);
> +		lport1 = fm10k_switch_epl_logical_get(flow-
> >fw_port[0].port_no - 1);
> +		break;
> +	case FM10K_CONFIG_FLOW_DPDK_PORT:
> +		dglort = fm10k_ffu_dpdk_port_glort_get(sw, flow-
> >fw_port[0].port_no);
> +		lport1 = fm10k_switch_pf_logical_get(flow-
> >fw_port[0].port_no);
> +		break;
> +	}
> +	svlan = flow->src_port.vlan_id;
> +	dvlan = flow->fw_port[0].vlan_id;
> +
> +	flow->rule_id = fm10k_ffu_rule_alloc();
> +
> +	FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, "Set rule cond sglort:%#x,
> vlan:%d ==> act dglort:%#x, vlan:%d",
> +					sglort, svlan, dglort, dvlan);
> +
> +	if (flow->fw_port[1].port_type)	{
> +		switch (flow->fw_port[1].port_type)	{
> +		case FM10K_CONFIG_FLOW_EXT_PORT:
> +			dglort = fm10k_switch_epl_glort_get(flow-
> >fw_port[1].port_no - 1);
> +			lport2 = fm10k_switch_epl_logical_get(flow-
> >fw_port[1].port_no - 1);
> +			break;
> +		case FM10K_CONFIG_FLOW_DPDK_PORT:
> +			dglort = fm10k_ffu_dpdk_port_glort_get(sw, flow-
> >fw_port[1].port_no);
> +			lport2 = fm10k_switch_pf_logical_get(flow-
> >fw_port[1].port_no);
> +			break;
> +		}
> +		dvlan2 = flow->fw_port[1].vlan_id;
> +		FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, " (bypass glort:%#x,
> vlan:%d)\n", dglort, dvlan2);
> +
> +		fm10k_ffu_rule_enable_multi_cast(sw, flow->rule_id, sglort,
> svlan, lport1, lport2, dvlan, dvlan2);
> +	} else {
> +		FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, "\n");
> +		fm10k_ffu_rule_enable_single_cast(sw, flow->rule_id, sglort,
> svlan, dglort, dvlan);
> +	}
> +}
> +
> +
> +void
> +fm10k_ffu_flow_disable(struct fm10k_switch *sw, struct fm10k_cfg_flow*
> flow)
> +{
> +	int i;
> +
> +	if (flow->rule_id == 0)
> +		return;
> +
> +	FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, "Remove flow %d rule %d\n",
> flow->flow_no, flow->rule_id);
> +
> +	for (i = FM10K_FFU_SLICE_START; i < FM10K_SW_FFU_NUM_SLICES;
> i++) {
> +		fm10k_ffu_always_mismatch(sw, i, flow->rule_id);
> +		fm10k_write_switch_reg64(sw, FM10K_SW_FFU_SLICE_SRAM(i,
> flow->rule_id), 0);
> +	}
> +	fm10k_ffu_rule_free(flow->rule_id);
> +}
> +
> +
> +int fm10k_flow_add(struct fm10k_hw *hw, struct fm10k_cfg_flow *cf);
> +static int
> +fm10k_ffu_configured_flowset_enable(struct fm10k_switch *sw)
> +{
> +	struct fm10k_cfg_flowset* flowset;
> +	struct fm10k_cfg_flow* flow;
> +
> +	flowset = fm10k_config_flowset_current_get();
> +	flow = flowset->flow_head.next;
> +	while (!fm10k_config_flow_list_end(&flowset->flow_head, flow)) {
> +		fm10k_ffu_flow_enable(sw, flow);
> +		flow = flow->next;
> +	}
> +
> +	return 0;
> +}
> +
> +
> +void
> +fm10k_ffu_flowset_switch(struct fm10k_switch *sw, const char *new_name)
> +{
> +	struct fm10k_cfg_flowset* flowset;
> +	struct fm10k_cfg_flowset* cur_fs;
> +	struct fm10k_cfg_flow* flow;
> +
> +	cur_fs = fm10k_config_flowset_current_get();
> +	if (strcmp(cur_fs->name, new_name) == 0)
> +		return;
> +
> +	flowset = fm10k_config_flowset_get(new_name);
> +	if (flowset == NULL) {
> +		FM10K_SW_ERR("Can not find flowset %s!!\n", new_name);
> +		return;
> +	}
> +
> +	/* disable current flowset */
> +	flow = cur_fs->flow_head.next;
> +	while (!fm10k_config_flow_list_end(&cur_fs->flow_head, flow)) {
> +		fm10k_ffu_flow_disable(sw, flow);
> +		flow = flow->next;
> +	}
> +
> +	/* enable new flowset */
> +	fm10k_config_flowset_current_set(flowset);
> +	flow = flowset->flow_head.next;
> +	while (!fm10k_config_flow_list_end(&flowset->flow_head, flow)) {
> +		fm10k_ffu_flow_enable(sw, flow);
> +		flow = flow->next;
> +	}
> +}
> +
> +
> +int
> +fm10k_ffu_init(struct fm10k_switch *sw, struct fm10k_dpdk_cfg *cfg)
> +{
> +	int ret = 0;
> +	uint64_t data64;
> +	uint16_t i, j;
> +	uint32_t sglort = 0, dglort = 0;
> +	uint16_t table_idx = 0;
> +	uint16_t ffu_slice = FM10K_FFU_SLICE_START;
> +
> +	sw->mcast_dest_table_idx = 1;
> +	sw->mcast_len_table_idx = 1;
> +	sw->mcast_vlan_table_idx = 1;
> +
> +	for (i = 0; i < sizeof(fm10k_ffu_slice_cfgs)/sizeof(uint64_t); i++)	{
> +		for (j = 0; j < FM10K_SW_FFU_NUM_SCENARIOS; j++) {
> +			data64 = fm10k_ffu_slice_cfgs[i];
> +			fm10k_write_switch_reg64(sw,
> +
> 	FM10K_SW_FFU_SLICE_CFG(FM10K_FFU_SLICE_START+i, j),
> +					data64);
> +		}
> +		FM10K_FFU_INIT_PRINT(cfg, "SET slice %d cfg = %#llx\n",
> +				FM10K_FFU_SLICE_START+i, (unsigned long
> long)data64);
> +	}
> +
> +	for (table_idx=0; table_idx < FM10K_SW_FFU_SLICE_TCAM_ENTRIES/2;
> table_idx++)
> +		for (i = ffu_slice; i < FM10K_SW_FFU_NUM_SLICES; i++)
> +			fm10k_ffu_always_mismatch(sw, i, table_idx);
> +
> +	/*
> +	 * Create a TCAM entry to match each SGLORT that might be used, and
> +	 * set the corresponding SRAM action entries to ROUTE_GLORT to the
> +	 * corresponding DGLORT (see above table).
> +	 * SGLORT ROUTE is always the first slice
> +	 */
> +	for (i = 0; i < FM10K_SW_EXT_PORTS_MAX; i++) {
> +		if (cfg->ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_NULL)
> +			continue;
> +
> +		if (cfg->ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PF) {
> +			sglort = fm10k_switch_epl_glort_get(i);
> +			dglort = fm10k_switch_pf_glort_get(cfg-
> >ext_port_map[i].map_no[0]);
> +		} else if (cfg->ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PFS) {
> +			sglort = fm10k_switch_epl_glort_get(i);
> +			dglort = fm10k_switch_pfs_glort_get(cfg-
> >ext_port_map[i].map_no[0], cfg->ext_port_map[i].map_no[1]);
> +		}
> +
> +		table_idx = FM10K_FFU_EXT_PORT_RULE_INGRESS(i);
> +		fm10k_ffu_route_dglort(sw, ffu_slice, table_idx, sglort, dglort);
> +
> +		/* blank the next ffu slice */
> +		fm10k_write_switch_reg128(sw,
> FM10K_SW_FFU_SLICE_TCAM(ffu_slice+1, table_idx),
> +			    0xffffffffff, 0x1);
> +		table_idx = FM10K_FFU_EXT_PORT_RULE_EGRESS(i);
> +		fm10k_ffu_route_dglort(sw, ffu_slice, table_idx, dglort, sglort);
> +
> +		/* blank the next ffu slice */
> +		fm10k_write_switch_reg128(sw,
> FM10K_SW_FFU_SLICE_TCAM(ffu_slice+1, table_idx),
> +			    0xffffffffff, 0x1);
> +	}
> +
> +	for (i = ffu_slice; i < FM10K_SW_FFU_NUM_SLICES; i++) {
> +		fm10k_write_switch_reg64(sw,
> FM10K_SW_FFU_SLICE_CASCADE_ACTION(i),
> +				0xf0f000f);
> +		/* Set slice 0 to valid for all scenarios */
> +		fm10k_write_switch_reg64(sw,
> FM10K_SW_FFU_SLICE_VALID(i),
> +		    FM10K_SW_FFU_SLICE_VALID_ALL_SCENARIOS);
> +	}
> +
> +	/* Mark slice 0 as valid and all chunks as invalid */
> +	data64 = 0;
> +	for (i = ffu_slice; i < FM10K_SW_FFU_NUM_SLICES; i++)
> +		data64 |= FM10K_SW_FFU_MASTER_VALID_SLICE_VALID(i);
> +	fm10k_write_switch_reg64(sw, FM10K_SW_FFU_MASTER_VALID,
> data64);
> +
> +	/*
> +	 * Set up the DGLORT map according to the desired
> +	 * SGLORT -> { DGLORT, logical_port } map.
> +	 */
> +	for (i = 0; i < sw->info->num_peps; i++) {
> +		if (sw->pep_map[i].glort == 0)
> +			continue;
> +		fm10k_ffu_set_dest_glort_mask(sw, sw->glort_cam_ram_idx++,
> sw->pep_map[i].glort,
> +				FM10K_SW_DPORT_MASK(sw-
> >pep_map[i].logical_port));
> +	}
> +
> +	for (i = 0; i < FM10K_SW_EPLS_SUPPORTED; i++) {
> +		if (sw->epl_map[i].glort == 0)
> +			continue;
> +		fm10k_ffu_set_dest_glort_mask(sw, sw->glort_cam_ram_idx++,
> sw->epl_map[i].glort,
> +				FM10K_SW_DPORT_MASK(sw-
> >epl_map[i].logical_port));
> +	}
> +
> +	for (i = 0; i < FM10K_SW_EXT_PORTS_MAX; i++) {
> +		uint64_t dport_mask = 0;
> +
> +		if (cfg->ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PFS) {
> +			dglort = fm10k_switch_pfs_glort_get(cfg-
> >ext_port_map[i].map_no[0], cfg->ext_port_map[i].map_no[1]);
> +			dport_mask = FM10K_SW_DPORT_MASK(sw-
> >pep_map[cfg->ext_port_map[i].map_no[0]].logical_port) |
> +					FM10K_SW_DPORT_MASK(sw-
> >pep_map[cfg->ext_port_map[i].map_no[1]].logical_port);
> +			fm10k_ffu_set_dest_glort_mask(sw, sw-
> >glort_cam_ram_idx++, dglort, dport_mask);
> +		}
> +	}
> +
> +	/* Ensure the rest of the DGLORT TCAM won't match */
> +	for (table_idx=sw->glort_cam_ram_idx; table_idx <
> FM10K_SW_GLORT_CAM_ENTRIES; table_idx++)
> +		fm10k_write_switch_reg(sw,
> FM10K_SW_GLORT_CAM(table_idx), FM10K_SW_GLORT_CAM_MATCH_NONE);
> +
> +	ret = fm10k_ffu_configured_flowset_enable(sw);
> +
> +	fm10k_ffu_register_dump(sw);
> +	fm10k_glort_register_dump(sw);
> +	return ret;
> +}
> diff --git a/drivers/net/fm10k/switch/fm10k_ffu.h
> b/drivers/net/fm10k/switch/fm10k_ffu.h
> new file mode 100644
> index 0000000..09480cb
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_ffu.h
> @@ -0,0 +1,42 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_FFU_H_
> +#define _FM10K_FFU_H_
> +
> +
> +#include <stdint.h>
> +
> +#define FM10K_FFU_EXT_PORT_RULE_INGRESS(i)		(i*2)
> +#define FM10K_FFU_EXT_PORT_RULE_EGRESS(i)		(i*2+1)
> +#define FM10K_FFU_RULE_MAX
> 	FM10K_SW_FFU_RULE_MAX
> +
> +struct fm10k_switch;
> +struct fm10k_dpdk_cfg;
> +struct fm10k_cfg_flow;
> +
> +int fm10k_ffu_init(struct fm10k_switch *sw, struct fm10k_dpdk_cfg *cfg);
> +
> +int fm10k_ffu_mirror_set(struct fm10k_switch *sw,
> +		uint16_t src_dpdk_port, u16 dest_dpdk_port, uint16_t vlan);
> +int fm10k_ffu_mirror_reset(struct fm10k_switch *sw, int src_dpdk_port);
> +
> +void fm10k_ffu_flow_enable(struct fm10k_switch *sw, struct
> fm10k_cfg_flow* flow);
> +void fm10k_ffu_flow_disable(struct fm10k_switch *sw, struct
> fm10k_cfg_flow* flow);
> +void fm10k_ffu_flowset_switch(struct fm10k_switch *sw, const char
> *new_name);
> +
> +#endif /* _FM10K_FFU_H */
> diff --git a/drivers/net/fm10k/switch/fm10k_i2c.c
> b/drivers/net/fm10k/switch/fm10k_i2c.c
> new file mode 100644
> index 0000000..28023b7
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_i2c.c
> @@ -0,0 +1,334 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#include <rte_malloc.h>
> +
> +#include "fm10k_debug.h"
> +#include "fm10k_i2c.h"
> +#include "fm10k_regs.h"
> +#include "fm10k_switch.h"
> +
> +static void fm10k_i2c_init(struct fm10k_i2c *);
> +
> +struct fm10k_i2c *
> +fm10k_i2c_attach(struct fm10k_switch *sw)
> +{
> +	struct fm10k_i2c *i2c;
> +
> +	FM10K_SW_TRACE("i2c: attaching");
> +
> +	i2c = (struct fm10k_i2c *)rte_zmalloc("fm10k_i2c", sizeof(struct
> fm10k_i2c), 0);
> +	if (i2c == NULL) {
> +		FM10K_SW_INFO("i2c: failed to allocate context");
> +		goto fail;
> +	}
> +
> +	i2c->sw = sw;
> +	pthread_mutex_init(&i2c->req_lock, NULL);
> +	pthread_mutex_init(&i2c->bus_lock, NULL);
> +	sem_init(&i2c->req_cv, 0, 0);
> +
> +	fm10k_i2c_init(i2c);
> +
> +	FM10K_SW_TRACE("i2c: attach successful");
> +	return (i2c);
> +fail:
> +	if (i2c)
> +		fm10k_i2c_detach(i2c);
> +	return (NULL);
> +}
> +
> +void
> +fm10k_i2c_detach(struct fm10k_i2c *i2c)
> +{
> +	FM10K_SW_TRACE("i2c: detaching");
> +
> +	rte_free(i2c);
> +}
> +
> +static void
> +fm10k_i2c_init(struct fm10k_i2c *i2c)
> +{
> +	struct fm10k_switch *sw = i2c->sw;
> +	struct fm10k_device_info *cfg = sw->info;
> +	uint32_t freq = FM10K_SW_I2C_CFG_DIVIDER_400_KHZ;
> +	uint32_t data;
> +
> +	if (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice) ==
> +			FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4))
> +		freq = FM10K_SW_I2C_CFG_DIVIDER_100_KHZ;
> +
> +	/* clear any pending interrupt */
> +	fm10k_write_switch_reg(sw, FM10K_SW_I2C_CTRL,
> +		FM10K_SW_I2C_CTRL_INTERRUPT_PENDING);
> +
> +	/* 400 KHz, master mode, unmask interrupt */
> +	data = fm10k_read_switch_reg(sw, FM10K_SW_I2C_CFG);
> +	data &= ~FM10K_SW_I2C_CFG_SLAVE_ENABLE;
> +	if (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice) ==
> +			FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4))
> +	FM10K_SW_REPLACE_REG_FIELD(data, I2C_CFG_DIVIDER, freq);
> +	data &=  ~FM10K_SW_I2C_CFG_INTERRUPT_MASK;
> +	fm10k_write_switch_reg(sw, FM10K_SW_I2C_CFG, data);
> +
> +	if (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice) ==
> +			FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4))
> +		/* reset I2C */
> +		fm10k_gpio_output_set(sw, 5, 1);
> +}
> +
> +unsigned int
> +fm10k_i2c_intr(struct fm10k_i2c *i2c)
> +{
> +	struct fm10k_switch *sw = i2c->sw;
> +	struct fm10k_i2c_req *req;
> +	int i;
> +	uint32_t data[3];
> +	uint32_t ctrl;
> +
> +	req = i2c->cur_req;
> +
> +	FM10K_SW_SWITCH_LOCK(sw);
> +	ctrl = fm10k_read_switch_reg(sw, FM10K_SW_I2C_CTRL);
> +	fm10k_write_switch_reg(sw, FM10K_SW_I2C_CTRL,
> +	    FM10K_SW_I2C_CTRL_INTERRUPT_PENDING);
> +
> +	req->status = FM10K_SW_REG_FIELD(ctrl,
> I2C_CTRL_COMMAND_COMPLETED);
> +
> +	if ((req->cmd == FM10K_SW_I2C_COMMAND_RD ||
> +		req->cmd == FM10K_SW_I2C_COMMAND_WR_RD) &&
> +	    req->status == FM10K_SW_I2C_COMPLETION_NORMAL) {
> +
> +		for (i = 0; i < FM10K_SW_HOWMANY(req->read_len, 4); i++)
> +			data[i] = fm10k_read_switch_reg(sw,
> FM10K_SW_I2C_DATA(i));
> +
> +		switch (req->read_len) {
> +		case 12: req->msg[11] =  data[2]        & 0xff; /* FALLTHROUGH
> */
> +		case 11: req->msg[10] = (data[2] >>  8) & 0xff; /*
> FALLTHROUGH */
> +		case 10: req->msg[9]  = (data[2] >> 16) & 0xff; /*
> FALLTHROUGH */
> +		case  9: req->msg[8]  = (data[2] >> 24) & 0xff; /* FALLTHROUGH
> */
> +
> +		case  8: req->msg[7]  =  data[1]        & 0xff; /* FALLTHROUGH */
> +		case  7: req->msg[6]  = (data[1] >>  8) & 0xff; /* FALLTHROUGH
> */
> +		case  6: req->msg[5]  = (data[1] >> 16) & 0xff; /* FALLTHROUGH
> */
> +		case  5: req->msg[4]  = (data[1] >> 24) & 0xff; /* FALLTHROUGH
> */
> +
> +		case  4: req->msg[3]  =  data[0]        & 0xff; /* FALLTHROUGH */
> +		case  3: req->msg[2]  = (data[0] >>  8) & 0xff; /* FALLTHROUGH
> */
> +		case  2: req->msg[1]  = (data[0] >> 16) & 0xff; /* FALLTHROUGH
> */
> +		case  1: req->msg[0]  = (data[0] >> 24) & 0xff; /* FALLTHROUGH
> */
> +		}
> +	}
> +	FM10K_SW_SWITCH_UNLOCK(sw);
> +	sem_post(&i2c->req_cv);
> +
> +	return (1);
> +}
> +
> +int
> +fm10k_i2c_exec(struct fm10k_i2c *i2c, struct fm10k_i2c_req *req)
> +{
> +	struct fm10k_switch *sw = i2c->sw;
> +	int i;
> +	uint32_t ctrl;
> +	uint32_t data[3];
> +
> +	if (((req->cmd == FM10K_SW_I2C_COMMAND_WR ||
> +		    req->cmd == FM10K_SW_I2C_COMMAND_WR_RD) &&
> +		req->write_len > FM10K_SW_I2C_MSG_MAX) ||
> +	    ((req->cmd == FM10K_SW_I2C_COMMAND_RD ||
> +		req->cmd == FM10K_SW_I2C_COMMAND_WR_RD) &&
> +		((req->read_len == 0  ||
> +		    req->read_len > FM10K_SW_I2C_MSG_MAX))))
> +		return (-1);
> +
> +	FM10K_SW_TRACE("i2c: initiating command %u", req->cmd);
> +
> +	ctrl =
> +	    FM10K_SW_MAKE_REG_FIELD(I2C_CTRL_ADDR, req->addr << 1) |
> +	    FM10K_SW_MAKE_REG_FIELD(I2C_CTRL_COMMAND, req->cmd);
> +
> +	if (req->cmd == FM10K_SW_I2C_COMMAND_WR ||
> +	    req->cmd == FM10K_SW_I2C_COMMAND_WR_RD) {
> +		ctrl |= FM10K_SW_MAKE_REG_FIELD(I2C_CTRL_LENGTH_W,
> req->write_len);
> +
> +		data[0] = data[1] = data[2] = 0;
> +		switch (req->write_len) {
> +		case 12: data[2] |= req->msg[11];      /* FALLTHROUGH */
> +		case 11: data[2] |= req->msg[10] << 8; /* FALLTHROUGH */
> +		case 10: data[2] |= req->msg[9] << 16; /* FALLTHROUGH */
> +		case  9: data[2] |= req->msg[8] << 24; /* FALLTHROUGH */
> +
> +		case  8: data[1] |= req->msg[7];       /* FALLTHROUGH */
> +		case  7: data[1] |= req->msg[6] << 8;  /* FALLTHROUGH */
> +		case  6: data[1] |= req->msg[5] << 16; /* FALLTHROUGH */
> +		case  5: data[1] |= req->msg[4] << 24; /* FALLTHROUGH */
> +
> +		case  4: data[0] |= req->msg[3];       /* FALLTHROUGH */
> +		case  3: data[0] |= req->msg[2] <<  8; /* FALLTHROUGH */
> +		case  2: data[0] |= req->msg[1] << 16; /* FALLTHROUGH */
> +		case  1: data[0] |= req->msg[0] << 24; /* FALLTHROUGH */
> +		}
> +
> +		for (i = 0; i < FM10K_SW_HOWMANY(req->write_len, 4); i++)
> +			fm10k_write_switch_reg(sw, FM10K_SW_I2C_DATA(i),
> data[i]);
> +	}
> +
> +	if (req->cmd == FM10K_SW_I2C_COMMAND_RD ||
> +	    req->cmd == FM10K_SW_I2C_COMMAND_WR_RD)
> +		ctrl |= FM10K_SW_MAKE_REG_FIELD(I2C_CTRL_LENGTH_R,
> req->read_len);
> +
> +	req->status = FM10K_SW_I2C_COMPLETION_RUNNING;
> +	i2c->cur_req = req;
> +
> +	FM10K_SW_SWITCH_LOCK(sw);
> +	/* zero command field */
> +	fm10k_write_switch_reg(sw, FM10K_SW_I2C_CTRL, 0);
> +	/* initiate command */
> +	fm10k_write_switch_reg(sw, FM10K_SW_I2C_CTRL, ctrl);
> +	FM10K_SW_SWITCH_UNLOCK(sw);
> +
> +	while (req->status == FM10K_SW_I2C_COMPLETION_RUNNING)
> +		sem_wait(&i2c->req_cv);
> +
> +	return (0);
> +}
> +
> +int
> +fm10k_i2c_read8(struct fm10k_i2c *i2c, uint8_t addr, uint8_t *result)
> +{
> +	struct fm10k_i2c_req req;
> +	int error;
> +
> +	req.addr = addr;
> +	req.cmd = FM10K_SW_I2C_COMMAND_RD;
> +	req.read_len = 1;
> +	req.msg[0] = 0;
> +
> +	error = fm10k_i2c_exec(i2c, &req);
> +	if (error)
> +		goto done;
> +
> +	if (req.status != FM10K_SW_I2C_COMPLETION_NORMAL) {
> +		FM10K_SW_INFO("i2c read failed (%u)", req.status);
> +		error = -1;
> +		goto done;
> +	}
> +
> +	*result = req.msg[0];
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_i2c_read8_ext(struct fm10k_i2c *i2c, uint8_t addr, uint8_t reg, uint8_t
> *result)
> +{
> +	struct fm10k_i2c_req req;
> +	int error;
> +
> +	req.addr = addr;
> +	req.cmd = FM10K_SW_I2C_COMMAND_WR_RD;
> +	req.write_len = 1;
> +	req.read_len = 1;
> +	req.msg[0] = reg;
> +
> +	error = fm10k_i2c_exec(i2c, &req);
> +	if (error)
> +		goto done;
> +
> +	if (req.status != FM10K_SW_I2C_COMPLETION_NORMAL) {
> +		FM10K_SW_INFO("i2c read failed (%u)", req.status);
> +		error = -1;
> +		goto done;
> +	}
> +
> +	*result = req.msg[0];
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_i2c_write8(struct fm10k_i2c *i2c, uint8_t addr, uint8_t data)
> +{
> +	struct fm10k_i2c_req req;
> +	int error;
> +
> +	req.addr = addr;
> +	req.cmd = FM10K_SW_I2C_COMMAND_WR;
> +	req.write_len = 1;
> +	req.msg[0] = data;
> +
> +	error = fm10k_i2c_exec(i2c, &req);
> +	if (error)
> +		goto done;
> +
> +	if (req.status != FM10K_SW_I2C_COMPLETION_NORMAL) {
> +		error = -1;
> +		goto done;
> +	}
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_i2c_write16(struct fm10k_i2c *i2c, uint8_t addr, uint8_t data0, uint8_t
> data1)
> +{
> +	struct fm10k_i2c_req req;
> +	int error;
> +
> +	req.addr = addr;
> +	req.cmd = FM10K_SW_I2C_COMMAND_WR;
> +	req.write_len = 2;
> +	req.msg[0] = data0;
> +	req.msg[1] = data1;
> +
> +	error = fm10k_i2c_exec(i2c, &req);
> +	if (error)
> +		goto done;
> +
> +	if (req.status != FM10K_SW_I2C_COMPLETION_NORMAL) {
> +		error = -1;
> +		goto done;
> +	}
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_i2c_probe(struct fm10k_i2c *i2c, uint8_t addr)
> +{
> +	struct fm10k_i2c_req req;
> +	int error;
> +
> +	req.addr = addr;
> +	req.cmd = FM10K_SW_I2C_COMMAND_WR;
> +	req.write_len = 0;
> +
> +	error = fm10k_i2c_exec(i2c, &req);
> +	if (error)
> +		goto done;
> +
> +	if (req.status != FM10K_SW_I2C_COMPLETION_NORMAL) {
> +		error = -1;
> +		goto done;
> +	}
> +
> +done:
> +	return (error);
> +}
> diff --git a/drivers/net/fm10k/switch/fm10k_i2c.h
> b/drivers/net/fm10k/switch/fm10k_i2c.h
> new file mode 100644
> index 0000000..ff3164f
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_i2c.h
> @@ -0,0 +1,68 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_SW_I2C_H_
> +#define _FM10K_SW_I2C_H_
> +
> +#include <semaphore.h>
> +#include <pthread.h>
> +#include "rte_spinlock.h"
> +#include "fm10k_debug.h"
> +
> +#define FM10K_SW_I2C_MSG_MAX	12
> +
> +struct fm10k_i2c_req {
> +	uint8_t addr; /* 7-bit address */
> +	uint8_t cmd;  /* FM10K_SW_I2C_COMMAND_* */
> +	uint8_t write_len;
> +	uint8_t read_len;
> +	uint8_t status; /* FM10K_SW_I2C_COMPLETION_ */
> +	uint8_t msg[FM10K_SW_I2C_MSG_MAX];
> +};
> +
> +struct fm10k_i2c {
> +	struct fm10k_switch *sw;
> +	pthread_mutex_t bus_lock;
> +	pthread_mutex_t req_lock;
> +	sem_t req_cv;
> +	struct fm10k_i2c_req *cur_req;
> +};
> +
> +#define FM10K_SW_I2C_LOCK(i2c_)		do { \
> +	FM10K_SW_TRACE("i2c %p bus lock", i2c_); \
> +	pthread_mutex_lock(&(i2c_)->bus_lock); \
> +}while(0)
> +
> +#define FM10K_SW_I2C_UNLOCK(i2c_)	do { \
> +	FM10K_SW_TRACE("i2c %p bus unlock", i2c_); \
> +	pthread_mutex_unlock(&(i2c_)->bus_lock); \
> +}while(0)
> +
> +#define FM10K_SW_I2C_REQ_LOCK(i2c_)
> 	pthread_mutex_lock(&((i2c_)->req_lock))
> +#define FM10K_SW_I2C_REQ_UNLOCK(i2c_)
> 	pthread_mutex_unlock(&((i2c_)->req_lock))
> +
> +struct fm10k_i2c *fm10k_i2c_attach(struct fm10k_switch *sw);
> +void fm10k_i2c_detach(struct fm10k_i2c *i2c);
> +unsigned int fm10k_i2c_intr(struct fm10k_i2c *i2c);
> +int fm10k_i2c_exec(struct fm10k_i2c *i2c, struct fm10k_i2c_req *req);
> +int fm10k_i2c_read8(struct fm10k_i2c *i2c, uint8_t addr, uint8_t *result);
> +int fm10k_i2c_read8_ext(struct fm10k_i2c *i2c, uint8_t addr, uint8_t reg,
> uint8_t *result);
> +int fm10k_i2c_write8(struct fm10k_i2c *i2c, uint8_t addr, uint8_t data);
> +int fm10k_i2c_write16(struct fm10k_i2c *i2c, uint8_t addr, uint8_t data0,
> uint8_t data1);
> +int fm10k_i2c_probe(struct fm10k_i2c *i2c, uint8_t addr);
> +
> +#endif /* _FM10K_SW_I2C_H_ */
> diff --git a/drivers/net/fm10k/switch/fm10k_regs.h
> b/drivers/net/fm10k/switch/fm10k_regs.h
> new file mode 100644
> index 0000000..60aa44b
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_regs.h
> @@ -0,0 +1,1944 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_REGS_H_
> +#define _FM10K_REGS_H_
> +
> +#include <stdint.h>
> +
> +/* Convert a 32-bit word offset into a byte offset */
> +#define FM10K_SW_REG_OFF(wo_)  					(wo_)
> +#define FM10K_SW_MASK32(max_bit_, min_bit_)		((0xffffffffU
> << (min_bit_)) & (0xffffffffU >> (31 - max_bit_)))
> +#define FM10K_SW_REG_FIELD(r_, name_)			\
> +			(((uint32_t)(r_) &
> 	\
> +		    FM10K_SW_MASK32(FM10K_SW_##name_##_msb,
> 		\
> +			FM10K_SW_##name_##_lsb)) >>
> FM10K_SW_##name_##_lsb)
> +#define FM10K_SW_REG_FIELD_IDX(r_, name_, i_)	\
> +			(((uint32_t)(r_) &
> 	\
> +		    FM10K_SW_MASK32(FM10K_SW_##name_##_msb(i_),
> 	\
> +			FM10K_SW_##name_##_lsb(i_))) >>
> 	\
> +		    FM10K_SW_##name_##_lsb(i_))
> +#define FM10K_SW_MAKE_REG_FIELD(name_, v_)		\
> +			(((uint32_t)(v_) << FM10K_SW_##name_##_lsb) &
> 	\
> +		    FM10K_SW_MASK32(FM10K_SW_##name_##_msb,
> 		\
> +			FM10K_SW_##name_##_lsb))
> +#define FM10K_SW_MAKE_REG_FIELD_IDX(name_, i_, v_)
> 	\
> +			(((uint32_t)(v_) << FM10K_SW_##name_##_lsb(i_)) &
> 	\
> +		    FM10K_SW_MASK32(FM10K_SW_##name_##_msb(i_),
> 	\
> +			FM10K_SW_##name_##_lsb(i_)))
> +#define FM10K_SW_REPLACE_REG_FIELD(r_, name_, v_)
> 	\
> +			(r_) = (((r_) &
> ~FM10K_SW_MASK32(FM10K_SW_##name_##_msb,	\
> +			FM10K_SW_##name_##_lsb)) |			\
> +		    FM10K_SW_MAKE_REG_FIELD(name_, v_))
> +#define FM10K_SW_REPLACE_REG_FIELD_IDX(r_, name_, i_, v_)	\
> +			(r_) = (((r_) &
> ~FM10K_SW_MASK32(FM10K_SW_##name_##_msb(i_),	\
> +			FM10K_SW_##name_##_lsb(i_))) |
> 	\
> +		    FM10K_SW_MAKE_REG_FIELD_IDX(name_, i_, v_))
> +#define FM10K_SW_MASK64(max_bit_, min_bit_)			\
> +			((0xffffffffffffffffULL << (min_bit_)) &	\
> +		    (0xffffffffffffffffULL >> (63 - max_bit_)))
> +#define FM10K_SW_REG_FIELD64(r_, name_)			    \
> +			(((uint64_t)(r_) &
> 	\
> +		    FM10K_SW_MASK64(FM10K_SW_##name_##_msb64,
> 		\
> +			FM10K_SW_##name_##_lsb64)) >>
> 	\
> +		    FM10K_SW_##name_##_lsb64)
> +#define FM10K_SW_REG_FIELD_IDX64(r_, name_, i_)		\
> +			(((uint64_t)(r_) &
> 	\
> +		    FM10K_SW_MASK64(FM10K_SW_##name_##_msb64(i_),
> 		\
> +			FM10K_SW_##name_##_lsb64(i_))) >>
> 	\
> +		    FM10K_SW_##name_##_lsb64(i_))
> +#define FM10K_SW_MAKE_REG_FIELD64(name_, v_)		\
> +			(((uint64_t)(v_) << FM10K_SW_##name_##_lsb64) &
> 		\
> +		    FM10K_SW_MASK64(FM10K_SW_##name_##_msb64,
> 		\
> +			FM10K_SW_##name_##_lsb64))
> +#define FM10K_SW_MAKE_REG_FIELD_IDX64(name_, i_, v_)
> 	\
> +			(((uint64_t)(v_) << FM10K_SW_##name_##_lsb64(i_)) &
> 	\
> +		    FM10K_SW_MASK64(FM10K_SW_##name_##_msb64(i_),
> 		\
> +			FM10K_SW_##name_##_lsb64(i_)))
> +#define FM10K_SW_REPLACE_REG_FIELD64(r_, name_, v_)
> 	\
> +			(r_) = (((r_) &
> ~FM10K_SW_MASK64(FM10K_SW_##name_##_msb64,	\
> +			FM10K_SW_##name_##_lsb64)) |
> 	\
> +		    FM10K_SW_MAKE_REG_FIELD64(name_, v_))
> +#define FM10K_SW_REPLACE_REG_FIELD_IDX64(r_, name_, i_, v_)
> 	\
> +			(r_) = (((r_) &
> ~FM10K_SW_MASK64(FM10K_SW_##name_##_msb64(i_),\
> +			FM10K_SW_##name_##_lsb64(i_))) |		\
> +		    FM10K_SW_MAKE_REG_FIELD_IDX64(name_, i_, v_))
> +
> +/* These operate on arrays of 32-bit words */
> +#define FM10K_SW_SET_ARRAY_BIT(a_, name_, b_)
> 	\
> +			(a_)[FM10K_SW_##name_##_bit / 32] =
> 	\
> +		    ((a_)[FM10K_SW_##name_##_bit / 32] &
> 	\
> +			~(1 << (FM10K_SW_##name_##_bit % 32))) |
> 	\
> +		    (((b_) & 0x1) << (FM10K_SW_##name_##_bit % 32))
> +
> +/* Does not support fields that cross 32-bit boundaries */
> +#define FM10K_SW_MAKE_ARRAY_FIELD(name_, v_)
> 	\
> +			(((uint32_t)(v_) << (FM10K_SW_##name_##_lsb % 32))
> &	\
> +		    FM10K_SW_MASK32(FM10K_SW_##name_##_msb % 32,
> 		\
> +			FM10K_SW_##name_##_lsb % 32))
> +
> +/* Does not support fields that cross 32-bit boundaries */
> +#define FM10K_SW_REPLACE_ARRAY_FIELD(a_, name_, v_)
> 	\
> +			(a_)[FM10K_SW_##name_##_lsb / 32] =
> 	\
> +		    (((a_)[FM10K_SW_##name_##_lsb / 32] &
> 	\
> +			~FM10K_SW_MASK32(FM10K_SW_##name_##_msb %
> 32,	\
> +			FM10K_SW_##name_##_lsb % 32)) |		\
> +			FM10K_SW_MAKE_ARRAY_FIELD(name_, v_))
> +
> +/*
> + * BAR0 registers
> + */
> +/* Interrupt throttle timer selection values */
> +#define	FM10K_SW_INT_TIMER_0			0
> +#define	FM10K_SW_INT_TIMER_1			1
> +#define	FM10K_SW_INT_TIMER_IMMEDIATE	2
> +#define	FM10K_SW_INT_TIMER_DISABLED		3
> +
> +#define FM10K_SW_CTRL
> 	FM10K_SW_REG_OFF(0x0)
> +#define	FM10K_SW_CTRL_BAR4_ALLOWED		(1 << 2)
> +#define FM10K_SW_CTRL_EXT
> 	FM10K_SW_REG_OFF(0x1)
> +#define FM10K_SW_CTRL_EXT_NS_DIS		(1 << 0)
> +#define	FM10K_SW_CTRL_EXT_RO_DIS		(1 << 1)
> +#define	FM10K_SW_CTRL_EXT_SWITCH_LOOPBACK	(1 << 2)
> +#define FM10K_SW_EXVET
> 	FM10K_SW_REG_OFF(0x2)
> +#define FM10K_SW_GCR
> 	FM10K_SW_REG_OFF(0x3)
> +#define FM10K_SW_FACTPS
> 	FM10K_SW_REG_OFF(0x4)
> +#define FM10K_SW_GCR_EXT
> 	FM10K_SW_REG_OFF(0x5)
> +#define FM10K_SW_EICR
> 	FM10K_SW_REG_OFF(0x6)
> +#define	FM10K_SW_EICR_PCA_FAULT_SHIFT	0
> +#define	FM10K_SW_EICR_PCA_FAULT 		(1 <<
> FM10K_SW_EICR_PCA_FAULT_SHIFT)
> +#define	FM10K_SW_EICR_THI_FAULT_SHIFT	2
> +#define	FM10K_SW_EICR_THI_FAULT 		(1 <<
> FM10K_SW_EICR_THI_FAULT_SHIFT)
> +#define	FM10K_SW_EICR_FUM_FAULT_SHIFT	5
> +#define	FM10K_SW_EICR_FUM_FAULT 		(1 <<
> FM10K_SW_EICR_FUM_FAULT_SHIFT)
> +#define	FM10K_SW_EICR_MAILBOX_SHIFT		6
> +#define	FM10K_SW_EICR_MAILBOX 			(1 <<
> FM10K_SW_EICR_MAILBOX_SHIFT)
> +#define	FM10K_SW_EICR_SWITCH_READY_SHIFT	7
> +#define	FM10K_SW_EICR_SWITCH_READY 		(1 <<
> FM10K_SW_EICR_SWITCH_READY_SHIFT)
> +#define	FM10K_SW_EICR_SWITCH_NREADY_SHIFT	8
> +#define	FM10K_SW_EICR_SWITCH_NREADY		(1 <<
> FM10K_SW_EICR_SWITCH_NREADY_SHIFT)
> +#define	FM10K_SW_EICR_SWITCH_INT_SHIFT	9
> +#define	FM10K_SW_EICR_SWITCH_INT \
> +			(1 << FM10K_SW_EICR_SWITCH_INT_SHIFT)
> +#define	FM10K_SW_EICR_SRAM_ERROR_SHIFT	10
> +#define	FM10K_SW_EICR_SRAM_ERROR \
> +			(1 << FM10K_SW_EICR_SRAM_ERROR_SHIFT)
> +#define	FM10K_SW_EICR_VFLR_SHIFT		11
> +#define	FM10K_SW_EICR_VFLR	\
> +			(1 << FM10K_SW_EICR_VFLR_SHIFT)
> +#define	FM10K_SW_EICR_MAX_HOLD_TIME_SHIFT	12
> +#define	FM10K_SW_EICR_MAX_HOLD_TIME \
> +			(1 << FM10K_SW_EICR_MAX_HOLD_TIME_SHIFT)
> +#define FM10K_SW_EIMR			FM10K_SW_REG_OFF(0x7)
> +#define	FM10K_SW_EIMR_DISABLE_ALL		0x55555555
> +#define	FM10K_SW_EIMR_NO_CHANGE			0x0
> +#define	FM10K_SW_EIMR_DISABLE			0x1
> +#define	FM10K_SW_EIMR_ENABLE			0x2
> +#define	FM10K_SW_EIMR_FIELD(i_, v_) 	(FM10K_SW_EIMR_##v_ <<
> (FM10K_SW_EICR_##i_##_SHIFT * 2))
> +#define	FM10K_SW_EIMR_ENABLED(e_, i_) 	\
> +			((((e_) >> (FM10K_SW_EICR_##i_##_SHIFT * 2)) & 0x3)
> == \
> +			FM10K_SW_EIMR_ENABLE)
> +#define FM10K_SW_PCA_FAULT
> 	FM10K_SW_REG_OFF(0x8)
> +#define FM10K_SW_THI_FAULT
> 	FM10K_SW_REG_OFF(0x10)
> +#define FM10K_SW_FUM_FAULT
> 	FM10K_SW_REG_OFF(0x1C)
> +#define FM10K_SW_MAXHOLDQ(n_)
> 	FM10K_SW_REG_OFF(0x20 + (n_))
> +#define	FM10K_SW_MAXHOLDQ_ENTRIES		8
> +#define FM10K_SW_SM_AREA
> 	FM10K_SW_REG_OFF(0x28)
> +#define FM10K_SW_DGLORTMAP(n_)
> 	FM10K_SW_REG_OFF(0x30 + (n_))
> +#define	FM10K_SW_DGLORTMAP_ENTRIES		8
> +#define	FM10K_SW_DGLORTMAP_MATCH_ANY	0x00000000
> +#define	FM10K_SW_DGLORTMAP_MATCH_NONE	0x0000ffff
> +#define	FM10K_SW_DGLORTMAP_VALUE_lsb	0
> +#define	FM10K_SW_DGLORTMAP_VALUE_msb	15
> +#define	FM10K_SW_DGLORTMAP_MASK_lsb		16
> +#define	FM10K_SW_DGLORTMAP_MASK_msb		31
> +#define FM10K_SW_DGLORTDEC(n_)
> 	FM10K_SW_REG_OFF(0x38 + (n_))
> +#define	FM10K_SW_DGLORTDEC_Q_LENGTH_lsb	0
> +#define	FM10K_SW_DGLORTDEC_Q_LENGTH_msb	3
> +#define	FM10K_SW_DGLORTDEC_VSI_LENGTH_lsb	4
> +#define	FM10K_SW_DGLORTDEC_VSI_LENGTH_msb	6
> +#define	FM10K_SW_DGLORTDEC_VSI_BASE_lsb	7
> +#define	FM10K_SW_DGLORTDEC_VSI_BASE_msb	13
> +#define	FM10K_SW_DGLORTDEC_PC_LENGTH_lsb	14
> +#define	FM10K_SW_DGLORTDEC_PC_LENGTH_msb	15
> +#define	FM10K_SW_DGLORTDEC_Q_BASE_lsb	16
> +#define	FM10K_SW_DGLORTDEC_Q_BASE_msb	23
> +#define	FM10K_SW_DGLORTDEC_RSS_LENGTH_MAX	7
> +#define	FM10K_SW_DGLORTDEC_RSS_LENGTH_lsb	24
> +#define	FM10K_SW_DGLORTDEC_RSS_LENGTH_msb	26
> +#define	FM10K_SW_DGLORTDEC_INNTER_RSS	(1 << 27)
> +#define FM10K_SW_TUNNEL_CFG
> 	FM10K_SW_REG_OFF(0x40)
> +#define FM10K_SW_SWPRI_MAP(pri_)		FM10K_SW_REG_OFF(0x50 +
> (pri_))
> +#define FM10K_SW_RSSRK(f_, n_)
> 	FM10K_SW_REG_OFF(0x800 + 0x10 * (f_) + (n_))
> +#define FM10K_SW_RSSRK_ENTRIES			10
> +#define FM10K_SW_RETA(f_, n_)
> 	FM10K_SW_REG_OFF(0x1000 + 0x20 * (f_) + (n_))
> +#define FM10K_SW_RETA_ENTRIES			32
> +#define FM10K_SW_RETA_ENTRY(e0_, e1_, e2_, e3_)	\
> +			(((e0_) & 0xff) |					\
> +		    (((e1_) & 0xff) << 8) |				\
> +		    (((e2_) & 0xff) << 16) |			\
> +		    (((e3_) & 0xff) << 24))
> +#define FM10K_SW_TC_CREDIT(g_)
> 	FM10K_SW_REG_OFF(0x2000 + (g_))
> +#define FM10K_SW_TC_MAXCREDIT(g_)
> 	FM10K_SW_REG_OFF(0x2040 + (g_))
> +#define FM10K_SW_TC_RATE(g_)
> 	FM10K_SW_REG_OFF(0x2080 + (g_))
> +#define FM10K_SW_TC_RATE_STATUS
> 	FM10K_SW_REG_OFF(0x20C0)
> +#define FM10K_SW_PAUSE
> 	FM10K_SW_REG_OFF(0x20C2)
> +#define FM10K_SW_DMA_CTRL
> 	FM10K_SW_REG_OFF(0x20C3)
> +#define	FM10K_SW_DMA_CTRL_TX_ENABLE		(1 << 0)
> +#define	FM10K_SW_DMA_CTRL_TX_HOST_PENDING	(1 << 1)
> +#define	FM10K_SW_DMA_CTRL_TX_DATA		(1 << 2)
> +#define	FM10K_SW_DMA_CTRL_TX_ACTIVE		(1 << 3)
> +#define	FM10K_SW_DMA_CTRL_RX_ENABLE		(1 << 4)
> +#define	FM10K_SW_DMA_CTRL_RX_HOST_PENDING	(1 << 5)
> +#define	FM10K_SW_DMA_CTRL_RX_DATA		(1 << 6)
> +#define	FM10K_SW_DMA_CTRL_RX_ACTIVE		(1 << 7)
> +#define	FM10K_SW_DMA_CTRL_RX_DESC_SIZE_32	(1 << 8)
> +#define	FM10K_SW_DMA_CTRL_MIN_MSS_lsb	9
> +#define	FM10K_SW_DMA_CTRL_MIN_MSS_msb	22
> +#define	FM10K_SW_DMA_CTRL_MAX_HOLD_TIME_lsb 23
> +#define	FM10K_SW_DMA_CTRL_MAX_HOLD_TIME_msb 27
> +#define	FM10K_SW_DMA_CTRL_DATA_PATH_RESET	(1 << 29)
> +#define	FM10K_SW_DMA_CTRL_MAX_QS_lsb	30
> +#define	FM10K_SW_DMA_CTRL_MAX_QS_msb	31
> +#define	FM10K_SW_DMA_CTRL_MAX_QS_256	0
> +#define	FM10K_SW_DMA_CTRL_MAX_QS_128	1
> +#define	FM10K_SW_DMA_CTRL_MAX_QS_64		2
> +#define FM10K_SW_DMA_CTRL2
> 	FM10K_SW_REG_OFF(0x20C4)
> +#define FM10K_SW_DTXTCPFLGL
> 	FM10K_SW_REG_OFF(0x20C5)
> +#define FM10K_SW_DTXTCPFLGH
> 	FM10K_SW_REG_OFF(0x20C6)
> +#define FM10K_SW_TPH_CTRL
> 	FM10K_SW_REG_OFF(0x20C7)
> +#define FM10K_SW_MRQC(f_)
> 	FM10K_SW_REG_OFF(0x2100 + (f_))
> +#define	FM10K_SW_MRQC_TCPIPV4			(1 << 0)
> +#define	FM10K_SW_MRQC_IPV4				(1 <<
> 1)
> +#define	FM10K_SW_MRQC_IPV6				(1 <<
> 4)
> +#define	FM10K_SW_MRQC_TCPIPV6			(1 << 5)
> +#define	FM10K_SW_MRQC_UDPIPV4			(1 << 6)
> +#define	FM10K_SW_MRQC_UDPIPV6			(1 << 7)
> +#define FM10K_SW_TQMAP(nvf_, vf_, vq_)	\
> +			FM10K_SW_REG_OFF(0x2800 +			\
> +		    (((nvf_) & ~0x7) ?					\
> +			((vf_) * 32 + ((vq_) & 0x1f)) :		\
> +			((vf_) * 256 + (vq_))))
> +#define FM10K_SW_RQMAP(nvf_, vf_, vq_) 	\
> +			FM10K_SW_REG_OFF(0x3000 +			\
> +		    (((nvf_) & ~0x7) ?					\
> +			((vf_) * 32 + ((vq_) & 0x1f)) :		\
> +			((vf_) * 256 + (vq_))))
> +#define FM10K_SW_STATS_TIMEOUT
> 	FM10K_SW_REG_OFF(0x3800)
> +#define FM10K_SW_STATS_UR
> 	FM10K_SW_REG_OFF(0x3801)
> +#define FM10K_SW_STATS_CA
> 	FM10K_SW_REG_OFF(0x3802)
> +#define FM10K_SW_STATS_UM
> 	FM10K_SW_REG_OFF(0x3803)
> +#define FM10K_SW_STATS_XEC
> 	FM10K_SW_REG_OFF(0x3804)
> +#define FM10K_SW_STATS_VLAN_DROP
> 	FM10K_SW_REG_OFF(0x3805)
> +#define FM10K_SW_STATS_LOOPBACK_DROP	FM10K_SW_REG_OFF(0x3806)
> +#define FM10K_SW_STATS_NODESC_DROP
> 	FM10K_SW_REG_OFF(0x3807)
> +#define FM10K_SW_RRTIME_CFG
> 	FM10K_SW_REG_OFF(0x3808)
> +#define FM10K_SW_RRTIME_LIMIT(n_)		FM10K_SW_REG_OFF(0x380C
> + 0x40 * (n_))
> +#define FM10K_SW_RRTIME_COUNT(n_)
> 	FM10K_SW_REG_OFF(0x3810 + 0x40 * (n_))
> +#define FM10K_SW_SYSTIME
> 	FM10K_SW_REG_OFF(0x3814)
> +#define FM10K_SW_SYSTIME0
> 	FM10K_SW_REG_OFF(0x3816)
> +#define FM10K_SW_SYSTIME_CFG
> 	FM10K_SW_REG_OFF(0x3818)
> +#define FM10K_SW_PFVFBME
> 	FM10K_SW_REG_OFF(0x381A)
> +#define FM10K_SW_PHYADDR
> 	FM10K_SW_REG_OFF(0x381C)
> +#define FM10K_SW_RDBAL(q_)
> 	FM10K_SW_REG_OFF(0x4000 + 0x40 * (q_))
> +#define FM10K_SW_RDBAH(q_)
> 	FM10K_SW_REG_OFF(0x4001 + 0x40 * (q_))
> +#define FM10K_SW_RDLEN(q_)
> 	FM10K_SW_REG_OFF(0x4002 + 0x40 * (q_))
> +#define FM10K_SW_TPH_RXCTRL(q_)
> 	FM10K_SW_REG_OFF(0x4003 + 0x40 * (q_))
> +#define	FM10K_SW_TPH_RXCTRL_DESC_TPHEN	(1 << 5)
> +#define	FM10K_SW_TPH_RXCTRL_HEADER_TPHEN	(1 << 6)
> +#define	FM10K_SW_TPH_RXCTRL_PAYLOAD_TPHEN	(1 << 7)
> +#define	FM10K_SW_TPH_RXCTRL_DESC_READ_RO_EN	(1 << 9)
> +#define	FM10K_SW_TPH_RXCTRL_DESC_WRITE_RO_EN (1 << 11)
> +#define	FM10K_SW_TPH_RXCTRL_DATA_WRITE_RO_EN (1 << 13)
> +#define	FM10K_SW_TPH_RXCTRL_REP_HEADER_RO_EN (1 << 15)
> +#define FM10K_SW_RDH(q_)
> 	FM10K_SW_REG_OFF(0x4004 + 0x40 * (q_))
> +#define FM10K_SW_RDT(q_)
> 	FM10K_SW_REG_OFF(0x4005 + 0x40 * (q_))
> +#define	FM10K_SW_RDT_RDT_lsb			0
> +#define	FM10K_SW_RDT_RDT_msb			15
> +#define FM10K_SW_RXQCTL(q_)
> 	FM10K_SW_REG_OFF(0x4006 + 0x40 * (q_))
> +#define	FM10K_SW_RXQCTL_ENABLE			(1 << 0)
> +#define	FM10K_SW_RXQCTL_VF_lsb			2
> +#define	FM10K_SW_RXQCTL_VF_msb			7
> +#define	FM10K_SW_RXQCTL_OWNED_BY_VF		(1 << 8)
> +#define FM10K_SW_RXDCTL(q_)
> 	FM10K_SW_REG_OFF(0x4007 + 0x40 * (q_))
> +#define	FM10K_SW_RXDCTL_MAX_TIME_lsb	0
> +#define	FM10K_SW_RXDCTL_MAX_TIME_msb	7
> +#define	FM10K_SW_RXDCTL_WRITE_BACK_IMM	(1 << 8)
> +#define	FM10K_SW_RXDCTL_DROP_ON_EMPTY	(1 << 9)
> +#define	FM10K_SW_RXDCTL_WRITE_RSS_HASH	(1 << 10)
> +#define FM10K_SW_RXINT(q_)
> 	FM10K_SW_REG_OFF(0x4008 + 0x40 * (q_))
> +#define	FM10K_SW_RXINT_INT_lsb			0
> +#define	FM10K_SW_RXINT_INT_msb			7
> +#define	FM10K_SW_RXINT_INT_TIMER_lsb	8
> +#define	FM10K_SW_RXINT_INT_TIMER_msb	9
> +#define FM10K_SW_SRRCTL(q_)
> 	FM10K_SW_REG_OFF(0x4009 + 0x40 * (q_))
> +#define	FM10K_SW_SRRCTL_BSIZE_PACKET_lsb	0
> +#define	FM10K_SW_SRRCTL_BSIZE_PACKET_msb	7
> +#define	FM10K_SW_SRRCTL_BSIZE_HEADER_lsb	8
> +#define	FM10K_SW_SRRCTL_BSIZE_HEADER_msb	13
> +#define	FM10K_SW_SRRCTL_DESC_TYPE_lsb	14
> +#define	FM10K_SW_SRRCTL_DESC_TYPE_msb	15
> +#define	FM10K_SW_SRRCTL_DESC_TYPE_NO_SPLIT	0
> +#define	FM10K_SW_SRRCTL_DESC_TYPE_HDR_SPLIT	1
> +#define	FM10K_SW_SRRCTL_DESC_TYPE_SIZE_SPLIT	2
> +#define	FM10K_SW_SRRCTL_PSR_TYPE_lsb	16
> +#define	FM10K_SW_SRRCTL_PSR_TYPE_msb	29
> +#define	FM10K_SW_SRRCTL_LOOPBACK_SUPPRESS	(1 << 30)
> +#define	FM10K_SW_SRRCTL_BUFFER_CHAINING_EN	(1 << 31)
> +#define FM10K_SW_QPRC(q_)
> 	FM10K_SW_REG_OFF(0x400A + 0x40 * (q_))
> +#define FM10K_SW_QPRDC(q_)
> 	FM10K_SW_REG_OFF(0x400B + 0x40 * (q_))
> +#define FM10K_SW_QBRC_L(q_)
> 	FM10K_SW_REG_OFF(0x400C + 0x40 * (q_))
> +#define FM10K_SW_QBRC_H(q_)
> 	FM10K_SW_REG_OFF(0x400D + 0x40 * (q_))
> +#define FM10K_SW_RX_SGLORT(q_)
> 	FM10K_SW_REG_OFF(0x400E + 0x40 * (q_))
> +#define FM10K_SW_TDBAL(q_)
> 	FM10K_SW_REG_OFF(0x8000 + 0x40 * (q_))
> +#define FM10K_SW_TDBAH(q_)
> 	FM10K_SW_REG_OFF(0x8001 + 0x40 * (q_))
> +#define FM10K_SW_TDLEN(q_)
> 	FM10K_SW_REG_OFF(0x8002 + 0x40 * (q_))
> +#define FM10K_SW_TPH_TXCTRL(q_)
> 	FM10K_SW_REG_OFF(0x8003 + 0x40 * (q_))
> +#define	FM10K_SW_TPH_TXCTRL_DESC_TPHEN	(1 << 5)
> +#define	FM10K_SW_TPH_TXCTRL_DESC_READ_RO_EN	(1 << 9)
> +#define	FM10K_SW_TPH_TXCTRL_DESC_WRITE_RO_EN (1 << 11)
> +#define	FM10K_SW_TPH_TXCTRL_DATA_READ_RO_EN	(1 << 13)
> +#define FM10K_SW_TDH(q_)
> 	FM10K_SW_REG_OFF(0x8004 + 0x40 * (q_))
> +#define FM10K_SW_TDT(q_)
> 	FM10K_SW_REG_OFF(0x8005 + 0x40 * (q_))
> +#define	FM10K_SW_TDT_TDT_lsb			0
> +#define	FM10K_SW_TDT_TDT_msb			15
> +#define FM10K_SW_TXDCTL(q_)
> 	FM10K_SW_REG_OFF(0x8006 + 0x40 * (q_))
> +#define	FM10K_SW_TXDCTL_PTHRESH_lsb		0
> +#define	FM10K_SW_TXDCTL_PTHRESH_msb		6
> +#define	FM10K_SW_TXDCTL_HTHRESH_lsb		7
> +#define	FM10K_SW_TXDCTL_HTHRESH_msb		13
> +#define	FM10K_SW_TXDCTL_ENABLE			(1 << 14)
> +#define	FM10K_SW_TXDCTL_MAX_TIME_lsb	16
> +#define	FM10K_SW_TXDCTL_MAX_TIME_msb	27
> +#define	FM10K_SW_TXDCTL_PUSH_DESC		(1 << 28)
> +#define FM10K_SW_TXQCTL(q_)
> 	FM10K_SW_REG_OFF(0x8007 + 0x40 * (q_))
> +#define	FM10K_SW_TXQCTL_VF_lsb			0
> +#define	FM10K_SW_TXQCTL_VF_msb			5
> +#define	FM10K_SW_TXQCTL_OWNED_BY_VF		(1 << 6)
> +#define	FM10K_SW_TXQCTL_PC_lsb			7
> +#define	FM10K_SW_TXQCTL_PC_msb			9
> +#define	FM10K_SW_TXQCTL_TC_lsb			10
> +#define	FM10K_SW_TXQCTL_TC_msb			15
> +#define	FM10K_SW_TXQCTL_VID_lsb			16
> +#define	FM10K_SW_TXQCTL_VID_msb			27
> +#define	FM10K_SW_TXQCTL_UNLIMITED_BW	(1 << 28)
> +#define	FM10K_SW_TXQCTL_PUSH_MODE_DIS	(1 << 29)
> +#define FM10K_SW_TXINT(q_)
> 	FM10K_SW_REG_OFF(0x8008 + 0x40 * (q_))
> +#define	FM10K_SW_TXINT_INT_lsb			0
> +#define	FM10K_SW_TXINT_INT_msb			7
> +#define	FM10K_SW_TXINT_INT_TIMER_lsb	8
> +#define	FM10K_SW_TXINT_INT_TIMER_msb	9
> +#define FM10K_SW_QPTC(q_)
> 	FM10K_SW_REG_OFF(0x8009 + 0x40 * (q_))
> +#define FM10K_SW_QBTC_L(q_)
> 	FM10K_SW_REG_OFF(0x800A + 0x40 * (q_))
> +#define FM10K_SW_QBTC_H(q_)
> 	FM10K_SW_REG_OFF(0x800B + 0x40 * (q_))
> +#define FM10K_SW_TQDLOC(q_)
> 	FM10K_SW_REG_OFF(0x800C + 0x40 * (q_))
> +#define	FM10K_SW_TQDLOC_BASE_lsb		0
> +#define	FM10K_SW_TQDLOC_BASE_msb		15
> +#define	FM10K_SW_TQDLOC_SIZE_lsb		16
> +#define	FM10K_SW_TQDLOC_SIZE_msb		19
> +#define	FM10K_SW_TQDLOC_SIZE_32	5
> +#define	FM10K_SW_TQDLOC_SIZE_64	6
> +#define	FM10K_SW_TQDLOC_SIZE_128		7
> +#define FM10K_SW_TX_SGLORT(q_)
> 	FM10K_SW_REG_OFF(0x800D + 0x40 * (q_))
> +#define	FM10K_SW_TX_SGLORT_SGLORT_lsb	0
> +#define	FM10K_SW_TX_SGLORT_SGLORT_msb	15
> +#define FM10K_SW_PFVTCTL(q_)
> 	FM10K_SW_REG_OFF(0x800E + 0x40 * (q_))
> +#define FM10K_SW_TX_DESC(q_, d_, w_) 	FM10K_SW_REG_OFF(0x40000
> + 0x400 * (q_) + 0x4 * (d_) + (w_))
> +#define FM10K_SW_PBACL(n_)
> 	FM10K_SW_REG_OFF(0x10000 + (n_))
> +#define FM10K_SW_INT_MAP(n_)
> 	FM10K_SW_REG_OFF(0x10080 + (n_))
> +#define	FM10K_SW_INT_MAP_ENTRIES		8
> +#define	FM10K_SW_INT_MAP_INDEX_MAILBOX	0
> +#define	FM10K_SW_INT_MAP_INDEX_FAULT	1
> +#define	FM10K_SW_INT_MAP_INDEX_SWITCH_UP_DOWN 2
> +#define	FM10K_SW_INT_MAP_INDEX_SWITCH	3
> +#define	FM10K_SW_INT_MAP_INDEX_SRAM		4
> +#define	FM10K_SW_INT_MAP_INDEX_VFLR		5
> +#define	FM10K_SW_INT_MAP_INDEX_MAX_HOLD_TIME 6
> +#define	FM10K_SW_INT_MAP_INT_lsb		0
> +#define	FM10K_SW_INT_MAP_INT_msb		7
> +#define	FM10K_SW_INT_MAP_INT_TIMER_lsb	8
> +#define	FM10K_SW_INT_MAP_INT_TIMER_msb	9
> +#define FM10K_SW_MSIX_VECTOR(v_)		FM10K_SW_REG_OFF(0x11000
> + 0x4 * (v_))
> +#define FM10K_SW_INT_CTRL
> 	FM10K_SW_REG_OFF(0x12000)
> +#define	FM10K_SW_INT_CTRL_NEXT_VECTOR_lsb	0
> +#define	FM10K_SW_INT_CTRL_NEXT_VECTOR_msb	9
> +#define	FM10K_SW_INT_CTRL_ENABLE_MODERATOR	(1 << 10)
> +#define FM10K_SW_ITR(v_)
> 	FM10K_SW_REG_OFF(0x12400 + (v_))
> +/*
> + * Interrupt throttle timer intervals in microseconds.  These provide the
> + * direct values for programming the ITR interval field when using a Gen3
> + * PCLK, otherwise they need to be scaled appropriately.
> + */
> +#define FM10K_SW_ITR_INTERVAL_20K		50
> +#define FM10K_SW_ITR_INTERVAL_40K		25
> +#define FM10K_SW_ITR_INTERVAL_0_lsb		0
> +#define FM10K_SW_ITR_INTERVAL_0_msb		11
> +#define FM10K_SW_ITR_INTERVAL_1_lsb		12
> +#define FM10K_SW_ITR_INTERVAL_1_msb		23
> +#define FM10K_SW_ITR_TIMER_0_EXPIRED		(1 << 24)
> +#define FM10K_SW_ITR_TIMER_1_EXPIRED		(1 << 25)
> +#define FM10K_SW_ITR_PENDING_0			(1 << 26)
> +#define FM10K_SW_ITR_PENDING_1			(1 << 27)
> +#define FM10K_SW_ITR_PENDING_2			(1 << 28)
> +#define FM10K_SW_ITR_AUTO_MASK			(1 << 29)
> +#define FM10K_SW_ITR_MASK_lsb			30
> +#define FM10K_SW_ITR_MASK_msb			31
> +#define	FM10K_SW_ITR_MASK_R_ENABLED 	0
> +#define	FM10K_SW_ITR_MASK_R_BLOCKED 	1
> +#define	FM10K_SW_ITR_MASK_W_KEEP		0
> +#define	FM10K_SW_ITR_MASK_W_BLOCK		1
> +#define	FM10K_SW_ITR_MASK_W_ENABLE		2
> +#define FM10K_SW_ITR2(v_)
> 	FM10K_SW_REG_OFF(0x12800 + 0x2 * (v_))
> +#define FM10K_SW_IP
> 	FM10K_SW_REG_OFF(0x13000)
> +#define FM10K_SW_IP_HOT_RESET			(1 << 0)
> +#define FM10K_SW_IP_DEVICE_STATE_CHANGE	(1 << 1)
> +#define FM10K_SW_IP_MAILBOX				(1 << 2)
> +#define FM10K_SW_IP_VPD_REQUEST			(1 << 3)
> +#define FM10K_SW_IP_SRAM_ERROR			(1 << 4)
> +#define FM10K_SW_IP_PFLR					(1 << 5)
> +#define FM10K_SW_IP_DATA_PATH_RESET		(1 << 6)
> +#define FM10K_SW_IP_OUT_OF_RESET			(1 << 7)
> +#define FM10K_SW_IP_NOT_IN_RESET			(1 << 8)
> +#define FM10K_SW_IP_TIMEOUT				(1 << 9)
> +#define FM10K_SW_IP_VFLR					(1 << 10)
> +#define FM10K_SW_IM
> 	FM10K_SW_REG_OFF(0x13001)
> +#define FM10K_SW_IM_ALL
> 	FM10K_SW_MASK32(10, 0)
> +#define FM10K_SW_IM_HOT_RESET			(1 << 0)
> +#define FM10K_SW_IM_DEVICE_STATE_CHANGE	(1 << 1)
> +#define FM10K_SW_IM_MAILBOX				(1 << 2)
> +#define FM10K_SW_IM_VPD_REQUEST			(1 << 3)
> +#define FM10K_SW_IM_SRAM_ERROR			(1 << 4)
> +#define FM10K_SW_IM_PFLR					(1 << 5)
> +#define FM10K_SW_IM_DATA_PATH_RESET		(1 << 6)
> +#define FM10K_SW_IM_OUT_OF_RESET			(1 << 7)
> +#define FM10K_SW_IM_TIMEOUT				(1 << 9)
> +#define FM10K_SW_IM_VFLR					(1 << 10)
> +#define FM10K_SW_IB
> 	FM10K_SW_REG_OFF(0x13002)
> +#define FM10K_SW_SRAM_IP
> 	FM10K_SW_REG_OFF(0x13003)
> +#define FM10K_SW_SRAM_IM
> 	FM10K_SW_REG_OFF(0x13004)
> +#define FM10K_SW_VLAN_TABLE(f_) 		FM10K_SW_REG_OFF(0x14000
> + 0x80 * (f_))
> +#define FM10K_SW_VLAN_TABLE_ENTRIES		128
> +#define FM10K_SW_VLAN_TABLE_ENTRY(f_, n_)
> 	FM10K_SW_REG_OFF(0x14000 + 0x80 * (f_) + (n_))
> +#define FM10K_SW_VLAN_TABLE_VLAN_ENTRY(f_, vl_)
> 	FM10K_SW_REG_OFF(0x14000 + 0x80 * (f_) + ((vl_) >> 5))
> +#define FM10K_SW_VLAN_TABLE_VLAN_BIT(vl_)	(1 << ((vl_) & 0x1f))
> +#define FM10K_SW_MBMEM(n_)
> 	FM10K_SW_REG_OFF(0x18000 + (n_))
> +#define FM10K_SW_MBX(vf_)
> 	FM10K_SW_REG_OFF(0x18800 + (vf_))
> +#define FM10K_SW_MBICR(vf_)
> 	FM10K_SW_REG_OFF(0x18840 + ((vf_) >> 5))
> +#define FM10K_SW_GMBX
> 	FM10K_SW_REG_OFF(0x18842)
> +#define FM10K_SW_GMBX_GLOBAL_REQ			(1 << 1)
> +#define FM10K_SW_GMBX_GLOBAL_ACK			(1 << 2)
> +#define FM10K_SW_GMBX_PF_REQ_INTERRUPT	(1 << 3)
> +#define FM10K_SW_GMBX_PF_ACK_INTERRUPT	(1 << 4)
> +#define FM10K_SW_GMBX_PF_INTERRUPT_ENABLE_lsb	5
> +#define FM10K_SW_GMBX_PF_INTERRUPT_ENABLE_msb	6
> +#define	FM10K_SW_GMBX_INTERRUPT_NO_CHANGE	0
> +#define	FM10K_SW_GMBX_INTERRUPT_ENABLE	1
> +#define	FM10K_SW_GMBX_INTERRUPT_DISABLE	2
> +#define FM10K_SW_GMBX_PF_REQ				(1 << 7)
> +#define FM10K_SW_GMBX_PF_ACK				(1 << 8)
> +#define FM10K_SW_GMBX_GLOBAL_REQ_INTERRUPT		(1 << 9)
> +#define FM10K_SW_GMBX_GLOBAL_ACK_INTERRUPT		(1 << 10)
> +#define FM10K_SW_GMBX_GLOBAL_INTERRUPT_ENABLE_lsb	11
> +#define FM10K_SW_GMBX_GLOBAL_INTERRUPT_ENABLE_msb	12
> +#define FM10K_SW_PFVFLRE
> 	FM10K_SW_REG_OFF(0x18844)
> +#define FM10K_SW_PFVFLREC
> 	FM10K_SW_REG_OFF(0x18846)
> +#define FM10K_SW_TEST_CFG0
> 	FM10K_SW_REG_OFF(0x18849)
> +#define FM10K_SW_INT_SRAM_CTRL
> 	FM10K_SW_REG_OFF(0x18850)
> +#define FM10K_SW_FUM_SRAM_CTRL
> 	FM10K_SW_REG_OFF(0x18852)
> +#define FM10K_SW_PCA_SRAM_CTRL
> 	FM10K_SW_REG_OFF(0x18854)
> +#define FM10K_SW_PP_SRAM_CTRL
> 	FM10K_SW_REG_OFF(0x18858)
> +#define FM10K_SW_PCW_SRAM_CTRL
> 	FM10K_SW_REG_OFF(0x1885C)
> +#define FM10K_SW_RHI_SRAM_CTRL1
> 	FM10K_SW_REG_OFF(0x18872)
> +#define FM10K_SW_RHI_SRAM_CTRL2
> 	FM10K_SW_REG_OFF(0x18860)
> +#define FM10K_SW_THI_SRAM_CTRL1
> 	FM10K_SW_REG_OFF(0x18864)
> +#define FM10K_SW_THI_SRAM_CTRL2
> 	FM10K_SW_REG_OFF(0x18868)
> +#define FM10K_SW_TIMEOUT_CFG
> 	FM10K_SW_REG_OFF(0x1886B)
> +#define FM10K_SW_LVMMC
> 	FM10K_SW_REG_OFF(0x18880)
> +#define FM10K_SW_LVMMI
> 	FM10K_SW_REG_OFF(0x18881)
> +#define FM10K_SW_HOST_MISC
> 	FM10K_SW_REG_OFF(0x19000)
> +#define FM10K_SW_HOST_LANE_CTRL
> 	FM10K_SW_REG_OFF(0x19001)
> +#define FM10K_SW_SERDES_CTRL(l_)		FM10K_SW_REG_OFF(0x19010
> + 0x2 * (l_))
> +
> +
> +/*
> + * BAR4 registers
> + */
> +
> +/*
> + * Access to non-master PEP registers via BAR4
> + */
> +#define FM10K_SW_PCIE_GLOBAL(p_, r_)	(FM10K_SW_REG_OFF(((p_) + 1)
> << 20) | FM10K_SW_##r_)
> +
> +/*
> + * SBUS register fields for use with both the PCIE and EPL SBUS interfaces.
> + */
> +#define FM10K_SW_SBUS_CFG_SBUS_CONTROLLER_RESET	(1 << 0)
> +#define FM10K_SW_SBUS_CFG_ROM_ENABLE			(1 << 1)
> +#define FM10K_SW_SBUS_CFG_ROM_BUSY				(1 <<
> 2)
> +#define FM10K_SW_SBUS_CFG_BIST_DONE_PASS		(1 << 3)
> +#define FM10K_SW_SBUS_CFG_BIST_DONE_FAIL		(1 << 4)
> +
> +#define FM10K_SW_SBUS_COMMAND_REGISTER_lsb		0
> +#define FM10K_SW_SBUS_COMMAND_REGISTER_msb		7
> +#define FM10K_SW_SBUS_COMMAND_ADDRESS_lsb		8
> +#define FM10K_SW_SBUS_COMMAND_ADDRESS_msb		15
> +#define FM10K_SW_SBUS_COMMAND_OP_lsb			16
> +#define FM10K_SW_SBUS_COMMAND_OP_msb			23
> +#define FM10K_SW_SBUS_OP_RESET					0x20
> +#define FM10K_SW_SBUS_OP_WRITE					0x21
> +#define FM10K_SW_SBUS_OP_READ					0x22
> +#define FM10K_SW_SBUS_COMMAND_EXECUTE			(1 <<
> 24)
> +#define FM10K_SW_SBUS_COMMAND_BUSY				(1 <<
> 25)
> +#define FM10K_SW_SBUS_COMMAND_RESULT_CODE_lsb	26
> +#define FM10K_SW_SBUS_COMMAND_RESULT_CODE_msb	28
> +#define FM10K_SW_SBUS_RESULT_RESET				0x00
> +#define FM10K_SW_SBUS_RESULT_WRITE				0x01
> +#define FM10K_SW_SBUS_RESULT_READ				0x04
> +
> +#define FM10K_SW_SBUS_ADDR_EPL_RMON2			1
> +#define FM10K_SW_SBUS_ADDR_EPL_LANE(e_, l_)		(4 * (e_) + (l_)
> + 2)
> +#define FM10K_SW_SBUS_ADDR_EPL_SERDES(s_)		((s_) + 2)
> +#define FM10K_SW_SBUS_ADDR_EPL_RMON3			38
> +#define FM10K_SW_SBUS_ADDR_EPL_PMRO				39
> +
> +/* Common to both EPL and PCIE */
> +#define FM10K_SW_SBUS_ADDR_SPICO				253
> +#define FM10K_SW_SBUS_ADDR_SBUS_CONTROLLER		254
> +#define FM10K_SW_SBUS_ADDR_BROADCAST			0xFF
> +
> +
> +#define FM10K_SW_MGMT_BASE
> 	FM10K_SW_REG_OFF(0x000000)
> +#define FM10K_SW_MGMT_REG(wo_)
> 	(FM10K_SW_MGMT_BASE + FM10K_SW_REG_OFF(wo_))
> +
> +#define FM10K_SW_FATAL_CODE
> 	FM10K_SW_MGMT_REG(0x0)
> +#define FM10K_SW_LAST_FATAL_CODE
> 	FM10K_SW_MGMT_REG(0x1)
> +#define FM10K_SW_FATAL_COUNT
> 	FM10K_SW_MGMT_REG(0x2)
> +#define FM10K_SW_SOFT_RESET
> 	FM10K_SW_MGMT_REG(0x3)
> +#define FM10K_SW_SOFT_RESET_COLD_RESET			(1 << 0)
> +#define FM10K_SW_SOFT_RESET_EPL_RESET			(1 << 1)
> +#define FM10K_SW_SOFT_RESET_SWITCH_RESET		(1 << 2)
> +#define FM10K_SW_SOFT_RESET_SWITCH_READY		(1 << 3)
> +#define FM10K_SW_SOFT_RESET_PCIE_RESET(p_)		(1 << ((p_) + 4))
> +#define FM10K_SW_SOFT_RESET_PCIE_ACTIVE(p_) 	(1 << ((p_) + 13))
> +#define FM10K_SW_DEVICE_CFG
> 	FM10K_SW_MGMT_REG(0x4)
> +#define FM10K_SW_DEVICE_CFG_PCIE_MODE_PAIRS 	4
> +#define FM10K_SW_DEVICE_CFG_PCIE_MODE_2X4(p_) 	(1 << (p_))
> +#define FM10K_SW_DEVICE_CFG_PCIE_100G_DIS		(1 << 4)
> +#define FM10K_SW_DEVICE_CFG_FEATURE_lsb			5
> +#define FM10K_SW_DEVICE_CFG_FEATURE_msb			6
> +#define	FM10K_SW_DEVICE_CFG_PCIE_FULL 			0
> +#define	FM10K_SW_DEVICE_CFG_PCIE_HALF 			1
> +#define	FM10K_SW_DEVICE_CFG_PCIE_BASIC 			2
> +#define FM10K_SW_DEVICE_CFG_PCIE_EN(p_)			(1 << (7 + (p_)))
> +#define FM10K_SW_RESET_CFG
> 	FM10K_SW_MGMT_REG(0x5)
> +#define FM10K_SW_WATCHDOG_CFG
> 	FM10K_SW_MGMT_REG(0x6)
> +#define FM10K_SW_MGMT_SCRATCH(n_)
> 	FM10K_SW_MGMT_REG(0x8 + (n_))
> +#define FM10K_SW_VITAL_PRODUCT_DATA
> 	FM10K_SW_MGMT_REG(0x304)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT
> 	FM10K_SW_MGMT_REG(0x400)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_PCIE_BSM_lsb64	0
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_PCIE_BSM_msb64	8
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_PCIE_BSM(n_)	(1ULL
> << (n_))
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_PCIE_lsb64		9
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_PCIE_msb64		17
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_PCIE(n_) 		(1ULL
> << ((n_) + 9))
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_EPL_lsb64		18
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_EPL_msb64		26
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_EPL(n_) 		(1ULL
> << ((n_) + 18))
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_TUNNEL_lsb64	27
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_TUNNEL_msb64	28
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_TUNNEL(n_) 	(1ULL
> << ((n_) + 27))
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_CORE
> 	(1ULL << 29)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_SOFTWARE		(1ULL
> << 30)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_GPIO
> 	(1ULL << 31)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_I2C			(1ULL
> << 32)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_MDIO
> 	(1ULL << 33)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_CRM
> 	(1ULL << 34)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_FH_TAIL		(1ULL
> << 35)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_FH_HEAD		(1ULL
> << 36)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_SBUS_EPL		(1ULL
> << 37)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_SBUS_PCIE		(1ULL
> << 38)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_PINS
> 	(1ULL << 39)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_FIBM
> 	(1ULL << 40)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_BSM
> 	(1ULL << 41)
> +#define FM10K_SW_GLOBAL_INTERRUPT_DETECT_XCLK
> 	(1ULL << 42)
> +#define FM10K_SW_INTERRUPT_MASK_INT
> 		FM10K_SW_MGMT_REG(0x402)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE(p_)
> 	FM10K_SW_MGMT_REG(0x420 + 0x2 * (p_))
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_PCIE_BSM_lsb64		0
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_PCIE_BSM_msb64
> 	8
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_PCIE_BSM(n_)		(1ULL
> << (n_))
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_PCIE_lsb64
> 	9
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_PCIE_msb64
> 	17
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_PCIE(n_)			(1ULL
> << ((n_) + 9))
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_EPL_lsb64
> 	18
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_EPL_msb64
> 	26
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_EPL(n_)			(1ULL
> << ((n_) + 18))
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_TUNNEL_lsb64		27
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_TUNNEL_msb64		28
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_TUNNEL(n_)
> 	(1ULL << ((n_) + 27))
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_CORE
> 	(1ULL << 29)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_SOFTWARE
> 	(1ULL << 30)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_GPIO
> 	(1ULL << 31)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_I2C
> 	(1ULL << 32)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_MDIO
> 	(1ULL << 33)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_CRM
> 	(1ULL << 34)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_FH_TAIL			(1ULL
> << 35)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_FH_HEAD			(1ULL
> << 36)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_SBUS_EPL
> 	(1ULL << 37)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_SBUS_PCIE
> 	(1ULL << 38)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_PINS
> 	(1ULL << 39)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_FIBM
> 	(1ULL << 40)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_BSM
> 	(1ULL << 41)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_XCLK
> 	(1ULL << 42)
> +#define FM10K_SW_INTERRUPT_MASK_PCIE_ALL
> 	FM10K_SW_MASK64(42, 0)
> +#define FM10K_SW_INTERRUPT_MASK_FIBM
> 	FM10K_SW_MGMT_REG(0x440)
> +#define FM10K_SW_INTERRUPT_MASK_BSM
> 	FM10K_SW_MGMT_REG(0x442)
> +#define FM10K_SW_CORE_INTERRUPT_DETECT
> 	FM10K_SW_MGMT_REG(0x444)
> +#define FM10K_SW_CORE_INTERRUPT_MASK
> 	FM10K_SW_MGMT_REG(0x445)
> +#define FM10K_SW_SRAM_ERR_IP
> 	FM10K_SW_MGMT_REG(0x446)
> +#define FM10K_SW_SRAM_ERR_IM
> 	FM10K_SW_MGMT_REG(0x448)
> +#define FM10K_SW_PINS_STAT
> 	FM10K_SW_MGMT_REG(0x44A)
> +#define FM10K_SW_PINS_IP
> 	FM10K_SW_MGMT_REG(0x44B)
> +#define FM10K_SW_PINS_IM
> 	FM10K_SW_MGMT_REG(0x44C)
> +#define FM10K_SW_SW_IP
> 	FM10K_SW_MGMT_REG(0x44D)
> +#define FM10K_SW_SW_IM
> 	FM10K_SW_MGMT_REG(0x44E)
> +#define FM10K_SW_SW_TEST_AND_SET
> 	FM10K_SW_MGMT_REG(0x44F)
> +#define FM10K_SW_LSM_CLKOBS_CTRL
> 	FM10K_SW_MGMT_REG(0x450)
> +#define FM10K_SW_CHIP_VERSION
> 	FM10K_SW_MGMT_REG(0x452)
> +#define FM10K_SW_BSM_SCRATCH(n_)
> 	FM10K_SW_MGMT_REG(0x800 + (n_))
> +#define FM10K_SW_BSM_CTRL
> 	FM10K_SW_MGMT_REG(0xC00)
> +#define FM10K_SW_BSM_ARGS
> 	FM10K_SW_MGMT_REG(0xC01)
> +#define FM10K_SW_BSM_ADDR_OFFSET(n_)
> 	FM10K_SW_MGMT_REG(0xC04 + (n_))
> +#define FM10K_SW_BSM_COUNTER(n_)
> 	FM10K_SW_MGMT_REG(0xC08 + (n_))
> +#define FM10K_SW_BSM_SRAM_CTRL
> 	FM10K_SW_MGMT_REG(0xC0A)
> +#define FM10K_SW_BSM_IP
> 	FM10K_SW_MGMT_REG(0xC0B)
> +#define FM10K_SW_BSM_IM
> 	FM10K_SW_MGMT_REG(0xC0C)
> +#define FM10K_SW_PIN_STRAP_STAT
> 	FM10K_SW_MGMT_REG(0xC0D)
> +#define FM10K_SW_FUSE_DATA_0
> 	FM10K_SW_MGMT_REG(0xC0E)
> +#define FM10K_SW_FUSE_SKU_lsb			11
> +#define FM10K_SW_FUSE_SKU_msb			15
> +#define FM10K_SW_FUSE_SKU_FM10840		0
> +#define FM10K_SW_FUSE_SKU_FM10420		1
> +#define FM10K_SW_FUSE_SKU_FM10064		2
> +#define FM10K_SW_FUSE_DATA_1
> 	FM10K_SW_MGMT_REG(0xC0F)
> +#define FM10K_SW_BIST_CTRL
> 	FM10K_SW_MGMT_REG(0xC10)
> +#define FM10K_SW_BIST_CTRL_BIST_RUN_PCIE(p_) 	(1ULL << (p_))
> +#define FM10K_SW_BIST_CTRL_BIST_RUN_EPL			(1ULL << 9)
> +#define FM10K_SW_BIST_CTRL_BIST_RUN_FABRIC		(1ULL << 10)
> +#define FM10K_SW_BIST_CTRL_BIST_RUN_TUNNEL		(1ULL << 11)
> +#define FM10K_SW_BIST_CTRL_BIST_RUN_BSM			(1ULL
> << 12)
> +#define FM10K_SW_BIST_CTRL_BIST_RUN_CRM			(1ULL
> << 13)
> +#define FM10K_SW_BIST_CTRL_BIST_RUN_FIBM		(1ULL << 14)
> +#define FM10K_SW_BIST_CTRL_BIST_RUN_SBM			(1ULL
> << 15)
> +#define FM10K_SW_BIST_CTRL_BIST_MODE_PCIE(p_) 	(1ULL << (p_))
> +#define FM10K_SW_BIST_CTRL_BIST_MODE_EPL		(1ULL << 41)
> +#define FM10K_SW_BIST_CTRL_BIST_MODE_FABRIC 	(1ULL << 42)
> +#define FM10K_SW_BIST_CTRL_BIST_MODE_TUNNEL 	(1ULL << 43)
> +#define FM10K_SW_BIST_CTRL_BIST_MODE_BSM		(1ULL << 44)
> +#define FM10K_SW_BIST_CTRL_BIST_MODE_CRM		(1ULL << 45)
> +#define FM10K_SW_BIST_CTRL_BIST_MODE_FIBM		(1ULL << 46)
> +#define FM10K_SW_BIST_CTRL_BIST_MODE_SBM		(1ULL << 47)
> +#define FM10K_SW_REI_CTRL
> 	FM10K_SW_MGMT_REG(0xC12)
> +#define FM10K_SW_REI_STAT
> 	FM10K_SW_MGMT_REG(0xC13)
> +#define FM10K_SW_GPIO_CFG
> 	FM10K_SW_MGMT_REG(0xC15)
> +#define FM10K_SW_GPIO_DATA
> 	FM10K_SW_MGMT_REG(0xC16)
> +#define FM10K_SW_GPIO_IP
> 	FM10K_SW_MGMT_REG(0xC17)
> +#define FM10K_SW_GPIO_IM
> 	FM10K_SW_MGMT_REG(0xC18)
> +#define FM10K_SW_I2C_CFG
> 	FM10K_SW_MGMT_REG(0xC19)
> +#define FM10K_SW_I2C_CFG_SLAVE_ENABLE			(1 << 0)
> +#define FM10K_SW_I2C_CFG_ADDR_lsb				1
> +#define FM10K_SW_I2C_CFG_ADDR_msb				7
> +#define FM10K_SW_I2C_CFG_DIVIDER_lsb			8
> +#define FM10K_SW_I2C_CFG_DIVIDER_msb			19
> +#define	FM10K_SW_I2C_CFG_DIVIDER_100_KHZ		52
> +#define	FM10K_SW_I2C_CFG_DIVIDER_400_KHZ		10
> +#define FM10K_SW_I2C_CFG_INTERRUPT_MASK			(1 <<
> 20)
> +#define FM10K_SW_I2C_CFG_DEBOUNCE_FILTER_COUNT_LIMIT_lsb 21
> +#define FM10K_SW_I2C_CFG_DEBOUNCE_FILTER_COUNT_LIMIT_msb 27
> +#define FM10K_SW_I2C_DATA(n_)
> 	FM10K_SW_MGMT_REG(0xC1C + (n_))
> +#define FM10K_SW_I2C_CTRL
> 	FM10K_SW_MGMT_REG(0xC20)
> +#define FM10K_SW_I2C_CTRL_ADDR_lsb				0
> +#define FM10K_SW_I2C_CTRL_ADDR_msb				7
> +#define FM10K_SW_I2C_CTRL_COMMAND_lsb			8
> +#define FM10K_SW_I2C_CTRL_COMMAND_msb			9
> +#define	FM10K_SW_I2C_COMMAND_NULL
> 	0
> +#define	FM10K_SW_I2C_COMMAND_WR
> 		1
> +#define	FM10K_SW_I2C_COMMAND_WR_RD
> 	2
> +#define	FM10K_SW_I2C_COMMAND_RD
> 		3
> +#define FM10K_SW_I2C_CTRL_LENGTH_W_lsb			10
> +#define FM10K_SW_I2C_CTRL_LENGTH_W_msb			13
> +#define FM10K_SW_I2C_CTRL_LENGTH_R_lsb			14
> +#define FM10K_SW_I2C_CTRL_LENGTH_R_msb			17
> +#define FM10K_SW_I2C_CTRL_LENGTH_SENT_lsb		18
> +#define FM10K_SW_I2C_CTRL_LENGTH_SENT_msb		21
> +#define FM10K_SW_I2C_CTRL_COMMAND_COMPLETED_lsb 22
> +#define FM10K_SW_I2C_CTRL_COMMAND_COMPLETED_msb 25
> +#define	FM10K_SW_I2C_COMPLETION_RUNNING
> 	0
> +#define	FM10K_SW_I2C_COMPLETION_NORMAL
> 	1
> +#define	FM10K_SW_I2C_COMPLETION_PREMATURE		2
> +#define	FM10K_SW_I2C_COMPLETION_NO_DEVICE		3
> +#define	FM10K_SW_I2C_COMPLETION_TIMEOUT
> 	4
> +#define	FM10K_SW_I2C_COMPLETION_LOST_ARB		5
> +#define	FM10K_SW_I2C_COMPLETION_BUS_WAIT		6
> +#define	FM10K_SW_I2C_COMPLETION_INVALID			7
> +#define FM10K_SW_I2C_CTRL_INTERRUPT_PENDING 	(1 << 26)
> +#define FM10K_SW_MDIO_CFG
> 	FM10K_SW_MGMT_REG(0xC22)
> +#define FM10K_SW_MDIO_DATA
> 	FM10K_SW_MGMT_REG(0xC23)
> +#define FM10K_SW_MDIO_CTRL
> 	FM10K_SW_MGMT_REG(0xC24)
> +#define FM10K_SW_SPI_TX_DATA
> 	FM10K_SW_MGMT_REG(0xC26)
> +#define FM10K_SW_SPI_RX_DATA
> 	FM10K_SW_MGMT_REG(0xC27)
> +#define FM10K_SW_SPI_HEADER
> 	FM10K_SW_MGMT_REG(0xC28)
> +#define FM10K_SW_SPI_CTRL
> 	FM10K_SW_MGMT_REG(0xC29)
> +#define FM10K_SW_LED_CFG
> 	FM10K_SW_MGMT_REG(0xC2B)
> +#define FM10K_SW_SCAN_DATA_IN
> 	FM10K_SW_MGMT_REG(0xC2D)
> +#define FM10K_SW_SCAN_DATA_IN_SCAN_DATA_lsb 	0
> +#define FM10K_SW_SCAN_DATA_IN_SCAN_DATA_msb 	24
> +#define FM10K_SW_SCAN_DATA_IN_SHIFT_IN			(1 << 25)
> +#define FM10K_SW_SCAN_DATA_IN_SHIFT_OUT			(1 <<
> 26)
> +#define FM10K_SW_SCAN_DATA_IN_UPDATE_NODES		(1 << 27)
> +#define FM10K_SW_SCAN_DATA_IN_INJECT			(1 << 28)
> +#define FM10K_SW_SCAN_DATA_IN_DRAIN				(1 <<
> 29)
> +#define FM10K_SW_SCAN_DATA_IN_PASSTHRU			(1 <<
> 30)
> +#define FM10K_SW_SCAN_DATA_IN_SINGLE			(1 << 31)
> +#define FM10K_SW_CRM_DATA(m_, n_)
> 	FM10K_SW_MGMT_REG(0x1000 + 0x2 * (m_) + (n_))
> +#define FM10K_SW_CRM_CTRL
> 	FM10K_SW_MGMT_REG(0x2000)
> +#define FM10K_SW_CRM_STATUS
> 	FM10K_SW_MGMT_REG(0x2001)
> +#define FM10K_SW_CRM_TIME
> 	FM10K_SW_MGMT_REG(0x2002)
> +#define FM10K_SW_CRM_SRAM_CTRL
> 	FM10K_SW_MGMT_REG(0x2004)
> +#define FM10K_SW_CRM_IP
> 	FM10K_SW_MGMT_REG(0x2008)
> +#define FM10K_SW_CRM_IM
> 	FM10K_SW_MGMT_REG(0x200C)
> +#define FM10K_SW_CRM_COMMAND(n_)
> 	FM10K_SW_MGMT_REG(0x2080 + 0x2 * (n_))
> +#define FM10K_SW_CRM_REGISTER(n_)
> 	FM10K_SW_MGMT_REG(0x2100 + 0x2 * (n_))
> +#define FM10K_SW_CRM_PERIOD(n_)
> 	FM10K_SW_MGMT_REG(0x2180 + 0x2 * (n_))
> +#define FM10K_SW_CRM_PARAM(n_)
> 	FM10K_SW_MGMT_REG(0x2200 + (n_))
> +#define FM10K_SW_PLL_PCIE_CTRL
> 	FM10K_SW_MGMT_REG(0x2241)
> +#define FM10K_SW_PLL_PCIE_STAT
> 	FM10K_SW_MGMT_REG(0x2242)
> +#define FM10K_SW_SBUS_PCIE_CFG
> 	FM10K_SW_MGMT_REG(0x2243)
> +#define FM10K_SW_SBUS_PCIE_COMMAND
> 	FM10K_SW_MGMT_REG(0x2244)
> +#define FM10K_SW_SBUS_PCIE_REQUEST
> 	FM10K_SW_MGMT_REG(0x2245)
> +#define FM10K_SW_SBUS_PCIE_RESPONSE
> 	FM10K_SW_MGMT_REG(0x2246)
> +#define FM10K_SW_SBUS_PCIE_SPICO_IN
> 	FM10K_SW_MGMT_REG(0x2247)
> +#define FM10K_SW_SBUS_PCIE_SPICO_OUT
> 	FM10K_SW_MGMT_REG(0x2248)
> +#define FM10K_SW_SBUS_PCIE_IP
> 	FM10K_SW_MGMT_REG(0x2249)
> +#define FM10K_SW_SBUS_PCIE_IM
> 	FM10K_SW_MGMT_REG(0x224A)
> +#define FM10K_SW_MGMT_SYSTIME_CFG
> 	FM10K_SW_MGMT_REG(0x224C)
> +#define FM10K_SW_MGMT_SYSTIME
> 	FM10K_SW_MGMT_REG(0x224E)
> +#define FM10K_SW_MGMT_SYSTIME0
> 	FM10K_SW_MGMT_REG(0x2250)
> +#define FM10K_SW_SYSTIME_PULSE_(n_)
> 	FM10K_SW_MGMT_REG(0x2252 + (n_))
> +#define FM10K_SW_SYSTIME_CAPTURE_LO(n_)
> 	FM10K_SW_MGMT_REG(0x2258 + 0x2 * (n_))
> +#define FM10K_SW_SYSTIME_CAPTURE_HI(n_)
> 	FM10K_SW_MGMT_REG(0x2258 + 0x2 * (n_) + 0x1)
> +#define FM10K_SW_PCIE_XPLL_CTRL
> 	FM10K_SW_MGMT_REG(0x3000)
> +#define FM10K_SW_PCIE_CLK_CTRL
> 	FM10K_SW_MGMT_REG(0x3001)
> +#define FM10K_SW_PCIE_CLK_CTRL2
> 	FM10K_SW_MGMT_REG(0x3002)
> +#define FM10K_SW_PCIE_CLKMON_RATIO_CFG
> 	FM10K_SW_MGMT_REG(0x3003)
> +#define FM10K_SW_PCIE_CLKMON_TOLERANCE_CFG
> 	FM10K_SW_MGMT_REG(0x3004)
> +#define FM10K_SW_PCIE_CLKMON_DEADLINES_CFG
> 	FM10K_SW_MGMT_REG(0x3005)
> +#define FM10K_SW_PCIE_CLK_STAT
> 	FM10K_SW_MGMT_REG(0x3006)
> +#define FM10K_SW_PCIE_CLK_IP
> 	FM10K_SW_MGMT_REG(0x3007)
> +#define FM10K_SW_PCIE_CLK_IM
> 	FM10K_SW_MGMT_REG(0x3008)
> +#define FM10K_SW_PCIE_WARM_RESET_DELAY
> 	FM10K_SW_MGMT_REG(0x3009)
> +#define FM10K_SW_EPL_BASE
> 	FM10K_SW_REG_OFF(0x0E0000)
> +#define FM10K_SW_EPL_PORT_REG(p_, r_)
> 	(FM10K_SW_EPL_BASE + FM10K_SW_REG_OFF(0x400 * (p_) + (r_)))
> +#define FM10K_SW_EPL_LANE_REG(p_, l_, r_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x80 * (l_) + (r_))
> +
> +/* EPL enumerated types */
> +#define FM10K_SW_EPL_QPL_MODE_XX_XX_XX_XX		0
> +#define FM10K_SW_EPL_QPL_MODE_L1_L1_L1_L1		1
> +#define FM10K_SW_EPL_QPL_MODE_XX_XX_XX_L4		2
> +#define FM10K_SW_EPL_QPL_MODE_XX_XX_L4_XX		3
> +#define FM10K_SW_EPL_QPL_MODE_XX_L4_XX_XX		4
> +#define FM10K_SW_EPL_QPL_MODE_L4_XX_XX_XX		5
> +#define FM10K_SW_EPL_PCS_SEL_DISABLE			0
> +#define FM10K_SW_EPL_PCS_SEL_AN_73				1
> +#define FM10K_SW_EPL_PCS_SEL_SGMII_10			2
> +#define FM10K_SW_EPL_PCS_SEL_SGMII_100			3
> +#define FM10K_SW_EPL_PCS_SEL_SGMII_1000			4
> +#define FM10K_SW_EPL_PCS_SEL_1000BASEX			5
> +#define FM10K_SW_EPL_PCS_SEL_10GBASER			6
> +#define FM10K_SW_EPL_PCS_SEL_40GBASER			7
> +#define FM10K_SW_EPL_PCS_SEL_100GBASER			8
> +
> +#define FM10K_SW_LANE_OVERRIDE_NORMAL			0
> +#define FM10K_SW_LANE_OVERRIDE_FORCE_GOOD		1
> +#define FM10K_SW_LANE_OVERRIDE_FORCE_BAD		2
> +
> +#define FM10K_SW_TX_MAX_FCS_MODE_PASSTHRU		0
> +#define FM10K_SW_TX_MAX_FCS_MODE_PASSSTHRU_CHECK	1
> +#define FM10K_SW_TX_MAX_FCS_MODE_REPLACE_GOOD	2
> +#define FM10K_SW_TX_MAX_FCS_MODE_REPLACE_BAD	3
> +#define FM10K_SW_TX_MAX_FCS_MODE_REPLACE_NORMAL	4
> +
> +#define FM10K_SW_TX_MAC_DRAIN_MODE_DRAIN_DRAIN	0
> +#define FM10K_SW_TX_MAC_DRAIN_MODE_DRAIN_NORMAL	1
> +#define FM10K_SW_TX_MAC_DRAIN_MODE_HOLD_NORMAL	2
> +#define FM10K_SW_TX_MAC_DRAIN_MODE_HOLD_HOLD	3
> +
> +#define FM10K_SW_TX_MAC_FAULT_MODE_NORMAL
> 	0
> +#define FM10K_SW_TX_MAC_FAULT_MODE_FORCE_IDLE
> 	1
> +#define FM10K_SW_TX_MAC_FAULT_MODE_FORCE_LOCAL_FAULT	2
> +#define FM10K_SW_TX_MAC_FAULT_MODE_FORCE_REMOTE_FAULT	3
> +#define FM10K_SW_TX_MAC_FAULT_MODE_FORCE_LINK_INTERRUPTION
> 	4
> +#define FM10K_SW_TX_MAC_FAULT_MODE_FORCE_OK
> 		5
> +#define FM10K_SW_TX_MAC_FAULT_MODE_FORCE_ERROR
> 	6
> +#define FM10K_SW_TX_MAC_FAULT_MODE_FORCE_USER_VAL		7
> +
> +#define FM10K_SW_EPL_IP(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x300)
> +#define FM10K_SW_EPL_IP_AN_PORT_INTERRUPT_lsb	0
> +#define FM10K_SW_EPL_IP_AN_PORT_INTERRUPT_msb	3
> +#define FM10K_SW_EPL_IP_AN_PORT_INTERRUPT(n_)	(1 << ((n_) + 0))
> +#define FM10K_SW_EPL_IP_LINK_PORT_INTERRUPT_lsb	4
> +#define FM10K_SW_EPL_IP_LINK_PORT_INTERRUPT_msb	7
> +#define FM10K_SW_EPL_IP_LINK_PORT_INTERRUPT(n_)	(1 << ((n_) + 4))
> +#define FM10K_SW_EPL_IP_SERDES_INTERRUPT_lsb	8
> +#define FM10K_SW_EPL_IP_SERDES_INTERRUPT_msb	11
> +#define FM10K_SW_EPL_IP_SERDES_INTERRUPT(n_)	(1 << ((n_) + 8))
> +#define FM10K_SW_EPL_IP_ERROR_INTERRUPT			(1 <<
> 12)
> +#define FM10K_SW_EPL_ERROR_IP(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x301)
> +#define FM10K_SW_EPL_ERROR_IM(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x302)
> +#define FM10K_SW_EPL_ERROR_IM_ALL
> 	FM10K_SW_MASK32(8, 0)
> +#define FM10K_SW_EPL_BIST_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x303)
> +#define FM10K_SW_EPL_CFG_A(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x304)
> +#define FM10K_SW_EPL_CFG_A_SPEED_UP				(1 <<
> 0)
> +#define FM10K_SW_EPL_CFG_A_TIMEOUT_lsb			1
> +#define FM10K_SW_EPL_CFG_A_TIMEOUT_msb			6
> +#define FM10K_SW_EPL_CFG_A_ACTIVE(p_)			(1 << ((p_) + 7))
> +#define FM10K_SW_EPL_CFG_A_ACTIVE_QUAD			(0xf
> << 7)
> +#define FM10K_SW_EPL_CFG_A_SKEW_TOLERANCE_lsb 	11
> +#define FM10K_SW_EPL_CFG_A_SKEW_TOLERANCE_msb 	16
> +#define FM10K_SW_EPL_CFG_B(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x305)
> +#define FM10K_SW_EPL_CFG_B_PCS_SEL_lsb(p_)		((p_) * 4)
> +#define FM10K_SW_EPL_CFG_B_PCS_SEL_msb(p_) 		(((p_) * 4) + 3)
> +#define FM10K_SW_EPL_CFG_B_QPL_MODE_lsb			16
> +#define FM10K_SW_EPL_CFG_B_QPL_MODE_msb			18
> +#define FM10K_SW_EPL_LED_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x306)
> +#define FM10K_SW_EPL_LED_STATUS_PORT_RESET(n_)	(1 << ((n_) * 6
> + 0))
> +#define FM10K_SW_EPL_LED_STATUS_PORT_LINK_UP(n_)	(1 << ((n_) * 6
> + 1))
> +#define FM10K_SW_EPL_LED_STATUS_PORT_LOCAL_FAULT(n_) 	(1 <<
> ((n_) * 6 + 2))
> +#define FM10K_SW_EPL_LED_STATUS_PORT_REMOTE_FAULT(n_) 	(1 <<
> ((n_) * 6 + 3))
> +#define FM10K_SW_EPL_LED_STATUS_PORT_TRANSMITTING(n_) 	(1 <<
> ((n_) * 6 + 4))
> +#define FM10K_SW_EPL_LED_STATUS_PORT_RECEIVING(n_)		(1 <<
> ((n_) * 6 + 5))
> +#define FM10K_SW_EPL_FIFO_ERROR_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x307)
> +#define FM10K_SW_EPL_TX_FIFO_RD_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x308)
> +#define FM10K_SW_EPL_TX_FIFO_WR_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x309)
> +#define FM10K_SW_EPL_TX_FIFO_A_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x30A)
> +#define FM10K_SW_EPL_TX_FIFO_B_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x30B)
> +#define FM10K_SW_EPL_TX_FIFO_C_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x30C)
> +#define FM10K_SW_EPL_TX_FIFO_D_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x30D)
> +#define FM10K_SW_EPL_RX_FIFO_RD_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x30E)
> +#define FM10K_SW_EPL_RX_FIFO_WR_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x30F)
> +#define FM10K_SW_EPL_RX_FIFO_A_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x310)
> +#define FM10K_SW_EPL_RX_FIFO_B_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x311)
> +#define FM10K_SW_EPL_RX_FIFO_C_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x312)
> +#define FM10K_SW_EPL_RX_FIFO_D_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x313)
> +#define FM10K_SW_PCS_ML_BASER_CFG(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x314)
> +#define FM10K_SW_PCS_ML_BASER_RX_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x315)
> +#define FM10K_SW_PCS_100GBASER_BIP_0(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x317)
> +#define FM10K_SW_PCS_100GBASER_BIP_1(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x318)
> +#define FM10K_SW_PCS_100GBASER_BIP_2(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x319)
> +#define FM10K_SW_PCS_100GBASER_BIP_3(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x31A)
> +#define FM10K_SW_PCS_100GBASER_BIP_4(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x31B)
> +#define FM10K_SW_PCS_100GBASER_BIP_5(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x31C)
> +#define FM10K_SW_PCS_100GBASER_BIP_6(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x31D)
> +#define FM10K_SW_PCS_100GBASER_BIP_7(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x31E)
> +#define FM10K_SW_PCS_100GBASER_BIP_8(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x31F)
> +#define FM10K_SW_PCS_100GBASER_BIP_9(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x320)
> +#define FM10K_SW_PCS_100GBASER_BIP_10(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x321)
> +#define FM10K_SW_PCS_100GBASER_BIP_11(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x322)
> +#define FM10K_SW_PCS_100GBASER_BIP_12(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x323)
> +#define FM10K_SW_PCS_100GBASER_BIP_13(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x324)
> +#define FM10K_SW_PCS_100GBASER_BIP_14(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x325)
> +#define FM10K_SW_PCS_100GBASER_BIP_15(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x326)
> +#define FM10K_SW_PCS_100GBASER_BIP_16(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x327)
> +#define FM10K_SW_PCS_100GBASER_BIP_17(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x328)
> +#define FM10K_SW_PCS_100GBASER_BIP_18(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x329)
> +#define FM10K_SW_PCS_100GBASER_BIP_19(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x32A)
> +#define FM10K_SW_PCS_100GBASER_BLOCK_LOCK(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x32B)
> +#define FM10K_SW_PCS_100GBASER_AMPS_LOCK(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x32C)
> +#define FM10K_SW_RS_FEC_UNCORRECTED(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x33D)
> +#define FM10K_SW_RS_FEC_CFG(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x32E)
> +#define FM10K_SW_RS_FEC_STATUS(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x330)
> +#define FM10K_SW_EPL_SYSTIME(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x331)
> +#define FM10K_SW_EPL_SYSTIME0(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x332)
> +#define FM10K_SW_EPL_SYSTIME_CFG(p_)
> 	FM10K_SW_EPL_PORT_REG((p_), 0x333)
> +#define FM10K_SW_PORT_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x0)
> +#define FM10K_SW_AN_IM(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x1)
> +#define FM10K_SW_AN_IM_ALL
> 	FM10K_SW_MASK32(18,0)
> +#define FM10K_SW_LINK_IM(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x2)
> +#define FM10K_SW_LINK_IM_ALL
> 	FM10K_SW_MASK32(29,0)
> +#define FM10K_SW_AN_IP(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x3)
> +#define FM10K_SW_LINK_IP(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x4)
> +#define FM10K_SW_MP_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x6)
> +#define FM10K_SW_AN_37_PAGE_RX(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x8)
> +#define FM10K_SW_AN_73_PAGE_RX(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0xA)
> +#define FM10K_SW_LINK_RULES(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0xC)
> +#define FM10K_SW_LINK_RULES_FAULT_TIME_SCALE_UP_lsb		0
> +#define FM10K_SW_LINK_RULES_FAULT_TIME_SCALE_UP_msb		3
> +#define FM10K_SW_LINK_RULES_FAULT_TICKS_UP_lsb			4
> +#define FM10K_SW_LINK_RULES_FAULT_TICKS_UP_msb
> 	8
> +#define FM10K_SW_LINK_RULES_FAULT_TIME_SCALE_DOWN_lsb	9
> +#define FM10K_SW_LINK_RULES_FAULT_TIME_SCALE_DOWN_msb	12
> +#define FM10K_SW_LINK_RULES_FAULT_TICKS_DOWN_lsb		13
> +#define FM10K_SW_LINK_RULES_FAULT_TICKS_DOWN_msb		17
> +#define FM10K_SW_LINK_RULES_HEARTBEAT_TIME_SCALE_lsb	18
> +#define FM10K_SW_LINK_RULES_HEARTBEAT_TIME_SCALE_msb	21
> +#define FM10K_SW_MAC_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x10)
> +#define FM10K_SW_MAC_CFG_ARRAY_SIZE
> 		8
> +#define FM10K_SW_MAC_CFG_TX_ANTI_BUBBLE_WATERMARK_lsb	0
> +#define FM10K_SW_MAC_CFG_TX_ANTI_BUBBLE_WATERMARK_msb	5
> +#define FM10K_SW_MAC_CFG_TX_RATE_FIFO_WATERMARK_lsb
> 	6
> +#define FM10K_SW_MAC_CFG_TX_RATE_FIFO_WATERMARK_msb
> 	9
> +#define FM10K_SW_MAC_CFG_TX_RATE_FIFO_FAST_INC_lsb		10
> +#define FM10K_SW_MAC_CFG_TX_RATE_FIFO_FAST_INC_msb		17
> +#define FM10K_SW_MAC_CFG_TX_RATE_FIFO_SLOW_INC_lsb		18
> +#define FM10K_SW_MAC_CFG_TX_RATE_FIFO_SLOW_INC_msb		25
> +#define FM10K_SW_MAC_CFG_TX_IDLE_MIN_IFG_BYTES_lsb		26
> +#define FM10K_SW_MAC_CFG_TX_IDLE_MIN_IFG_BYTES_msb		31
> +#define FM10K_SW_MAC_CFG_TX_CLOCK_COMPENSATION_TIMEOUT_lsb
> 	32
> +#define FM10K_SW_MAC_CFG_TX_CLOCK_COMPENSATION_TIMEOUT_msb
> 	47
> +#define FM10K_SW_MAC_CFG_TX_CLOCK_COMPENSATION_ENABLE_bit
> 	48
> +#define FM10K_SW_MAC_CFG_TX_FAULT_MODE_lsb
> 	49
> +#define FM10K_SW_MAC_CFG_TX_FAULT_MODE_msb
> 	51
> +#define FM10K_SW_MAC_CFG_TX_PC_ACT_TIME_SCALE_lsb		52
> +#define FM10K_SW_MAC_CFG_TX_PC_ACT_TIME_SCALE_msb		55
> +#define FM10K_SW_MAC_CFG_TX_PC_ACT_TIMEOUT_lsb
> 	56
> +#define FM10K_SW_MAC_CFG_TX_PC_ACT_TIMEOUT_msb
> 	63
> +#define FM10K_SW_MAC_CFG_TX_DRAIN_MODE_lsb
> 	64
> +#define FM10K_SW_MAC_CFG_TX_DRAIN_MODE_msb
> 	65
> +#define FM10K_SW_MAC_CFG_TX_MIN_COLUMNS_lsb
> 	66
> +#define FM10K_SW_MAC_CFG_TX_MIN_COLUMNS_msb
> 		71
> +#define FM10K_SW_MAC_CFG_TX_SEG_MIN_SPACING_lsb
> 	72
> +#define FM10K_SW_MAC_CFG_TX_SEG_MIN_SPACING_msb
> 	83
> +#define FM10K_SW_MAC_CFG_TX_SEG_MAX_CREDIT_lsb
> 	84
> +#define FM10K_SW_MAC_CFG_TX_SEG_MAX_CREDIT_msb
> 	95
> +#define FM10K_SW_MAC_CFG_TX_SEG_SIZE_lsb
> 	96
> +#define FM10K_SW_MAC_CFG_TX_SEG_SIZE_msb
> 	107
> +#define FM10K_SW_MAC_CFG_TX_LP_IDLE_REQUEST_bit
> 	108
> +#define FM10K_SW_MAC_CFG_TX_LPI_AUTOMATIC_bit
> 	109
> +#define FM10K_SW_MAC_CFG_TX_LPI_TIMEOUT_lsb
> 	110
> +#define FM10K_SW_MAC_CFG_TX_LPI_TIMEOUT_msb
> 	117
> +#define FM10K_SW_MAC_CFG_TX_LPI_TIME_SCALE_lsb
> 	118
> +#define FM10K_SW_MAC_CFG_TX_LPI_TIME_SCALE_msb
> 	119
> +#define FM10K_SW_MAC_CFG_TX_LPI_HOLD_TIMEOUT_lsb		120
> +#define FM10K_SW_MAC_CFG_TX_LPI_HOLD_TIMEOUT_msb		127
> +#define FM10K_SW_MAC_CFG_TX_LPI_HOLD_TIME_SCALE_lsb		128
> +#define FM10K_SW_MAC_CFG_TX_LPI_HOLD_TIME_SCALE_msb
> 	129
> +#define FM10K_SW_MAC_CFG_TX_FCS_MODE_lsb
> 	130
> +#define FM10K_SW_MAC_CFG_TX_FCS_MODE_msb
> 	132
> +#define FM10K_SW_MAC_CFG_TX_OBEY_LINT_bit
> 	133
> +#define FM10K_SW_MAC_CFG_TX_IDLE_ENABLE_DIC_bit
> 	134
> +#define FM10K_SW_MAC_CFG_CJPAT_ENABLE_bit
> 	135
> +#define FM10K_SW_MAC_CFG_RX_MIN_FRAME_LENGTH_lsb		136
> +#define FM10K_SW_MAC_CFG_RX_MIN_FRAME_LENGTH_msb		143
> +#define FM10K_SW_MAC_CFG_RX_MAX_FRAME_LENGTH_lsb		144
> +#define FM10K_SW_MAC_CFG_RX_MAX_FRAME_LENGTH_msb		159
> +#define FM10K_SW_MAC_CFG_START_CHAR_D_lsb
> 	160
> +#define FM10K_SW_MAC_CFG_START_CHAR_D_msb
> 	167
> +#define FM10K_SW_MAC_CFG_IEEE_1588_ENABLE_bit			168
> +#define FM10K_SW_MAC_CFG_FCS_START_bit
> 	169
> +#define FM10K_SW_MAC_CFG_PREAMBLE_MODE_bit
> 	170
> +#define FM10K_SW_MAC_CFG_COUNTER_WRAP_bit
> 	171
> +#define FM10K_SW_MAC_CFG_LINK_FAULT_DISABLE_bit
> 	172
> +#define FM10K_SW_MAC_CFG_RX_DRAIN_bit
> 	173
> +#define FM10K_SW_MAC_CFG_RX_FCS_FORCE_BAD_bit
> 	174
> +#define FM10K_SW_MAC_CFG_RX_IGNORE_CODE_ERRORS_bit		175
> +#define FM10K_SW_MAC_CFG_RX_IGNORE_UNDERSIZE_ERRORS_bit	176
> +#define FM10K_SW_MAC_CFG_RX_IGNORE_OVERSIZE_ERRORS_bit	177
> +#define FM10K_SW_MAC_CFG_RX_IGNORE_FCS_ERRORS_bit		178
> +#define FM10K_SW_MAC_CFG_RX_IGNORE_PREAMBLE_ERRORS_bit	179
> +#define FM10K_SW_MAC_CFG_RX_IGNORE_IFG_ERRORS_bit		180
> +#define FM10K_SW_MAC_CFG_ERR_WRITE_lsb
> 	181
> +#define FM10K_SW_MAC_CFG_ERR_WRITE_msb
> 		182
> +#define FM10K_SW_MAC_CFG_RX_MIN_EVENT_RATE_lsb
> 	183
> +#define FM10K_SW_MAC_CFG_RX_MIN_EVENT_RATE_msb
> 	186
> +#define FM10K_SW_MAC_CFG_RX_PC_REQUEST_lsb
> 	187
> +#define FM10K_SW_MAC_CFG_RX_PC_REQUEST_msb
> 	191
> +#define FM10K_SW_MAC_CFG_RX_PC_SEG_SIZE_lsb
> 	192
> +#define FM10K_SW_MAC_CFG_RX_PC_SEG_SIZE_msb
> 	196
> +#define FM10K_SW_TX_SEQUENCE(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x1A)
> +#define FM10K_SW_RX_SEQUENCE(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x1C)
> +#define FM10K_SW_MAC_1588_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x1E)
> +#define FM10K_SW_WAKE_ERROR_COUNTER(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x20)
> +#define FM10K_SW_MAC_OVERSIZE_COUNTER(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x21)
> +#define FM10K_SW_MAC_JABBER_COUNTER(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x22)
> +#define FM10K_SW_MAC_UNDERSIZE_COUNTER(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x23)
> +#define FM10K_SW_MAC_RUNT_COUNTER(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x24)
> +#define FM10K_SW_MAC_OVERRUN_COUNTER(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x25)
> +#define FM10K_SW_MAC_UNDERRUN_COUNTER(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x26)
> +#define FM10K_SW_MAC_CODE_ERROR_COUNTER(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x27)
> +#define FM10K_SW_EPL_TX_FRAME_ERROR_COUNTER(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x28)
> +#define FM10K_SW_MAC_LINK_COUNTER(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x29)
> +#define FM10K_SW_PCS_1000BASEX_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x2A)
> +#define FM10K_SW_PCS_1000BASEX_RX_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x2B)
> +#define FM10K_SW_PCS_1000BASEX_TX_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x2C)
> +#define FM10K_SW_PCS_10GBASER_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x2D)
> +#define FM10K_SW_PCS_10GBASER_RX_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x2E)
> +#define FM10K_SW_PCS_10GBASER_TX_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x2F)
> +#define FM10K_SW_AN_37_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x30)
> +#define FM10K_SW_AN_37_TIMER_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x34)
> +#define FM10K_SW_AN_37_BASE_PAGE_TX(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x6)
> +#define FM10K_SW_AN_37_BASE_PAGE_RX(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x8)
> +#define FM10K_SW_AN_37_NEXT_PAGE_TX(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x6)
> +#define FM10K_SW_AN_37_NEXT_PAGE_RX(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x8)
> +#define FM10K_SW_SGMII_AN_TIMER_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x34)
> +#define FM10K_SW_SGMII_AN_TX_CONFIG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x6)
> +#define FM10K_SW_SGMII_AN_TX_CONFIG_LOOPBACK(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x6)
> +#define FM10K_SW_SGMII_AN_RX_CONFIG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x8)
> +#define FM10K_SW_AN_37_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x32)
> +#define FM10K_SW_AN_73_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x33)
> +#define FM10K_SW_AN_73_TIMER_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x34)
> +#define FM10K_SW_AN_73_BASE_PAGE_TX(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x6)
> +#define FM10K_SW_AN_73_BASE_PAGE_RX(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0xA)
> +#define FM10K_SW_AN_73_NEXT_PAGE_TX(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x6)
> +#define FM10K_SW_AN_73_NEXT_PAGE_RX(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0xA)
> +#define FM10K_SW_AN_73_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x36)
> +#define FM10K_SW_AN_73_TX_LCW(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x38)
> +#define FM10K_SW_AN_73_RX_LCW(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x3A)
> +#define FM10K_SW_PCSL_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x3C)
> +#define FM10K_SW_PCSL_CFG_SLIP_TIME_lsb
> 	0
> +#define FM10K_SW_PCSL_CFG_SLIP_TIME_msb
> 	7
> +#define FM10K_SW_PCSL_CFG_RX_BIT_SLIP_ENABLE			(1 <<
> 8)
> +#define FM10K_SW_PCSL_CFG_RX_BIT_SLIP_INITIAL			(1 <<
> 9)
> +#define FM10K_SW_PCSL_CFG_RX_GB_NARROW
> 		(1 << 10)
> +#define FM10K_SW_PCSL_CFG_TX_GB_NARROW
> 		(1 << 11)
> +#define FM10K_SW_MP_EEE_CFG(p_, l_)
> 		FM10K_SW_EPL_LANE_REG((p_), (l_), 0x40)
> +#define FM10K_SW_PCS_1000BASEX_EEE_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x40)
> +#define FM10K_SW_PCS_10GBASER_EEE_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x40)
> +#define FM10K_SW_MP_STATUS(p_, l_)
> 		FM10K_SW_EPL_LANE_REG((p_), (l_), 0x44)
> +#define FM10K_SW_PCS_40GBASER_RX_BIP_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x44)
> +#define FM10K_SW_PCS_10GBASER_RX_BER_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x44)
> +#define FM10K_SW_DISPARITY_ERROR_8B10B(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x44)
> +#define FM10K_SW_LANE_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x45)
> +
> +#define FM10K_SW_LANE_SERDES_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x46)
> +#define FM10K_SW_LANE_ENERGY_DETECT_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x47)
> +#define FM10K_SW_LANE_ENERGY_DETECT_CFG_ED_OVERRIDE_lsb
> 	0
> +#define FM10K_SW_LANE_ENERGY_DETECT_CFG_ED_OVERRIDE_msb
> 	1
> +#define FM10K_SW_LANE_ENERGY_DETECT_CFG_ED_MASK_RX_SIGNAL_OK
> 	(1 << 2)
> +#define FM10K_SW_LANE_ENERGY_DETECT_CFG_ED_MASK_RX_RDY
> 		(1 << 3)
> +#define FM10K_SW_LANE_ENERGY_DETECT_CFG_ED_MASK_RX_ACTIVITY
> 		(1 << 4)
> +#define FM10K_SW_LANE_ENERGY_DETECT_CFG_ED_MASK_ENERGY_DETECT
> 	(1 << 5)
> +#define FM10K_SW_LANE_ACTIVITY_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x48)
> +#define FM10K_SW_LANE_SIGNAL_DETECT_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x49)
> +#define FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_OVERRIDE_lsb	0
> +#define FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_OVERRIDE_msb	1
> +#define FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_MASK_RX_SIGNAL_OK
> 	(1 << 2)
> +#define FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_MASK_RX_RDY
> 		(1 << 3)
> +#define FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_MASK_RX_ACTIVITY
> 	(1 << 4)
> +#define FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_MASK_ENERGY_DETECT
> 	(1 << 5)
> +#define FM10K_SW_LANE_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x4A)
> +#define FM10K_SW_LANE_SERDES_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x4B)
> +#define FM10K_SW_LANE_SERDES_STATUS_ANALOG_TO_CORE_lsb	0
> +#define FM10K_SW_LANE_SERDES_STATUS_ANALOG_TO_CORE_msb	7
> +#define FM10K_SW_LANE_SERDES_STATUS_CORE_STATUS_lsb		8
> +#define FM10K_SW_LANE_SERDES_STATUS_CORE_STATUS_msb
> 	23
> +#define FM10K_SW_LANE_SERDES_STATUS_RX_SIGNAL_OK		(1 <<
> 12)
> +#define FM10K_SW_LANE_SERDES_STATUS_RX_RDY
> 	(1 << 24)
> +#define FM10K_SW_LANE_SERDES_STATUS_TX_RDY
> 	(1 << 25)
> +#define FM10K_SW_LANE_SERDES_STATUS_RX_IDLE_DETECT		(1 <<
> 26)
> +#define FM10K_SW_LANE_SERDES_STATUS_RX_ACTIVITY
> 	(1 << 27)
> +#define FM10K_SW_SERDES_IM(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x4C)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_0
> 	(1 << 0)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_1
> 	(1 << 1)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_2
> 	(1 << 2)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_3
> 	(1 << 3)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_4
> 	(1 << 4)
> +#define FM10K_SW_SERDES_IM_RX_SIGNAL_OK
> 	FM10K_SW_SERDES_IM_CORE_STATUS_4
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_5
> 	(1 << 5)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_6
> 	(1 << 6)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_7
> 	(1 << 7)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_8
> 	(1 << 8)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_9
> 	(1 << 9)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_10
> 	(1 << 10)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_11
> 	(1 << 11)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_12
> 	(1 << 12)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_13
> 	(1 << 13)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_14
> 	(1 << 14)
> +#define FM10K_SW_SERDES_IM_CORE_STATUS_15
> 	(1 << 15)
> +#define FM10K_SW_SERDES_IM_TX_RDY
> 		(1 << 16)
> +#define FM10K_SW_SERDES_IM_RX_ENERGY_DETECT
> 	(1 << 17)
> +#define FM10K_SW_SERDES_IM_RX_SIGNAL_DETECT
> 	(1 << 18)
> +#define FM10K_SW_SERDES_IM_RX_RDY
> 		(1 << 19)
> +#define FM10K_SW_SERDES_IM_RX_ACTIVITY
> 	(1 << 20)
> +#define FM10K_SW_SERDES_IM_RX_IDLE_DETECT
> 	(1 << 21)
> +#define FM10K_SW_SERDES_IM_SAI_COMPLETE
> 		(1 << 22)
> +#define FM10K_SW_SERDES_IM_SAI_REQUEST_ERROR			(1 <<
> 23)
> +#define FM10K_SW_SERDES_IM_TX_CDC_FIFO_U_ERR			(1 <<
> 24)
> +#define FM10K_SW_SERDES_IM_TX_CDC_FIFO_ERROR			(1 <<
> 25)
> +#define FM10K_SW_SERDES_IM_RX_CDC_FIFO_U_ERR			(1 <<
> 26)
> +#define FM10K_SW_SERDES_IM_RX_CDC_FIFO_ERROR			(1 <<
> 27)
> +#define FM10K_SW_SERDES_IM_SLIP_REQUEST
> 		(1 << 28)
> +#define FM10K_SW_SERDES_IM_ANALOG_IP
> 	(1 << 29)
> +#define FM10K_SW_SERDES_IM_ALL
> 		FM10K_SW_MASK32(29,0)
> +#define FM10K_SW_SERDES_IP(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x4D)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_0
> 	(1 << 0)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_1
> 	(1 << 1)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_2
> 	(1 << 2)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_3
> 	(1 << 3)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_4
> 	(1 << 4)
> +#define FM10K_SW_SERDES_IP_RX_SIGNAL_OK
> 	FM10K_SW_SERDES_IP_CORE_STATUS_4
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_5
> 	(1 << 5)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_6
> 	(1 << 6)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_7
> 	(1 << 7)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_8
> 	(1 << 8)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_9
> 	(1 << 9)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_10
> 	(1 << 10)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_11
> 	(1 << 11)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_12
> 	(1 << 12)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_13
> 	(1 << 13)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_14
> 	(1 << 14)
> +#define FM10K_SW_SERDES_IP_CORE_STATUS_15
> 	(1 << 15)
> +#define FM10K_SW_SERDES_IP_TX_RDY
> 		(1 << 16)
> +#define FM10K_SW_SERDES_IP_RX_ENERGY_DETECT
> 	(1 << 17)
> +#define FM10K_SW_SERDES_IP_RX_SIGNAL_DETECT
> 	(1 << 18)
> +#define FM10K_SW_SERDES_IP_RX_RDY
> 		(1 << 19)
> +#define FM10K_SW_SERDES_IP_RX_ACTIVITY
> 	(1 << 20)
> +#define FM10K_SW_SERDES_IP_RX_IDLE_DETECT
> 	(1 << 21)
> +#define FM10K_SW_SERDES_IP_SAI_COMPLETE
> 		(1 << 22)
> +#define FM10K_SW_SERDES_IP_SAI_REQUEST_ERROR			(1 <<
> 23)
> +#define FM10K_SW_SERDES_IP_TX_CDC_FIFO_U_ERR			(1 <<
> 24)
> +#define FM10K_SW_SERDES_IP_TX_CDC_FIFO_ERROR			(1 <<
> 25)
> +#define FM10K_SW_SERDES_IP_RX_CDC_FIFO_U_ERR			(1 <<
> 26)
> +#define FM10K_SW_SERDES_IP_RX_CDC_FIFO_ERROR			(1 <<
> 27)
> +#define FM10K_SW_SERDES_IP_SLIP_REQUEST
> 	(1 << 28)
> +#define FM10K_SW_SERDES_IP_ANALOG_IP
> 	(1 << 29)
> +#define FM10K_SW_SERDES_IP_ALL
> 		FM10K_SW_MASK32(29,0)
> +#define FM10K_SW_LANE_ANALOG_IM(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x4E)
> +#define FM10K_SW_LANE_ANALOG_IP(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x4F)
> +#define FM10K_SW_LANE_SAI_CFG(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x50)
> +#define FM10K_SW_LANE_SAI_CFG_CODE_lsb64
> 	0
> +#define FM10K_SW_LANE_SAI_CFG_CODE_msb64
> 	15
> +#define FM10K_SW_LANE_SAI_CFG_DATA_lsb64
> 	16
> +#define FM10K_SW_LANE_SAI_CFG_DATA_msb64
> 	31
> +#define FM10K_SW_LANE_SAI_CFG_RESULT_PATTERN_lsb64		32
> +#define FM10K_SW_LANE_SAI_CFG_RESULT_PATTERN_msb64		47
> +#define FM10K_SW_LANE_SAI_CFG_RESULT_MODE_lsb64
> 	48
> +#define FM10K_SW_LANE_SAI_CFG_RESULT_MODE_msb64
> 	49
> +#define FM10K_SW_LANE_SAI_CFG_REQUEST
> 	(1ULL << 50)
> +#define FM10K_SW_LANE_SAI_STATUS(p_, l_)
> 	FM10K_SW_EPL_LANE_REG((p_), (l_), 0x52)
> +#define FM10K_SW_LANE_SAI_STATUS_RESULT_lsb
> 	0
> +#define FM10K_SW_LANE_SAI_STATUS_RESULT_msb
> 	15
> +#define FM10K_SW_LANE_SAI_STATUS_COMPLETE
> 	(1 << 16)
> +#define FM10K_SW_LANE_SAI_STATUS_ACCESS_REQUEST
> 	(1 << 17)
> +#define FM10K_SW_LANE_SAI_STATUS_IN_PROGRESS			(1 <<
> 18)
> +#define FM10K_SW_LANE_SAI_STATUS_BUSY
> 	(1 << 19)
> +#define FM10K_SW_LANE_SAI_STATUS_REQUEST_ERROR
> 	(1 << 20)
> +
> +#define FM10K_SW_PORTS_MGMT_BASE
> 		FM10K_SW_REG_OFF(0x0E8000)
> +#define FM10K_SW_PORTS_MGMT_REG(wo_)
> 	(FM10K_SW_PORTS_MGMT_BASE + FM10K_SW_REG_OFF(wo_))
> +
> +#define FM10K_SW_PLL_EPL_CTRL
> 		FM10K_SW_PORTS_MGMT_REG(0x0)
> +#define FM10K_SW_PLL_EPL_STAT
> 		FM10K_SW_PORTS_MGMT_REG(0x1)
> +#define FM10K_SW_PLL_FABRIC_CTRL
> 	FM10K_SW_PORTS_MGMT_REG(0x2)
> +#define FM10K_SW_PLL_FABRIC_REFDIV_lsb
> 	3
> +#define FM10K_SW_PLL_FABRIC_REFDIV_msb
> 	8
> +#define FM10K_SW_PLL_FABRIC_FBDIV4_lsb
> 	9
> +#define FM10K_SW_PLL_FABRIC_FBDIV4_msb
> 	9
> +#define FM10K_SW_PLL_FABRIC_FBDIV255_lsb				10
> +#define FM10K_SW_PLL_FABRIC_FBDIV255_msb
> 	17
> +#define FM10K_SW_PLL_FABRIC_OUTDIV_lsb
> 	18
> +#define FM10K_SW_PLL_FABRIC_OUTDIV_msb
> 	23
> +#define FM10K_SW_PLL_FABRIC_STAT
> 	FM10K_SW_PORTS_MGMT_REG(0x3)
> +#define FM10K_SW_PLL_FABRIC_LOCK
> 	FM10K_SW_PORTS_MGMT_REG(0x4)
> +#define FM10K_SW_PLL_FABRIC_FREQSEL_lsb
> 	4
> +#define FM10K_SW_PLL_FABRIC_FREQSEL_msb
> 		7
> +#define	FM10K_SW_PLL_FABRIC_FREQSEL_CTRL
> 	0
> +#define	FM10K_SW_PLL_FABRIC_FREQSEL_F600
> 	1
> +#define	FM10K_SW_PLL_FABRIC_FREQSEL_F500
> 	2
> +#define	FM10K_SW_PLL_FABRIC_FREQSEL_F400
> 	3
> +#define	FM10K_SW_PLL_FABRIC_FREQSEL_F300
> 	4
> +#define FM10K_SW_SBUS_EPL_CFG
> 		FM10K_SW_PORTS_MGMT_REG(0x5)
> +#define FM10K_SW_SBUS_EPL_COMMAND
> 		FM10K_SW_PORTS_MGMT_REG(0x6)
> +#define FM10K_SW_SBUS_EPL_REQUEST
> 		FM10K_SW_PORTS_MGMT_REG(0x7)
> +#define FM10K_SW_SBUS_EPL_RESPONSE
> 		FM10K_SW_PORTS_MGMT_REG(0x8)
> +#define FM10K_SW_SBUS_EPL_SPICO_IN
> 		FM10K_SW_PORTS_MGMT_REG(0x9)
> +#define FM10K_SW_SBUS_EPL_SPICO_OUT
> 		FM10K_SW_PORTS_MGMT_REG(0xA)
> +#define FM10K_SW_SBUS_EPL_IP
> 		FM10K_SW_PORTS_MGMT_REG(0xB)
> +#define FM10K_SW_SBUS_EPL_IM
> 		FM10K_SW_PORTS_MGMT_REG(0xC)
> +#define FM10K_SW_ETHCLK_CFG(n_)
> 		FM10K_SW_PORTS_MGMT_REG(0xE + (n_))
> +#define FM10K_SW_ETHCLK_RATIO(n_)
> 		FM10K_SW_PORTS_MGMT_REG(0x10 + (n_))
> +#define FM10K_SW_PM_CLKOBS_CTRL
> 		FM10K_SW_PORTS_MGMT_REG(0x12)
> +
> +#define FM10K_SW_PCIE_CFG_BASE
> 		FM10K_SW_REG_OFF(0x120000)
> +#define FM10K_SW_PCIE_CFG_REG(wo_)
> 		(FM10K_SW_PCIE_CFG_BASE + FM10K_SW_REG_OFF(wo_))
> +/*
> + * These register offsets can also be passed to fm10k_read_config(), which
> + * will mask off the upper bits
> + */
> +#define FM10K_SW_PCIE_CFG_ID
> 	FM10K_SW_PCIE_CFG_REG(0x0)
> +#define FM10K_SW_PCIE_CFG_CMD
> 	FM10K_SW_PCIE_CFG_REG(0x1)
> +#define FM10K_SW_PCIE_CFG_1
> 	FM10K_SW_PCIE_CFG_REG(0x2)
> +#define FM10K_SW_PCIE_CFG_2
> 	FM10K_SW_PCIE_CFG_REG(0x3)
> +#define FM10K_SW_PCIE_CFG_BAR0
> 	FM10K_SW_PCIE_CFG_REG(0x4)
> +#define FM10K_SW_PCIE_CFG_BAR1
> 	FM10K_SW_PCIE_CFG_REG(0x5)
> +#define FM10K_SW_PCIE_CFG_BAR2
> 	FM10K_SW_PCIE_CFG_REG(0x6)
> +#define FM10K_SW_PCIE_CFG_BAR3
> 	FM10K_SW_PCIE_CFG_REG(0x7)
> +#define FM10K_SW_PCIE_CFG_BAR4
> 	FM10K_SW_PCIE_CFG_REG(0x8)
> +#define FM10K_SW_PCIE_CFG_BAR5
> 	FM10K_SW_PCIE_CFG_REG(0x9)
> +#define FM10K_SW_PCIE_CFG_CARDBUS
> 	FM10K_SW_PCIE_CFG_REG(0xA)
> +#define FM10K_SW_PCIE_CFG_SUBID
> 	FM10K_SW_PCIE_CFG_REG(0xB)
> +#define FM10K_SW_PCIE_CFG_EXP_ROM
> 	FM10K_SW_PCIE_CFG_REG(0xC)
> +#define FM10K_SW_PCIE_CFG_CAP_PTR
> 	FM10K_SW_PCIE_CFG_REG(0xD)
> +#define FM10K_SW_PCIE_CFG_RSVD
> 	FM10K_SW_PCIE_CFG_REG(0xE)
> +#define FM10K_SW_PCIE_CFG_INT
> 	FM10K_SW_PCIE_CFG_REG(0xF)
> +#define FM10K_SW_PCIE_CFG_PM_CAP
> 	FM10K_SW_PCIE_CFG_REG(0x10)
> +#define FM10K_SW_PCIE_CFG_PM_CTRL
> 	FM10K_SW_PCIE_CFG_REG(0x11)
> +#define FM10K_SW_PCIE_CFG_PCIE_CAP
> 	FM10K_SW_PCIE_CFG_REG(0x1C)
> +#define FM10K_SW_PCIE_CFG_PCIE_DEV_CAP
> 	FM10K_SW_PCIE_CFG_REG(0x1D)
> +#define FM10K_SW_PCIE_CFG_PCIE_DEV_CTRL
> 	FM10K_SW_PCIE_CFG_REG(0x1E)
> +#define FM10K_SW_PCIE_CFG_PCIE_LINK_CAP
> 	FM10K_SW_PCIE_CFG_REG(0x1F)
> +#define FM10K_SW_PCIE_CFG_PCIE_LINK_CTRL
> 	FM10K_SW_PCIE_CFG_REG(0x20)
> +#define FM10K_SW_PCIE_CFG_LINK_SPEED_lsb	16
> +#define FM10K_SW_PCIE_CFG_LINK_SPEED_msb	19
> +#define FM10K_SW_PCIE_CFG_LINK_SPEED_2P5	1
> +#define FM10K_SW_PCIE_CFG_LINK_SPEED_5		2
> +#define FM10K_SW_PCIE_CFG_LINK_SPEED_8		3
> +#define FM10K_SW_PCIE_CFG_LINK_WIDTH_lsb	20
> +#define FM10K_SW_PCIE_CFG_LINK_WIDTH_msb	24
> +#define FM10K_SW_PCIE_CFG_PCIE_DEV_CAP2
> 	FM10K_SW_PCIE_CFG_REG(0x25)
> +#define FM10K_SW_PCIE_CFG_PCIE_DEV_CTRL2
> 	FM10K_SW_PCIE_CFG_REG(0x26)
> +#define FM10K_SW_PCIE_CFG_PCIE_LINK_CTRL2
> 	FM10K_SW_PCIE_CFG_REG(0x28)
> +#define FM10K_SW_PCIE_CFG_MSIX_CAP
> 	FM10K_SW_PCIE_CFG_REG(0x2C)
> +#define FM10K_SW_PCIE_CFG_MSIX_TABLE_OFFSET
> FM10K_SW_PCIE_CFG_REG(0x2D)
> +#define FM10K_SW_PCIE_CFG_MSIX_PBA
> 	FM10K_SW_PCIE_CFG_REG(0x2E)
> +#define FM10K_SW_PCIE_CFG_VPD_CAP
> 	FM10K_SW_PCIE_CFG_REG(0x34)
> +#define FM10K_SW_PCIE_CFG_VPD_DATA
> 	FM10K_SW_PCIE_CFG_REG(0x35)
> +#define FM10K_SW_PCIE_CFG_AER_HDR
> 	FM10K_SW_PCIE_CFG_REG(0x40)
> +#define FM10K_SW_PCIE_CFG_AER_UNERR_STATUS
> 	FM10K_SW_PCIE_CFG_REG(0x41)
> +#define FM10K_SW_PCIE_CFG_AER_UNERR_MASK
> 	FM10K_SW_PCIE_CFG_REG(0x42)
> +#define FM10K_SW_PCIE_CFG_AER_UNERR_SEVERITY
> FM10K_SW_PCIE_CFG_REG(0x43)
> +#define FM10K_SW_PCIE_CFG_AER_COERR_STATUS
> 	FM10K_SW_PCIE_CFG_REG(0x44)
> +#define FM10K_SW_PCIE_CFG_AER_COERR_MASK
> 	FM10K_SW_PCIE_CFG_REG(0x45)
> +#define FM10K_SW_PCIE_CFG_AER_CTRL
> 	FM10K_SW_PCIE_CFG_REG(0x46)
> +#define FM10K_SW_PCIE_CFG_AER_HEADER_LOG0
> 	FM10K_SW_PCIE_CFG_REG(0x47)
> +#define FM10K_SW_PCIE_CFG_AER_HEADER_LOG1
> 	FM10K_SW_PCIE_CFG_REG(0x48)
> +#define FM10K_SW_PCIE_CFG_AER_HEADER_LOG2
> 	FM10K_SW_PCIE_CFG_REG(0x49)
> +#define FM10K_SW_PCIE_CFG_AER_HEADER_LOG3
> 	FM10K_SW_PCIE_CFG_REG(0x4A)
> +#define FM10K_SW_PCIE_CFG_SPD_HDR
> 	FM10K_SW_PCIE_CFG_REG(0x52)
> +#define FM10K_SW_PCIE_CFG_SPD_NUMBER_L
> 	FM10K_SW_PCIE_CFG_REG(0x53)
> +#define FM10K_SW_PCIE_CFG_SPD_NUMBER_H
> 	FM10K_SW_PCIE_CFG_REG(0x54)
> +#define FM10K_SW_PCIE_CFG_ARI_HDR
> 	FM10K_SW_PCIE_CFG_REG(0x56)
> +#define FM10K_SW_PCIE_CFG_ARI_CTRL
> 	FM10K_SW_PCIE_CFG_REG(0x57)
> +#define FM10K_SW_PCIE_CFG_SPCIE_HDR
> 	FM10K_SW_PCIE_CFG_REG(0x5A)
> +#define FM10K_SW_PCIE_CFG_SPCIE_LINK_CTRL3
> 	FM10K_SW_PCIE_CFG_REG(0x5B)
> +#define FM10K_SW_PCIE_CFG_SPCIE_ERR_STS
> 	FM10K_SW_PCIE_CFG_REG(0x5C)
> +#define FM10K_SW_PCIE_CFG_SPCIE_LINK_EQ01
> 	FM10K_SW_PCIE_CFG_REG(0x5D)
> +#define FM10K_SW_PCIE_CFG_SPCIE_LINK_EQ23
> 	FM10K_SW_PCIE_CFG_REG(0x5E)
> +#define FM10K_SW_PCIE_CFG_SPCIE_LINK_EQ45
> 	FM10K_SW_PCIE_CFG_REG(0x5F)
> +#define FM10K_SW_PCIE_CFG_SPCIE_LINK_EQ67
> 	FM10K_SW_PCIE_CFG_REG(0x60)
> +#define FM10K_SW_PCIE_CFG_SRIOV_HDR
> 	FM10K_SW_PCIE_CFG_REG(0x62)
> +#define FM10K_SW_PCIE_CFG_SRIOV_CAP
> 	FM10K_SW_PCIE_CFG_REG(0x63)
> +#define FM10K_SW_PCIE_CFG_SRIOV_CTRL
> 	FM10K_SW_PCIE_CFG_REG(0x64)
> +#define FM10K_SW_PCIE_CFG_SRIOV_CFG
> 	FM10K_SW_PCIE_CFG_REG(0x65)
> +#define FM10K_SW_PCIE_CFG_SRIOV_NUM
> 	FM10K_SW_PCIE_CFG_REG(0x66)
> +#define FM10K_SW_PCIE_CFG_SRIOV_MAP
> 	FM10K_SW_PCIE_CFG_REG(0x67)
> +#define FM10K_SW_PCIE_CFG_SRIOV_DEVID
> 	FM10K_SW_PCIE_CFG_REG(0x69)
> +#define FM10K_SW_PCIE_CFG_SRIOV_PAGE_SUP
> 	FM10K_SW_PCIE_CFG_REG(0x69)
> +#define FM10K_SW_PCIE_CFG_SRIOV_PAGE_CFG
> 	FM10K_SW_PCIE_CFG_REG(0x6A)
> +#define FM10K_SW_PCIE_CFG_SRIOV_BAR0
> 	FM10K_SW_PCIE_CFG_REG(0x6B)
> +#define FM10K_SW_PCIE_CFG_SRIOV_BAR1
> 	FM10K_SW_PCIE_CFG_REG(0x6C)
> +#define FM10K_SW_PCIE_CFG_SRIOV_BAR2
> 	FM10K_SW_PCIE_CFG_REG(0x6D)
> +#define FM10K_SW_PCIE_CFG_SRIOV_BAR3
> 	FM10K_SW_PCIE_CFG_REG(0x6E)
> +#define FM10K_SW_PCIE_CFG_SRIOV_BAR4
> 	FM10K_SW_PCIE_CFG_REG(0x6F)
> +#define FM10K_SW_PCIE_CFG_SRIOV_BAR5
> 	FM10K_SW_PCIE_CFG_REG(0x70)
> +#define FM10K_SW_PCIE_CFG_SRIOV_MIG
> 	FM10K_SW_PCIE_CFG_REG(0x71)
> +#define FM10K_SW_PCIE_CFG_TPH_HDR
> 	FM10K_SW_PCIE_CFG_REG(0x72)
> +#define FM10K_SW_PCIE_CFG_TPH_CAP
> 	FM10K_SW_PCIE_CFG_REG(0x73)
> +#define FM10K_SW_PCIE_CFG_TPH_CTRL
> 	FM10K_SW_PCIE_CFG_REG(0x74)
> +#define FM10K_SW_PCIE_CFG_ACS_HDR
> 	FM10K_SW_PCIE_CFG_REG(0x76)
> +#define FM10K_SW_PCIE_CFG_ACS_CAP
> 	FM10K_SW_PCIE_CFG_REG(0x77)
> +#define FM10K_SW_PCIE_PORTLOGIC
> 	FM10K_SW_PCIE_CFG_REG(0x1C0)
> +#define FM10K_SW_PCIE_PORTLOGIC_LINK_STATE
> 	FM10K_SW_PCIE_CFG_REG(0x1CA)
> +
> +
> +#define FM10K_SW_FFU_BASE
> 	FM10K_SW_REG_OFF(0xC00000)
> +#define FM10K_SW_FFU_REG(wo_)
> 	(FM10K_SW_FFU_BASE + FM10K_SW_REG_OFF(wo_))
> +#define FM10K_SW_FFU_NUM_SLICES				32
> +#define FM10K_SW_FFU_NUM_SCENARIOS			32
> +
> +/* FFU enumerated types */
> +#define FM10K_SW_FFU_MUX_SEL_MAP_DIP_MAP_SIP	0
> +#define FM10K_SW_FFU_MUX_SEL_MAP_DMAC_MAP_SMAC	1
> +#define FM10K_SW_FFU_MUX_SEL_MAP_PROT_MAP_LENGTH	2
> +#define FM10K_SW_FFU_MUX_SEL_MAP_SRC_MAP_TYPE	3
> +#define FM10K_SW_FFU_MUX_SEL_USER				4
> +#define FM10K_SW_FFU_MUX_SEL_FTYPE_SWPRI		5
> +#define FM10K_SW_FFU_MUX_SEL_IPMISC				6
> +#define FM10K_SW_FFU_MUX_SEL_TOS				7
> +#define FM10K_SW_FFU_MUX_SEL_PROT				8
> +#define FM10K_SW_FFU_MUX_SEL_TTL				9
> +#define FM10K_SW_FFU_MUX_SEL_SRC_PORT			10
> +#define FM10K_SW_FFU_MUX_SEL_VPRI_VID_11_8		11
> +#define FM10K_SW_FFU_MUX_SEL_VID_7_0			12
> +#define FM10K_SW_FFU_MUX_SEL_RXTAG				13
> +#define FM10K_SW_FFU_MUX_SEL_L2_DMAC_15_0		14
> +#define FM10K_SW_FFU_MUX_SEL_L2_DMAC_31_16		15
> +#define FM10K_SW_FFU_MUX_SEL_L2_DMAC_47_32		16
> +#define FM10K_SW_FFU_MUX_SEL_L2_SMAC_15_0		17
> +#define FM10K_SW_FFU_MUX_SEL_L2_SMAC_31_16		18
> +#define FM10K_SW_FFU_MUX_SEL_L2_SMAC_47_32		19
> +#define FM10K_SW_FFU_MUX_SEL_DGLORT				20
> +#define FM10K_SW_FFU_MUX_SEL_SGLORT				21
> +#define FM10K_SW_FFU_MUX_SEL_VPRI_VID			22
> +#define FM10K_SW_FFU_MUX_SEL_VPRI2_VID2			23
> +#define FM10K_SW_FFU_MUX_SEL_L2_TYPE			24
> +#define FM10K_SW_FFU_MUX_SEL_L4_DST				25
> +#define FM10K_SW_FFU_MUX_SEL_L4_SRC				26
> +#define FM10K_SW_FFU_MUX_SEL_MAP_L4_DST			27
> +#define FM10K_SW_FFU_MUX_SEL_MAP_L4_SRC			28
> +#define FM10K_SW_FFU_MUX_SEL_L4A				29
> +#define FM10K_SW_FFU_MUX_SEL_L4B				30
> +#define FM10K_SW_FFU_MUX_SEL_L4C				31
> +#define FM10K_SW_FFU_MUX_SEL_L4D				32
> +#define FM10K_SW_FFU_MUX_SEL_MAP_VPRI1_VID1		33
> +#define FM10K_SW_FFU_MUX_SEL_L3_DIP_31_0		34
> +#define FM10K_SW_FFU_MUX_SEL_L3_DIP_63_32		35
> +#define FM10K_SW_FFU_MUX_SEL_L3_DIP_95_64		36
> +#define FM10K_SW_FFU_MUX_SEL_L3_DIP_127_96		37
> +#define FM10K_SW_FFU_MUX_SEL_L3_SIP_31_0		38
> +#define FM10K_SW_FFU_MUX_SEL_L3_SIP_63_32		39
> +#define FM10K_SW_FFU_MUX_SEL_L3_SIP_95_64		40
> +#define FM10K_SW_FFU_MUX_SEL_L3_SIP_127_96		41
> +
> +#define	FM10K_SW_FFU_SLICE_SRAM_ROUTE_ARP_INDEX_lsb
> 	0
> +#define	FM10K_SW_FFU_SLICE_SRAM_ROUTE_ARP_INDEX_msb
> 	15
> +#define	FM10K_SW_FFU_SLICE_SRAM_ROUTE_ARP_COUNT_lsb
> 	16
> +#define	FM10K_SW_FFU_SLICE_SRAM_ROUTE_ARP_COUNT_msb
> 		19
> +#define FM10K_SW_FFU_SLICE_SRAM_ROUTE_ARP_TYPE_EXP		(1 <<
> 20)
> +
> +#define	FM10K_SW_FFU_SLICE_SRAM_ROUTE_GLORT_DGLORT_lsb
> 	0
> +#define	FM10K_SW_FFU_SLICE_SRAM_ROUTE_GLORT_DGLORT_msb
> 	15
> +#define FM10K_SW_FFU_SLICE_SRAM_ROUTE_GLORT_FLOOD_SET	(1 <<
> 20)
> +
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_BITS_BYTE_MASK_lsb
> 	0
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_BITS_BYTE_MASK_msb
> 	7
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_BITS_BYTE_DATA_lsb
> 	8
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_BITS_BYTE_DATA_msb
> 	15
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_BITS_SUB_CMD_lsb	16
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_BITS_SUB_CMD_msb
> 	20
> +
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_VLAN_VLAN_lsb
> 	0
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_VLAN_VLAN_msb
> 	11
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_VLAN_PRI_lsb
> 	12
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_VLAN_PRI_msb
> 	15
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_VLAN_TX_TAG_lsb
> 	16
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_VLAN_TX_TAG_msb
> 	17
> +#define FM10K_SW_FFU_SLICE_SRAM_SET_VLAN_SET_VPRI		(1 <<
> 18)
> +#define FM10K_SW_FFU_SLICE_SRAM_SET_VLAN_SET_PRI		(1 <<
> 19)
> +
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_PRI_DSCP_lsb
> 	0
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_PRI_DSCP_msb
> 	5
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_PRI_PRI_lsb
> 	12
> +#define	FM10K_SW_FFU_SLICE_SRAM_SET_PRI_PRI_msb
> 		15
> +#define FM10K_SW_FFU_SLICE_SRAM_SET_PRI_SET_DSCP		(1 <<
> 17)
> +#define FM10K_SW_FFU_SLICE_SRAM_SET_PRI_SET_VPRI		(1 <<
> 18)
> +#define FM10K_SW_FFU_SLICE_SRAM_SET_PRI_SET_PRI
> 	(1 << 19)
> +
> +/* FFU Registers */
> +#define FM10K_SW_FFU_SLICE_TCAM(sl_, n_)
> 	FM10K_SW_FFU_REG(0x2000 * (sl_) + 0x4 * (n_))
> +#define FM10K_SW_FFU_SLICE_TCAM_ENTRIES
> 		1024
> +#define FM10K_SW_FFU_SLICE_TCAM_KEY_lsb64
> 	0
> +#define FM10K_SW_FFU_SLICE_TCAM_KEY_msb64
> 	31
> +#define FM10K_SW_FFU_SLICE_TCAM_KEY_TOP_lsb64			32
> +#define FM10K_SW_FFU_SLICE_TCAM_KEY_TOP_msb64
> 	39
> +#define FM10K_SW_FFU_SLICE_SRAM(sl_, n_)
> 	FM10K_SW_FFU_REG(0x1000 + 0x2000 * (sl_) + 0x2 * (n_))
> +#define FM10K_SW_FFU_SLICE_SRAM_COMMAND_lsb64
> 	21
> +#define FM10K_SW_FFU_SLICE_SRAM_COMMAND_msb64
> 	22
> +#define	FM10K_SW_FFU_SLICE_SRAM_COMMAND_ROUTE_ARP
> 	0
> +#define	FM10K_SW_FFU_SLICE_SRAM_COMMAND_ROUTE_GLORT
> 	1
> +#define	FM10K_SW_FFU_SLICE_SRAM_COMMAND_BIT_SET
> 		2
> +#define	FM10K_SW_FFU_SLICE_SRAM_COMMAND_FIELD_SET
> 	3
> +#define FM10K_SW_FFU_SLICE_SRAM_COUNTER_INDEX_lsb64 	23
> +#define FM10K_SW_FFU_SLICE_SRAM_COUNTER_INDEX_msb64 	34
> +#define FM10K_SW_FFU_SLICE_SRAM_COUNTER_BANK_lsb64		35
> +#define FM10K_SW_FFU_SLICE_SRAM_COUNTER_BANK_msb64
> 	36
> +#define FM10K_SW_FFU_SLICE_SRAM_PRECEDENCE_lsb64		37
> +#define FM10K_SW_FFU_SLICE_SRAM_PRECEDENCE_msb64		39
> +#define FM10K_SW_FFU_SLICE_VALID(sl_)
> 	FM10K_SW_FFU_REG(0x1800 + 0x2000 * (sl_))
> +#define FM10K_SW_FFU_SLICE_VALID_SCENARIO(s_)			(1ULL
> << (s_))
> +#define FM10K_SW_FFU_SLICE_VALID_ALL_SCENARIOS
> 	FM10K_SW_MASK32(31, 0)
> +#define FM10K_SW_FFU_SLICE_CASCADE_ACTION(sl_)
> 	FM10K_SW_FFU_REG(0x1804 + 0x2000 * (sl_))
> +#define FM10K_SW_FFU_SLICE_CFG(sl_, scen_)
> 	FM10K_SW_FFU_REG(0x1840 + 0x2 * (scen_) + 0x2000 * (sl_))
> +#define FM10K_SW_FFU_SLICE_CFG_SELECT_0_lsb64			0
> +#define FM10K_SW_FFU_SLICE_CFG_SELECT_0_msb64			5
> +#define FM10K_SW_FFU_SLICE_CFG_SELECT_1_lsb64			6
> +#define FM10K_SW_FFU_SLICE_CFG_SELECT_1_msb64			11
> +#define FM10K_SW_FFU_SLICE_CFG_SELECT_2_lsb64			12
> +#define FM10K_SW_FFU_SLICE_CFG_SELECT_2_msb64			17
> +#define FM10K_SW_FFU_SLICE_CFG_SELECT_3_lsb64			18
> +#define FM10K_SW_FFU_SLICE_CFG_SELECT_3_msb64			23
> +#define FM10K_SW_FFU_SLICE_CFG_SELECT_TOP_lsb64
> 	24
> +#define FM10K_SW_FFU_SLICE_CFG_SELECT_TOP_msb64
> 	29
> +#define FM10K_SW_FFU_SLICE_CFG_START_COMPARE			(1ULL
> << 30)
> +#define FM10K_SW_FFU_SLICE_CFG_START_ACTION
> 	(1ULL << 31)
> +#define FM10K_SW_FFU_SLICE_CFG_VALID_LOW
> 	(1ULL << 32)
> +#define FM10K_SW_FFU_SLICE_CFG_VALID_HIGH
> 	(1ULL << 33)
> +#define FM10K_SW_FFU_SLICE_CFG_CASE_lsb64
> 	34
> +#define FM10K_SW_FFU_SLICE_CFG_CASE_msb64
> 	37
> +#define FM10K_SW_FFU_SLICE_CFG_CASE_LOCATION_lsb64		38
> +#define FM10K_SW_FFU_SLICE_CFG_CASE_LOCATION_msb64		39
> +#define	FM10K_SW_FFU_SLICE_CFG_CASE_LOCATION_NOT_MAPPED
> 			0
> +#define
> 	FM10K_SW_FFU_SLICE_CFG_CASE_LOCATION_TOP_LOW_NIBBLE
> 	1
> +#define
> 	FM10K_SW_FFU_SLICE_CFG_CASE_LOCATION_TOP_HIGH_NIBBLE
> 	2
> +#define FM10K_SW_FFU_MASTER_VALID
> 		FM10K_SW_FFU_REG(0x40000)
> +#define FM10K_SW_FFU_MASTER_VALID_SLICE_VALID(s_)		(1ULL
> << (s_))
> +#define FM10K_SW_FFU_MASTER_VALID_ALL_SLICES_VALID
> 	FM10K_SW_MASK64(31, 0)
> +#define FM10K_SW_FFU_MASTER_VALID_CHUNK_VALID(c_)		(1ULL
> << ((c_) + 32))
> +#define FM10K_SW_FFU_MASTER_VALID_ALL_CHUNKS_VALID
> 	FM10K_SW_MASK64(63, 32)
> +
> +#define FM10K_SW_L2LOOKUP_BASE
> 		FM10K_SW_REG_OFF(0xC80000)
> +#define FM10K_SW_L2LOOKUP_REG(wo_)
> 		(FM10K_SW_L2LOOKUP_BASE + FM10K_SW_REG_OFF(wo_))
> +
> +#define FM10K_SW_MA_TABLE(t_, n_)
> 	FM10K_SW_L2LOOKUP_REG(0x10000 * (t_) + 0x4 * (n_))
> +#define FM10K_SW_INGRESS_VID_TABLE(v_)
> 	FM10K_SW_L2LOOKUP_REG(0x20000 + 0x4 * (v_))
> +#define FM10K_SW_INGRESS_VID_TABLE_ENTRIES
> 	4096
> +#define FM10K_SW_INGRESS_VID_TABLE_MEMBERSHIP(l_)		(1ULL
> << (l_))
> +/* note these bit positions are relative to the start of the upper 64-bit word */
> +#define FM10K_SW_INGRESS_VID_TABLE_FID_lsb64			(64 -
> 64)
> +#define FM10K_SW_INGRESS_VID_TABLE_FID_msb64			(75 -
> 64)
> +#define FM10K_SW_INGRESS_VID_TABLE_MST_INDEX_lsb64		(76 -
> 64)
> +#define FM10K_SW_INGRESS_VID_TABLE_MST_INDEX_msb64		(83 -
> 64)
> +#define FM10K_SW_INGRESS_VID_TABLE_COUNTER_INDEX_lsb64 	(84 -
> 64)
> +#define FM10K_SW_INGRESS_VID_TABLE_COUNTER_INDEX_msb64 	(89 -
> 64)
> +#define FM10K_SW_INGRESS_VID_TABLE_REFLECT
> 	(1ULL << (90 - 64))
> +#define FM10K_SW_INGRESS_VID_TABLE_TRAP_IGMP			(1ULL
> << (91 - 64))
> +#define FM10K_SW_EGRESS_VID_TABLE(v_)
> 	FM10K_SW_L2LOOKUP_REG(0x24000 + 0x4 * (v_))
> +#define FM10K_SW_EGRESS_VID_TABLE_ENTRIES
> 	4096
> +#define FM10K_SW_EGRESS_VID_TABLE_MEMBERSHIP(l_)		(1ULL
> << (l_))
> +/* note these bit positions are relative to the start of the upper 64-bit word */
> +#define FM10K_SW_EGRESS_VID_TABLE_FID_lsb64
> 	(64 - 64)
> +#define FM10K_SW_EGRESS_VID_TABLE_FID_msb64
> 	(75 - 64)
> +#define FM10K_SW_EGRESS_VID_TABLE_MST_INDEX_lsb64		(76 -
> 64)
> +#define FM10K_SW_EGRESS_VID_TABLE_MST_INDEX_msb64		(83 -
> 64)
> +#define FM10K_SW_EGRESS_VID_TABLE_MTU_INDEX_lsb64		(84 -
> 64)
> +#define FM10K_SW_EGRESS_VID_TABLE_MTU_INDEX_msb64		(86 -
> 64)
> +#define FM10K_SW_EGRESS_VID_TABLE_TRIG_ID_lsb64
> 	(87 - 64)
> +#define FM10K_SW_EGRESS_VID_TABLE_TRIG_ID_msb64
> 	(92 - 64)
> +#define FM10K_SW_MA_USED_TABLE(t_, n_)
> 	FM10K_SW_L2LOOKUP_REG(0x28000 + 0x200 * (t_) + (n_))
> +#define FM10K_SW_INGRESS_MST_TABLE(t_, n_)
> 	FM10K_SW_L2LOOKUP_REG(0x28400 + 0x200 * (t_) + 0x2 * (n_))
> +#define FM10K_SW_INGRESS_MST_TABLE_PORTS_PER_TABLE		24
> +#define FM10K_SW_INGRESS_MST_TABLE_STP_STATE_lsb64(l_) 	(((l_) %
> FM10K_SW_INGRESS_MST_TABLE_PORTS_PER_TABLE) * 2)
> +#define FM10K_SW_INGRESS_MST_TABLE_STP_STATE_msb64(l_)
> 	(FM10K_SW_INGRESS_MST_TABLE_STP_STATE_lsb64(l_) + 1)
> +#define	FM10K_SW_INGRESS_MST_TABLE_STP_STATE_DISABLE	0
> +#define	FM10K_SW_INGRESS_MST_TABLE_STP_STATE_LISTENING
> 	1
> +#define	FM10K_SW_INGRESS_MST_TABLE_STP_STATE_LEARNING
> 	2
> +#define	FM10K_SW_INGRESS_MST_TABLE_STP_STATE_FORWARD
> 	3
> +#define FM10K_SW_EGRESS_MST_TABLE(t_)
> 	FM10K_SW_L2LOOKUP_REG(0x28800 + 0x2 * (t_))
> +#define FM10K_SW_EGRESS_MST_TABLE_FORWARDING(l_)		(1ULL
> << (l_))
> +#define FM10K_SW_MA_TABLE_CFG_1
> 		FM10K_SW_L2LOOKUP_REG(0x28A00)
> +#define FM10K_SW_MA_TABLE_CFG_2
> 		FM10K_SW_L2LOOKUP_REG(0x28A02)
> +#define FM10K_SW_MTU_TABLE(n_)
> 		FM10K_SW_L2LOOKUP_REG(0x28A08 + (n_))
> +#define FM10K_SW_IEEE_RESERVED_MAC_ACTION
> 	FM10K_SW_L2LOOKUP_REG(0x28A10)
> +#define FM10K_SW_IEEE_RESERVED_MAC_TRAP_PRIORITY
> 	FM10K_SW_L2LOOKUP_REG(0x28A14)
> +#define FM10K_SW_IEEE_RESERVED_MAC_CFG
> 		FM10K_SW_L2LOOKUP_REG(0x28A16)
> +
> +
> +#define FM10K_SW_GLORT_BASE
> 			FM10K_SW_REG_OFF(0xCE0000)
> +#define FM10K_SW_GLORT_REG(wo_)
> 	(FM10K_SW_GLORT_BASE + FM10K_SW_REG_OFF(wo_))
> +#define FM10K_SW_GLORT_CAM_ENTRIES
> 		256
> +#define FM10K_SW_GLORT_DEST_TABLE(n_)
> 	FM10K_SW_GLORT_REG(0x0 + 0x2 * (n_))
> +#define FM10K_SW_GLORT_DEST_TABLE_MASK_lsb64			0
> +#define FM10K_SW_GLORT_DEST_TABLE_MASK_msb64
> 	47
> +#define FM10K_SW_GLORT_DEST_TABLE_IP_MCAST_IDX_lsb64 	48
> +#define FM10K_SW_GLORT_DEST_TABLE_IP_MCAST_IDX_msb64 	59
> +#define FM10K_SW_GLORT_CAM(n_)
> 		FM10K_SW_GLORT_REG(0x2000 + (n_))
> +#define FM10K_SW_GLORT_CAM_MATCH_ANY
> 	0x00000000
> +#define FM10K_SW_GLORT_CAM_MATCH_NONE
> 		FM10K_SW_MASK32(31, 0)
> +#define FM10K_SW_GLORT_CAM_KEY_lsb
> 		0
> +#define FM10K_SW_GLORT_CAM_KEY_msb
> 		15
> +#define FM10K_SW_GLORT_CAM_KEY_INVERT_lsb
> 	16
> +#define FM10K_SW_GLORT_CAM_KEY_INVERT_msb
> 	31
> +#define FM10K_SW_GLORT_RAM(n_)
> 		FM10K_SW_GLORT_REG(0x2200 + 0x2 * (n_))
> +#define FM10K_SW_GLORT_RAM_STRICT_lsb64
> 		0
> +#define FM10K_SW_GLORT_RAM_STRICT_msb64
> 		1
> +#define	FM10K_SW_GLORT_RAM_STRICT_FTYPE
> 			0
> +#define	FM10K_SW_GLORT_RAM_STRICT_RSVD
> 		1
> +#define	FM10K_SW_GLORT_RAM_STRICT_HASHED
> 		2
> +#define	FM10K_SW_GLORT_RAM_STRICT_STRICT
> 		3
> +#define FM10K_SW_GLORT_RAM_DEST_INDEX_lsb64
> 	2
> +#define FM10K_SW_GLORT_RAM_DEST_INDEX_msb64
> 	13
> +#define FM10K_SW_GLORT_RAM_RANGE_SUBIDX_A_lsb64
> 	14
> +#define FM10K_SW_GLORT_RAM_RANGE_SUBIDX_A_msb64
> 	21
> +#define FM10K_SW_GLORT_RAM_RANGE_SUBIDX_B_lsb64
> 	22
> +#define FM10K_SW_GLORT_RAM_RANGE_SUBIDX_B_msb64
> 	29
> +#define FM10K_SW_GLORT_RAM_DEST_COUNT_lsb64
> 	30
> +#define FM10K_SW_GLORT_RAM_DEST_COUNT_msb64
> 		33
> +#define FM10K_SW_GLORT_RAM_HASH_ROTATION
> 	(1ULL << 34)
> +
> +
> +#define FM10K_SW_PARSER_BASE
> 		FM10K_SW_REG_OFF(0xCF0000)
> +#define FM10K_SW_PARSER_REG(wo_)
> 		(FM10K_SW_PARSER_BASE + FM10K_SW_REG_OFF(wo_))
> +#define FM10K_SW_PARSER_PORT_CFG_1(p_)
> 	FM10K_SW_PARSER_REG(0x0 + 0x2 * (p_))
> +#define FM10K_SW_PARSER_PORT_CFG_1_FTAG
> 		(1ULL << 0)
> +#define FM10K_SW_PARSER_PORT_CFG_1_VLAN1_TAG(v_)		(1ULL
> << (1 + (v_)))
> +#define FM10K_SW_PARSER_PORT_CFG_1_VLAN2_TAG(v_)		(1ULL
> << (5 + (v_)))
> +#define FM10K_SW_PARSER_PORT_CFG_1_VLAN2_FIRST
> 	(1ULL << 9)
> +#define FM10K_SW_PARSER_PORT_CFG_1_DEFAULT_VID_lsb		10
> +#define FM10K_SW_PARSER_PORT_CFG_1_DEFAULT_VID_msb		21
> +#define FM10K_SW_PARSER_PORT_CFG_1_DEFAULT_VPRI_lsb 	22
> +#define FM10K_SW_PARSER_PORT_CFG_1_DEFAULT_VPRI_msb 	25
> +#define FM10K_SW_PARSER_PORT_CFG_1_DEFAULT_VID2_lsb 	26
> +#define FM10K_SW_PARSER_PORT_CFG_1_DEFAULT_VID2_msb 	37
> +#define FM10K_SW_PARSER_PORT_CFG_1_DEFAULT_VPRI2_lsb 	38
> +#define FM10K_SW_PARSER_PORT_CFG_1_DEFAULT_VPRI2_msb 	41
> +#define FM10K_SW_PARSER_PORT_CFG_1_USE_DEFAULT_VLAN 	(1ULL
> << 42)
> +#define FM10K_SW_PARSER_PORT_CFG_2(p_)
> 	FM10K_SW_PARSER_REG(0x80 + 0x2 * (p_))
> +#define FM10K_SW_PARSER_PORT_CFG_2_CUSTOM_TAG_1_lsb
> 	0
> +#define FM10K_SW_PARSER_PORT_CFG_2_CUSTOM_TAG_1_msb
> 	3
> +#define FM10K_SW_PARSER_PORT_CFG_2_CUSTOM_TAG_2_lsb
> 	4
> +#define FM10K_SW_PARSER_PORT_CFG_2_CUSTOM_TAG_2_msb
> 	7
> +#define FM10K_SW_PARSER_PORT_CFG_2_PARSE_MPLS
> 	(1ULL << 8)
> +#define FM10K_SW_PARSER_PORT_CFG_2_STORE_MPLS_lsb		9
> +#define FM10K_SW_PARSER_PORT_CFG_2_STORE_MPLS_msb		11
> +#define FM10K_SW_PARSER_PORT_CFG_2_PARSE_L3
> 	(1ULL << 12)
> +#define FM10K_SW_PARSER_PORT_CFG_2_PARSE_L4
> 	(1ULL << 13)
> +#define FM10K_SW_PARSER_PORT_CFG_2_FLAG_IPV4_OPTIONS	(1ULL
> << 14)
> +#define FM10K_SW_PARSER_PORT_CFG_2_FLAG_IPV6_HOP_BY_HOP	(1ULL
> << 15)
> +#define FM10K_SW_PARSER_PORT_CFG_2_FLAG_IPV6_ROUTING	(1ULL
> << 16)
> +#define FM10K_SW_PARSER_PORT_CFG_2_FLAG_IPV6_FRAG		(1ULL
> << 17)
> +#define FM10K_SW_PARSER_PORT_CFG_2_FLAG_IPV6_DEST		(1ULL
> << 18)
> +#define FM10K_SW_PARSER_PORT_CFG_2_FLAG_IPV6_AUTH		(1ULL
> << 19)
> +#define FM10K_SW_PARSER_PORT_CFG_2_DEFAULT_DSCP_lsb		20
> +#define FM10K_SW_PARSER_PORT_CFG_2_DEFAULT_DSCP_msb
> 	25
> +#define FM10K_SW_PARSER_PORT_CFG_2_DROP_TAGGED
> 	(1ULL << 26)
> +#define FM10K_SW_PARSER_PORT_CFG_2_DROP_UNTAGGED		(1ULL
> << 27)
> +#define FM10K_SW_PARSER_PORT_CFG_2_USE_DEFAULT_DSCP
> 	(1ULL << 28)
> +#define FM10K_SW_PARSER_PORT_CFG_2_SWITCH_PRI_FROM_VLAN	(1ULL
> << 29)
> +#define FM10K_SW_PARSER_PORT_CFG_2_SWITCH_PRI_FROM_DSCP	(1ULL
> << 30)
> +#define FM10K_SW_PARSER_PORT_CFG_2_SWITCH_PRI_FROM_ISL	(1ULL
> << 31)
> +#define FM10K_SW_PARSER_PORT_CFG_2_SWITCH_PRI_PREFER_DSCP	(1ULL
> << 32)
> +#define FM10K_SW_PARSER_PORT_CFG_3(p_)
> 	FM10K_SW_PARSER_REG(0x100 + 0x2 * (p_))
> +#define FM10K_SW_PORT_CFG_ISL(p_)
> 	FM10K_SW_PARSER_REG(0x180 + (p_))
> +#define FM10K_SW_PORT_CFG_ISL_SGLORT_lsb
> 	0
> +#define FM10K_SW_PORT_CFG_ISL_SGLORT_msb
> 	15
> +#define FM10K_SW_PORT_CFG_ISL_USR_lsb
> 	16
> +#define FM10K_SW_PORT_CFG_ISL_USR_msb
> 	23
> +#define FM10K_SW_PORT_CFG_ISL_DEFAULT_PRI_lsb			24
> +#define FM10K_SW_PORT_CFG_ISL_DEFAULT_PRI_msb			27
> +#define FM10K_SW_PARSER_VLAN_TAG(n_)
> 	FM10K_SW_PARSER_REG(0x1C0 + (n_))
> +#define FM10K_SW_PARSER_CUSTOM_TAG(n_)
> 	FM10K_SW_PARSER_REG(0x1C4 + (n_))
> +#define FM10K_SW_PARSER_MPLS_TAG
> 		FM10K_SW_PARSER_REG(0x1C8)
> +#define FM10K_SW_PARSER_DI_CFG(n_)
> 		FM10K_SW_PARSER_REG(0x1D0 + 0x2 * (n_))
> +#define FM10K_SW_RX_VPRI_MAP(p_)
> 	FM10K_SW_PARSER_REG(0x200 + 0x2 * (p_))
> +#define FM10K_SW_DSCP_PRI_MAP(pri_)
> 		FM10K_SW_PARSER_REG(0x280 + (pri_))
> +#define FM10K_SW_VPRI_PRI_MAP(pri_)
> 		FM10K_SW_PARSER_REG(0x2C0 + (pri_))
> +
> +
> +#define FM10K_SW_HANDLER_BASE
> 		FM10K_SW_REG_OFF(0xD50000)
> +#define FM10K_SW_HANDLER_REG(wo_)
> 		(FM10K_SW_HANDLER_BASE + FM10K_SW_REG_OFF(wo_))
> +
> +#define FM10K_SW_SYS_CFG_1
> 			FM10K_SW_HANDLER_REG(0x0)
> +#define FM10K_SW_SYS_CFG_1_DROP_PAUSE
> 	(1 << 0)
> +#define FM10K_SW_SYS_CFG_1_TRAP_MTU_VIOLATIONS
> 	(1 << 1)
> +#define FM10K_SW_SYS_CFG_1_ENABLE_TRAP_PLUS_LOG
> 	(1 << 2)
> +#define FM10K_SW_SYS_CFG_1_DROP_INVALID_SMAC			(1 <<
> 3)
> +#define FM10K_SW_SYS_CFG_1_DROP_MAC_CTRL_ETHERTYPE		(1 <<
> 4)
> +#define FM10K_SW_CPU_MAC
> 		FM10K_SW_HANDLER_REG(0x2)
> +#define FM10K_SW_SYS_CFG_ROUTER
> 		FM10K_SW_HANDLER_REG(0x4)
> +#define FM10K_SW_L34_HASH_CFG
> 		FM10K_SW_HANDLER_REG(0x5)
> +#define FM10K_SW_L34_HASH_CFG_SYMMETRIC
> 		(1 << 0)
> +#define FM10K_SW_L34_HASH_CFG_USE_SIP
> 	(1 << 1)
> +#define FM10K_SW_L34_HASH_CFG_USE_DIP
> 	(1 << 2)
> +#define FM10K_SW_L34_HASH_CFG_USE_PROT
> 		(1 << 3)
> +#define FM10K_SW_L34_HASH_CFG_USE_TCP
> 	(1 << 4)
> +#define FM10K_SW_L34_HASH_CFG_USE_UDP
> 	(1 << 5)
> +#define FM10K_SW_L34_HASH_CFG_USE_PROT1
> 		(1 << 6)
> +#define FM10K_SW_L34_HASH_CFG_USE_PROT2
> 		(1 << 7)
> +#define FM10K_SW_L34_HASH_CFG_USE_L4SRC
> 		(1 << 8)
> +#define FM10K_SW_L34_HASH_CFG_USE_L4DST
> 		(1 << 9)
> +#define FM10K_SW_L34_HASH_CFG_ECMP_ROTATION_lsb
> 	10
> +#define FM10K_SW_L34_HASH_CFG_ECMP_ROTATION_msb
> 	11
> +#define FM10K_SW_L34_HASH_CFG_PROT1_lsb
> 		16
> +#define FM10K_SW_L34_HASH_CFG_PROT1_msb
> 		23
> +#define FM10K_SW_L34_HASH_CFG_PROT2_lsb
> 		24
> +#define FM10K_SW_L34_HASH_CFG_PROT2_msb
> 		31
> +#define FM10K_SW_L34_FLOW_HASH_CFG_1
> 	FM10K_SW_HANDLER_REG(0x6)
> +#define FM10K_SW_L34_FLOW_HASH_CFG_2
> 	FM10K_SW_HANDLER_REG(0x7)
> +#define FM10K_SW_L234_HASH_CFG
> 		FM10K_SW_HANDLER_REG(0x8)
> +#define FM10K_SW_L234_HASH_CFG_USE_L2_IF_IP
> 	(1 << 0)
> +#define FM10K_SW_L234_HASH_CFG_USE_L34
> 	(1 << 1)
> +#define FM10K_SW_L234_HASH_CFG_SYMMETRIC
> 	(1 << 2)
> +#define FM10K_SW_L234_HASH_CFG_USE_DMAC
> 		(1 << 3)
> +#define FM10K_SW_L234_HASH_CFG_USE_SMAC
> 		(1 << 4)
> +#define FM10K_SW_L234_HASH_CFG_USE_TYPE
> 		(1 << 5)
> +#define FM10K_SW_L234_HASH_CFG_USE_VPRI
> 		(1 << 6)
> +#define FM10K_SW_L234_HASH_CFG_USE_VID
> 	(1 << 8)
> +#define FM10K_SW_L234_HASH_CFG_ROTATION_A_lsb			8
> +#define FM10K_SW_L234_HASH_CFG_ROTATION_A_msb
> 	9
> +#define FM10K_SW_L234_HASH_CFG_ROTATION_B_lsb			10
> +#define FM10K_SW_L234_HASH_CFG_ROTATION_B_msb
> 	11
> +#define FM10K_SW_CPU_TRAP_MASK_FH
> 		FM10K_SW_HANDLER_REG(0xA)
> +#define FM10K_SW_TRAP_GLORT
> 			FM10K_SW_HANDLER_REG(0xC)
> +#define FM10K_SW_RX_MIRROR_CFG
> 		FM10K_SW_HANDLER_REG(0xD)
> +#define FM10K_SW_LOG_MIRROR_PROFILE
> 		FM10K_SW_HANDLER_REG(0xE)
> +#define FM10K_SW_FH_MIRROR_PROFILE_TABLE(n_)
> 	FM10K_SW_HANDLER_REG(0x40 + (n_))
> +#define FM10K_SW_PORT_CFG_2(p_)
> 		FM10K_SW_HANDLER_REG(0x80 + 0x2 * (p_))
> +#define FM10K_SW_PORT_CFG_3(p_)
> 		FM10K_SW_HANDLER_REG(0x100 + (p_))
> +#define FM10K_SW_FH_LOOPBACK_SUPPRESS(p_)
> 	FM10K_SW_HANDLER_REG(0x140 + (p_))
> +#define FM10K_SW_FH_HEAD_IP
> 			FM10K_SW_HANDLER_REG(0x180)
> +#define FM10K_SW_FH_HEAD_IM
> 			FM10K_SW_HANDLER_REG(0x182)
> +#define FM10K_SW_PARSER_EARLY_SRAM_CTRL
> 		FM10K_SW_HANDLER_REG(0x184)
> +#define FM10K_SW_PARSER_LATE_SRAM_CTRL
> 		FM10K_SW_HANDLER_REG(0x185)
> +#define FM10K_SW_MAPPER_SRAM_CTRL
> 		FM10K_SW_HANDLER_REG(0x186)
> +#define FM10K_SW_FFU_SRAM_CTRL(n_)
> 		FM10K_SW_HANDLER_REG(0x1A0 + 0x4 * (n_))
> +#define FM10K_SW_ARP_SRAM_CTRL
> 		FM10K_SW_HANDLER_REG(0x1C0)
> +#define FM10K_SW_VLAN_LOOKUP_SRAM_CTRL
> 		FM10K_SW_HANDLER_REG(0x1C1)
> +#define FM10K_SW_MA_TABLE_SRAM_CTRL(n_)
> 		FM10K_SW_HANDLER_REG(0x1C4 + 0x2 * (n_))
> +#define FM10K_SW_FID_GLORT_LOOKUP_SRAM_CTRL
> 	FM10K_SW_HANDLER_REG(0x1C8)
> +#define FM10K_SW_GLORT_RAM_SRAM_CTRL
> 	FM10K_SW_HANDLER_REG(0x1CA)
> +#define FM10K_SW_GLORT_TABLE_SRAM_CTRL
> 		FM10K_SW_HANDLER_REG(0x1CB)
> +#define FM10K_SW_FH_HEAD_OUTPUT_FIFO_SRAM_CTRL
> 	FM10K_SW_HANDLER_REG(0x1CC)
> +
> +
> +#define FM10K_SW_LAG_BASE
> 		FM10K_SW_REG_OFF(0xD90000)
> +#define FM10K_SW_LAG_REG(wo_)
> 		(FM10K_SW_LAG_BASE + FM10K_SW_REG_OFF(wo_))
> +#define	FM10K_SW_LAG_CFG(l_)
> 			FM10K_SW_LAG_REG(l_)
> +#define FM10K_SW_LAG_CFG_LAG_SIZE_lsb
> 	0
> +#define FM10K_SW_LAG_CFG_LAG_SIZE_msb
> 	3
> +#define FM10K_SW_LAG_CFG_INDEX_lsb
> 		4
> +#define FM10K_SW_LAG_CFG_INDEX_msb
> 		7
> +#define FM10K_SW_LAG_CFG_HASH_ROTATION
> 		(1 << 8)
> +#define FM10K_SW_LAG_CFG_IN_LAG
> 		(1 << 9)
> +#define	FM10K_SW_CANONICAL_GLORT_CAM(n_)
> 		FM10K_SW_LAG_REG((n_) + 0x40)
> +#define FM10K_SW_CANONICAL_GLORT_CAM_LAG_GLORT_lsb		0
> +#define FM10K_SW_CANONICAL_GLORT_CAM_LAG_GLORT_msb
> 	15
> +#define FM10K_SW_CANONICAL_GLORT_CAM_MASK_SIZE_lsb		16
> +#define FM10K_SW_CANONICAL_GLORT_CAM_MASK_SIZE_msb
> 	19
> +#define FM10K_SW_CANONICAL_GLORT_CAM_PORT_FIELD_SIZE_lsb 20
> +#define FM10K_SW_CANONICAL_GLORT_CAM_PORT_FIELD_SIZE_msb 22
> +
> +
> +#define FM10K_SW_RX_STATS_BASE
> 		FM10K_SW_REG_OFF(0xE00000)
> +#define FM10K_SW_RX_STATS_REG(wo_)
> 		(FM10K_SW_RX_STATS_BASE + FM10K_SW_REG_OFF(wo_))
> +#define FM10K_SW_RX_STATS_BANK(b_, i_)
> 	FM10K_SW_RX_STATS_REG(0x1000 * (b_) + 0x4 * (i_))
> +#define FM10K_SW_RX_STATS_BANK_1_INDEX
> 	0
> +#define FM10K_SW_RX_STATS_BANK_2_INDEX
> 	1
> +#define FM10K_SW_RX_STATS_BANK_3_INDEX
> 	2
> +#define FM10K_SW_RX_STATS_BANK_4_INDEX
> 	3
> +#define FM10K_SW_RX_STATS_BANK_5_INDEX
> 	4
> +#define FM10K_SW_RX_STATS_BANK_6_INDEX
> 	5
> +#define FM10K_SW_RX_STATS_BANK_1_NON_IP_L2_UCAST		0
> +#define FM10K_SW_RX_STATS_BANK_1_NON_IP_L2_MCAST		1
> +#define FM10K_SW_RX_STATS_BANK_1_NON_IP_L2_BCAST		2
> +#define FM10K_SW_RX_STATS_BANK_1_IPV4_L2_UCAST
> 	3
> +#define FM10K_SW_RX_STATS_BANK_1_IPV4_L2_MCAST
> 	4
> +#define FM10K_SW_RX_STATS_BANK_1_IPV4_L2_BCAST
> 	5
> +#define FM10K_SW_RX_STATS_BANK_1_IPV6_L2_UCAST
> 	6
> +#define FM10K_SW_RX_STATS_BANK_1_IPV6_L2_MCAST
> 	7
> +#define FM10K_SW_RX_STATS_BANK_1_IPV6_L2_BCAST
> 	8
> +#define FM10K_SW_RX_STATS_BANK_1_IEEE802_3_PAUSE		9
> +#define FM10K_SW_RX_STATS_BANK_1_CLASS_BASED_PAUSE		10
> +#define FM10K_SW_RX_STATS_BANK_1_FRAMING_ERR			11
> +#define FM10K_SW_RX_STATS_BANK_1_FCS_ERR
> 	12
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_LT_64
> 	0
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_EQ_64
> 	1
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_65_127
> 	2
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_128_255			3
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_256_511			4
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_512_1023
> 	5
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_1024_1522
> 	6
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_1523_2047
> 	7
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_2048_4095
> 	8
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_4096_8191
> 	9
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_8192_10239
> 	10
> +#define FM10K_SW_RX_STATS_BANK_2_LEN_GE_10240
> 	11
> +#define FM10K_SW_RX_STATS_BANK_3_PRI(p_)
> 	(p_)
> +#define FM10K_SW_RX_STATS_BANK_4_FID_FORWARDED
> 	0
> +#define FM10K_SW_RX_STATS_BANK_4_FLOOD_FORWARDED		1
> +#define FM10K_SW_RX_STATS_BANK_4_SPECIALLY_HANDLED		2
> +#define FM10K_SW_RX_STATS_BANK_4_PARSER_ERROR_DROP		3
> +#define FM10K_SW_RX_STATS_BANK_4_ECC_ERROR_DROP
> 	4
> +#define FM10K_SW_RX_STATS_BANK_4_TRAPPED
> 	5
> +#define FM10K_SW_RX_STATS_BANK_4_PAUSE_DROPS			6
> +#define FM10K_SW_RX_STATS_BANK_4_STP_DROPS
> 	7
> +#define FM10K_SW_RX_STATS_BANK_4_SECURITY_VIOLATIONS 	8
> +#define FM10K_SW_RX_STATS_BANK_4_VLAN_TAG_DROPS
> 	9
> +#define FM10K_SW_RX_STATS_BANK_4_VLAN_INGRESS_DROPS 	10
> +#define FM10K_SW_RX_STATS_BANK_4_VLAN_EGRESS_DROPS		11
> +#define FM10K_SW_RX_STATS_BANK_4_GLORT_MISS_DROPS		12
> +#define FM10K_SW_RX_STATS_BANK_4_FFU_DROPS
> 	13
> +#define FM10K_SW_RX_STATS_BANK_4_TRIGGER_DROPS
> 	14
> +#define FM10K_SW_RX_STATS_BANK_5_POLICER_DROPS
> 	0
> +#define FM10K_SW_RX_STATS_BANK_5_TTL_DROPS
> 	1
> +#define FM10K_SW_RX_STATS_BANK_5_CM_PRIV_DROPS
> 	2
> +#define FM10K_SW_RX_STATS_BANK_5_CM_SMP0_DROPS
> 	3
> +#define FM10K_SW_RX_STATS_BANK_5_CM_SMP1_DROPS
> 	4
> +#define FM10K_SW_RX_STATS_BANK_5_CM_RX_HOG0_DROPS		5
> +#define FM10K_SW_RX_STATS_BANK_5_CM_RX_HOG1_DROPS		6
> +#define FM10K_SW_RX_STATS_BANK_5_CM_TX_HOG0_DROPS		7
> +#define FM10K_SW_RX_STATS_BANK_5_CM_TX_HOG1_DROPS		8
> +#define FM10K_SW_RX_STATS_BANK_5_TRIGGER_REDIRECTS		10
> +#define FM10K_SW_RX_STATS_BANK_5_FLOOD_CONTROL_DROPS 	11
> +#define FM10K_SW_RX_STATS_BANK_5_GLORT_FORWARDED		12
> +#define FM10K_SW_RX_STATS_BANK_5_LOOPBACK_SUPP_DROPS 	13
> +#define FM10K_SW_RX_STATS_BANK_5_OTHER_DROPS
> 	14
> +#define FM10K_SW_RX_PORT_STAT(b_, s_, p_, f_) \
> +
> 	(FM10K_SW_RX_STATS_BANK(FM10K_SW_RX_STATS_##b_##_INDEX, \
> +		    16 * (p_) +	FM10K_SW_RX_STATS_##b_##_##s_) + \
> +		    ((f_) ? 0 : FM10K_SW_REG_OFF(2)))
> +#define FM10K_SW_RX_STATS_CFG(p_)
> 	FM10K_SW_RX_STATS_REG(0x10000 + (p_))
> +#define FM10K_SW_RX_STATS_CFG_PER_FRAME_ADJUSTMENT_lsb 	0
> +#define FM10K_SW_RX_STATS_CFG_PER_FRAME_ADJUSTMENT_msb 	7
> +#define FM10K_SW_RX_STATS_CFG_ENABLE_ALL_BANKS
> 	0x00003f00
> +#define FM10K_SW_RX_STATS_CFG_ENABLE_BANK_1
> 	(1 << 8)
> +#define FM10K_SW_RX_STATS_CFG_ENABLE_BANK_2
> 	(1 << 9)
> +#define FM10K_SW_RX_STATS_CFG_ENABLE_BANK_3
> 	(1 << 10)
> +#define FM10K_SW_RX_STATS_CFG_ENABLE_BANK_4
> 	(1 << 11)
> +#define FM10K_SW_RX_STATS_CFG_ENABLE_BANK_5
> 	(1 << 12)
> +#define FM10K_SW_RX_STATS_CFG_ENABLE_BANK_6
> 	(1 << 13)
> +#define FM10K_SW_RX_STATS_CFG_SWITCH_PRI
> 	(1 << 14)
> +
> +
> +#define FM10K_SW_HANDLER_TAIL_BASE
> 		FM10K_SW_REG_OFF(0xE30000)
> +#define FM10K_SW_HANDLER_TAIL_REG(wo_)
> 	(FM10K_SW_HANDLER_TAIL_BASE + FM10K_SW_REG_OFF(wo_))
> +#define FM10K_SW_SAF_MATRIX(l_)
> 		FM10K_SW_HANDLER_TAIL_REG(0x2 * (l_))
> +#define FM10K_SW_SAF_MATRIX_ENABLE_SNF(l_)
> 	(1ULL << (l_))
> +#define FM10K_SW_SAF_MATRIX_ENABLE_SNF_ALL_PORTS
> 	FM10K_SW_MASK64(47, 0)
> +#define FM10K_SW_SAF_MATRIX_CUT_THRU_MODE_lsb64
> 	48
> +#define FM10K_SW_SAF_MATRIX_CUT_THRU_MODE_msb64
> 	49
> +#define	FM10K_SW_SAF_MATRIX_CUT_THRU_MODE_FULL
> 		0
> +#define	FM10K_SW_SAF_MATRIX_CUT_THRU_MODE_1SEG_SNF
> 	1
> +#define	FM10K_SW_SAF_MATRIX_CUT_THRU_MODE_2SEG_SNF
> 	2
> +#define	FM10K_SW_SAF_MATRIX_CUT_THRU_MODE_EOF_SNF
> 	3
> +#define FM10K_SW_SAF_MATRIX_IGNORE_ERROR
> 	(1ULL << 50)
> +#define FM10K_SW_FRAME_TIME_OUT
> 			FM10K_SW_HANDLER_TAIL_REG(0x80)
> +#define FM10K_SW_SAF_SRAM_CTRL
> 		FM10K_SW_HANDLER_TAIL_REG(0x81)
> +#define FM10K_SW_EGRESS_PAUSE_SRAM_CTRL
> 		FM10K_SW_HANDLER_TAIL_REG(0x82)
> +#define FM10K_SW_RX_STATS_SRAM_CTRL
> 		FM10K_SW_HANDLER_TAIL_REG(0x84)
> +#define FM10K_SW_POLICER_USAGE_SRAM_CTRL
> 	FM10K_SW_HANDLER_TAIL_REG(0x88)
> +#define FM10K_SW_TCN_SRAM_CTRL
> 		FM10K_SW_HANDLER_TAIL_REG(0x8C)
> +#define FM10K_SW_FH_TAIL_IP
> 			FM10K_SW_HANDLER_TAIL_REG(0x8D)
> +#define FM10K_SW_FH_TAIL_IM
> 			FM10K_SW_HANDLER_TAIL_REG(0x8E)
> +#define FM10K_SW_TAIL_PERMIT_MGMT
> 		FM10K_SW_HANDLER_TAIL_REG(0x8F)
> +#define FM10K_SW_TAIL_FORCE_IDLE
> 	FM10K_SW_HANDLER_TAIL_REG(0x90)
> +
> +
> +#define FM10K_SW_CM_USAGE_BASE
> 		FM10K_SW_REG_OFF(0xE60000)
> +#define FM10K_SW_CM_USAGE_REG(wo_)
> 		(FM10K_SW_CM_USAGE_BASE + FM10K_SW_REG_OFF(wo_))
> +#define FM10K_SW_CM_SWEEPER_SWITCH_PRI_TO_TC
> 	FM10K_SW_CM_USAGE_REG(0x0)
> +#define FM10K_SW_CM_SWEEPER_TC_TO_SMP
> 		FM10K_SW_CM_USAGE_REG(0x2)
> +#define FM10K_SW_CM_TX_TC_PRIVATE_WM(l_, c_)
> 	FM10K_SW_CM_USAGE_REG(0x200 + 0x8 * (l_) + (c_))
> +#define FM10K_SW_CM_TX_TC_HOG_WM(l_, c_)
> 	FM10K_SW_CM_USAGE_REG(0x400 + 0x8 * (l_) + (c_))
> +#define FM10K_SW_CM_RX_SMP_PAUSE_WM(l_, s_)
> 	FM10K_SW_CM_USAGE_REG(0x600 + 0x2 * (l_) + (s_))
> +#define FM10K_SW_CM_RX_SMP_PRIVATE_WM(l_, s_)
> 	FM10K_SW_CM_USAGE_REG(0x680 + 0x2 * (l_) + (s_))
> +#define FM10K_SW_CM_RX_SMP_HOG_WM(l_, s_)
> 	FM10K_SW_CM_USAGE_REG(0x700 + 0x2 * (l_) + (s_))
> +#define FM10K_SW_CM_PAUSE_RESEND_INTERVAL(l_)
> 	FM10K_SW_CM_USAGE_REG(0x780 + (l_))
> +#define FM10K_SW_CM_PAUSE_BASE_FREQ
> 		FM10K_SW_CM_USAGE_REG(0x7C0)
> +#define FM10K_SW_CM_PAUSE_CFG(l_)
> 		FM10K_SW_CM_USAGE_REG(0x800 + (l_))
> +#define FM10K_SW_CM_SHARED_WM(p_)
> 		FM10K_SW_CM_USAGE_REG(0x840 + (p_))
> +#define FM10K_SW_CM_SHARED_SMP_PAUSE_WM(s_)
> 	FM10K_SW_CM_USAGE_REG(0x850 + (s_))
> +#define FM10K_SW_CM_GLOBAL_WM
> 		FM10K_SW_CM_USAGE_REG(0x852)
> +#define FM10K_SW_CM_GLOBAL_WM_WATERMARK_lsb
> 		0
> +#define FM10K_SW_CM_GLOBAL_WM_WATERMARK_msb
> 		14
> +#define FM10K_SW_CM_GLOBAL_CFG
> 		FM10K_SW_CM_USAGE_REG(0x853)
> +#define FM10K_SW_CM_GLOBAL_CFG_IFG_PENALTY_lsb
> 	0
> +#define FM10K_SW_CM_GLOBAL_CFG_IFG_PENALTY_msb
> 	7
> +#define FM10K_SW_CM_GLOBAL_CFG_FORCE_PAUSE_ON
> 	(1 << 8)
> +#define FM10K_SW_CM_GLOBAL_CFG_FORCE_PAUSE_OFF
> 	(1 << 9)
> +#define FM10K_SW_CM_GLOBAL_CFG_WM_SWEEP_EN
> 		(1 << 10)
> +#define FM10K_SW_CM_GLOBAL_CFG_PAUSE_GEN_SWEEP_EN
> 	(1 << 11)
> +#define FM10K_SW_CM_GLOBAL_CFG_PAUSE_REC_SWEEP_EN		(1 <<
> 12)
> +#define FM10K_SW_CM_GLOBAL_CFG_NUM_SWEEPER_PORTS_lsb	 13
> +#define FM10K_SW_CM_GLOBAL_CFG_NUM_SWEEPER_PORTS_msb 	18
> +#define FM10K_SW_CM_TC_PC_MAP(l_)
> 		FM10K_SW_CM_USAGE_REG(0x880 + (l_))
> +#define FM10K_SW_CM_PC_SMP_MAP(l_)
> 		FM10K_SW_CM_USAGE_REG(0x8C0 + (l_))
> +#define FM10K_SW_CM_SOFTDROP_WM(p_)
> 		FM10K_SW_CM_USAGE_REG(0x900 + (p_))
> +#define FM10K_SW_CM_SHARED_SMP_PAUSE_CFG(s_)
> 	FM10K_SW_CM_USAGE_REG(0x910 + 0x2 * (s_))
> +#define FM10K_SW_TX_RATE_LIM_CFG(l_, c_)
> 	FM10K_SW_CM_USAGE_REG(0xA00 + 0x8 * (l_) + (c_))
> +#define FM10K_SW_TX_RATE_LIM_USAGE(l_, c_)
> 	FM10K_SW_CM_USAGE_REG(0xC00 + 0x8 * (l_) + (c_))
> +#define FM10K_SW_CM_BSG_MAP(l_)
> 		FM10K_SW_CM_USAGE_REG(0xE00 + (l_))
> +#define FM10K_SW_CM_TX_TC_USAGE(l_, c_)
> 	FM10K_SW_CM_USAGE_REG(0x1000 + 0x8 * (l_) + (c_))
> +#define FM10K_SW_CM_RX_SMP_USAGE(l_, s_)
> 	FM10K_SW_CM_USAGE_REG(0x1200 + 0x2 * (l_) + (s_))
> +#define FM10K_SW_MCAST_EPOCH_USAGE(s_)
> 	FM10K_SW_CM_USAGE_REG(0x1280 + (s_))
> +#define FM10K_SW_CM_SHARED_SMP_USAGE(s_)
> 	FM10K_SW_CM_USAGE_REG(0x1282 + (s_))
> +#define FM10K_SW_CM_SMP_USAGE(s_)
> 		FM10K_SW_CM_USAGE_REG(0x1284 + (s_))
> +#define FM10K_SW_CM_GLOBAL_USAGE
> 		FM10K_SW_CM_USAGE_REG(0x1286)
> +#define FM10K_SW_CM_PAUSE_GEN_STATE(l_)
> 		FM10K_SW_CM_USAGE_REG(0x12C0 + (l_))
> +#define FM10K_SW_CM_PAUSE_RCV_TIMER
> 		FM10K_SW_CM_USAGE_REG(0x1300)
> +#define FM10K_SW_CM_PAUSE_RCV_PORT_TIMER(l_)
> FM10K_SW_CM_USAGE_REG(0x1340 + (l_))
> +/* FM10K_SW_CM_EGRESS_PAUSE_COUNT is also known as
> FM10K_SW_CM_PAUSE_RCV_STATE */
> +#define FM10K_SW_CM_EGRESS_PAUSE_COUNT(l_, dw_)
> 	FM10K_SW_CM_USAGE_REG(0x1400 + 0x4 * (l_) + 0x2 * (dw_))
> +
> +#define FM10K_SW_MOD_BASE
> 			FM10K_SW_REG_OFF(0xE80000)
> +#define FM10K_SW_MOD_REG(wo_)
> 		(FM10K_SW_MOD_BASE + FM10K_SW_REG_OFF(wo_))
> +
> +#define FM10K_SW_MOD_MAX_MGMT_WAIT_CYCLE
> 	FM10K_SW_MOD_REG(0xF8)
> +#define FM10K_SW_MOD_IP
> 			FM10K_SW_MOD_REG(0x106)
> +#define FM10K_SW_MOD_IM
> 			FM10K_SW_MOD_REG(0x108)
> +#define FM10K_SW_MOD_SRAM_BIST_OUT
> 		FM10K_SW_MOD_REG(0x10A)
> +#define FM10K_SW_MOD_SRAM_ERROR_WRITE
> 		FM10K_SW_MOD_REG(0x10C)
> +#define FM10K_SW_MOD_PAUSE_SMAC
> 			FM10K_SW_MOD_REG(0x10E)
> +#define FM10K_SW_MOD_ROUTER_SMAC(n_)
> 	FM10K_SW_MOD_REG(0x120 + 0x2 * (n_))
> +#define FM10K_SW_MOD_MCAST_VLAN_TABLE(n_)
> 	FM10K_SW_MOD_REG(0x10000 + 0x2 * (n_))
> +#define FM10K_SW_MOD_VLAN_TAG_VID1_MAP(v_)
> 	FM10K_SW_MOD_REG(0x20000 + 0x2 *(v_))
> +#define FM10K_SW_MOD_VID2_MAP(v_)
> 		FM10K_SW_MOD_REG(0x22000 + 0x2 * (v_))
> +#define FM10K_SW_MOD_MIRROR_PROFILE_TABLE(n_)
> 	FM10K_SW_MOD_REG(0x24000 + 0x2 * (n_))
> +#define FM10K_SW_MOD_PER_PORT_CFG_1(p_)
> 		FM10K_SW_MOD_REG(0x24080 + 0x2 * (p_))
> +#define FM10K_SW_MOD_PER_PORT_CFG_2(p_)
> 		FM10K_SW_MOD_REG(0x24100 + 0x2 * (p_))
> +#define
> FM10K_SW_MOD_PER_PORT_CFG_2_MIRROR_TRUNCATION_LEN_lsb64	0
> +#define
> FM10K_SW_MOD_PER_PORT_CFG_2_MIRROR_TRUNCATION_LEN_msb64
> 	5
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_ENABLE_PCP1_UPDATE	(1ULL
> << 6)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_ENABLE_PCP2_UPDATE	(1ULL
> << 7)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_ENABLE_DEI1_UPDATE	(1ULL
> << 8)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_ENABLE_DEI2_UPDATE	(1ULL
> << 9)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_VLAN1_ETYPE_lsb64	10
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_VLAN1_ETYPE_msb64	11
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_VLAN2_ETYPE_lsb64	12
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_VLAN2_ETYPE_msb64	13
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_ENABLE_DMAC_ROUTING
> 	(1ULL << 14)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_ENABLE_SMAC_ROUTING
> 	(1ULL << 15)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_ENABLE_TTL_DECREMENT
> 	(1ULL << 16)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_ENABLE_DSCP_MODIFICATION
> (1ULL << 17)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_FTAG
> 	(1ULL << 18)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_VID2_FIRST
> 	(1ULL << 19)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_VLAN_TAGGING_lsb64	20
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_VLAN_TAGGING_msb64	22
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_TX_PAUSE_PRI_EN_VEC_lsb64
> 23
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_TX_PAUSE_PRI_EN_VEC_msb64
> 30
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_TX_PAUSE_TYPE		(1ULL
> << 31)
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_TX_PAUSE_VALUE_lsb64	32
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_TX_PAUSE_VALUE_msb64
> 	47
> +#define FM10K_SW_MOD_PER_PORT_CFG_2_MIN_FRAME_SIZE
> 	(1ULL << 48)
> +#define FM10K_SW_MOD_VPRI1_MAP(p_)
> 		FM10K_SW_MOD_REG(0x24180 + 0x2 * (p_))
> +#define FM10K_SW_MOD_VPRI2_MAP(p_)
> 		FM10K_SW_MOD_REG(0x24200 + 0x2 * (p_))
> +#define FM10K_SW_MOD_VLAN_ETYPE(n_)
> 		FM10K_SW_MOD_REG(0x24280 + 0x2 * (n_))
> +#define FM10K_SW_MOD_STATS_CFG(p_)
> 		FM10K_SW_MOD_REG(0x24300 + 0x2 * (p_))
> +#define FM10K_SW_MOD_STATS_CFG_ENABLE_GROUP_7
> 	(1 << 0)
> +#define FM10K_SW_MOD_STATS_CFG_ENABLE_GROUP_8
> 	(1 << 1)
> +#define FM10K_SW_MOD_STATS_BANK_FRAME(b_, i_)
> 	FM10K_SW_MOD_REG(0x25000 + 0x800 * (b_) + 0x2 * (i_))
> +#define FM10K_SW_MOD_STATS_BANK_BYTE(b_, i_)
> 	FM10K_SW_MOD_REG(0x26000 + 0x800 * (b_) + 0x2 * (i_))
> +#define FM10K_SW_MOD_STATS_BANK_7_INDEX
> 		0
> +#define FM10K_SW_MOD_STATS_BANK_8_INDEX
> 		1
> +#define FM10K_SW_MOD_STATS_BANK_7_L2_UCAST
> 	0
> +#define FM10K_SW_MOD_STATS_BANK_7_L2_MCAST
> 	1
> +#define FM10K_SW_MOD_STATS_BANK_7_L2_BCAST
> 	2
> +#define FM10K_SW_MOD_STATS_BANK_7_TX_ERROR
> 	3
> +#define FM10K_SW_MOD_STATS_BANK_7_TIMEOUT_DROP
> 	4
> +#define FM10K_SW_MOD_STATS_BANK_7_TX_ERROR_DROP
> 	5
> +#define FM10K_SW_MOD_STATS_BANK_7_TX_ECC_DROP
> 	6
> +#define FM10K_SW_MOD_STATS_BANK_7_LOOPBACK_DROP
> 	7
> +#define FM10K_SW_MOD_STATS_BANK_7_TTL1_DROP
> 	8
> +#define FM10K_SW_MOD_STATS_BANK_7_PAUSE
> 		9
> +#define FM10K_SW_MOD_STATS_BANK_7_CB_PAUSE
> 	10
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_LT_64
> 	0
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_EQ_64
> 	1
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_65_127
> 	2
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_128_255
> 	3
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_256_511
> 	4
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_512_1023
> 	5
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_1024_1522
> 	6
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_1523_2047
> 	7
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_2048_4095
> 	8
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_4096_8191
> 	9
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_8192_10239		10
> +#define FM10K_SW_MOD_STATS_BANK_8_LEN_GE_10240
> 	11
> +#define FM10K_SW_TX_PORT_STAT(b_, s_, p_, f_) \
> +			((f_) ? \
> +
> FM10K_SW_MOD_STATS_BANK_FRAME(FM10K_SW_MOD_STATS_##b_##_IND
> EX, \
> +			16 * (p_) + FM10K_SW_MOD_STATS_##b_##_##s_) : \
> +
> FM10K_SW_MOD_STATS_BANK_BYTE(FM10K_SW_MOD_STATS_##b_##_INDEX,
> \
> +			16 * (p_) + FM10K_SW_MOD_STATS_##b_##_##s_))
> +
> +#define FM10K_SW_SCHED_BASE
> 			FM10K_SW_REG_OFF(0xF00000)
> +#define FM10K_SW_SCHED_REG(wo_)
> 	(FM10K_SW_SCHED_BASE + FM10K_SW_REG_OFF(wo_))
> +
> +/*
> + * Schedule fields for both FM10K_SW_SCHED_RX_SCHEDULE and
> + * FM10K_SW_SCHED_TX_SCHEDULE
> + */
> +#define	FM10K_SW_SCHED_SCHEDULE_ENTRY(p_, l_, q_)
> 			\
> +    		(FM10K_SW_MAKE_REG_FIELD(SCHED_SCHEDULE_PHYS_PORT,
> (p_)) |	\
> +
> FM10K_SW_MAKE_REG_FIELD(SCHED_SCHEDULE_LOG_PORT, (l_)) | \
> +		    ((q_) ? FM10K_SW_SCHED_SCHEDULE_QUAD : 0))
> +#define FM10K_SW_SCHED_SCHEDULE_PHYS_PORT_lsb
> 	0
> +#define FM10K_SW_SCHED_SCHEDULE_PHYS_PORT_msb
> 	7
> +#define FM10K_SW_SCHED_SCHEDULE_LOG_PORT_lsb			8
> +#define FM10K_SW_SCHED_SCHEDULE_LOG_PORT_msb
> 	13
> +#define FM10K_SW_SCHED_SCHEDULE_QUAD
> 	(1 << 14)
> +#define FM10K_SW_SCHED_SCHEDULE_COLOR
> 	(1 << 15)
> +#define FM10K_SW_SCHED_SCHEDULE_IDLE
> 	(1 << 16)
> +
> +#define FM10K_SW_SCHED_RX_SCHEDULE(p_, n_)
> 	FM10K_SW_SCHED_REG(0x20000 + 0x200 * (p_) + (n_))
> +#define FM10K_SW_SCHED_TX_SCHEDULE(p_, n_)
> 	FM10K_SW_SCHED_REG(0x20400 + 0x200 * (p_) + (n_))
> +#define FM10K_SW_SCHED_SCHEDULE_CTRL
> 	FM10K_SW_SCHED_REG(0x20800)
> +#define FM10K_SW_SCHED_SCHEDULE_CTRL_RX_ENABLE
> 	(1 << 0)
> +#define FM10K_SW_SCHED_SCHEDULE_CTRL_RX_PAGE			(1 <<
> 1)
> +#define FM10K_SW_SCHED_SCHEDULE_CTRL_RX_MAX_INDEX_lsb 	2
> +#define FM10K_SW_SCHED_SCHEDULE_CTRL_RX_MAX_INDEX_msb 	10
> +#define FM10K_SW_SCHED_SCHEDULE_CTRL_TX_ENABLE
> 	(1 << 11)
> +#define FM10K_SW_SCHED_SCHEDULE_CTRL_TX_PAGE			(1 <<
> 12)
> +#define FM10K_SW_SCHED_SCHEDULE_CTRL_TX_MAX_INDEX_lsb 	13
> +#define FM10K_SW_SCHED_SCHEDULE_CTRL_TX_MAX_INDEX_msb 	21
> +#define FM10K_SW_SCHED_CONFIG_SRAM_CTRL
> 		FM10K_SW_SCHED_REG(0x20801)
> +#define FM10K_SW_SCHED_SSCHED_RX_PERPORT(l_)
> 	FM10K_SW_SCHED_REG(0x20840 + (l_))
> +#define FM10K_SW_SCHED_SSCHED_RX_PERPORT_NEXT_lsb		0
> +#define FM10K_SW_SCHED_SSCHED_RX_PERPORT_NEXT_msb		15
> +#define FM10K_SW_SCHED_SSCHED_SRAM_CTRL
> 		FM10K_SW_SCHED_REG(0x30050)
> +#define FM10K_SW_SCHED_ESCHED_CFG_1(l_)
> 	FM10K_SW_SCHED_REG(0x30080 + (l_))
> +#define FM10K_SW_SCHED_ESCHED_CFG_2(l_)
> 	FM10K_SW_SCHED_REG(0x300C0 + (l_))
> +#define FM10K_SW_SCHED_ESCHED_CFG_3(l_)
> 	FM10K_SW_SCHED_REG(0x30100 + (l_))
> +#define FM10K_SW_SCHED_MGMT_TIMER_ESCHED
> 	FM10K_SW_SCHED_REG(0x30240)
> +#define FM10K_SW_SCHED_ESCHED_SRAM_CTRL
> 		FM10K_SW_SCHED_REG(0x30242)
> +#define FM10K_SW_SCHED_FREELIST_INIT
> 	FM10K_SW_SCHED_REG(0x30244)
> +#define FM10K_SW_SCHED_FREELIST_INIT_ENTRIES			(24 *
> 1024)
> +#define FM10K_SW_SCHED_FREELIST_INIT_ADDRESS_lsb		0
> +#define FM10K_SW_SCHED_FREELIST_INIT_ADDRESS_msb		15
> +#define FM10K_SW_SCHED_FREELIST_SRAM_CTRL
> 	FM10K_SW_SCHED_REG(0x30246)
> +#define FM10K_SW_SCHED_MONITOR_DRR_Q_PERQ(q_)
> 	FM10K_SW_SCHED_REG(0x30400 + (q_))
> +#define FM10K_SW_SCHED_MONITOR_DRR_CFG_PERPORT(l_)
> 	FM10K_SW_SCHED_REG(0x30600 + (l_))
> +#define FM10K_SW_SCHED_MGMT_TIMER_MONITOR
> 	FM10K_SW_SCHED_REG(0x30A40)
> +#define FM10K_SW_SCHED_MONITOR_SRAM_CTRL
> 	FM10K_SW_SCHED_REG(0x30A41)
> +#define FM10K_SW_SCHED_MCAST_LEN_TABLE(n_)
> 	FM10K_SW_SCHED_REG(0x34000 + (n_))
> +#define FM10K_SW_SCHED_MCAST_DEST_TABLE(n_)
> 	FM10K_SW_SCHED_REG(0x38000 + 0x2 * (n_))
> +#define FM10K_SW_SCHED_MCAST_LIMITED_SKEW_MULTICAST
> 	FM10K_SW_SCHED_REG(0x3A000)
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS(n_)
> 	FM10K_SW_SCHED_REG(0x60400 + 0x2 * (n_))
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_ENTRIES
> 	8
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_HEAD_PAGE_lsb	0
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_HEAD_PAGE_msb
> 	9
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_TAIL_PAGE_lsb	10
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_TAIL_PAGE_msb	19
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_HEAD_IDX_lsb	20
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_HEAD_IDX_msb	24
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_TAIL_IDX_lsb	25
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_TAIL_IDX_msb	29
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_NEXT_PAGE_lsb	30
> +#define FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_NEXT_PAGE_msb
> 	39
> +#define FM10K_SW_SCHED_RXQ_FREELIST_INIT
> 	FM10K_SW_SCHED_REG(0x60410)
> +#define FM10K_SW_SCHED_RXQ_FREELIST_INIT_ENTRIES		1024
> +#define FM10K_SW_SCHED_RXQ_FREELIST_INIT_ADDRESS_lsb 	0
> +#define FM10K_SW_SCHED_RXQ_FREELIST_INIT_ADDRESS_msb 	9
> +#define FM10K_SW_SCHED_MGMT_TIMER_RXQ
> 		FM10K_SW_SCHED_REG(0x60412)
> +#define FM10K_SW_SCHED_MGMT_TIMER_LG
> 	FM10K_SW_SCHED_REG(0x60413)
> +#define FM10K_SW_SCHED_RXQ_SRAM_CTRL
> 	FM10K_SW_SCHED_REG(0x60414)
> +#define FM10K_SW_SCHED_TXQ_TAIL0_PERQ(q_)
> 	FM10K_SW_SCHED_REG(0x60600 + (q_))
> +#define FM10K_SW_SCHED_TXQ_TAIL0_PERQ_TAIL_lsb			0
> +#define FM10K_SW_SCHED_TXQ_TAIL0_PERQ_TAIL_msb
> 	15
> +#define FM10K_SW_SCHED_TXQ_TAIL1_PERQ(q_)
> 	FM10K_SW_SCHED_REG(0x60800 + (q_))
> +#define FM10K_SW_SCHED_TXQ_TAIL1_PERQ_TAIL_lsb			0
> +#define FM10K_SW_SCHED_TXQ_TAIL1_PERQ_TAIL_msb
> 	15
> +#define FM10K_SW_SCHED_TXQ_HEAD_PERQ(q_)
> 	FM10K_SW_SCHED_REG(0x60A00 + (q_))
> +#define FM10K_SW_SCHED_TXQ_HEAD_PERQ_ENTRIES			384
> +#define FM10K_SW_SCHED_TXQ_HEAD_PERQ_HEAD_lsb
> 	0
> +#define FM10K_SW_SCHED_TXQ_HEAD_PERQ_HEAD_msb
> 	15
> +#define FM10K_SW_SCHED_TXQ_FREELIST_INIT
> 	FM10K_SW_SCHED_REG(0x62000)
> +#define FM10K_SW_SCHED_TXQ_FREELIST_INIT_ENTRIES
> 	(24*1024)
> +#define FM10K_SW_SCHED_TXQ_FREELIST_INIT_ADDRESS_lsb	0
> +#define FM10K_SW_SCHED_TXQ_FREELIST_INIT_ADDRESS_msb 	15
> +#define FM10K_SW_SCHED_TXQ_SRAM_CTRL
> 	FM10K_SW_SCHED_REG(0x62002)
> +#define FM10K_SW_SCHED_FIFO_SRAM_CTRL
> 	FM10K_SW_SCHED_REG(0x62004)
> +#define FM10K_SW_SCHED_IP
> 		FM10K_SW_SCHED_REG(0x62006)
> +#define FM10K_SW_SCHED_IM
> 		FM10K_SW_SCHED_REG(0x62007)
> +
> +#endif /* _FM10K_REGS_H_ */
> diff --git a/drivers/net/fm10k/switch/fm10k_sbus.c
> b/drivers/net/fm10k/switch/fm10k_sbus.c
> new file mode 100644
> index 0000000..2340d0d
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_sbus.c
> @@ -0,0 +1,294 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#include <rte_malloc.h>
> +
> +#include "fm10k_regs.h"
> +#include "fm10k_sbus.h"
> +#include "fm10k_switch.h"
> +#include "fm10k_debug.h"
> +
> +#define FM10K_SW_SBUS_COMMAND_WAIT_LOCK_US_MAX	4
> +#define FM10K_SW_SBUS_COMMAND_TIMEOUT_US		500000
> +#define FM10K_SW_SBUS_RING_DIVIDER				0x01
> +
> +static int fm10k_sbus_init(struct fm10k_sbus *);
> +static int fm10k_sbus_exec(struct fm10k_sbus *, struct fm10k_sbus_req *);
> +static int fm10k_sbus_reset_all(struct fm10k_sbus *);
> +static int fm10k_sbus_sbm_reset(struct fm10k_sbus *);
> +
> +struct fm10k_sbus *
> +fm10k_sbus_attach(struct fm10k_switch *sw,
> +		const char *name,
> +		unsigned int cfg_reg)
> +{
> +	struct fm10k_sbus *sb;
> +	int error;
> +
> +	FM10K_SW_TRACE("sbus %s: attaching", name);
> +
> +	sb = (struct fm10k_sbus *)rte_zmalloc("fm10k_sbus", sizeof(struct
> fm10k_sbus), 0);
> +	if (sb == NULL) {
> +		FM10K_SW_INFO("sbus %s: failed to allocate context", name);
> +		goto fail;
> +	}
> +
> +	sb->sw = sw;
> +	sb->name = name;
> +	pthread_mutex_init(&sb->lock, NULL);
> +
> +	sb->cfg_reg = cfg_reg;
> +	sb->cmd_reg = cfg_reg + FM10K_SW_REG_OFF(1);
> +	sb->req_reg = cfg_reg + FM10K_SW_REG_OFF(2);
> +	sb->resp_reg = cfg_reg + FM10K_SW_REG_OFF(3);
> +
> +	error = fm10k_sbus_init(sb);
> +	if (error)
> +		goto fail;
> +
> +	FM10K_SW_TRACE("sbus %s: attach successful", name);
> +	return (sb);
> +fail:
> +	if (sb)
> +		fm10k_sbus_detach(sb);
> +	return (NULL);
> +}
> +
> +void
> +fm10k_sbus_detach(struct fm10k_sbus *sb)
> +{
> +	FM10K_SW_TRACE("sbus %s: detaching", sb->name);
> +
> +	rte_free(sb);
> +}
> +
> +static int
> +fm10k_sbus_init(struct fm10k_sbus *sb)
> +{
> +	uint32_t data;
> +	int error;
> +
> +	error = fm10k_sbus_sbm_reset(sb);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_sbus_reset_all(sb);
> +	if (error)
> +		goto done;
> +
> +	/* set clock to REFCLK/2 */
> +	error = fm10k_sbus_write(sb,
> FM10K_SW_SBUS_ADDR_SBUS_CONTROLLER, 0x0a,
> +	    FM10K_SW_SBUS_RING_DIVIDER);
> +	if (error) {
> +		FM10K_SW_ERR("sbus %s: failed to set ring divider", sb->name);
> +		goto done;
> +	}
> +
> +	error = fm10k_sbus_read(sb,
> FM10K_SW_SBUS_ADDR_SBUS_CONTROLLER, 0x0a,
> +	    &data);
> +	if (error) {
> +		FM10K_SW_ERR("sbus %s: failed to read back ring divider", sb-
> >name);
> +		goto done;
> +	}
> +	if (data != FM10K_SW_SBUS_RING_DIVIDER) {
> +		FM10K_SW_ERR("sbus %s: ring divider verify failed
> (expected %u, got %u)",
> +				sb->name, FM10K_SW_SBUS_RING_DIVIDER,
> data);
> +		error = -1;
> +		goto done;
> +	}
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_sbus_exec(struct fm10k_sbus *sb, struct fm10k_sbus_req *req)
> +{
> +	struct fm10k_switch *sw =  sb->sw;
> +	unsigned int total_usecs;
> +	unsigned int drop_lock;
> +	unsigned int delay_time;
> +	int error = 0;
> +	uint32_t data;
> +	uint8_t expected_result;
> +
> +	FM10K_SW_SBUS_LOCK(sb);
> +
> +	FM10K_SW_SWITCH_LOCK(sw);
> +	data = fm10k_read_switch_reg(sw, sb->cmd_reg);
> +	if (data & FM10K_SW_SBUS_COMMAND_BUSY) {
> +		FM10K_SW_INFO("sbus %s: bus busy (0x%08x)",
> +		    sb->name, data);
> +		error = -1;
> +		goto done;
> +	}
> +
> +	switch (req->op) {
> +	case FM10K_SW_SBUS_OP_RESET:
> +		FM10K_SW_TRACE("sbus %s: RESET dev=0x%02x reg=0x%02x
> data=0x%08x",
> +		    sb->name, req->dev, req->reg, req->data);
> +		expected_result = FM10K_SW_SBUS_RESULT_RESET;
> +		fm10k_write_switch_reg(sw, sb->req_reg, req->data);
> +		break;
> +	case FM10K_SW_SBUS_OP_WRITE:
> +		FM10K_SW_TRACE("sbus %s: WRITE dev=0x%02x reg=0x%02x
> data=0x%08x",
> +		    sb->name, req->dev, req->reg, req->data);
> +		expected_result = FM10K_SW_SBUS_RESULT_WRITE;
> +		fm10k_write_switch_reg(sw, sb->req_reg, req->data);
> +		break;
> +	case FM10K_SW_SBUS_OP_READ:
> +		FM10K_SW_TRACE("sbus %s: READ dev=0x%02x reg=0x%02x",
> +		    sb->name, req->dev, req->reg);
> +		expected_result = FM10K_SW_SBUS_RESULT_READ;
> +		req->data = 0;
> +		break;
> +	default:
> +		FM10K_SW_INFO("sbus %s: invalid opcode 0x%02x",
> +		    sb->name, req->op);
> +		error = -1;
> +		goto done;
> +	}
> +
> +	/* Clear the execute bit */
> +	fm10k_write_switch_reg(sw, sb->cmd_reg, 0);
> +
> +	data =
> +	    FM10K_SW_MAKE_REG_FIELD(SBUS_COMMAND_OP, req->op) |
> +	    FM10K_SW_MAKE_REG_FIELD(SBUS_COMMAND_ADDRESS, req->dev)
> |
> +	    FM10K_SW_MAKE_REG_FIELD(SBUS_COMMAND_REGISTER, req-
> >reg) |
> +	    FM10K_SW_SBUS_COMMAND_EXECUTE;
> +	fm10k_write_switch_reg(sw, sb->cmd_reg, data);
> +	fm10k_write_flush(sw);
> +
> +	total_usecs = 0;
> +	delay_time = 1;
> +	drop_lock = 0;
> +	do {
> +		if (drop_lock)
> +			FM10K_SW_SWITCH_UNLOCK(sw);
> +		fm10k_udelay(delay_time);
> +		if (drop_lock)
> +			FM10K_SW_SWITCH_LOCK(sw);
> +		total_usecs += delay_time;
> +		if (total_usecs >=
> FM10K_SW_SBUS_COMMAND_WAIT_LOCK_US_MAX) {
> +			drop_lock = 1;
> +			delay_time <<= 1;
> +		}
> +
> +		data = fm10k_read_switch_reg(sw, sb->cmd_reg);
> +		if (!(data & FM10K_SW_SBUS_COMMAND_BUSY)) {
> +			if (FM10K_SW_REG_FIELD(data,
> SBUS_COMMAND_RESULT_CODE) !=
> +			    expected_result) {
> +				FM10K_SW_INFO("sbus %s: expected "
> +				    "result code %u, got %u", sb->name,
> +				    expected_result,
> +				    FM10K_SW_REG_FIELD(data,
> +					SBUS_COMMAND_RESULT_CODE));
> +				error = -1;
> +				goto done;
> +			}
> +			if (req->op == FM10K_SW_SBUS_OP_READ) {
> +				req->data =
> +				    fm10k_read_switch_reg(sw, sb->resp_reg);
> +				FM10K_SW_TRACE("sbus %s: READ
> data=0x%02x", sb->name,
> +				    req->data);
> +			}
> +			goto done;
> +		}
> +
> +	} while (total_usecs < FM10K_SW_SBUS_COMMAND_TIMEOUT_US);
> +
> +	error = -1;
> +	FM10K_SW_INFO("sbus %s: command timed out after %u us "
> +	    "(op=0x%02x dev=0x%02x reg=0x%02x data=0x%08x)", sb->name,
> +	    total_usecs, req->op, req->dev, req->reg, req->data);
> +
> +done:
> +	FM10K_SW_SWITCH_UNLOCK(sw);
> +	FM10K_SW_SBUS_UNLOCK(sb);
> +	return (error);
> +}
> +
> +static int
> +fm10k_sbus_reset_all(struct fm10k_sbus *sb)
> +{
> +	struct fm10k_sbus_req req;
> +	int error;
> +
> +	req.op = FM10K_SW_SBUS_OP_RESET;
> +	req.dev = FM10K_SW_SBUS_ADDR_BROADCAST;
> +	req.reg = 0;
> +	req.data = 0;
> +
> +	error = fm10k_sbus_exec(sb, &req);
> +
> +	FM10K_SW_TRACE("sbus %s: broadcast reset %s (%d)", sb->name,
> +	    error ? "failed" : "succeeded", error);
> +
> +	return (error);
> +}
> +
> +static int
> +fm10k_sbus_sbm_reset(struct fm10k_sbus *sb)
> +{
> +	struct fm10k_sbus_req req;
> +	int error;
> +
> +	req.op = FM10K_SW_SBUS_OP_RESET;
> +	req.dev = FM10K_SW_SBUS_ADDR_SPICO;
> +	req.reg = 0;
> +	req.data = 0;
> +
> +	error = fm10k_sbus_exec(sb, &req);
> +
> +	FM10K_SW_TRACE("sbus %s: SBM reset %s (%d)", sb->name,
> +	    error ? "failed" : "succeeded", error);
> +
> +	return (error);
> +}
> +
> +int
> +fm10k_sbus_read(struct fm10k_sbus *sb, uint8_t dev, uint8_t reg, uint32_t
> *data)
> +{
> +	struct fm10k_sbus_req req;
> +	int error;
> +
> +	req.op = FM10K_SW_SBUS_OP_READ;
> +	req.dev = dev;
> +	req.reg = reg;
> +
> +	error = fm10k_sbus_exec(sb, &req);
> +	*data = error ? 0 : req.data;
> +
> +	return (error);
> +}
> +
> +int
> +fm10k_sbus_write(struct fm10k_sbus *sb, uint8_t dev, uint8_t reg, uint32_t
> data)
> +{
> +	struct fm10k_sbus_req req;
> +	int error;
> +
> +	req.op = FM10K_SW_SBUS_OP_WRITE;
> +	req.dev = dev;
> +	req.reg = reg;
> +	req.data = data;
> +
> +	error = fm10k_sbus_exec(sb, &req);
> +
> +	return (error);
> +}
> diff --git a/drivers/net/fm10k/switch/fm10k_sbus.h
> b/drivers/net/fm10k/switch/fm10k_sbus.h
> new file mode 100644
> index 0000000..e57137d
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_sbus.h
> @@ -0,0 +1,55 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_SW_SBUS_H_
> +#define _FM10K_SW_SBUS_H_
> +
> +#include <pthread.h>
> +
> +
> +struct fm10k_sbus {
> +	struct fm10k_switch *sw;
> +	const char *name;
> +	pthread_mutex_t lock;
> +	unsigned int cfg_reg;
> +	unsigned int cmd_reg;
> +	unsigned int req_reg;
> +	unsigned int resp_reg;
> +};
> +
> +#define FM10K_SW_SBUS_LOCK(sb_)			do { 	\
> +	pthread_mutex_lock(&((sb_)->lock)); 		\
> +} while(0)
> +#define FM10K_SW_SBUS_UNLOCK(sb_)		do { 	\
> +	pthread_mutex_unlock(&((sb_)->lock));		\
> +} while(0)
> +
> +struct fm10k_sbus_req {
> +	uint8_t op;
> +	uint8_t dev;
> +	uint8_t reg;
> +	uint32_t data;
> +};
> +
> +
> +struct fm10k_sbus *fm10k_sbus_attach(struct fm10k_switch *sw,
> +		const char *name, unsigned int cfg_reg);
> +void fm10k_sbus_detach(struct fm10k_sbus *sb);
> +int fm10k_sbus_read(struct fm10k_sbus *sb, uint8_t dev, uint8_t reg, uint32_t
> *data);
> +int fm10k_sbus_write(struct fm10k_sbus *sb, uint8_t dev, uint8_t reg, uint32_t
> data);
> +
> +#endif /* _FM10K_SW_SBUS_H_ */
> diff --git a/drivers/net/fm10k/switch/fm10k_serdes.c
> b/drivers/net/fm10k/switch/fm10k_serdes.c
> new file mode 100644
> index 0000000..9e60465
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_serdes.c
> @@ -0,0 +1,1898 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#include "fm10k_debug.h"
> +#include "fm10k_ext_port.h"
> +#include "fm10k_regs.h"
> +#include "fm10k_sbus.h"
> +#include "fm10k_serdes.h"
> +#include "fm10k_spico_code.h"
> +#include "fm10k_switch.h"
> +
> +
> +#define FM10K_SW_SERDES_BIST_TIMEOUT_MS			5000
> +#define FM10K_SW_SBM_INTERRUPT_TIMEOUT_MS		5000
> +#define FM10K_SW_SERDES_INTERRUPT_TIMEOUT_MS	3000
> +#define FM10K_SW_SERDES_INT02_TIMEOUT_MS		500
> +
> +#define FM10K_SW_SERDES_CONFIG_DELAY_US			20
> +#define FM10K_SW_SERDES_RESET_DELAY_US			22
> +#define FM10K_SW_SERDES_DFE_STOP_CYCLE_DELAY_US	200
> +
> +#define FM10K_SW_SERDES_DIVIDER_ETHMODE_25G		0xa5
> +#define FM10K_SW_SERDES_DIVIDER_ETHMODE_10G		0x42
> +
> +#define FM10K_SW_SERDES_WIDTH_40				3  /*
> 25G */
> +#define FM10K_SW_SERDES_WIDTH_20				1  /*
> 10G */
> +
> +#define FM10K_SW_SERDES_EQ_SEL_PRECUR			0
> +#define FM10K_SW_SERDES_EQ_SEL_ATTEN			1
> +#define FM10K_SW_SERDES_EQ_SEL_POSTCUR			2
> +
> +#define FM10K_SW_SERDES_DFE_DEFAULT_HF			0x00
> +#define FM10K_SW_SERDES_DFE_DEFAULT_LF			0x0c
> +#define FM10K_SW_SERDES_DFE_DEFAULT_DC			0x38
> +#define FM10K_SW_SERDES_DFE_DEFAULT_BW			0x0f
> +
> +#define FM10K_SW_SERDES_ICAL_STOP_MAX_CYCLES	10
> +#define FM10K_SW_SERDES_PCAL_STOP_MAX_CYCLES	500
> +
> +/*
> + * These values correspond to IES FM_PORT_LINK_OPTIMIZATION_BALANCE
> + * settings.
> + */
> +#define FM10K_SW_LINK_OPT_PARAM_A10G			0x4800
> +#define FM10K_SW_LINK_OPT_PARAM_B10G			0xA000
> +#define FM10K_SW_LINK_OPT_PARAM_A25G			0x10001
> +#define FM10K_SW_LINK_OPT_PARAM_B25G			0x10001
> +
> +#define FM10K_SW_SERDES_DFE_DATA_LEVEL0_THRESHOLD	10
> +
> +
> +static int fm10k_spico_ram_bist(struct fm10k_sbus *sb);
> +static int fm10k_load_epl_spico_code(struct fm10k_switch *sw);
> +static int fm10k_sbm_spico_upload_image(struct fm10k_sbus *sb, const
> uint16_t *image,
> +	    unsigned int num_words);
> +static int fm10k_sbm_check_crc_version_build_id(struct fm10k_sbus *sb,
> uint32_t expected_version_build_id);
> +static int fm10k_sbm_spico_do_crc(struct fm10k_sbus *sb);
> +static int fm10k_sbm_get_version_build_id(struct fm10k_sbus *sb, uint32_t
> *version_build_id);
> +static int fm10k_serdes_swap_upload_image(struct fm10k_sbus *sb, const
> uint16_t *image,
> +	    unsigned int num_words);
> +static int fm10k_serdes_swap_alt_upload_image(struct fm10k_sbus *sb, const
> uint16_t *image,
> +	    unsigned int num_words);
> +static int fm10k_swap_image_check_crc(struct fm10k_sbus *sb, unsigned int
> crc_code);
> +static int fm10k_serdes_spico_upload_image(struct fm10k_sbus *sb, uint8_t
> dev,
> +	    const uint16_t *image, unsigned int num_words);
> +static int fm10k_epl_serdes_check_crc_version_build_id(struct fm10k_switch
> *sw,
> +	    uint32_t expected_version_build_id);
> +static int fm10k_epl_serdes_spico_do_crc(struct fm10k_switch *sw, unsigned
> int serdes);
> +static int fm10k_epl_serdes_spico_reset(struct fm10k_switch *sw, unsigned int
> serdes);
> +static int fm10k_epl_serdes_get_version_build_id(struct fm10k_switch *sw,
> +	    unsigned int serdes, uint32_t *version_build_id);
> +static int fm10k_sbm_spico_int(struct fm10k_sbus *sb, uint8_t int_num,
> uint32_t param,
> +	    uint32_t *result);
> +static int fm10k_epl_serdes_spico_int(struct fm10k_switch *sw, unsigned int
> serdes,
> +	    uint16_t int_num, uint32_t param, uint32_t *result);
> +static int fm10k_epl_serdes_set_bit_rate(struct fm10k_switch *sw, unsigned
> int serdes,
> +	    unsigned int divider);
> +static int fm10k_epl_serdes_set_width_mode(struct fm10k_switch *sw,
> unsigned int serdes,
> +	    unsigned int width_mode);
> +static void fm10k_epl_serdes_set_pcsl_width_mode(struct fm10k_switch *sw,
> +	    unsigned int serdes, unsigned int width_mode);
> +static int fm10k_epl_serdes_set_pcsl_bit_slip(struct fm10k_switch *sw,
> unsigned int serdes);
> +static int fm10k_epl_serdes_init_signal_ok(struct fm10k_switch *sw, unsigned
> int serdes,
> +		unsigned int threshold);
> +static int fm10k_epl_serdes_set_tx_eq(struct fm10k_switch *sw, unsigned int
> serdes,
> +	    unsigned int which, unsigned int tx_eq);
> +static int fm10k_epl_serdes_spico_int02_retry(struct fm10k_switch *sw,
> unsigned int serdes,
> +	    uint32_t data, unsigned int timeout_ms);
> +static int fm10k_epl_serdes_dma_reg_write(struct fm10k_switch *sw,
> unsigned int serdes,
> +	    unsigned int addr, uint32_t data);
> +static int fm10k_epl_serdes_dma_esb_write(struct fm10k_switch *sw,
> unsigned int serdes,
> +	    unsigned int addr, uint32_t data);
> +static int fm10k_epl_serdes_dma_esb_read_modify_write(struct fm10k_switch
> *sw,
> +	    unsigned int serdes, unsigned int addr, uint32_t data, uint32_t mask,
> +	    uint32_t *result);
> +static int fm10k_epl_serdes_dma_esb_read(struct fm10k_switch *sw, unsigned
> int serdes,
> +	    unsigned int addr, uint32_t *result);
> +static int fm10k_epl_serdes_spico_wr_only_int(struct fm10k_switch *sw,
> unsigned int serdes,
> +	    unsigned int int_num, uint32_t param);
> +static void fm10k_epl_serdes_eplno_lane(struct fm10k_switch *sw, unsigned
> int serdes,
> +	    unsigned int *eplno, unsigned int *lane);
> +static int fm10k_epl_serdes_configure_near_loopback(struct
> fm10k_ext_port_lane *lane);
> +static int fm10k_epl_serdes_config_dfe_param(struct fm10k_switch *sw,
> +	    unsigned int serdes, uint32_t param);
> +static int fm10k_epl_serdes_get_dfe_status(struct fm10k_switch *sw, unsigned
> int serdes,
> +	    uint32_t *status);
> +static int fm10k_epl_serdes_get_ical_result(struct fm10k_switch *sw, unsigned
> int serdes,
> +	    uint32_t *converged);
> +
> +
> +int
> +fm10k_epl_serdes_reset_and_load_all(struct fm10k_switch *sw)
> +{
> +	struct fm10k_sbus *sb = sw->epl_sbus;
> +	int error;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: initializing EPL serdes", sb->name);
> +
> +	error = fm10k_spico_ram_bist(sb);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_load_epl_spico_code(sw);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_spico_ram_bist(struct fm10k_sbus *sb)
> +{
> +	uint64_t start_time_us, elapsed_time_ms;
> +	uint32_t data;
> +	int error;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: starting SPICO RAM BIST", sb->name);
> +
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x00,
> 0x03);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x00,
> 0x05);
> +	if (error)
> +		goto done;
> +
> +	start_time_us = fm10k_uptime_us();
> +	elapsed_time_ms = 0;
> +	while (elapsed_time_ms < FM10K_SW_SERDES_BIST_TIMEOUT_MS) {
> +		elapsed_time_ms = (fm10k_uptime_us() - start_time_us) / 1000;
> +		error = fm10k_sbus_read(sb, FM10K_SW_SBUS_ADDR_SPICO,
> 0x00, &data);
> +		if (error)
> +			goto done;
> +
> +		if (data & 0x18) {
> +			error = fm10k_sbus_write(sb,
> FM10K_SW_SBUS_ADDR_SPICO, 0x00,
> +			    0x00);
> +			if (error)
> +				goto done;
> +			if ((data & 0x18) != 0x08) {
> +				FM10K_SW_INFO("sbus %s: SPICO RAM "
> +				    "BIST failed with bad status (0x%08x)",
> +				    sb->name, data);
> +				error = -1;
> +				goto done;
> +			}
> +			goto done;
> +		}
> +	}
> +	fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x00, 0x00);
> +	error = -1;
> +	FM10K_SW_INFO("sbus %s: SPICO RAM BIST timed out after %u "
> +	    "ms", sb->name, (uint32_t)elapsed_time_ms);
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_load_epl_spico_code(struct fm10k_switch *sw)
> +{
> +	struct fm10k_sbus *sb = sw->epl_sbus;
> +	const uint16_t *sbm_code_image;
> +	uint32_t sbm_code_size;
> +	uint32_t sbm_code_version_build_id;
> +	const uint16_t *serdes_code_image;
> +	uint32_t serdes_code_size;
> +	uint32_t serdes_code_version_build_id;
> +	const uint16_t *swap_code_image;
> +	uint32_t swap_code_size;
> +	unsigned int swap_crc_code;
> +	int error = 0;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: loading SPICO code", sb->name);
> +
> +	sbm_code_image = fm10000_sbus_master_code_prd;
> +	sbm_code_size = fm10000_sbus_master_code_size_prd;
> +	sbm_code_version_build_id =
> +	    fm10000_sbus_master_code_versionBuildId_prd;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: sbm code version=%4.4x build=%4.4x",
> +	    sb->name, sbm_code_version_build_id >> 16,
> +	    sbm_code_version_build_id & 0xffff);
> +
> +	serdes_code_image = fm10000_serdes_spico_code_prd2;
> +	serdes_code_size = fm10000_serdes_spico_code_size_prd2;
> +	serdes_code_version_build_id =
> +	    fm10000_serdes_spico_code_versionBuildId_prd2;
> +	sw->epl_serdes_code_version_build_id = serdes_code_version_build_id;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes code version=%4.4x build=%4.4x",
> +	    sb->name, serdes_code_version_build_id >> 16,
> +	    serdes_code_version_build_id & 0xffff);
> +
> +	swap_code_image = fm10000_serdes_swap_code_prd2;
> +	swap_code_size = fm10000_serdes_swap_code_size_prd2;
> +
> +	error = fm10k_sbm_spico_upload_image(sb, sbm_code_image,
> +	    sbm_code_size);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_sbm_check_crc_version_build_id(sb,
> +	    sbm_code_version_build_id);
> +	if (error)
> +		goto done;
> +
> +	if (swap_code_size > 0) {
> +		if ((sbm_code_version_build_id & 0x00008000) == 0) {
> +			error = fm10k_serdes_swap_upload_image(sb,
> +			    swap_code_image, swap_code_size);
> +			swap_crc_code = 0x1a;
> +		} else {
> +			error = fm10k_serdes_swap_alt_upload_image(sb,
> +			    swap_code_image, swap_code_size);
> +			swap_crc_code = 0x04;
> +		}
> +		if (error)
> +			goto done;
> +
> +		error = fm10k_swap_image_check_crc(sb, swap_crc_code);
> +		if (error)
> +			goto done;
> +	}
> +
> +	error = fm10k_serdes_spico_upload_image(sb,
> FM10K_SW_SBUS_ADDR_BROADCAST,
> +	    serdes_code_image, serdes_code_size);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_check_crc_version_build_id(sw,
> +	    serdes_code_version_build_id);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +
> +static int
> +fm10k_sbm_spico_upload_image(struct fm10k_sbus *sb, const uint16_t
> *image,
> +    unsigned int num_words)
> +{
> +	uint64_t start_time_us, elapsed_time_us;
> +	unsigned int i;
> +	uint32_t data;
> +	int error;
> +
> +	FM10K_SW_TRACE("sbus %s: uploading SBM SPICO image "
> +	    "(%u words)", sb->name, num_words);
> +
> +	data = (1 << 6) | (1 << 7);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> data);
> +	if (error)
> +		goto done;
> +
> +	data &= ~(1 << 7);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> data);
> +	if (error)
> +		goto done;
> +
> +	data |= (1 << 9);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> data);
> +	if (error)
> +		goto done;
> +
> +	start_time_us = fm10k_uptime_us();
> +	for (i = 0; i < num_words; i++) {
> +		data = 0x80000000 | ((uint32_t)image[i] << 16) | i;
> +		error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO,
> 0x03, data);
> +		if (error)
> +			goto done;
> +	}
> +	elapsed_time_us = fm10k_uptime_us() - start_time_us;
> +	FM10K_SW_TRACE("sbus %s: SBM image upload time %u ms",
> +	    sb->name, (uint32_t)(elapsed_time_us/1000));
> +
> +	data = (1 << 6);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> data);
> +	if (error)
> +		goto done;
> +
> +	data = (1 << 18) | (1 << 19);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x16,
> data);
> +	if (error)
> +		goto done;
> +
> +	data = (1 << 6) | (1 << 8);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> data);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_sbm_check_crc_version_build_id(struct fm10k_sbus *sb, uint32_t
> expected_version_build_id)
> +{
> +	int error;
> +	uint32_t version_build_id;
> +
> +	FM10K_SW_TRACE("sbus %s: checking SBM SPICO code CRC "
> +	    "and version", sb->name);
> +
> +	error = fm10k_sbm_spico_do_crc(sb);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_sbm_get_version_build_id(sb, &version_build_id);
> +	if (error)
> +		goto done;
> +
> +	if (version_build_id != expected_version_build_id) {
> +		FM10K_SW_INFO("sbus %s: SBM SPICO code version "
> +		    "compare failed (expected 0x%08x, got 0x%08x)",
> +		    sb->name, expected_version_build_id, version_build_id);
> +		error = -1;
> +		goto done;
> +	}
> +	FM10K_SW_TRACE("sbus %s: SBM SPICO image "
> +	    "version=0x%4.4x build_id=0x%4.4x", sb->name,
> +	    version_build_id >> 16,
> +	    version_build_id & 0xffff);
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_sbm_spico_do_crc(struct fm10k_sbus *sb)
> +{
> +	int error;
> +	uint32_t crc;
> +
> +	FM10K_SW_TRACE("sbus %s: performing SBM SPICO CRC "
> +	    "check", sb->name);
> +
> +	error = fm10k_sbm_spico_int(sb, 0x02, 0, &crc);
> +	if (error)
> +		goto done;
> +
> +	crc = crc >> 16;
> +	if (crc == 0xffff) {
> +		FM10K_SW_INFO("sbus %s: SBM SPICO CRC check failed "
> +		    "(CRC interrupt returned 0xffff)", sb->name);
> +		error = -1;
> +		goto done;
> +	} else if (crc == 0x0001)
> +		FM10K_SW_TRACE("sbus %s: SBM SPICO CRC check "
> +		    "passed ", sb->name);
> +	else
> +		FM10K_SW_INFO("sbus %s: unexpected SBM SPICO CRC "
> +		    "check result 0x%04x", sb->name, crc);
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_sbm_get_version_build_id(struct fm10k_sbus *sb, uint32_t
> *version_build_id)
> +{
> +	int error;
> +	uint32_t result;
> +
> +	FM10K_SW_TRACE("sbus %s: getting SBM code version",
> +	    sb->name);
> +
> +	error = fm10k_sbm_spico_int(sb, 0x00, 0, &result);
> +	if (error)
> +		goto done;
> +
> +	*version_build_id = result & 0xffff0000;
> +	error = fm10k_sbm_spico_int(sb, 0x01, 0, &result);
> +	if (error)
> +		goto done;
> +
> +	*version_build_id |= (result >> 16) & 0xffff;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_serdes_swap_upload_image(struct fm10k_sbus *sb, const uint16_t
> *image,
> +    unsigned int num_words)
> +{
> +	uint64_t start_time_us, elapsed_time_us;
> +	unsigned int i;
> +	uint32_t addr;
> +	uint32_t reg01, reg05;
> +	int error;
> +
> +	FM10K_SW_TRACE("sbus %s: uploading SBM swap image "
> +	    "(%u words)", sb->name, num_words);
> +
> +	error = fm10k_sbm_spico_int(sb, 0x1c, 0, &addr);
> +	if (error)
> +		goto done;
> +
> +	addr >>= 16;
> +	if (addr == 0xffff) {
> +		FM10K_SW_INFO("sbus %s: invalid build - cannot "
> +		    "upload SBM swap image", sb->name);
> +		error = -1;
> +		goto done;
> +	}
> +	FM10K_SW_TRACE("sbus %s: SBM swap image initial load "
> +	    "address 0x%04x (%u)", sb->name, addr, addr);
> +
> +	reg05 = 1;
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x05,
> reg05);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_sbus_read(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> &reg01);
> +	if (error)
> +		goto done;
> +
> +	reg01 |= (1 << 9);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> reg01);
> +	if (error)
> +		goto done;
> +
> +	start_time_us = fm10k_uptime_us();
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x03,
> addr);
> +	if (error)
> +		goto done;
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x03,
> 0x80000000 | addr);
> +	if (error)
> +		goto done;
> +
> +	for (i = 0; i < num_words - 2; i += 3) {
> +		error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO,
> 0x14,
> +		    0xc0000000 |
> +		    image[i] |
> +		    ((uint32_t)image[i + 1] << 10) |
> +		    ((uint32_t)image[i + 2] << 20));
> +		if (error)
> +			goto done;
> +	}
> +
> +	if (num_words - i == 2) {
> +		error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO,
> 0x14,
> +		    0x80000000 | image[i] | ((uint32_t)image[i + 1] << 10));
> +		if (error)
> +			goto done;
> +	} else if (num_words - i == 1) {
> +		error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO,
> 0x14,
> +		    0x40000000 | image[i]);
> +		if (error)
> +			goto done;
> +	}
> +	elapsed_time_us = fm10k_uptime_us() - start_time_us;
> +	FM10K_SW_TRACE("sbus %s: SBM swap image upload time "
> +	    "%u ms", sb->name, (uint32_t)(elapsed_time_us/1000));
> +
> +	reg01 &= ~(1 << 9);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> reg01);
> +	if (error)
> +		goto done;
> +
> +	reg05 &= ~(1 << 0);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x05,
> reg05);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_serdes_swap_alt_upload_image(struct fm10k_sbus *sb, const uint16_t
> *image,
> +    unsigned int num_words)
> +{
> +	uint64_t start_time_us, elapsed_time_us;
> +	unsigned int i;
> +	uint32_t addr;
> +	uint32_t reg01, reg05;
> +	int error;
> +
> +	FM10K_SW_TRACE("sbus %s: alt-uploading SBM swap image "
> +	    "(%u words)", sb->name, num_words);
> +
> +	reg05 = 1;
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x05,
> reg05);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_sbus_read(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> &reg01);
> +	if (error)
> +		goto done;
> +
> +	reg01 |= (1 << 10) | (1 << 11);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> reg01);
> +	if (error)
> +		goto done;
> +
> +	addr = 0x0400;
> +	FM10K_SW_TRACE("sbus %s: SBM swap image initial load "
> +	    "address 0x%04x (%u)", sb->name, addr, addr);
> +
> +	start_time_us = fm10k_uptime_us();
> +	for (i = 0; i < num_words; i++) {
> +		error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO,
> 0x04,
> +		    0x8000 |
> +		    ((uint32_t)image[i + 1] << 16) |
> +		    (addr + i));
> +		if (error)
> +			goto done;
> +	}
> +	elapsed_time_us = fm10k_uptime_us() - start_time_us;
> +	FM10K_SW_TRACE("sbus %s: SBM swap image alt-upload "
> +	    "time %u ms", sb->name, (uint32_t)(elapsed_time_us/1000));
> +
> +	reg01 &= ~((1 << 10) | (1 << 11));
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01,
> reg01);
> +	if (error)
> +		goto done;
> +
> +	reg05 &= ~(1 << 0);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x05,
> reg05);
> +	if (error)
> +		goto done;
> +
> +	done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_swap_image_check_crc(struct fm10k_sbus *sb, unsigned int crc_code)
> +{
> +	int error;
> +	uint32_t crc;
> +
> +	FM10K_SW_TRACE("sbus %s: performing SBM swap image CRC "
> +	    "check", sb->name);
> +
> +	error =
> +	    fm10k_sbm_spico_int(sb, crc_code, 0, &crc);
> +	if (error)
> +		goto done;
> +
> +	crc >>= 16;
> +	if (crc == 0xffff) {
> +		FM10K_SW_INFO("sbus %s: SBM swap image CRC check "
> +		    "failed (CRC interrupt 0x%02x returned 0xffff)",
> +		    sb->name, crc_code);
> +		error = -1;
> +		goto done;
> +	} else if (crc == 0x0001)
> +		FM10K_SW_TRACE("sbus %s: SBM swap image CRC "
> +		    "check passed ", sb->name);
> +	else
> +		FM10K_SW_INFO("sbus %s: unexpected SBM swap image "
> +		    "CRC check result 0x%04x", sb->name, crc);
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_serdes_spico_upload_image(struct fm10k_sbus *sb, uint8_t dev,
> +    const uint16_t *image, unsigned int num_words)
> +{
> +	uint64_t start_time_us, elapsed_time_us;
> +	unsigned int i;
> +	uint32_t data;
> +	uint32_t reg07;
> +	int error;
> +
> +	FM10K_SW_TRACE("sbus %s: uploading serdes SPICO image "
> +	    "to bus address 0x%02x (%u words)", sb->name, dev, num_words);
> +
> +	reg07 = (1 << 0) | (1 << 4);
> +	error = fm10k_sbus_write(sb, dev, 0x07, reg07);
> +	if (error)
> +		goto done;
> +
> +	reg07 &= ~(1 << 0);
> +	error = fm10k_sbus_write(sb, dev, 0x07, reg07);
> +	if (error)
> +		goto done;
> +
> +	data = (1 << 30);
> +	error = fm10k_sbus_write(sb, dev, 0x00, data);
> +	if (error)
> +		goto done;
> +
> +	data = (1 << 4) | (1 << 5);
> +	error = fm10k_sbus_write(sb, dev, 0x08, data);
> +	if (error)
> +		goto done;
> +
> +	start_time_us = fm10k_uptime_us();
> +	for (i = 0; i < num_words; i+= 3) {
> +		data = 0xc0000000 | image[i];
> +		if (i + 1 < num_words) {
> +			data |= (uint32_t)image[i + 1] << 10;
> +
> +			if (i + 2 < num_words)
> +				data |= (uint32_t)image[i + 2] << 20;
> +		}
> +		error = fm10k_sbus_write(sb, dev, 0x0a, data);
> +		if (error)
> +			goto done;
> +	}
> +	elapsed_time_us = fm10k_uptime_us() - start_time_us;
> +	FM10K_SW_TRACE("sbus %s: serdes SPICO image upload "
> +	    "time %u ms", sb->name, (uint32_t)(elapsed_time_us/1000));
> +
> +	error = fm10k_sbus_write(sb, dev, 0x00, 0);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_sbus_write(sb, dev, 0x01, 0x20000000);
> +	if (error)
> +		goto done;
> +
> +	data = (1 << 18) | (1 << 19);
> +	error = fm10k_sbus_write(sb, dev, 0x0b, data);
> +	if (error)
> +		goto done;
> +
> +	reg07 |= (1 << 0);
> +	error = fm10k_sbus_write(sb, dev, 0x07, reg07);
> +	if (error)
> +		goto done;
> +
> +	reg07 &= ~(1 << 0);
> +	error = fm10k_sbus_write(sb, dev, 0x07, reg07);
> +	if (error)
> +		goto done;
> +
> +	reg07 |= (1 << 1);
> +	error = fm10k_sbus_write(sb, dev, 0x07, reg07);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_sbus_write(sb, dev, 0x08, 0);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_check_crc_version_build_id(struct fm10k_switch *sw,
> +    uint32_t expected_version_build_id)
> +{
> +	struct fm10k_sbus *sb = sw->epl_sbus;
> +	unsigned int first = 0;
> +	unsigned int last = FM10K_SW_EPLS_MAX * FM10K_SW_EPL_LANES - 1;
> +	unsigned int i;
> +	int error;
> +	uint32_t data;
> +	uint32_t version_build_id;
> +
> +	FM10K_SW_TRACE("sbus %s: checking SPICO code CRC and "
> +	    "version for serdes %u thru %u", sb->name, first, last);
> +
> +	for (i = first; i <= last; i++) {
> +		error = fm10k_sbus_read(sb,
> FM10K_SW_SBUS_ADDR_EPL_SERDES(i), 0xff,
> +		    &data);
> +		if (error || (data != 0x01)) {
> +			FM10K_SW_TRACE("sbus %s: skipping "
> +			    "serdes %u (error=%d, data=0x%08x)", sb->name, i,
> +			    error, data);
> +			continue;
> +		}
> +
> +		error = fm10k_epl_serdes_spico_do_crc(sw, i);
> +		if (error)
> +			goto done;
> +
> +		error = fm10k_epl_serdes_get_version_build_id(sw, i,
> +		    &version_build_id);
> +		if (error)
> +			goto done;
> +
> +		if (version_build_id != expected_version_build_id) {
> +			FM10K_SW_INFO("sbus %s: SERDES SPICO code "
> +			    "version compare failed (expected 0x%08x, got "
> +			    "0x%08x)", sb->name, expected_version_build_id,
> +			    version_build_id);
> +			error = -1;
> +			goto done;
> +		}
> +	}
> +	FM10K_SW_TRACE("sbus %s: serdes %u thru %u are OK",
> +	    sb->name, first, last);
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_spico_do_crc(struct fm10k_switch *sw, unsigned int serdes)
> +{
> +	struct fm10k_sbus *sb = sw->epl_sbus;
> +	int error;
> +	uint32_t crc;
> +
> +	FM10K_SW_TRACE("sbus %s: serdes %u: performing SPICO "
> +	    "CRC check", sb->name, serdes);
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x3c, 0, &crc);
> +	if (error)
> +		goto done;
> +
> +	if (crc != 0) {
> +		FM10K_SW_INFO("sbus %s: serdes %u:  SPICO CRC check "
> +		    "failed (CRC interrupt returned 0x%08x)",
> +		    sb->name, serdes, crc);
> +		error = -1;
> +		goto done;
> +	}
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_spico_reset(struct fm10k_switch *sw, unsigned int serdes)
> +{
> +	struct fm10k_sbus *sb = sw->epl_sbus;
> +	int error;
> +	uint32_t data;
> +	uint8_t addr = FM10K_SW_SBUS_ADDR_EPL_SERDES(serdes);
> +
> +	FM10K_SW_TRACE("sbus %s: serdes %u: resetting SPICO",
> +	    sb->name, serdes);
> +
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	error = fm10k_sbus_write(sb, addr, 0, 0x00);
> +	if (error)
> +		goto done;
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +
> +	data = (1 << 0) | (1 << 4);
> +	error = fm10k_sbus_write(sb, addr, 0x07, data);
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	if (error)
> +		goto done;
> +
> +	data = (1 << 18) | (1 << 19);
> +	error = fm10k_sbus_write(sb, addr, 0x0b, data);
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	if (error)
> +		goto done;
> +
> +	data = (1 << 4);
> +	error = fm10k_sbus_write(sb, addr, 0x07, data);
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	if (error)
> +		goto done;
> +
> +	data = (1 << 1);
> +	error = fm10k_sbus_write(sb, addr, 0x07, data);
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_sbus_write(sb, addr, 0x08, 0);
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_get_version_build_id(struct fm10k_switch *sw,
> +    unsigned int serdes, uint32_t *version_build_id)
> +{
> +	int error;
> +	uint32_t data;
> +
> +	FM10K_SW_TRACE("sbus %s: serdes %u: getting code "
> +	    "version", sw->epl_sbus->name, serdes);
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x00, 0, &data);
> +	if (error)
> +		goto done;
> +
> +	*version_build_id = data << 16;
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x3f, 0, &data);
> +	if (error)
> +		goto done;
> +
> +	*version_build_id |= data & 0xffff;
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_sbm_spico_int(struct fm10k_sbus *sb, uint8_t int_num, uint32_t param,
> +    uint32_t *result)
> +{
> +	uint64_t start_time_us, elapsed_time_ms;
> +	uint32_t data;
> +	int error;
> +
> +	FM10K_SW_TRACE("sbus %s: SBM interrupt 0x%02x "
> +	    "(param=0x%08x)", sb->name, int_num, param);
> +
> +	/* int write */
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x02,
> +	    (param << 16) | int_num);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_sbus_read(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x07,
> &data);
> +	if (error)
> +		goto done;
> +
> +	data |= (1 << 0);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x07,
> data);
> +	if (error)
> +		goto done;
> +
> +	data &= ~(1 << 0);
> +	error = fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x07,
> data);
> +	if (error)
> +		goto done;
> +
> +	/* int read */
> +	start_time_us = fm10k_uptime_us();
> +	elapsed_time_ms = 0;
> +	while (elapsed_time_ms < FM10K_SW_SBM_INTERRUPT_TIMEOUT_MS)
> {
> +		elapsed_time_ms = (fm10k_uptime_us() - start_time_us) / 1000;
> +		error = fm10k_sbus_read(sb, FM10K_SW_SBUS_ADDR_SPICO,
> 0x08, &data);
> +		if (error)
> +			goto done;
> +
> +		if ((data & 0x8000) || ((data & 0x3ff) == 0)) {
> +			if (elapsed_time_ms > 5)
> +				fm10k_udelay(5);
> +		} else {
> +			FM10K_SW_TRACE("sbus %s: SBM "
> +			    "interrupt 0x%02x (param=0x%08x, result=0x%08x)",
> +			    sb->name, int_num, param, data);
> +			*result = data;
> +			goto done;
> +		}
> +	}
> +	error = -1;
> +	FM10K_SW_INFO("sbus %s: SBM interrupt timed out after %u "
> +	    "ms", sb->name, (uint32_t)elapsed_time_ms);
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_spico_int(struct fm10k_switch *sw, unsigned int serdes,
> +    uint16_t int_num, uint32_t param, uint32_t *result)
> +{
> +	struct fm10k_sbus *sb = sw->epl_sbus;
> +	uint64_t start_time_us, elapsed_time_ms;
> +	unsigned int sbus_addr;
> +	int error;
> +	uint32_t data, intr;
> +#if 0
> +	/* XXX */
> +	return (fm10k_epl_serdes_spico_sai_int(sw, serdes, int_num, param,
> result));
> +#endif
> +
> +	sbus_addr = FM10K_SW_SBUS_ADDR_EPL_SERDES(serdes);
> +
> +	FM10K_SW_TRACE("sbus %s: serdes %u: (sbus addr 0x%02x) "
> +	    "interrupt 0x%04x (param=0x%08x)", sb->name, serdes, sbus_addr,
> +	    int_num, param);
> +
> +	/* int write */
> +	start_time_us = fm10k_uptime_us();
> +	elapsed_time_ms = 0;
> +	while (elapsed_time_ms <
> FM10K_SW_SERDES_INTERRUPT_TIMEOUT_MS) {
> +		elapsed_time_ms = (fm10k_uptime_us() - start_time_us) / 1000;
> +		error = fm10k_sbus_read(sb, sbus_addr, 0x04, &data);
> +		if (error)
> +			goto done;
> +
> +		if (data & ((1 << 16) | (1 << 17))) {
> +			if (elapsed_time_ms > 5)
> +				fm10k_udelay(5);
> +		} else
> +			break;
> +	}
> +	if (elapsed_time_ms >= FM10K_SW_SERDES_INTERRUPT_TIMEOUT_MS)
> {
> +		error = fm10k_sbus_read(sb, sbus_addr, 0x03, &intr);
> +		FM10K_SW_INFO("sbus %s: serdes %u: interrupt timed out "
> +		    "after %u ms (intr=0x%04x param=0x%04x error=%u "
> +		    "reg[4]=0x%08x)", sb->name, serdes,
> +		    (uint32_t)elapsed_time_ms, intr >> 16, intr & 0xffff, error,
> +		    data);
> +		error = -1;
> +		goto done;
> +	} else {
> +		error = fm10k_sbus_write(sb, sbus_addr, 0x03,
> +		    ((uint32_t)int_num << 16) | param);
> +		if (error)
> +			goto done;
> +	}
> +
> +	/* int read */
> +	start_time_us = fm10k_uptime_us();
> +	elapsed_time_ms = 0;
> +	while (elapsed_time_ms <
> FM10K_SW_SERDES_INTERRUPT_TIMEOUT_MS) {
> +		elapsed_time_ms = (fm10k_uptime_us() - start_time_us) / 1000;
> +		error = fm10k_sbus_read(sb, sbus_addr, 0x04, &data);
> +		if (error)
> +			goto done;
> +
> +		if (data & ((1 << 16) | (1 << 17))) {
> +			if (elapsed_time_ms > 5)
> +				fm10k_udelay(5);
> +		} else
> +			break;
> +	}
> +	if (elapsed_time_ms >= FM10K_SW_SERDES_INTERRUPT_TIMEOUT_MS)
> {
> +		error = fm10k_sbus_read(sb, sbus_addr, 0x03, &intr);
> +		FM10K_SW_INFO("sbus %s: serdes %u: interrupt timed out "
> +		    "(2) after %u ms (intr=0x%04x param=0x%04x error=%u "
> +		    "reg[4]=0x%08x)", sb->name, serdes,
> +		    (uint32_t)elapsed_time_ms, intr >> 16, intr & 0xffff, error,
> +		    data);
> +		error = -1;
> +		goto done;
> +	} else {
> +		FM10K_SW_TRACE("sbus %s: serdes %u: interrupt "
> +		    "0x%04x (param=0x%08x, result=0x%08x)", sb->name, serdes,
> +		    int_num, param, data);
> +		if (result)
> +			*result = data;
> +	}
> +
> +done:
> +	return (error);
> +}
> +
> +
> +int
> +fm10k_epl_serdes_start_bringup(struct fm10k_ext_port_lane *lane)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int serdes = lane->abs_laneno;
> +	unsigned int speed = lane->port->lane_speed;
> +	unsigned int divider, width_mode;
> +	int error = 0;
> +	uint32_t data;
> +
> +	/*
> +	 * Bit rate and width
> +	 */
> +	if (speed == 25) {
> +		/* 25G */
> +		divider = FM10K_SW_SERDES_DIVIDER_ETHMODE_25G;
> +		width_mode = FM10K_SW_SERDES_WIDTH_40;
> +	} else {
> +		/* 10G */
> +		divider = FM10K_SW_SERDES_DIVIDER_ETHMODE_10G;
> +		width_mode = FM10K_SW_SERDES_WIDTH_20;
> +	}
> +
> +	/*
> +	 * state = CONFIGURED
> +	 */
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: configuring", sw->epl_sbus->name,
> +	    serdes);
> +
> +	error = fm10k_epl_serdes_spico_reset(sw, serdes);
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_spico_do_crc(sw, serdes);
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	if (error)
> +		goto done;
> +
> +	fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US);
> +	error = fm10k_epl_serdes_set_bit_rate(sw, serdes, divider);
> +	if (error)
> +		goto done;
> +
> +	fm10k_epl_serdes_set_pcsl_width_mode(sw, serdes,
> +	    width_mode);
> +
> +	/*
> +	 * Data select
> +	 */
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: setting TX data select",
> +	    sw->epl_sbus->name, serdes);
> +	error = fm10k_epl_serdes_spico_int02_retry(sw, serdes, 0x1ff,
> +	    FM10K_SW_SERDES_INT02_TIMEOUT_MS);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_dma_reg_write(sw, serdes, 0x21, 0x0c00);
> +	if (error)
> +		goto done;
> +
> +	/*
> +	 * Configure TX equalization
> +	 *
> +	 * Use defaults - copper and optical are the same.
> +	 *
> +	 * DEFAULTS| precursor | cursor | postcursor |
> +	 * --------+-----------+--------+------------+
> +	 *  copper |     0     |    0   |     15     |
> +	 * --------+-----------+--------+------------+
> +	 *  optical|     0     |    0   |     15     |
> +	 * --------+-----------+--------+------------+
> +	 */
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: setting TX cursors",
> +	    sw->epl_sbus->name, serdes);
> +	error = fm10k_epl_serdes_set_tx_eq(sw, serdes,
> +	    FM10K_SW_SERDES_EQ_SEL_ATTEN, 0);
> +	if (error)
> +		goto done;
> +	error = fm10k_epl_serdes_set_tx_eq(sw, serdes,
> +	    FM10K_SW_SERDES_EQ_SEL_PRECUR, 0);
> +	if (error)
> +		goto done;
> +	error = fm10k_epl_serdes_set_tx_eq(sw, serdes,
> +	    FM10K_SW_SERDES_EQ_SEL_POSTCUR, 15);
> +	if (error)
> +		goto done;
> +
> +	/*
> +	 * Configure 'options', which means:
> +	 *   - PLL calibration mode
> +	 *   - Phase slip
> +	 *   - RX termination
> +	 */
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: setting PLL calibration mode",
> +	    sw->epl_sbus->name, serdes);
> +	/* enable PLL calibration */
> +	data = (1 << 0) | (1 << 1);
> +	error =
> +	    fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x11, data);
> +	if (error)
> +		goto done;
> +	/* There appears to be no action to take for phase slip */
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: configuring RX termination",
> +	    sw->epl_sbus->name, serdes);
> +	/* RX termination appears to default to AVDD */
> +	data = (1 << 0);
> +	error =
> +	    fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x2b, data);
> +	if (error)
> +		goto done;
> +
> +	/*
> +	 * Set TX and RX lane polarity.
> +	 * Assuming no inversion required.
> +	 */
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: configuring TX/RX lane polarity",
> +	    sw->epl_sbus->name, serdes);
> +	data = 0x0300;
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x13, data, NULL);
> +	if (error)
> +		goto done;
> +
> +	/*
> +	 * Force local fault
> +	 */
> +	fm10k_epl_serdes_set_signal_detect(lane,
> FM10K_SW_LANE_OVERRIDE_FORCE_BAD);
> +
> +	/*
> +	 * Enable TX/RX
> +	 */
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: enabling TX/RX",
> +	    sw->epl_sbus->name, serdes);
> +	fm10k_epl_serdes_set_signal_detect(lane,
> FM10K_SW_LANE_OVERRIDE_FORCE_BAD);
> +	error =
> +	    fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x01, 0x03);
> +	if (error)
> +		goto done;
> +
> +	/*
> +	 * Clear and enable interrupts
> +	 */
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: configuring interrupts",
> +	    sw->epl_sbus->name, serdes);
> +	error = fm10k_sbus_write(sw->epl_sbus,
> +	    FM10K_SW_SBUS_ADDR_EPL_SERDES(serdes), 0x08, 0);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_epl_serdes_continue_bringup(struct fm10k_ext_port_lane *lane)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int serdes = lane->abs_laneno;
> +	unsigned int speed = lane->port->lane_speed;
> +	unsigned int width_mode;
> +	int error = 0;
> +	int near_loopback = sw->serdes_loopback;
> +
> +	if (speed == 25) {
> +		/* 25G */
> +		width_mode = FM10K_SW_SERDES_WIDTH_40;
> +	} else {
> +		/* 10G */
> +		width_mode = FM10K_SW_SERDES_WIDTH_20;
> +	}
> +
> +	fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US);
> +	error = fm10k_epl_serdes_set_pcsl_bit_slip(sw, serdes);
> +	if (error)
> +		goto done;
> +
> +	fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US);
> +	error = fm10k_epl_serdes_set_width_mode(sw, serdes, width_mode);
> +	if (error)
> +		goto done;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: enabling TX output",
> +	    sw->epl_sbus->name, serdes);
> +	fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US);
> +	error =
> +	    fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x01, 0x07);
> +	if (error)
> +		goto done;
> +
> +	fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US);
> +	error = fm10k_epl_serdes_init_signal_ok(sw, serdes, 0);
> +	if (error)
> +		goto done;
> +
> +	if (near_loopback) {
> +		/* enable near loopback */
> +		error = fm10k_epl_serdes_configure_near_loopback(lane);
> +		if (error)
> +			goto done;
> +	}
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_epl_serdes_disable(struct fm10k_ext_port_lane *lane)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int serdes = lane->abs_laneno;
> +	int error = 0;
> +
> +	fm10k_epl_serdes_set_signal_detect(lane,
> FM10K_SW_LANE_OVERRIDE_FORCE_BAD);
> +
> +	/* XXX is this delay necessary? in some places the IES SDK does this */
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	error = fm10k_epl_serdes_spico_reset(sw, serdes);
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_set_bit_rate(struct fm10k_switch *sw, unsigned int serdes,
> +    unsigned int divider)
> +{
> +	int error;
> +	uint32_t data;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: setting bit rate",
> +	    sw->epl_sbus->name, serdes);
> +
> +	data = divider & 0x7ff;
> +	data |= (1 << 12);
> +	data |= (1 << 15);
> +
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x05, data);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_set_width_mode(struct fm10k_switch *sw, unsigned int
> serdes,
> +    unsigned int width_mode)
> +{
> +	int error;
> +	uint32_t data;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: setting width mode to %u",
> +	    sw->epl_sbus->name, serdes, width_mode);
> +
> +	data = FM10K_SW_SERDES_WIDTH_20 |
> (FM10K_SW_SERDES_WIDTH_20 << 4);
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x14, data);
> +	if (error)
> +		goto done;
> +
> +	data = width_mode | (width_mode << 4);
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x14, data);
> +	if (error)
> +		goto done;
> +
> +done:
> +	fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US);
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_set_tx_eq(struct fm10k_switch *sw, unsigned int serdes,
> +    unsigned int which, unsigned int tx_eq)
> +{
> +	int error;
> +	uint32_t data;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: setting TX cursor %u to %u",
> +	    sw->epl_sbus->name, serdes, which, tx_eq);
> +
> +	data = (tx_eq & 0xff) | (which << 14);
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x15, data);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +void
> +fm10k_epl_serdes_set_signal_detect(struct fm10k_ext_port_lane *lane,
> +    unsigned int override)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int eplno = lane->port->eplno;
> +	uint32_t data;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: setting signal detect to %s",
> +	    sw->epl_sbus->name, lane->abs_laneno,
> +	    (override == 0) ? "NORMAL" :
> +	    (override == 1) ? "FORCE_GOOD" :
> +	    (override == 2) ? "FORCE_BAD" : "<unknown>");
> +
> +	FM10K_SW_SWITCH_LOCK(sw);
> +	data = fm10k_read_switch_reg(sw,
> +	    FM10K_SW_LANE_SIGNAL_DETECT_CFG(eplno, lane->rel_laneno));
> +	FM10K_SW_REPLACE_REG_FIELD(data,
> +	    LANE_SIGNAL_DETECT_CFG_SD_OVERRIDE,
> +	    override);
> +	fm10k_write_switch_reg(sw,
> +	    FM10K_SW_LANE_SIGNAL_DETECT_CFG(eplno, lane->rel_laneno),
> data);
> +	FM10K_SW_SWITCH_UNLOCK(sw);
> +}
> +
> +static void
> +fm10k_epl_serdes_set_pcsl_width_mode(struct fm10k_switch *sw,
> +    unsigned int serdes, unsigned int width_mode)
> +{
> +	unsigned int eplno, lane;
> +	uint32_t pcsl_cfg;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: setting pcsl width mode",
> +	    sw->epl_sbus->name, serdes);
> +
> +	fm10k_epl_serdes_eplno_lane(sw, serdes, &eplno, &lane);
> +
> +	FM10K_SW_SWITCH_LOCK(sw);
> +	pcsl_cfg = fm10k_read_switch_reg(sw, FM10K_SW_PCSL_CFG(eplno,
> lane));
> +	if (width_mode == FM10K_SW_SERDES_WIDTH_40) {
> +		pcsl_cfg &= ~FM10K_SW_PCSL_CFG_RX_GB_NARROW;
> +		pcsl_cfg &= ~FM10K_SW_PCSL_CFG_TX_GB_NARROW;
> +	} else {
> +		pcsl_cfg |= FM10K_SW_PCSL_CFG_RX_GB_NARROW;
> +		pcsl_cfg |= FM10K_SW_PCSL_CFG_TX_GB_NARROW;
> +	}
> +	pcsl_cfg &= ~FM10K_SW_PCSL_CFG_RX_BIT_SLIP_ENABLE;
> +	fm10k_write_switch_reg(sw, FM10K_SW_PCSL_CFG(eplno, lane),
> pcsl_cfg);
> +	FM10K_SW_SWITCH_UNLOCK(sw);
> +}
> +
> +static int
> +fm10k_epl_serdes_set_pcsl_bit_slip(struct fm10k_switch *sw, unsigned int
> serdes)
> +{
> +	unsigned int eplno, lane;
> +	int error;
> +	uint32_t int_return, pcsl_cfg;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: setting pcsl bit slip",
> +	    sw->epl_sbus->name, serdes);
> +
> +	fm10k_epl_serdes_eplno_lane(sw, serdes, &eplno, &lane);
> +	error =
> +	    fm10k_epl_serdes_spico_int(sw, serdes, 0x0c, (1 << 7), &int_return);
> +	if (error)
> +		goto done;
> +
> +	FM10K_SW_SWITCH_LOCK(sw);
> +	pcsl_cfg = fm10k_read_switch_reg(sw, FM10K_SW_PCSL_CFG(eplno,
> lane));
> +	pcsl_cfg |= FM10K_SW_PCSL_CFG_RX_BIT_SLIP_ENABLE;
> +	if (int_return & 0x1)
> +		pcsl_cfg |= FM10K_SW_PCSL_CFG_RX_BIT_SLIP_INITIAL;
> +	fm10k_write_switch_reg(sw, FM10K_SW_PCSL_CFG(eplno, lane),
> pcsl_cfg);
> +	FM10K_SW_SWITCH_UNLOCK(sw);
> +
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x0c, (1 << 8));
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_init_signal_ok(struct fm10k_switch *sw, unsigned int serdes,
> +	unsigned int threshold)
> +{
> +	int error;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: setting signal OK threshold to %u",
> +	    sw->epl_sbus->name, serdes, threshold);
> +
> +	error =
> +	    fm10k_epl_serdes_spico_int(sw, serdes, 0x20, 0x20, NULL);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_dma_esb_read_modify_write(sw, serdes,
> 0x080,
> +	    (threshold & 0xf) << 2, 0x3c, NULL);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_spico_int02_retry(struct fm10k_switch *sw, unsigned int
> serdes,
> +    uint32_t data, unsigned int timeout_ms)
> +{
> +	uint64_t start_time_us, elapsed_time_ms;
> +	uint32_t result;
> +	int error;
> +
> +	start_time_us = fm10k_uptime_us();
> +	elapsed_time_ms = 0;
> +	while (elapsed_time_ms < timeout_ms) {
> +		elapsed_time_ms = (fm10k_uptime_us() - start_time_us) / 1000;
> +		error =
> +		    fm10k_epl_serdes_spico_int(sw, serdes, 0x02, data, &result);
> +		if (result == 0x02) {
> +			error = 0;
> +			break;
> +		}
> +
> +		fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US);
> +	}
> +
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_dma_reg_write(struct fm10k_switch *sw, unsigned int
> serdes,
> +    unsigned int addr, uint32_t data)
> +{
> +	int error;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x18,
> +	    0x8000 | (addr & 0xff), NULL);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x19, data, NULL);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_dma_esb_read(struct fm10k_switch *sw, unsigned int
> serdes,
> +    unsigned int addr, uint32_t *result)
> +{
> +	int error;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x18,
> +	    0x4000 | (addr & 0x3fff), result);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x1a, 0x00, result);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_dma_esb_write(struct fm10k_switch *sw, unsigned int
> serdes,
> +    unsigned int addr, uint32_t data)
> +{
> +	int error;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x18,
> +	    0x4000 | (addr & 0x3fff), NULL);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x19, data, NULL);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_dma_esb_read_modify_write(struct fm10k_switch *sw,
> +    unsigned int serdes, unsigned int addr, uint32_t data, uint32_t mask,
> +    uint32_t *result)
> +{
> +	int error;
> +	uint32_t read_data;
> +
> +	error = fm10k_epl_serdes_dma_esb_read(sw, serdes, addr, &read_data);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_dma_esb_write(sw, serdes, addr,
> +	    (data & mask) | (read_data & ~mask));
> +	if (error)
> +		goto done;
> +	if(result)
> +		*result = (data & mask) | (read_data & ~mask);
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_spico_wr_only_int(struct fm10k_switch *sw, unsigned int
> serdes,
> +    unsigned int int_num, uint32_t param)
> +{
> +	int error;
> +	uint32_t result;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, int_num, param,
> &result);
> +	if (error)
> +		goto done;
> +	if (result != int_num) {
> +		error = -1;
> +		goto done;
> +	}
> +done:
> +	return (error);
> +}
> +
> +static void
> +fm10k_epl_serdes_eplno_lane(struct fm10k_switch *sw, unsigned int serdes,
> +    unsigned int *eplno, unsigned int *lane)
> +{
> +	if (sw) {
> +		*eplno = serdes / FM10K_SW_EPL_LANES;
> +		*lane = serdes % FM10K_SW_EPL_LANES;
> +	}
> +}
> +
> +static int
> +fm10k_epl_serdes_configure_near_loopback(struct fm10k_ext_port_lane
> *lane)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int serdes = lane->abs_laneno;
> +	uint32_t data;
> +	int error;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: configuring near loopback",
> +	    sw->epl_sbus->name, serdes);
> +
> +	/* XXX assuming no lane polarity has been set */
> +
> +	/* set near loopback mode */
> +	fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US);
> +	data = (1 << 8) | (1 << 0);
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x08, data);
> +	if (error)
> +		goto done;
> +
> +	/* disable tx output, leave tx/ex enabled */
> +	fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US);
> +	error =
> +	    fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x01, 0x03);
> +	if (error)
> +		goto done;
> +
> +	/* set signal detect override to normal */
> +	fm10k_epl_serdes_set_signal_detect(lane,
> FM10K_SW_LANE_OVERRIDE_NORMAL);
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_epl_serdes_configure_for_dfe_tuning(struct fm10k_ext_port_lane
> *lane)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int serdes = lane->abs_laneno;
> +	int error;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: configuring serdes for dfe tuning",
> +	    sw->epl_sbus->name, serdes);
> +
> +	/*
> +	 * Configure the serdes to run DFE tuning
> +	 */
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x26,
> +	    ((2 << 12) | (0 << 8) | (FM10K_SW_SERDES_DFE_DEFAULT_HF & 0xff)),
> +	    NULL);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x26,
> +	    ((2 << 12) | (1 << 8) | (FM10K_SW_SERDES_DFE_DEFAULT_LF & 0xff)),
> +	    NULL);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x26,
> +	    ((2 << 12) | (2 << 8) | (FM10K_SW_SERDES_DFE_DEFAULT_DC & 0xff)),
> +	    NULL);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x26,
> +	    ((2 << 12) | (3 << 8) | (FM10K_SW_SERDES_DFE_DEFAULT_BW &
> 0xff)),
> +	    NULL);
> +	if (error)
> +		goto done;
> +
> +	/* allow early link up */
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x26, 0x5b01, NULL);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_epl_serdes_start_dfe_ical(struct fm10k_ext_port_lane *lane)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int serdes = lane->abs_laneno;
> +	unsigned int speed = lane->port->lane_speed;
> +	int error;
> +	uint32_t param;
> +
> +	/*
> +	 * Start DFE tuning initial calibration (ical)
> +	 */
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: starting dfe ical",
> +	    sw->epl_sbus->name, serdes);
> +
> +	if (speed == 25)
> +		param = FM10K_SW_LINK_OPT_PARAM_A25G;
> +	else
> +		param = FM10K_SW_LINK_OPT_PARAM_A10G;
> +
> +	if ((sw->epl_serdes_code_version_build_id >> 16) > 0x1055)
> +		error = fm10k_epl_serdes_config_dfe_param(sw, serdes,
> param);
> +
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x0a, 0x01);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_epl_serdes_dfe_ical_status(struct fm10k_ext_port_lane *lane,
> +    uint32_t *status)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int serdes = lane->abs_laneno;
> +	int error;
> +	uint32_t dfe_status, converged;
> +
> +	error = fm10k_epl_serdes_get_dfe_status(sw, serdes, &dfe_status);
> +	if (error)
> +		goto done;
> +
> +	if ((dfe_status & 0x11) == 0x11) {
> +		*status = FM10K_SW_SERDES_DFE_ICAL_IN_PROGRESS;
> +	} else {
> +		error = fm10k_epl_serdes_get_ical_result(sw, serdes,
> &converged);
> +		if (error)
> +			goto done;
> +		if (converged)
> +			*status = FM10K_SW_SERDES_DFE_ICAL_CONVERGED;
> +		else
> +			*status = FM10K_SW_SERDES_DFE_ICAL_FAILED;
> +	}
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_epl_serdes_start_dfe_pcal(struct fm10k_ext_port_lane *lane)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int serdes = lane->abs_laneno;
> +	unsigned int speed = lane->port->lane_speed;
> +	int error;
> +	uint32_t param;
> +
> +	/*
> +	 * Start DFE tuning periodic calibration (pcal), just one
> +	 */
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: starting dfe pcal",
> +	    sw->epl_sbus->name, serdes);
> +	if (speed == 25)
> +		param = FM10K_SW_LINK_OPT_PARAM_B25G;
> +	else
> +		param = FM10K_SW_LINK_OPT_PARAM_B10G;
> +
> +	if ((sw->epl_serdes_code_version_build_id >> 16) > 0x1055)
> +		error = fm10k_epl_serdes_config_dfe_param(sw, serdes,
> param);
> +
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x0a, 0x02);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_epl_serdes_dfe_pcal_status(struct fm10k_ext_port_lane *lane,
> +    uint32_t *status)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int serdes = lane->abs_laneno;
> +	int error;
> +	uint32_t dfe_status;
> +
> +	error = fm10k_epl_serdes_get_dfe_status(sw, serdes, &dfe_status);
> +	if (error)
> +		goto done;
> +	if (dfe_status & 0x02)
> +		*status = FM10K_SW_SERDES_DFE_PCAL_COMPLETE;
> +	else
> +		*status = FM10K_SW_SERDES_DFE_PCAL_IN_PROGRESS;
> +
> +done:
> +	return (error);
> +}
> +
> +int
> +fm10k_epl_serdes_stop_dfe_tuning(struct fm10k_ext_port_lane *lane,
> +    unsigned int force_reset)
> +{
> +	struct fm10k_switch *sw = lane->port->ports->sw;
> +	unsigned int serdes = lane->abs_laneno;
> +	int error;
> +	unsigned int ical_stopped, pcal_stopped;
> +	unsigned int i;
> +	uint32_t dfe_status, status;
> +
> +	error = fm10k_epl_serdes_get_dfe_status(sw, serdes, &dfe_status);
> +	if (error)
> +		goto done;
> +
> +	ical_stopped = 0;
> +	pcal_stopped = 0;
> +
> +	if (!force_reset) {
> +		if (dfe_status & 0x3) {
> +			/* stop all DFE tuning */
> +			error = fm10k_epl_serdes_spico_wr_only_int(sw,
> serdes,
> +			    0x0a, 0);
> +			if (error)
> +				goto done;
> +
> +			for (i = 0;
> +			     i < FM10K_SW_SERDES_ICAL_STOP_MAX_CYCLES;
> +			     i++) {
> +				error = fm10k_epl_serdes_dfe_ical_status(lane,
> +				    &status);
> +				if (error)
> +					goto done;
> +				if (status !=
> +
> FM10K_SW_SERDES_DFE_ICAL_IN_PROGRESS) {
> +					ical_stopped = 1;
> +					break;
> +				}
> +				fm10k_udelay(
> +
> FM10K_SW_SERDES_DFE_STOP_CYCLE_DELAY_US);
> +			}
> +
> +			if (ical_stopped)
> +				for (i = 0;
> +				     i <
> FM10K_SW_SERDES_PCAL_STOP_MAX_CYCLES;
> +				     i++) {
> +					error =
> +					    fm10k_epl_serdes_dfe_pcal_status(
> +						lane,
> +						&status);
> +					if (error)
> +						goto done;
> +					if (status !=
> +
> FM10K_SW_SERDES_DFE_PCAL_IN_PROGRESS) {
> +						pcal_stopped = 0;
> +						break;
> +					}
> +					fm10k_udelay(
> +
> FM10K_SW_SERDES_DFE_STOP_CYCLE_DELAY_US);
> +				}
> +		}
> +
> +		if (ical_stopped && pcal_stopped && (dfe_status & 0x40)) {
> +			error = fm10k_epl_serdes_start_dfe_pcal(lane);
> +			if (error)
> +				goto done;
> +			pcal_stopped = 0;
> +			for (i = 0; i <
> FM10K_SW_SERDES_PCAL_STOP_MAX_CYCLES; i++) {
> +				error = fm10k_epl_serdes_dfe_pcal_status(lane,
> +				    &status);
> +				if (error)
> +					goto done;
> +				if (status !=
> +
> FM10K_SW_SERDES_DFE_PCAL_IN_PROGRESS) {
> +					pcal_stopped = 1;
> +					break;
> +				}
> +
> 	fm10k_udelay(FM10K_SW_SERDES_DFE_STOP_CYCLE_DELAY_US);
> +			}
> +		}
> +	}
> +
> +	if (!ical_stopped || !pcal_stopped) {
> +		error = -1;
> +		goto done;
> +	}
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_config_dfe_param(struct fm10k_switch *sw,
> +    unsigned int serdes, uint32_t param)
> +{
> +	int error;
> +
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x18, 0x07);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x19,
> +	    param & 0xffff);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x19,
> +	    param >> 16);
> +	if (error)
> +		goto done;
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_get_dfe_status(struct fm10k_switch *sw, unsigned int
> serdes,
> +    uint32_t *status)
> +{
> +	int error;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x126, (0x0b << 8),
> +	    status);
> +	if (error)
> +		goto done;
> +
> +	FM10K_SW_TRACE(
> +	    "sbus %s: serdes %u: dfe status: "
> +	    "coarse_active=%u fine_active=%u adaptive=%u",
> +	    sw->epl_sbus->name, serdes, *status & (1 << 0),
> +	    *status & (1 << 1), *status & (1 << 6));
> +
> +done:
> +	return (error);
> +}
> +
> +static int
> +fm10k_epl_serdes_get_ical_result(struct fm10k_switch *sw, unsigned int
> serdes,
> +    uint32_t *converged)
> +{
> +	uint32_t val1;
> +	uint32_t val2;
> +	uint32_t diff;
> +	int error;
> +
> +	*converged = 0;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x126,
> +	    (4 << 12), &val1);
> +	if (error)
> +		goto done;
> +
> +	error = fm10k_epl_serdes_spico_int(sw, serdes, 0x126,
> +	    (4 << 12) | (1 << 8), &val2);
> +	if (error)
> +		goto done;
> +
> +	/* sign extension */
> +	if (val1 & 0x8000)
> +		val1 |= 0xffff0000;
> +	if (val2 & 0x8000)
> +		val2 |= 0xffff0000;
> +	diff = abs(val2 - val1);
> +
> +	if (diff >= FM10K_SW_SERDES_DFE_DATA_LEVEL0_THRESHOLD)
> +		*converged = 1;
> +
> +done:
> +	return (error);
> +}
> diff --git a/drivers/net/fm10k/switch/fm10k_serdes.h
> b/drivers/net/fm10k/switch/fm10k_serdes.h
> new file mode 100644
> index 0000000..d0925b9
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_serdes.h
> @@ -0,0 +1,41 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_SW_SERDES_H_
> +#define _FM10K_SW_SERDES_H_
> +
> +
> +#define FM10K_SW_SERDES_DFE_ICAL_IN_PROGRESS	0
> +#define FM10K_SW_SERDES_DFE_ICAL_CONVERGED		1
> +#define FM10K_SW_SERDES_DFE_ICAL_FAILED			2
> +#define FM10K_SW_SERDES_DFE_PCAL_IN_PROGRESS	0
> +#define FM10K_SW_SERDES_DFE_PCAL_COMPLETE		1
> +
> +
> +int fm10k_epl_serdes_reset_and_load_all(struct fm10k_switch *sw);
> +int fm10k_epl_serdes_start_bringup(struct fm10k_ext_port_lane *lane);
> +int fm10k_epl_serdes_continue_bringup(struct fm10k_ext_port_lane *lane);
> +int fm10k_epl_serdes_disable(struct fm10k_ext_port_lane *lane);
> +int fm10k_epl_serdes_configure_for_dfe_tuning(struct fm10k_ext_port_lane
> *lane);
> +int fm10k_epl_serdes_start_dfe_ical(struct fm10k_ext_port_lane *lane);
> +int fm10k_epl_serdes_dfe_ical_status(struct fm10k_ext_port_lane *lane,
> uint32_t *status);
> +int fm10k_epl_serdes_start_dfe_pcal(struct fm10k_ext_port_lane *lane);
> +int fm10k_epl_serdes_dfe_pcal_status(struct fm10k_ext_port_lane *lane,
> uint32_t *status);
> +int fm10k_epl_serdes_stop_dfe_tuning(struct fm10k_ext_port_lane *lane,
> unsigned int force_reset);
> +void fm10k_epl_serdes_set_signal_detect(struct fm10k_ext_port_lane *lane,
> unsigned int override);
> +
> +#endif /* _FM10K_SW_SERDES_H_ */
> diff --git a/drivers/net/fm10k/switch/fm10k_sm.c
> b/drivers/net/fm10k/switch/fm10k_sm.c
> new file mode 100644
> index 0000000..55c2dc7
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_sm.c
> @@ -0,0 +1,195 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#include <stdint.h>
> +#include <stdlib.h>
> +#include <rte_malloc.h>
> +
> +#include "../base/fm10k_osdep.h"
> +#include "fm10k_debug.h"
> +#include "fm10k_sm.h"
> +
> +static void *fm10k_sm_handle_event(void *);
> +static void *fm10k_sm_handle_timer(void *);
> +static void fm10k_sm_event_heap_init(struct fm10k_sm_event_heap*);
> +static uint16_t fm10k_sm_event_heap_pop(struct fm10k_sm_event_heap*);
> +static void fm10k_sm_event_heap_push(struct fm10k_sm_event_heap*,
> uint16_t);
> +
> +
> +struct fm10k_sm *
> +fm10k_sm_attach(/*struct taskqueue *tq,*/ uint16_t num_events,
> +    uint16_t num_timers, fm10k_sm_process_event_t event_handler,
> +    fm10k_sm_process_timer_t timer_handler, void *ctx)
> +{
> +	struct fm10k_sm *sm;
> +	struct fm10k_sm_timer *timer;
> +	unsigned int i;
> +
> +	sm = (struct fm10k_sm *)rte_zmalloc("fm10k_sm", sizeof(struct
> fm10k_sm), 0);
> +	if (sm == NULL)
> +		goto fail;
> +
> +	sm->num_events = num_events;
> +	fm10k_sm_event_heap_init(&sm->events);
> +	pthread_create(&sm->event_task, NULL, fm10k_sm_handle_event, sm);
> +	sm->num_timers = num_timers;
> +	if (sm->num_timers > 0) {
> +		sm->timers = (struct fm10k_sm_timer
> *)rte_zmalloc("fm10k_sm_timers",
> +		    sizeof(struct fm10k_sm_timer) * sm->num_timers, 0);
> +		if (sm->timers == NULL)
> +			goto fail;
> +	}
> +
> +	sm->event_handler = event_handler;
> +	sm->timer_handler = timer_handler;
> +	sm->ctx = ctx;
> +
> +	for (i = 0; i < sm->num_timers; i++) {
> +		timer = &sm->timers[i];
> +		sem_init(&timer->tq, 0, 0);
> +		timer->sm = sm;
> +		pthread_create(&timer->t, NULL, fm10k_sm_handle_timer,
> timer);
> +		timer->timer_id = i;
> +	}
> +
> +	return (sm);
> +
> +fail:
> +	if (sm)
> +		fm10k_sm_detach(sm);
> +
> +	return (NULL);
> +}
> +
> +void
> +fm10k_sm_detach(struct fm10k_sm *sm)
> +{
> +	rte_free(sm);
> +}
> +
> +void
> +fm10k_sm_send_event(struct fm10k_sm *sm, uint16_t event_id)
> +{
> +	fm10k_sm_event_heap_push(&sm->events, event_id);
> +}
> +
> +void
> +fm10k_sm_timer_start(struct fm10k_sm *sm, uint16_t timer_id,
> +    unsigned int timeout_ms)
> +{
> +	struct fm10k_sm_timer *timer = &sm->timers[timer_id];
> +
> +	gettimeofday(&timer->start, 0);
> +	timer->timeout_ms = timeout_ms;
> +	timer->running = 1;
> +	sem_post(&timer->tq);
> +}
> +
> +/*
> + * It is possible that an expiration events from this timer will
> + * occur after this is called.
> + */
> +void
> +fm10k_sm_timer_cancel(struct fm10k_sm *sm, uint16_t timer_id)
> +{
> +	struct fm10k_sm_timer *timer = &sm->timers[timer_id];
> +	timer->running = 0;
> +}
> +
> +static void *
> +fm10k_sm_handle_event(void *ctx)
> +{
> +	struct fm10k_sm *sm = ctx;
> +	uint16_t event_id;
> +
> +	while (1) {
> +		event_id = fm10k_sm_event_heap_pop(&sm->events);
> +		sm->event_handler(sm, event_id);
> +	}
> +	return NULL;
> +}
> +
> +static void *
> +fm10k_sm_handle_timer(void *ctx)
> +{
> +	struct fm10k_sm_timer *timer = ctx;
> +	struct fm10k_sm *sm = timer->sm;
> +	struct timeval now;
> +	struct timeval sleep;
> +	uint64_t cost, timeout;
> +
> +	while (1) {
> +		sem_wait(&timer->tq);
> +		if (timer->running)	{
> +			gettimeofday(&now, 0);
> +			cost = (now.tv_sec - timer->start.tv_sec)*1000000;
> +			cost += (now.tv_usec - timer->start.tv_usec);
> +			if (cost < timer->timeout_ms*1000) {
> +				timeout = timer->timeout_ms*1000;
> +				timeout -= cost;
> +				sleep.tv_sec = timeout/1000000;
> +				sleep.tv_usec = timeout%1000000;
> +				select(0, NULL, NULL, NULL, &sleep);
> +			}
> +			if (timer->running) {
> +				sm->timer_handler(sm, timer->timer_id);
> +			}
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +
> +static void
> +fm10k_sm_event_heap_init(struct fm10k_sm_event_heap* heap)
> +{
> +	heap->count = 0;
> +	pthread_mutex_init(&heap->lock, NULL);
> +	sem_init(&heap->s, 0, 0);
> +}
> +
> +static uint16_t
> +fm10k_sm_event_heap_pop(struct fm10k_sm_event_heap* heap)
> +{
> +	int i;
> +	uint16_t id;
> +
> +	sem_wait(&heap->s);
> +	pthread_mutex_lock(&heap->lock);
> +	id = heap->heap[0];
> +	for (i=1; i<heap->count; i++) {
> +		heap->heap[i-1] = heap->heap[i];
> +	}
> +	heap->count--;
> +	pthread_mutex_unlock(&heap->lock);
> +	return id;
> +}
> +
> +static void
> +fm10k_sm_event_heap_push(struct fm10k_sm_event_heap* heap, uint16_t id)
> +{
> +	pthread_mutex_lock(&heap->lock);
> +	if (heap->count >= FM10K_SM_ID_HEAP_MAX) {
> +		pthread_mutex_unlock(&heap->lock);
> +		return;
> +	}
> +	heap->heap[heap->count] = id;
> +	heap->count++;
> +	pthread_mutex_unlock(&heap->lock);
> +	sem_post(&heap->s);
> +}
> diff --git a/drivers/net/fm10k/switch/fm10k_sm.h
> b/drivers/net/fm10k/switch/fm10k_sm.h
> new file mode 100644
> index 0000000..b39244f
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_sm.h
> @@ -0,0 +1,120 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_SW_SM_H_
> +#define _FM10K_SW_SM_H_
> +
> +#include <stdint.h>
> +
> +#include <signal.h>
> +#include <sys/time.h>
> +#include <pthread.h>
> +#include <semaphore.h>
> +
> +/*
> + * This framework provides state machine implementation support for use in
> + * the rest of the driver.
> + *
> + * In general, a given state machine needs to receive events from interrupts
> + * and from timers, and in general, the actions that are taken during a
> + * state transition may be time consuming.  In order to keep the state
> + * transition actions out of the interrupt and timer subsystem execution
> + * contexts, so as not to arbitrarily delay the processing of other
> + * interrupts and timers, all event handling is performed in a taskqueue.
> + *
> + * The framework does not associate a given timer expiration with a specific
> + * event, as it is often the case that a timer is used to poll for status,
> + * and different events might be generated upong timer expiration depending
> + * on the status found or whether an overall timeout period has expired.
> + * For this reason, there is a separate timer expiration handler which
> + * receives the expired timer id.  That handler can then decide what state
> + * transition to make or what event to send to the state machine.
> + *
> + * The model is that for a given state machine, there are N>0 events
> + * identified by the integers [0..N-1] and there are M>=0 timers identified
> + * by the integers [0..M-1].
> + *
> + * The timers are one-shot timers.
> + *
> + * Since all state machine processing occurs in the context of the
> + * taskqueue, if that taskqueue was created with only a single thread, then
> + * no locking is required in the provided event and timer handlers to
> + * prevent overlapping execution.
> + *
> + */
> +
> +struct fm10k_sm;
> +
> +// replace it by event heap
> +#if 0
> +struct fm10k_sm_event {
> +	struct fm10k_sm *sm;
> +//	struct task t;
> +	pthread_t t;
> +	uint16_t event_id;
> +};
> +#endif
> +
> +struct fm10k_sm_timer {
> +	struct fm10k_sm *sm;
> +//	struct callout c;
> +//	struct task t;
> +	pthread_t t;
> +	sem_t tq;
> +	struct timeval start;
> +	uint16_t timeout_ms;
> +	uint16_t timer_id;
> +	uint8_t running;
> +};
> +
> +typedef void (*fm10k_sm_process_event_t)(struct fm10k_sm *, uint16_t);
> +typedef void (*fm10k_sm_process_timer_t)(struct fm10k_sm *, uint16_t);
> +
> +/**/
> +#define FM10K_SM_ID_HEAP_MAX	128
> +struct fm10k_sm_event_heap {
> +	pthread_mutex_t lock;
> +	sem_t s;
> +	uint16_t count;
> +	uint16_t heap[FM10K_SM_ID_HEAP_MAX];
> +};
> +
> +struct fm10k_sm {
> +//	struct taskqueue *tq;
> +	pthread_t event_task;
> +//	struct fm10k_sm_event *events;
> +	struct fm10k_sm_timer *timers;
> +	struct fm10k_sm_event_heap events;
> +	fm10k_sm_process_event_t event_handler;
> +	fm10k_sm_process_timer_t timer_handler;
> +	void *ctx;
> +	unsigned int state;
> +	uint16_t num_events;
> +	uint16_t num_timers;
> +	uint8_t portno;
> +	uint8_t laneno;
> +};
> +
> +struct fm10k_sm *fm10k_sm_attach(/*struct taskqueue *tq,*/ uint16_t
> num_events,
> +	    uint16_t num_timers, fm10k_sm_process_event_t event_handler,
> +	    fm10k_sm_process_timer_t timer_handler, void *ctx);
> +void fm10k_sm_detach(struct fm10k_sm *sm);
> +void fm10k_sm_send_event(struct fm10k_sm *sm, uint16_t event_id);
> +void fm10k_sm_timer_start(struct fm10k_sm *sm, uint16_t timer_id, unsigned
> int timeout_ms);
> +void fm10k_sm_timer_cancel(struct fm10k_sm *sm, uint16_t timer_id);
> +
> +#endif /* _FM10K_SW_SM_H_ */
> diff --git a/drivers/net/fm10k/switch/fm10k_spico_code.c
> b/drivers/net/fm10k/switch/fm10k_spico_code.c
> new file mode 100644
> index 0000000..e551cac
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_spico_code.c
> @@ -0,0 +1,2977 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#include "fm10k_spico_code.h"
> +
> +
> +/* Production versions */
> +
> +
> +/* SBus master code (production version)
> + *  source file:   release_2015_01_14/sbus_master.0x1013_0001.rom */
> +
> +const uint32_t fm10000_sbus_master_code_versionBuildId_prd = 0x10130001;
> +const uint32_t fm10000_sbus_master_code_size_prd           = 3338;
> +
> +const uint16_t fm10000_sbus_master_code_prd[] = {
> +    0x132, 0x002, 0x006, 0x000, 0x390, 0x002, 0x080, 0x247,
> +    0x071, 0x247, 0x01f, 0x247, 0x020, 0x247, 0x02e, 0x247,
> +    0x02f, 0x247, 0x03f, 0x247, 0x040, 0x247, 0x042, 0x247,
> +    0x043, 0x247, 0x03d, 0x0c0, 0x02d, 0x247, 0x031, 0x247,
> +    0x032, 0x081, 0x18b, 0x247, 0x039, 0x248, 0x03a, 0x181,
> +    0x247, 0x034, 0x248, 0x036, 0x209, 0x247, 0x033, 0x248,
> +    0x035, 0x305, 0x034, 0x247, 0x037, 0x248, 0x038, 0x190,
> +    0x247, 0x03b, 0x248, 0x03c, 0x3d4, 0x1ff, 0x00c, 0x3d5,
> +    0x100, 0x00c, 0x3d4, 0x2ff, 0x00c, 0x3c7, 0x0fe, 0x018,
> +    0x0c2, 0x019, 0x044, 0x233, 0x000, 0x152, 0x01b, 0x347,
> +    0x01b, 0x030, 0x085, 0x187, 0x247, 0x03e, 0x3c7, 0x100,
> +    0x041, 0x080, 0x247, 0x065, 0x3c4, 0x3fc, 0x010, 0x3d4,
> +    0x22f, 0x00e, 0x347, 0x033, 0x008, 0x247, 0x008, 0x081,
> +    0x189, 0x227, 0x2c7, 0x044, 0x220, 0x2c7, 0x045, 0x220,
> +    0x2c7, 0x046, 0x220, 0x2c7, 0x047, 0x220, 0x2c7, 0x048,
> +    0x220, 0x2c7, 0x049, 0x220, 0x2c7, 0x04a, 0x220, 0x2c7,
> +    0x04b, 0x3a7, 0x05b, 0x1a7, 0x3a5, 0x08d, 0x2c7, 0x04c,
> +    0x0c0, 0x04d, 0x044, 0x07d, 0x001, 0x0df, 0x02c, 0x000,
> +    0x009, 0x322, 0x02c, 0x009, 0x005, 0x347, 0x02d, 0x02c,
> +    0x3d4, 0x3df, 0x00e, 0x307, 0x02c, 0x384, 0x01f, 0x229,
> +    0x220, 0x3b0, 0x0aa, 0x287, 0x199, 0x390, 0x000, 0x041,
> +    0x040, 0x045, 0x020, 0x12c, 0x000, 0x020, 0x163, 0x000,
> +    0x020, 0x175, 0x000, 0x020, 0x27e, 0x000, 0x020, 0x362,
> +    0x000, 0x020, 0x10a, 0x000, 0x020, 0x10a, 0x000, 0x020,
> +    0x1de, 0x000, 0x020, 0x330, 0x001, 0x020, 0x270, 0x001,
> +    0x020, 0x2af, 0x001, 0x020, 0x2a1, 0x001, 0x020, 0x338,
> +    0x001, 0x020, 0x285, 0x001, 0x020, 0x2b9, 0x001, 0x020,
> +    0x2a8, 0x001, 0x020, 0x001, 0x002, 0x020, 0x105, 0x001,
> +    0x020, 0x19e, 0x001, 0x020, 0x3e6, 0x000, 0x020, 0x10a,
> +    0x000, 0x020, 0x10a, 0x000, 0x020, 0x10a, 0x000, 0x020,
> +    0x10a, 0x000, 0x020, 0x10a, 0x000, 0x020, 0x10a, 0x000,
> +    0x020, 0x10a, 0x000, 0x020, 0x10a, 0x000, 0x020, 0x10a,
> +    0x000, 0x020, 0x10a, 0x000, 0x020, 0x10a, 0x000, 0x020,
> +    0x10a, 0x000, 0x044, 0x140, 0x000, 0x054, 0x362, 0x03d,
> +    0x000, 0x001, 0x0b0, 0x364, 0x03d, 0x001, 0x001, 0x0c6,
> +    0x307, 0x02e, 0x044, 0x187, 0x000, 0x055, 0x141, 0x02e,
> +    0x307, 0x030, 0x302, 0x02e, 0x00b, 0x374, 0x0c0, 0x02e,
> +    0x327, 0x02d, 0x000, 0x367, 0x044, 0x140, 0x000, 0x3d4,
> +    0x3df, 0x00e, 0x207, 0x009, 0x00a, 0x04f, 0x04e, 0x055,
> +    0x3d5, 0x200, 0x014, 0x000, 0x35d, 0x054, 0x000, 0x3f8,
> +    0x055, 0x081, 0x364, 0x010, 0x001, 0x001, 0x00d, 0x364,
> +    0x011, 0x002, 0x009, 0x009, 0x3c4, 0x3fe, 0x010, 0x3d4,
> +    0x3bf, 0x00e, 0x080, 0x101, 0x364, 0x010, 0x002, 0x001,
> +    0x00a, 0x364, 0x011, 0x001, 0x001, 0x006, 0x3c4, 0x3fd,
> +    0x010, 0x111, 0x045, 0x347, 0x026, 0x018, 0x347, 0x027,
> +    0x019, 0x347, 0x028, 0x01b, 0x347, 0x029, 0x01c, 0x044,
> +    0x222, 0x000, 0x0a1, 0x000, 0x31e, 0x347, 0x026, 0x018,
> +    0x347, 0x027, 0x019, 0x044, 0x233, 0x000, 0x347, 0x01b,
> +    0x028, 0x347, 0x01c, 0x029, 0x0a2, 0x000, 0x30c, 0x044,
> +    0x1b9, 0x000, 0x362, 0x01b, 0x000, 0x001, 0x016, 0x362,
> +    0x01b, 0x001, 0x001, 0x013, 0x362, 0x01b, 0x002, 0x001,
> +    0x00d, 0x362, 0x01b, 0x003, 0x001, 0x013, 0x362, 0x01b,
> +    0x004, 0x001, 0x013, 0x04e, 0x045, 0x364, 0x03d, 0x002,
> +    0x001, 0x005, 0x044, 0x01a, 0x001, 0x000, 0x3f7, 0x348,
> +    0x01b, 0x01a, 0x000, 0x3f2, 0x348, 0x01b, 0x01a, 0x000,
> +    0x3ed, 0x101, 0x247, 0x018, 0x3d7, 0x0ff, 0x019, 0x000,
> +    0x074, 0x3c7, 0x100, 0x014, 0x364, 0x004, 0x100, 0x009,
> +    0x00f, 0x044, 0x08d, 0x001, 0x2c7, 0x042, 0x044, 0x1de,
> +    0x001, 0x001, 0x005, 0x044, 0x239, 0x001, 0x055, 0x0c1,
> +    0x03d, 0x0bf, 0x000, 0x2b7, 0x000, 0x2bc, 0x3c7, 0x3ff,
> +    0x028, 0x087, 0x0b6, 0x0c1, 0x04e, 0x044, 0x37c, 0x000,
> +    0x347, 0x067, 0x029, 0x2c7, 0x02a, 0x322, 0x04e, 0x009,
> +    0x00c, 0x3c2, 0x016, 0x067, 0x009, 0x00c, 0x0c1, 0x028,
> +    0x0a7, 0x000, 0x298, 0x347, 0x033, 0x028, 0x000, 0x3fa,
> +    0x347, 0x034, 0x028, 0x000, 0x3f5, 0x111, 0x009, 0x3ff,
> +    0x045, 0x397, 0x003, 0x189, 0x395, 0x105, 0x105, 0x040,
> +    0x103, 0x051, 0x042, 0x2a7, 0x001, 0x00c, 0x040, 0x280,
> +    0x051, 0x1a7, 0x101, 0x050, 0x225, 0x042, 0x280, 0x045,
> +    0x287, 0x045, 0x364, 0x005, 0x008, 0x009, 0x3fd, 0x347,
> +    0x01b, 0x00a, 0x347, 0x01c, 0x00b, 0x3c7, 0x041, 0x00c,
> +    0x020, 0x260, 0x000, 0x364, 0x005, 0x008, 0x009, 0x3fd,
> +    0x3d5, 0x100, 0x00c, 0x3c7, 0x042, 0x00c, 0x044, 0x260,
> +    0x000, 0x364, 0x005, 0x010, 0x001, 0x3fd, 0x307, 0x005,
> +    0x384, 0x007, 0x262, 0x004, 0x009, 0x009, 0x347, 0x002,
> +    0x01b, 0x347, 0x003, 0x01c, 0x045, 0x262, 0x006, 0x009,
> +    0x3ef, 0x141, 0x020, 0x0c0, 0x01b, 0x0c0, 0x01c, 0x045,
> +    0x347, 0x019, 0x00d, 0x1c7, 0x00d, 0x345, 0x018, 0x00d,
> +    0x3d5, 0x200, 0x00c, 0x364, 0x005, 0x008, 0x001, 0x3fd,
> +    0x3d4, 0x1ff, 0x00c, 0x045, 0x364, 0x005, 0x008, 0x009,
> +    0x3fd, 0x0c0, 0x00c, 0x020, 0x260, 0x000, 0x054, 0x347,
> +    0x032, 0x031, 0x307, 0x031, 0x044, 0x2ad, 0x000, 0x141,
> +    0x031, 0x307, 0x030, 0x302, 0x031, 0x00b, 0x004, 0x0c0,
> +    0x031, 0x2a7, 0x001, 0x00a, 0x347, 0x031, 0x032, 0x347,
> +    0x031, 0x070, 0x000, 0x00b, 0x307, 0x032, 0x302, 0x031,
> +    0x009, 0x3e2, 0x3c7, 0x3ff, 0x070, 0x055, 0x3d4, 0x2ff,
> +    0x00e, 0x0a3, 0x020, 0x091, 0x000, 0x044, 0x1b9, 0x000,
> +    0x362, 0x01b, 0x001, 0x001, 0x009, 0x362, 0x01b, 0x016,
> +    0x001, 0x004, 0x000, 0x00b, 0x0cf, 0x019, 0x044, 0x233,
> +    0x000, 0x307, 0x01b, 0x003, 0x004, 0x0a0, 0x045, 0x304,
> +    0x035, 0x227, 0x1bc, 0x2e2, 0x003, 0x001, 0x093, 0x2e2,
> +    0x002, 0x001, 0x046, 0x2e2, 0x001, 0x001, 0x063, 0x227,
> +    0x001, 0x03d, 0x2e4, 0x001, 0x009, 0x010, 0x2e4, 0x002,
> +    0x009, 0x019, 0x2e4, 0x004, 0x009, 0x029, 0x2e4, 0x008,
> +    0x009, 0x029, 0x000, 0x02b, 0x041, 0x0a2, 0x1a7, 0x3b5,
> +    0x03a, 0x044, 0x1b1, 0x001, 0x043, 0x3a4, 0x3fe, 0x000,
> +    0x3e1, 0x041, 0x327, 0x018, 0x041, 0x044, 0x08d, 0x001,
> +    0x247, 0x01e, 0x043, 0x2c7, 0x018, 0x044, 0x0fb, 0x001,
> +    0x043, 0x3a4, 0x3fd, 0x000, 0x3cd, 0x3a4, 0x3fb, 0x000,
> +    0x3c9, 0x3a4, 0x3f7, 0x000, 0x3c5, 0x0a1, 0x045, 0x227,
> +    0x3a4, 0x0ff, 0x197, 0x384, 0x01f, 0x001, 0x010, 0x262,
> +    0x001, 0x001, 0x00e, 0x262, 0x002, 0x001, 0x00f, 0x262,
> +    0x003, 0x001, 0x00d, 0x000, 0x3ea, 0x000, 0x3e8, 0x044,
> +    0x079, 0x002, 0x000, 0x3e3, 0x000, 0x3e1, 0x000, 0x3df,
> +    0x0bf, 0x1aa, 0x2a8, 0x224, 0x19a, 0x384, 0x003, 0x001,
> +    0x00c, 0x262, 0x001, 0x001, 0x017, 0x262, 0x002, 0x001,
> +    0x015, 0x000, 0x015, 0x0c5, 0x019, 0x247, 0x01b, 0x0a2,
> +    0x1a7, 0x3b5, 0x03a, 0x2c7, 0x01c, 0x044, 0x222, 0x000,
> +    0x000, 0x3bd, 0x000, 0x3bb, 0x000, 0x3b9, 0x000, 0x3b7,
> +    0x000, 0x3b5, 0x054, 0x307, 0x066, 0x191, 0x384, 0x07f,
> +    0x3c7, 0x0fe, 0x018, 0x0c2, 0x019, 0x044, 0x233, 0x000,
> +    0x347, 0x01b, 0x064, 0x0a7, 0x044, 0x0bf, 0x003, 0x055,
> +    0x0a4, 0x020, 0x091, 0x000, 0x186, 0x285, 0x181, 0x0a7,
> +    0x1ab, 0x324, 0x004, 0x285, 0x055, 0x364, 0x010, 0x002,
> +    0x009, 0x026, 0x364, 0x011, 0x001, 0x009, 0x029, 0x247,
> +    0x064, 0x044, 0x0cd, 0x003, 0x3c4, 0x2ff, 0x065, 0x04f,
> +    0x04e, 0x055, 0x364, 0x065, 0x100, 0x001, 0x3fa, 0x327,
> +    0x065, 0x3a4, 0x007, 0x364, 0x065, 0x040, 0x001, 0x007,
> +    0x287, 0x302, 0x04e, 0x009, 0x3ec, 0x045, 0x364, 0x011,
> +    0x001, 0x001, 0x005, 0x3c4, 0x3fd, 0x010, 0x054, 0x04e,
> +    0x000, 0x3cc, 0x309, 0x023, 0x003, 0x024, 0x347, 0x023,
> +    0x04f, 0x00b, 0x01f, 0x3d5, 0x010, 0x00e, 0x08f, 0x187,
> +    0x395, 0x0a0, 0x247, 0x017, 0x080, 0x247, 0x016, 0x0c0,
> +    0x015, 0x3c5, 0x001, 0x014, 0x3c5, 0x004, 0x014, 0x3c4,
> +    0x3fe, 0x014, 0x3c5, 0x002, 0x014, 0x3d4, 0x3ef, 0x00e,
> +    0x347, 0x04f, 0x009, 0x020, 0x20b, 0x002, 0x307, 0x04f,
> +    0x00b, 0x028, 0x3c5, 0x002, 0x03d, 0x3d5, 0x010, 0x00e,
> +    0x387, 0x0b2, 0x187, 0x385, 0x080, 0x247, 0x017, 0x08e,
> +    0x187, 0x385, 0x0e6, 0x247, 0x016, 0x0c0, 0x015, 0x3c5,
> +    0x001, 0x014, 0x3c5, 0x004, 0x014, 0x3c4, 0x3fe, 0x014,
> +    0x3c5, 0x002, 0x014, 0x3d4, 0x3ef, 0x00e, 0x000, 0x006,
> +    0x082, 0x208, 0x244, 0x03d, 0x0df, 0x02c, 0x0b3, 0x020,
> +    0x091, 0x000, 0x307, 0x018, 0x3a7, 0x051, 0x044, 0x061,
> +    0x001, 0x2c7, 0x061, 0x04c, 0x324, 0x061, 0x001, 0x020,
> +    0x040, 0x3b7, 0x126, 0x08b, 0x187, 0x044, 0x1c4, 0x001,
> +    0x009, 0x005, 0x3c7, 0x022, 0x01b, 0x042, 0x364, 0x01b,
> +    0x022, 0x009, 0x027, 0x04c, 0x348, 0x061, 0x061, 0x324,
> +    0x061, 0x04d, 0x151, 0x050, 0x000, 0x01c, 0x327, 0x04f,
> +    0x3a4, 0x0ff, 0x322, 0x050, 0x00f, 0x014, 0x040, 0x0aa,
> +    0x084, 0x044, 0x1c4, 0x001, 0x042, 0x362, 0x01b, 0x00a,
> +    0x009, 0x008, 0x04c, 0x325, 0x061, 0x04d, 0x141, 0x050,
> +    0x045, 0x384, 0x0ff, 0x040, 0x193, 0x220, 0x042, 0x384,
> +    0x00f, 0x041, 0x0a1, 0x111, 0x003, 0x005, 0x2a9, 0x000,
> +    0x3fc, 0x042, 0x045, 0x0a0, 0x0d0, 0x061, 0x04d, 0x101,
> +    0x151, 0x061, 0x009, 0x3fc, 0x045, 0x0c0, 0x04f, 0x0c0,
> +    0x050, 0x387, 0x051, 0x044, 0x073, 0x001, 0x044, 0x209,
> +    0x000, 0x051, 0x101, 0x051, 0x045, 0x307, 0x03f, 0x001,
> +    0x006, 0x247, 0x018, 0x000, 0x01f, 0x0a0, 0x287, 0x044,
> +    0x1b9, 0x000, 0x362, 0x01b, 0x012, 0x001, 0x012, 0x362,
> +    0x01b, 0x011, 0x009, 0x005, 0x347, 0x018, 0x040, 0x121,
> +    0x307, 0x030, 0x282, 0x00b, 0x3eb, 0x0a0, 0x045, 0x347,
> +    0x018, 0x03f, 0x0c0, 0x019, 0x3c7, 0x070, 0x01b, 0x3c5,
> +    0x001, 0x01b, 0x044, 0x222, 0x000, 0x3d4, 0x3fe, 0x01b,
> +    0x044, 0x222, 0x000, 0x307, 0x03e, 0x044, 0x205, 0x000,
> +    0x3c5, 0x002, 0x01b, 0x044, 0x222, 0x000, 0x307, 0x03e,
> +    0x194, 0x044, 0x205, 0x000, 0x0c1, 0x019, 0x044, 0x233,
> +    0x000, 0x327, 0x01b, 0x0c0, 0x019, 0x3c5, 0x001, 0x01b,
> +    0x044, 0x222, 0x000, 0x3b5, 0x200, 0x045, 0x2c7, 0x01e,
> +    0x0a0, 0x287, 0x044, 0x300, 0x001, 0x001, 0x007, 0x041,
> +    0x044, 0x0fb, 0x001, 0x043, 0x121, 0x307, 0x030, 0x282,
> +    0x00b, 0x3f1, 0x045, 0x3b7, 0x03b, 0x307, 0x01e, 0x000,
> +    0x0b2, 0x091, 0x020, 0x362, 0x002, 0x054, 0x327, 0x06f,
> +    0x009, 0x009, 0x044, 0x08d, 0x001, 0x001, 0x080, 0x000,
> +    0x00d, 0x044, 0x2f8, 0x001, 0x362, 0x01b, 0x012, 0x009,
> +    0x076, 0x044, 0x0b2, 0x001, 0x2c7, 0x042, 0x044, 0x1de,
> +    0x001, 0x287, 0x001, 0x06b, 0x2c7, 0x01d, 0x327, 0x040,
> +    0x3a4, 0x0ff, 0x2c7, 0x018, 0x0c9, 0x01a, 0x044, 0x2d7,
> +    0x001, 0x044, 0x206, 0x001, 0x324, 0x035, 0x0c0, 0x01a,
> +    0x087, 0x187, 0x385, 0x06c, 0x282, 0x00b, 0x015, 0x0c1,
> +    0x01a, 0x087, 0x187, 0x385, 0x0bc, 0x282, 0x00b, 0x00c,
> +    0x0c2, 0x01a, 0x088, 0x187, 0x08c, 0x282, 0x00b, 0x004,
> +    0x0c3, 0x01a, 0x0a0, 0x287, 0x044, 0x300, 0x001, 0x001,
> +    0x010, 0x041, 0x307, 0x01a, 0x18b, 0x305, 0x042, 0x385,
> +    0x0e0, 0x3b7, 0x33b, 0x044, 0x1b1, 0x001, 0x043, 0x121,
> +    0x307, 0x030, 0x282, 0x00b, 0x3e8, 0x307, 0x03e, 0x044,
> +    0x205, 0x000, 0x0a0, 0x287, 0x044, 0x300, 0x001, 0x001,
> +    0x00b, 0x041, 0x307, 0x01d, 0x3b7, 0x03b, 0x044, 0x1b1,
> +    0x001, 0x043, 0x121, 0x307, 0x030, 0x282, 0x00b, 0x3ed,
> +    0x0c1, 0x008, 0x081, 0x000, 0x007, 0x387, 0x3ff, 0x3c7,
> +    0x0ff, 0x008, 0x055, 0x0b1, 0x020, 0x296, 0x001, 0x347,
> +    0x023, 0x043, 0x092, 0x020, 0x365, 0x002, 0x054, 0x044,
> +    0x1de, 0x001, 0x001, 0x005, 0x044, 0x239, 0x001, 0x387,
> +    0x3ff, 0x3c7, 0x0ff, 0x008, 0x055, 0x0b1, 0x020, 0x296,
> +    0x001, 0x040, 0x044, 0x1c9, 0x001, 0x001, 0x00c, 0x042,
> +    0x0c5, 0x019, 0x2c7, 0x01c, 0x247, 0x01b, 0x020, 0x222,
> +    0x000, 0x042, 0x080, 0x045, 0x044, 0x1b1, 0x001, 0x001,
> +    0x3fb, 0x041, 0x3a7, 0x0ff, 0x0c6, 0x019, 0x131, 0x001,
> +    0x00c, 0x044, 0x233, 0x000, 0x30a, 0x01c, 0x002, 0x3f8,
> +    0x081, 0x000, 0x003, 0x080, 0x043, 0x045, 0x307, 0x040,
> +    0x384, 0x0ff, 0x009, 0x017, 0x0a0, 0x287, 0x044, 0x1b9,
> +    0x000, 0x362, 0x01b, 0x011, 0x001, 0x00a, 0x121, 0x307,
> +    0x030, 0x282, 0x00b, 0x3f3, 0x0a0, 0x045, 0x347, 0x018,
> +    0x040, 0x0c0, 0x01a, 0x327, 0x040, 0x044, 0x2c3, 0x001,
> +    0x324, 0x034, 0x009, 0x3f2, 0x227, 0x045, 0x247, 0x01c,
> +    0x2c7, 0x01b, 0x280, 0x001, 0x3e9, 0x0c3, 0x019, 0x044,
> +    0x222, 0x000, 0x0c0, 0x019, 0x0c1, 0x01b, 0x044, 0x222,
> +    0x000, 0x0c2, 0x01b, 0x044, 0x222, 0x000, 0x347, 0x01e,
> +    0x019, 0x3d0, 0x041, 0x019, 0x307, 0x041, 0x044, 0x205,
> +    0x000, 0x044, 0x233, 0x000, 0x327, 0x01b, 0x00b, 0x3f6,
> +    0x0c0, 0x019, 0x0c1, 0x01b, 0x044, 0x222, 0x000, 0x287,
> +    0x045, 0x2c7, 0x01e, 0x0a0, 0x287, 0x044, 0x300, 0x001,
> +    0x001, 0x007, 0x041, 0x044, 0x24e, 0x001, 0x043, 0x121,
> +    0x307, 0x030, 0x282, 0x00b, 0x3f1, 0x045, 0x09f, 0x18a,
> +    0x0a1, 0x1aa, 0x324, 0x01e, 0x001, 0x006, 0x305, 0x01e,
> +    0x000, 0x005, 0x208, 0x304, 0x01e, 0x300, 0x043, 0x00b,
> +    0x005, 0x080, 0x000, 0x008, 0x272, 0x3e8, 0x00b, 0x004,
> +    0x397, 0x3e8, 0x305, 0x033, 0x3b7, 0x13b, 0x000, 0x343,
> +    0x327, 0x06e, 0x0c0, 0x01a, 0x044, 0x2c3, 0x001, 0x0a9,
> +    0x305, 0x033, 0x247, 0x007, 0x344, 0x035, 0x007, 0x3d4,
> +    0x37f, 0x00e, 0x020, 0x091, 0x000, 0x327, 0x06f, 0x0c0,
> +    0x01a, 0x044, 0x2c3, 0x001, 0x324, 0x034, 0x009, 0x005,
> +    0x347, 0x06f, 0x040, 0x0ad, 0x0c1, 0x008, 0x247, 0x009,
> +    0x345, 0x033, 0x008, 0x344, 0x035, 0x008, 0x020, 0x091,
> +    0x000, 0x327, 0x06e, 0x054, 0x055, 0x0ab, 0x000, 0x3d2,
> +    0x327, 0x06f, 0x054, 0x055, 0x0af, 0x000, 0x3e7, 0x327,
> +    0x06e, 0x0c9, 0x01a, 0x044, 0x2c3, 0x001, 0x0aa, 0x000,
> +    0x3c1, 0x327, 0x06f, 0x0c9, 0x01a, 0x044, 0x2c3, 0x001,
> +    0x0ae, 0x000, 0x3d3, 0x044, 0x2f8, 0x001, 0x362, 0x01b,
> +    0x011, 0x009, 0x00a, 0x044, 0x2d7, 0x001, 0x044, 0x206,
> +    0x001, 0x055, 0x045, 0x307, 0x034, 0x000, 0x3fc, 0x080,
> +    0x1bb, 0x2e2, 0x008, 0x00b, 0x00d, 0x0a1, 0x0c0, 0x01e,
> +    0x340, 0x01a, 0x01e, 0x001, 0x014, 0x1a8, 0x000, 0x011,
> +    0x320, 0x01a, 0x2c7, 0x01e, 0x2c7, 0x01a, 0x0a1, 0x151,
> +    0x01a, 0x003, 0x006, 0x2a9, 0x20b, 0x000, 0x3fa, 0x045,
> +    0x054, 0x287, 0x384, 0x0ff, 0x111, 0x020, 0x1b9, 0x000,
> +    0x044, 0x1b9, 0x000, 0x362, 0x01b, 0x016, 0x001, 0x007,
> +    0x362, 0x01b, 0x001, 0x009, 0x023, 0x3d7, 0x0fe, 0x019,
> +    0x044, 0x233, 0x000, 0x387, 0x0bb, 0x187, 0x385, 0x031,
> +    0x302, 0x01b, 0x001, 0x014, 0x387, 0x0b9, 0x187, 0x385,
> +    0x031, 0x302, 0x01b, 0x001, 0x00b, 0x387, 0x0b6, 0x187,
> +    0x385, 0x031, 0x302, 0x01b, 0x009, 0x003, 0x080, 0x045,
> +    0x327, 0x06e, 0x044, 0x340, 0x001, 0x0a8, 0x000, 0x342,
> +    0x327, 0x06f, 0x044, 0x340, 0x001, 0x0ac, 0x000, 0x356,
> +    0x044, 0x2f8, 0x001, 0x362, 0x01b, 0x00b, 0x009, 0x38d,
> +    0x0c0, 0x01c, 0x041, 0x1bb, 0x3a4, 0x007, 0x001, 0x047,
> +    0x131, 0x001, 0x02f, 0x131, 0x001, 0x017, 0x083, 0x3a7,
> +    0x3ff, 0x044, 0x3f6, 0x001, 0x084, 0x0a0, 0x044, 0x3f6,
> +    0x001, 0x082, 0x044, 0x3f6, 0x001, 0x081, 0x044, 0x3f6,
> +    0x001, 0x000, 0x03e, 0x082, 0x3a7, 0x3ff, 0x044, 0x3f6,
> +    0x001, 0x084, 0x0a0, 0x044, 0x3f6, 0x001, 0x083, 0x044,
> +    0x3f6, 0x001, 0x081, 0x044, 0x3f6, 0x001, 0x000, 0x029,
> +    0x081, 0x3a7, 0x3ff, 0x044, 0x3f6, 0x001, 0x084, 0x0a0,
> +    0x044, 0x3f6, 0x001, 0x083, 0x044, 0x3f6, 0x001, 0x082,
> +    0x044, 0x3f6, 0x001, 0x000, 0x014, 0x081, 0x3a7, 0x3ff,
> +    0x044, 0x3f6, 0x001, 0x084, 0x044, 0x3f6, 0x001, 0x083,
> +    0x044, 0x3f6, 0x001, 0x082, 0x044, 0x3f6, 0x001, 0x0c6,
> +    0x019, 0x0c0, 0x01b, 0x044, 0x222, 0x000, 0x0c5, 0x019,
> +    0x387, 0x0ff, 0x3a7, 0x3ff, 0x322, 0x04c, 0x303, 0x04d,
> +    0x2c7, 0x01b, 0x247, 0x01c, 0x044, 0x222, 0x000, 0x0c0,
> +    0x019, 0x0c1, 0x01b, 0x044, 0x222, 0x000, 0x397, 0x3ff,
> +    0x044, 0x205, 0x000, 0x044, 0x233, 0x000, 0x3c4, 0x001,
> +    0x01b, 0x009, 0x3f5, 0x0c6, 0x019, 0x044, 0x233, 0x000,
> +    0x307, 0x01b, 0x043, 0x2a7, 0x003, 0x016, 0x0c0, 0x01a,
> +    0x397, 0x044, 0x04c, 0x322, 0x01b, 0x00b, 0x00b, 0x272,
> +    0x04b, 0x001, 0x007, 0x101, 0x141, 0x01a, 0x000, 0x3f4,
> +    0x307, 0x01a, 0x305, 0x033, 0x055, 0x045, 0x247, 0x019,
> +    0x2c7, 0x01b, 0x020, 0x222, 0x000, 0x090, 0x020, 0x362,
> +    0x002, 0x327, 0x06f, 0x287, 0x384, 0x0ff, 0x262, 0x0df,
> +    0x00b, 0x00a, 0x262, 0x0e7, 0x003, 0x006, 0x247, 0x018,
> +    0x000, 0x00a, 0x044, 0x2f8, 0x001, 0x362, 0x01b, 0x001,
> +    0x009, 0x057, 0x0c7, 0x019, 0x0d1, 0x01b, 0x0c0, 0x01c,
> +    0x044, 0x222, 0x000, 0x0d0, 0x01b, 0x044, 0x222, 0x000,
> +    0x0c0, 0x019, 0x0c0, 0x01b, 0x347, 0x034, 0x01c, 0x044,
> +    0x222, 0x000, 0x0ca, 0x019, 0x081, 0x189, 0x247, 0x012,
> +    0x327, 0x013, 0x1a7, 0x325, 0x013, 0x133, 0x347, 0x013,
> +    0x01b, 0x347, 0x013, 0x01c, 0x044, 0x222, 0x000, 0x132,
> +    0x007, 0x3f6, 0x0c0, 0x019, 0x0c0, 0x01b, 0x0c0, 0x01c,
> +    0x044, 0x222, 0x000, 0x0cb, 0x019, 0x0cc, 0x01c, 0x044,
> +    0x222, 0x000, 0x0c7, 0x019, 0x0c2, 0x01b, 0x0c0, 0x01c,
> +    0x044, 0x222, 0x000, 0x0c8, 0x019, 0x0c0, 0x01b, 0x044,
> +    0x222, 0x000, 0x0c1, 0x008, 0x081, 0x000, 0x007, 0x387,
> +    0x3ff, 0x3c7, 0x0ff, 0x008, 0x055, 0x0b0, 0x020, 0x296,
> +    0x001, 0x0c1, 0x019, 0x0c0, 0x01b, 0x0c1, 0x01c, 0x1cc,
> +    0x01c, 0x044, 0x222, 0x000, 0x0c2, 0x019, 0x3c7, 0x054,
> +    0x01c, 0x044, 0x222, 0x000, 0x345, 0x033, 0x01c, 0x044,
> +    0x222, 0x000, 0x0c0, 0x019, 0x397, 0x003, 0x189, 0x395,
> +    0x105, 0x105, 0x247, 0x01d, 0x102, 0x050, 0x282, 0x00f,
> +    0x08f, 0x307, 0x01d, 0x104, 0x1a0, 0x280, 0x051, 0x1a7,
> +    0x101, 0x050, 0x285, 0x300, 0x01d, 0x051, 0x1a7, 0x2c7,
> +    0x01d, 0x101, 0x051, 0x2c5, 0x01d, 0x101, 0x051, 0x1a7,
> +    0x2c7, 0x01e, 0x101, 0x051, 0x2c5, 0x01e, 0x347, 0x034,
> +    0x01c, 0x227, 0x044, 0x222, 0x000, 0x287, 0x044, 0x11b,
> +    0x002, 0x044, 0x11b, 0x002, 0x347, 0x01d, 0x01b, 0x347,
> +    0x034, 0x01c, 0x044, 0x222, 0x000, 0x327, 0x01e, 0x001,
> +    0x057, 0x0ca, 0x019, 0x101, 0x052, 0x01b, 0x101, 0x051,
> +    0x041, 0x1a9, 0x2c5, 0x01b, 0x043, 0x1b5, 0x2c7, 0x01c,
> +    0x101, 0x051, 0x1a3, 0x325, 0x037, 0x2c5, 0x01c, 0x044,
> +    0x222, 0x000, 0x153, 0x01e, 0x007, 0x3e7, 0x0c0, 0x019,
> +    0x0c0, 0x01c, 0x044, 0x222, 0x000, 0x0ca, 0x01b, 0x0c5,
> +    0x019, 0x090, 0x187, 0x395, 0x03a, 0x247, 0x01c, 0x044,
> +    0x222, 0x000, 0x0c2, 0x019, 0x3c7, 0x020, 0x01b, 0x0c0,
> +    0x01c, 0x044, 0x222, 0x000, 0x347, 0x033, 0x01c, 0x044,
> +    0x222, 0x000, 0x045, 0x101, 0x051, 0x1a7, 0x2c7, 0x01b,
> +    0x101, 0x051, 0x2c5, 0x01b, 0x101, 0x051, 0x325, 0x037,
> +    0x2c7, 0x01c, 0x044, 0x222, 0x000, 0x045, 0x0c5, 0x01b,
> +    0x000, 0x3cf, 0x347, 0x000, 0x022, 0x347, 0x001, 0x023,
> +    0x0c0, 0x008, 0x0c0, 0x009, 0x307, 0x022, 0x384, 0x03f,
> +    0x229, 0x220, 0x3b0, 0x14b, 0x287, 0x199, 0x390, 0x002,
> +    0x041, 0x040, 0x045, 0x020, 0x21a, 0x002, 0x020, 0x223,
> +    0x002, 0x020, 0x22c, 0x002, 0x020, 0x351, 0x002, 0x020,
> +    0x281, 0x002, 0x020, 0x304, 0x002, 0x020, 0x309, 0x002,
> +    0x020, 0x30e, 0x002, 0x020, 0x313, 0x002, 0x020, 0x318,
> +    0x002, 0x020, 0x31d, 0x002, 0x020, 0x322, 0x002, 0x020,
> +    0x327, 0x002, 0x020, 0x32c, 0x002, 0x020, 0x331, 0x002,
> +    0x020, 0x336, 0x002, 0x020, 0x339, 0x002, 0x020, 0x33f,
> +    0x002, 0x020, 0x344, 0x002, 0x020, 0x348, 0x002, 0x020,
> +    0x354, 0x002, 0x020, 0x358, 0x002, 0x020, 0x361, 0x002,
> +    0x020, 0x36a, 0x002, 0x020, 0x36d, 0x002, 0x020, 0x370,
> +    0x002, 0x020, 0x2f1, 0x002, 0x020, 0x373, 0x002, 0x020,
> +    0x384, 0x002, 0x020, 0x215, 0x002, 0x020, 0x215, 0x002,
> +    0x020, 0x38e, 0x002, 0x020, 0x215, 0x002, 0x020, 0x215,
> +    0x002, 0x020, 0x215, 0x002, 0x020, 0x215, 0x002, 0x020,
> +    0x215, 0x002, 0x020, 0x215, 0x002, 0x020, 0x215, 0x002,
> +    0x020, 0x215, 0x002, 0x020, 0x3fd, 0x001, 0x020, 0x101,
> +    0x001, 0x020, 0x197, 0x001, 0x020, 0x3ba, 0x000, 0x020,
> +    0x215, 0x002, 0x020, 0x215, 0x002, 0x020, 0x215, 0x002,
> +    0x020, 0x215, 0x002, 0x020, 0x215, 0x002, 0x020, 0x215,
> +    0x002, 0x020, 0x215, 0x002, 0x020, 0x215, 0x002, 0x020,
> +    0x215, 0x002, 0x020, 0x215, 0x002, 0x020, 0x215, 0x002,
> +    0x020, 0x215, 0x002, 0x020, 0x215, 0x002, 0x020, 0x215,
> +    0x002, 0x020, 0x215, 0x002, 0x020, 0x215, 0x002, 0x020,
> +    0x215, 0x002, 0x020, 0x215, 0x002, 0x020, 0x215, 0x002,
> +    0x020, 0x215, 0x002, 0x0c1, 0x008, 0x345, 0x033, 0x008,
> +    0x344, 0x035, 0x008, 0x04e, 0x047, 0x3c7, 0x3ff, 0x008,
> +    0x000, 0x3f8, 0x3b7, 0x010, 0x1a7, 0x3a5, 0x013, 0x2c7,
> +    0x009, 0x000, 0x3ea, 0x3b7, 0x000, 0x1a7, 0x3a5, 0x001,
> +    0x2c7, 0x009, 0x000, 0x3e1, 0x080, 0x3b7, 0x003, 0x1a9,
> +    0x3b5, 0x105, 0x2c7, 0x023, 0x0c0, 0x028, 0x0c0, 0x029,
> +    0x052, 0x022, 0x044, 0x2d6, 0x002, 0x001, 0x005, 0x101,
> +    0x000, 0x3f8, 0x101, 0x052, 0x022, 0x346, 0x028, 0x022,
> +    0x3c4, 0x0ff, 0x022, 0x362, 0x022, 0x0ef, 0x009, 0x02e,
> +    0x101, 0x052, 0x022, 0x327, 0x028, 0x1b7, 0x2c6, 0x022,
> +    0x362, 0x022, 0x0be, 0x009, 0x021, 0x101, 0x052, 0x022,
> +    0x346, 0x029, 0x022, 0x3c4, 0x0ff, 0x022, 0x362, 0x022,
> +    0x0ad, 0x009, 0x013, 0x101, 0x052, 0x022, 0x327, 0x029,
> +    0x1b7, 0x2c6, 0x022, 0x362, 0x022, 0x0de, 0x009, 0x006,
> +    0x0c1, 0x009, 0x000, 0x391, 0x3c7, 0x3ff, 0x009, 0x000,
> +    0x38c, 0x081, 0x189, 0x247, 0x012, 0x0c0, 0x028, 0x0c0,
> +    0x029, 0x327, 0x013, 0x1a7, 0x325, 0x013, 0x2c7, 0x023,
> +    0x247, 0x012, 0x080, 0x347, 0x013, 0x022, 0x044, 0x2d6,
> +    0x002, 0x001, 0x005, 0x101, 0x000, 0x3f7, 0x347, 0x013,
> +    0x022, 0x346, 0x028, 0x022, 0x3c4, 0x0ff, 0x022, 0x362,
> +    0x022, 0x0ef, 0x009, 0x3d2, 0x347, 0x013, 0x022, 0x327,
> +    0x028, 0x1b7, 0x2c6, 0x022, 0x362, 0x022, 0x0be, 0x009,
> +    0x3c5, 0x347, 0x013, 0x022, 0x346, 0x029, 0x022, 0x3c4,
> +    0x0ff, 0x022, 0x362, 0x022, 0x0ad, 0x009, 0x3b7, 0x347,
> +    0x013, 0x022, 0x327, 0x029, 0x1b7, 0x2c6, 0x022, 0x362,
> +    0x022, 0x0de, 0x009, 0x3aa, 0x000, 0x3a4, 0x340, 0x022,
> +    0x028, 0x3c1, 0x000, 0x029, 0x3c6, 0x0d8, 0x028, 0x349,
> +    0x028, 0x028, 0x34b, 0x029, 0x029, 0x00a, 0x008, 0x3c0,
> +    0x0e5, 0x028, 0x3c1, 0x000, 0x029, 0x327, 0x023, 0x222,
> +    0x045, 0x397, 0x003, 0x189, 0x395, 0x105, 0x105, 0x051,
> +    0x1a7, 0x2c7, 0x023, 0x101, 0x051, 0x2c5, 0x023, 0x111,
> +    0x240, 0x023, 0x000, 0x332, 0x347, 0x023, 0x026, 0x000,
> +    0x304, 0x347, 0x023, 0x027, 0x000, 0x2ff, 0x347, 0x023,
> +    0x028, 0x000, 0x2fa, 0x347, 0x023, 0x029, 0x000, 0x2f5,
> +    0x347, 0x023, 0x02a, 0x000, 0x2f0, 0x347, 0x023, 0x02b,
> +    0x000, 0x2eb, 0x347, 0x028, 0x009, 0x000, 0x2e6, 0x347,
> +    0x029, 0x009, 0x000, 0x2e1, 0x347, 0x02a, 0x009, 0x000,
> +    0x2dc, 0x347, 0x02b, 0x009, 0x000, 0x2d7, 0x347, 0x023,
> +    0x02d, 0x055, 0x347, 0x023, 0x02c, 0x000, 0x2ce, 0x347,
> +    0x023, 0x021, 0x000, 0x2c9, 0x307, 0x021, 0x000, 0x006,
> +    0x307, 0x021, 0x141, 0x021, 0x327, 0x023, 0x04d, 0x000,
> +    0x2bc, 0x347, 0x023, 0x021, 0x307, 0x021, 0x000, 0x006,
> +    0x307, 0x021, 0x141, 0x021, 0x04c, 0x2c7, 0x009, 0x000,
> +    0x2ac, 0x08c, 0x347, 0x023, 0x06f, 0x055, 0x247, 0x02c,
> +    0x000, 0x2ab, 0x08d, 0x000, 0x3f7, 0x08e, 0x000, 0x3f4,
> +    0x08f, 0x000, 0x3f1, 0x307, 0x022, 0x183, 0x19b, 0x262,
> +    0x009, 0x00b, 0x007, 0x347, 0x037, 0x008, 0x000, 0x292,
> +    0x390, 0x044, 0x000, 0x3ca, 0x397, 0x003, 0x189, 0x395,
> +    0x105, 0x105, 0x247, 0x009, 0x000, 0x27f, 0x000, 0x27d,
> +    0x364, 0x004, 0x002, 0x009, 0x090, 0x364, 0x004, 0x008,
> +    0x009, 0x165, 0x364, 0x004, 0x004, 0x009, 0x08e, 0x0c0,
> +    0x007, 0x3d5, 0x080, 0x00e, 0x347, 0x006, 0x062, 0x0c0,
> +    0x064, 0x307, 0x062, 0x197, 0x384, 0x00f, 0x229, 0x220,
> +    0x3b0, 0x3ca, 0x287, 0x199, 0x390, 0x002, 0x041, 0x040,
> +    0x045, 0x345, 0x033, 0x064, 0x347, 0x064, 0x007, 0x344,
> +    0x035, 0x007, 0x3d4, 0x37f, 0x00e, 0x3c5, 0x020, 0x00e,
> +    0x04e, 0x047, 0x020, 0x3ff, 0x002, 0x020, 0x00a, 0x003,
> +    0x020, 0x011, 0x003, 0x020, 0x01a, 0x003, 0x020, 0x01d,
> +    0x003, 0x020, 0x020, 0x003, 0x020, 0x3fa, 0x002, 0x020,
> +    0x3fa, 0x002, 0x020, 0x3fa, 0x002, 0x020, 0x3fa, 0x002,
> +    0x020, 0x3fa, 0x002, 0x020, 0x3fa, 0x002, 0x020, 0x3fa,
> +    0x002, 0x020, 0x3fa, 0x002, 0x020, 0x3fa, 0x002, 0x020,
> +    0x3fa, 0x002, 0x345, 0x037, 0x064, 0x000, 0x3bf, 0x3b7,
> +    0x010, 0x1a7, 0x3a5, 0x013, 0x324, 0x038, 0x2c7, 0x064,
> +    0x000, 0x3b1, 0x3b7, 0x000, 0x1a7, 0x3a5, 0x001, 0x000,
> +    0x3f5, 0x088, 0x055, 0x247, 0x02c, 0x347, 0x062, 0x06e,
> +    0x000, 0x3ad, 0x089, 0x000, 0x3f7, 0x08a, 0x000, 0x3f4,
> +    0x08b, 0x000, 0x3f1, 0x055, 0x0c3, 0x02c, 0x3d5, 0x100,
> +    0x00e, 0x000, 0x39c, 0x347, 0x011, 0x066, 0x3c4, 0x3fc,
> +    0x066, 0x364, 0x065, 0x040, 0x009, 0x0a3, 0x044, 0x085,
> +    0x003, 0x001, 0x06f, 0x044, 0x06b, 0x003, 0x001, 0x005,
> +    0x055, 0x000, 0x384, 0x044, 0x074, 0x003, 0x3c4, 0x37f,
> +    0x065, 0x1b5, 0x3a4, 0x038, 0x3c4, 0x3c7, 0x065, 0x2c5,
> +    0x065, 0x1b2, 0x2e2, 0x007, 0x001, 0x047, 0x2e2, 0x006,
> +    0x001, 0x043, 0x2e2, 0x002, 0x001, 0x047, 0x2e2, 0x001,
> +    0x001, 0x031, 0x3d7, 0x07f, 0x064, 0x0a6, 0x044, 0x0bf,
> +    0x003, 0x000, 0x35c, 0x364, 0x010, 0x002, 0x009, 0x005,
> +    0x364, 0x011, 0x001, 0x045, 0x3d5, 0x040, 0x00e, 0x3c5,
> +    0x001, 0x010, 0x3c4, 0x3bf, 0x065, 0x327, 0x066, 0x00b,
> +    0x005, 0x3c5, 0x040, 0x065, 0x045, 0x327, 0x004, 0x307,
> +    0x066, 0x198, 0x384, 0x038, 0x1b8, 0x3a4, 0x038, 0x222,
> +    0x045, 0x3b7, 0x010, 0x1a7, 0x3a5, 0x013, 0x2c7, 0x064,
> +    0x0a7, 0x000, 0x3cd, 0x347, 0x066, 0x064, 0x044, 0x0cd,
> +    0x003, 0x000, 0x324, 0x055, 0x0c4, 0x02c, 0x000, 0x31f,
> +    0x044, 0x074, 0x003, 0x3c5, 0x080, 0x065, 0x3c4, 0x3f8,
> +    0x065, 0x3a4, 0x1fc, 0x081, 0x245, 0x065, 0x1b1, 0x390,
> +    0x066, 0x04d, 0x3c5, 0x100, 0x065, 0x000, 0x308, 0x3c4,
> +    0x07f, 0x064, 0x1c1, 0x064, 0x307, 0x066, 0x198, 0x384,
> +    0x038, 0x285, 0x188, 0x245, 0x064, 0x3c4, 0x003, 0x010,
> +    0x345, 0x064, 0x010, 0x3c5, 0x002, 0x010, 0x045, 0x044,
> +    0x085, 0x003, 0x009, 0x009, 0x307, 0x065, 0x364, 0x065,
> +    0x080, 0x009, 0x00c, 0x044, 0x06b, 0x003, 0x009, 0x35a,
> +    0x044, 0x074, 0x003, 0x000, 0x3b0, 0x044, 0x074, 0x003,
> +    0x384, 0x007, 0x262, 0x007, 0x001, 0x2d1, 0x141, 0x065,
> +    0x101, 0x324, 0x035, 0x000, 0x3bb, 0x3d5, 0x010, 0x00e,
> +    0x055, 0x0d3, 0x02c, 0x000, 0x2c2, 0x04e, 0x062, 0x0b1,
> +    0x0e7, 0x079
> +
> +};  /* end fm10000_sbus_master_code_prd */
> +
> +/* Spico SerDes code (production version 2)
> + *  source file:   serdes.0x2055/serdes.0x2055_0045.rom
> + *  KR support */
> +const uint32_t fm10000_serdes_spico_code_versionBuildId_prd2 =
> 0x20550045;
> +const uint32_t fm10000_serdes_spico_code_size_prd2           = 12167;
> +
> +const uint16_t fm10000_serdes_spico_code_prd2[] = {
> +    0x035, 0x006, 0x00a, 0x000, 0x1a7, 0x006, 0x020, 0x055,
> +    0x000, 0x045, 0x3c7, 0x03f, 0x000, 0x0c0, 0x200, 0x307,
> +    0x200, 0x304, 0x02b, 0x009, 0x00b, 0x0a0, 0x397, 0x3bb,
> +    0x04d, 0x111, 0x272, 0x1ff, 0x009, 0x3fc, 0x3c8, 0x000,
> +    0x21e, 0x3ce, 0x3ff, 0x21f, 0x348, 0x21f, 0x21d, 0x34e,
> +    0x21d, 0x221, 0x34e, 0x221, 0x21c, 0x34e, 0x21c, 0x220,
> +    0x3c7, 0x3fd, 0x23d, 0x3c7, 0x020, 0x23e, 0x3c7, 0x077,
> +    0x22d, 0x0c0, 0x202, 0x044, 0x36d, 0x003, 0x044, 0x360,
> +    0x002, 0x3d7, 0x303, 0x030, 0x347, 0x032, 0x236, 0x3b7,
> +    0x213, 0x090, 0x044, 0x1a9, 0x000, 0x3b7, 0x204, 0x387,
> +    0x07c, 0x044, 0x1a9, 0x000, 0x0a4, 0x397, 0x27c, 0x044,
> +    0x1a9, 0x000, 0x3d5, 0x230, 0x232, 0x345, 0x21d, 0x232,
> +    0x3b7, 0x221, 0x081, 0x18b, 0x044, 0x1b7, 0x000, 0x3b7,
> +    0x080, 0x044, 0x192, 0x000, 0x385, 0x00c, 0x384, 0x3cf,
> +    0x044, 0x1bd, 0x000, 0x3c5, 0x040, 0x021, 0x3b7, 0x020,
> +    0x387, 0x021, 0x189, 0x044, 0x1a9, 0x000, 0x0c0, 0x008,
> +    0x0c0, 0x005, 0x0c0, 0x00b, 0x0c0, 0x000, 0x3c5, 0x020,
> +    0x027, 0x055, 0x307, 0x221, 0x304, 0x233, 0x009, 0x012,
> +    0x374, 0x027, 0x200, 0x001, 0x00d, 0x044, 0x340, 0x001,
> +    0x264, 0x080, 0x009, 0x006, 0x3b8, 0x200, 0x2c4, 0x027,
> +    0x054, 0x364, 0x200, 0x004, 0x029, 0x3de, 0x003, 0x364,
> +    0x33b, 0x010, 0x029, 0x3de, 0x003, 0x054, 0x364, 0x200,
> +    0x040, 0x029, 0x034, 0x008, 0x364, 0x2cf, 0x040, 0x009,
> +    0x01c, 0x307, 0x026, 0x384, 0x003, 0x266, 0x003, 0x009,
> +    0x014, 0x362, 0x26b, 0x0e0, 0x009, 0x00f, 0x364, 0x234,
> +    0x002, 0x001, 0x00a, 0x3c5, 0x060, 0x2cf, 0x0c0, 0x26b,
> +    0x3c5, 0x040, 0x200, 0x054, 0x364, 0x200, 0x100, 0x029,
> +    0x22f, 0x003, 0x054, 0x044, 0x141, 0x001, 0x055, 0x364,
> +    0x23f, 0x003, 0x001, 0x012, 0x044, 0x34c, 0x001, 0x029,
> +    0x0af, 0x006, 0x044, 0x340, 0x001, 0x227, 0x326, 0x249,
> +    0x1ba, 0x029, 0x0af, 0x006, 0x3c4, 0x3df, 0x000, 0x364,
> +    0x33c, 0x020, 0x001, 0x017, 0x364, 0x059, 0x080, 0x001,
> +    0x012, 0x364, 0x24b, 0x080, 0x009, 0x00d, 0x364, 0x001,
> +    0x080, 0x009, 0x008, 0x3c5, 0x080, 0x24b, 0x044, 0x12d,
> +    0x005, 0x055, 0x364, 0x200, 0x080, 0x001, 0x00d, 0x3c4,
> +    0x3fd, 0x26f, 0x3c4, 0x3fe, 0x200, 0x366, 0x200, 0x080,
> +    0x001, 0x00f, 0x140, 0x200, 0x009, 0x365, 0x364, 0x23f,
> +    0x003, 0x009, 0x360, 0x04f, 0x04e, 0x000, 0x35c, 0x3c5,
> +    0x030, 0x000, 0x347, 0x244, 0x054, 0x374, 0x000, 0x2c0,
> +    0x009, 0x34c, 0x387, 0x0c1, 0x187, 0x245, 0x054, 0x04f,
> +    0x055, 0x141, 0x26c, 0x347, 0x245, 0x200, 0x347, 0x245,
> +    0x26d, 0x0c0, 0x245, 0x364, 0x026, 0x002, 0x001, 0x336,
> +    0x364, 0x020, 0x005, 0x009, 0x007, 0x0c2, 0x26f, 0x044,
> +    0x1b8, 0x001, 0x055, 0x364, 0x020, 0x005, 0x009, 0x326,
> +    0x362, 0x26b, 0x0e0, 0x009, 0x321, 0x364, 0x234, 0x002,
> +    0x001, 0x31c, 0x3c5, 0x060, 0x2cf, 0x3c5, 0x040, 0x200,
> +    0x000, 0x314, 0x044, 0x290, 0x001, 0x3c5, 0x080, 0x200,
> +    0x347, 0x2cf, 0x26b, 0x3c4, 0x0e0, 0x26b, 0x3c4, 0x3bf,
> +    0x2cf, 0x045, 0x387, 0x080, 0x020, 0x2f8, 0x001, 0x387,
> +    0x02f, 0x111, 0x009, 0x3ff, 0x045, 0x054, 0x111, 0x009,
> +    0x3fe, 0x045, 0x044, 0x1a0, 0x000, 0x307, 0x032, 0x054,
> +    0x045, 0x044, 0x1a0, 0x000, 0x307, 0x033, 0x054, 0x045,
> +    0x055, 0x2c7, 0x030, 0x364, 0x035, 0x001, 0x009, 0x3fd,
> +    0x045, 0x044, 0x1a0, 0x000, 0x305, 0x033, 0x000, 0x012,
> +    0x044, 0x1a0, 0x000, 0x306, 0x033, 0x000, 0x00b, 0x208,
> +    0x044, 0x1a0, 0x000, 0x304, 0x033, 0x055, 0x2c7, 0x030,
> +    0x247, 0x031, 0x345, 0x21d, 0x030, 0x140, 0x035, 0x009,
> +    0x3fe, 0x346, 0x21d, 0x030, 0x054, 0x045, 0x040, 0x140,
> +    0x036, 0x00b, 0x020, 0x044, 0x206, 0x000, 0x344, 0x21f,
> +    0x036, 0x3c4, 0x3ef, 0x036, 0x09f, 0x044, 0x189, 0x000,
> +    0x000, 0x010, 0x040, 0x140, 0x036, 0x003, 0x00c, 0x044,
> +    0x206, 0x000, 0x345, 0x21d, 0x036, 0x3c4, 0x3ef, 0x036,
> +    0x054, 0x327, 0x22b, 0x3a4, 0x003, 0x133, 0x009, 0x00e,
> +    0x0a1, 0x1aa, 0x2a8, 0x2c4, 0x021, 0x08f, 0x044, 0x189,
> +    0x000, 0x2a8, 0x2c5, 0x021, 0x042, 0x045, 0x055, 0x088,
> +    0x3c5, 0x010, 0x036, 0x000, 0x37e, 0x3c4, 0x3fe, 0x026,
> +    0x327, 0x22c, 0x3a4, 0x007, 0x2e6, 0x001, 0x001, 0x01b,
> +    0x044, 0x1e2, 0x000, 0x364, 0x234, 0x001, 0x009, 0x013,
> +    0x364, 0x33b, 0x007, 0x001, 0x00d, 0x044, 0x3b6, 0x003,
> +    0x364, 0x33c, 0x020, 0x009, 0x005, 0x044, 0x066, 0x004,
> +    0x054, 0x045, 0x364, 0x233, 0x002, 0x009, 0x00d, 0x347,
> +    0x271, 0x270, 0x044, 0x2f6, 0x002, 0x009, 0x005, 0x044,
> +    0x02b, 0x008, 0x374, 0x232, 0x200, 0x001, 0x0a5, 0x3d7,
> +    0x200, 0x27b, 0x044, 0x29c, 0x001, 0x044, 0x2f6, 0x002,
> +    0x009, 0x005, 0x044, 0x028, 0x008, 0x3b7, 0x221, 0x364,
> +    0x22b, 0x003, 0x009, 0x007, 0x083, 0x18b, 0x044, 0x1a9,
> +    0x000, 0x398, 0x200, 0x244, 0x232, 0x3b7, 0x221, 0x091,
> +    0x189, 0x385, 0x128, 0x044, 0x1a9, 0x000, 0x083, 0x044,
> +    0x1b7, 0x000, 0x3b7, 0x220, 0x044, 0x192, 0x000, 0x197,
> +    0x264, 0x007, 0x009, 0x005, 0x091, 0x000, 0x003, 0x081,
> +    0x3b7, 0x221, 0x189, 0x044, 0x1b7, 0x000, 0x364, 0x246,
> +    0x010, 0x009, 0x002, 0x3b7, 0x221, 0x081, 0x18d, 0x044,
> +    0x1a9, 0x000, 0x081, 0x189, 0x044, 0x1a9, 0x000, 0x387,
> +    0x2d7, 0x044, 0x1b8, 0x000, 0x364, 0x22b, 0x003, 0x009,
> +    0x009, 0x3b7, 0x221, 0x081, 0x18b, 0x044, 0x1b7, 0x000,
> +    0x364, 0x02b, 0x020, 0x009, 0x020, 0x0a3, 0x364, 0x22b,
> +    0x003, 0x001, 0x006, 0x044, 0x025, 0x008, 0x0a0, 0x307,
> +    0x251, 0x197, 0x384, 0x00f, 0x220, 0x001, 0x005, 0x044,
> +    0x182, 0x000, 0x327, 0x251, 0x3a4, 0x01f, 0x001, 0x005,
> +    0x044, 0x0d9, 0x001, 0x044, 0x1ce, 0x000, 0x364, 0x232,
> +    0x100, 0x001, 0x005, 0x044, 0x0a9, 0x001, 0x3c4, 0x3f0,
> +    0x22d, 0x3c5, 0x001, 0x026, 0x364, 0x026, 0x002, 0x001,
> +    0x1c5, 0x044, 0x283, 0x001, 0x3b7, 0x300, 0x387, 0x020,
> +    0x000, 0x2c1, 0x307, 0x036, 0x00b, 0x3ea, 0x044, 0x1ce,
> +    0x000, 0x000, 0x3e5, 0x387, 0x3ff, 0x327, 0x22c, 0x3a4,
> +    0x007, 0x131, 0x001, 0x01a, 0x3d5, 0x200, 0x232, 0x000,
> +    0x006, 0x080, 0x131, 0x001, 0x011, 0x3b7, 0x205, 0x044,
> +    0x1bd, 0x000, 0x3b7, 0x222, 0x044, 0x1bd, 0x000, 0x3b7,
> +    0x251, 0x044, 0x1bd, 0x000, 0x3b7, 0x214, 0x100, 0x009,
> +    0x00a, 0x044, 0x1bd, 0x000, 0x3c4, 0x37b, 0x021, 0x000,
> +    0x29e, 0x3c5, 0x084, 0x021, 0x000, 0x299, 0x364, 0x233,
> +    0x002, 0x009, 0x00d, 0x347, 0x272, 0x270, 0x044, 0x2f6,
> +    0x002, 0x009, 0x005, 0x044, 0x02e, 0x008, 0x307, 0x22d,
> +    0x384, 0x070, 0x386, 0x010, 0x001, 0x04a, 0x364, 0x02b,
> +    0x020, 0x009, 0x045, 0x3b7, 0x071, 0x387, 0x128, 0x044,
> +    0x1a9, 0x000, 0x387, 0x368, 0x044, 0x1b8, 0x000, 0x387,
> +    0x2d7, 0x044, 0x1b8, 0x000, 0x0a1, 0x307, 0x22b, 0x384,
> +    0x030, 0x001, 0x003, 0x0ac, 0x307, 0x256, 0x384, 0x01f,
> +    0x220, 0x001, 0x005, 0x044, 0x0de, 0x001, 0x080, 0x327,
> +    0x22b, 0x3a4, 0x030, 0x3a2, 0x030, 0x009, 0x00e, 0x0a1,
> +    0x1ab, 0x2a8, 0x2c4, 0x024, 0x08f, 0x044, 0x189, 0x000,
> +    0x2a8, 0x2c5, 0x024, 0x327, 0x256, 0x1b7, 0x3a4, 0x07f,
> +    0x220, 0x001, 0x005, 0x044, 0x0e2, 0x001, 0x044, 0x2f6,
> +    0x002, 0x009, 0x007, 0x0c0, 0x27b, 0x044, 0x29c, 0x001,
> +    0x044, 0x0e6, 0x001, 0x3c4, 0x30f, 0x22d, 0x044, 0x2f6,
> +    0x002, 0x009, 0x005, 0x044, 0x031, 0x008, 0x345, 0x21d,
> +    0x01c, 0x307, 0x21d, 0x304, 0x233, 0x001, 0x007, 0x3a7,
> +    0x071, 0x044, 0x1a9, 0x000, 0x3c5, 0x002, 0x026, 0x044,
> +    0x141, 0x001, 0x020, 0x283, 0x001, 0x055, 0x3c4, 0x3ef,
> +    0x027, 0x3c4, 0x3fd, 0x026, 0x364, 0x26f, 0x002, 0x001,
> +    0x008, 0x3c4, 0x3fd, 0x26f, 0x044, 0x290, 0x001, 0x344,
> +    0x21f, 0x01c, 0x3c4, 0x3bf, 0x200, 0x3c4, 0x39f, 0x2cf,
> +    0x0c0, 0x2d8, 0x0c0, 0x26b, 0x364, 0x234, 0x002, 0x009,
> +    0x012, 0x364, 0x33b, 0x007, 0x001, 0x00d, 0x044, 0x066,
> +    0x004, 0x364, 0x33c, 0x020, 0x009, 0x005, 0x044, 0x3b6,
> +    0x003, 0x054, 0x0a0, 0x081, 0x189, 0x020, 0x1a9, 0x000,
> +    0x044, 0x3fd, 0x000, 0x387, 0x3ff, 0x044, 0x02b, 0x001,
> +    0x3a7, 0x022, 0x020, 0x1bd, 0x000, 0x0a0, 0x081, 0x189,
> +    0x020, 0x1a9, 0x000, 0x080, 0x044, 0x02b, 0x001, 0x3b7,
> +    0x300, 0x387, 0x020, 0x044, 0x1a9, 0x000, 0x364, 0x024,
> +    0x002, 0x001, 0x006, 0x399, 0x305, 0x000, 0x004, 0x397,
> +    0x200, 0x044, 0x322, 0x001, 0x3a7, 0x022, 0x044, 0x1bd,
> +    0x000, 0x364, 0x232, 0x002, 0x001, 0x005, 0x044, 0x382,
> +    0x001, 0x000, 0x0c9, 0x3a7, 0x061, 0x044, 0x1bd, 0x000,
> +    0x0a5, 0x044, 0x1bd, 0x000, 0x3a7, 0x072, 0x044, 0x1bd,
> +    0x000, 0x3a7, 0x0f1, 0x044, 0x1bd, 0x000, 0x385, 0x004,
> +    0x0b1, 0x020, 0x1bd, 0x000, 0x364, 0x22c, 0x002, 0x009,
> +    0x2ac, 0x364, 0x234, 0x001, 0x001, 0x058, 0x020, 0x232,
> +    0x000, 0x3c4, 0x3fe, 0x027, 0x364, 0x234, 0x002, 0x001,
> +    0x04d, 0x000, 0x2cd, 0x3b7, 0x211, 0x044, 0x199, 0x000,
> +    0x384, 0x00f, 0x140, 0x239, 0x00b, 0x004, 0x385, 0x010,
> +    0x140, 0x237, 0x00b, 0x004, 0x385, 0x020, 0x044, 0x1bd,
> +    0x000, 0x307, 0x239, 0x00b, 0x004, 0x208, 0x101, 0x384,
> +    0x01f, 0x183, 0x327, 0x237, 0x00b, 0x004, 0x2a8, 0x121,
> +    0x3a4, 0x00f, 0x285, 0x184, 0x3c4, 0x01f, 0x238, 0x362,
> +    0x238, 0x017, 0x00b, 0x005, 0x0a1, 0x1ad, 0x285, 0x305,
> +    0x238, 0x32a, 0x238, 0x3a4, 0x008, 0x285, 0x3b7, 0x210,
> +    0x044, 0x1bd, 0x000, 0x347, 0x237, 0x23a, 0x347, 0x238,
> +    0x23c, 0x347, 0x239, 0x23b, 0x045, 0x345, 0x21c, 0x021,
> +    0x045, 0x308, 0x21c, 0x244, 0x021, 0x0c0, 0x240, 0x307,
> +    0x022, 0x384, 0x001, 0x245, 0x240, 0x142, 0x240, 0x364,
> +    0x240, 0x100, 0x009, 0x3eb, 0x0a1, 0x044, 0x0d9, 0x001,
> +    0x307, 0x240, 0x327, 0x022, 0x286, 0x384, 0x001, 0x001,
> +    0x3ee, 0x0a2, 0x307, 0x22b, 0x384, 0x003, 0x001, 0x008,
> +    0x0aa, 0x262, 0x003, 0x001, 0x003, 0x0a5, 0x289, 0x240,
> +    0x240, 0x387, 0x084, 0x020, 0x2f8, 0x001, 0x094, 0x020,
> +    0x2f2, 0x001, 0x090, 0x020, 0x2f2, 0x001, 0x0a0, 0x082,
> +    0x18b, 0x304, 0x020, 0x009, 0x3b9, 0x081, 0x189, 0x020,
> +    0x1b7, 0x000, 0x0a1, 0x1a9, 0x364, 0x234, 0x002, 0x001,
> +    0x018, 0x364, 0x22c, 0x020, 0x001, 0x016, 0x364, 0x22c,
> +    0x010, 0x001, 0x009, 0x364, 0x232, 0x080, 0x001, 0x00c,
> +    0x000, 0x007, 0x364, 0x232, 0x040, 0x001, 0x005, 0x2c5,
> +    0x024, 0x045, 0x309, 0x024, 0x003, 0x3fb, 0x2a8, 0x2c4,
> +    0x024, 0x045, 0x3b7, 0x213, 0x364, 0x234, 0x004, 0x009,
> +    0x017, 0x307, 0x233, 0x182, 0x00a, 0x007, 0x3c5, 0x040,
> +    0x021, 0x000, 0x005, 0x3c4, 0x3bf, 0x021, 0x082, 0x044,
> +    0x1b7, 0x000, 0x088, 0x020, 0x1a9, 0x000, 0x082, 0x044,
> +    0x1a9, 0x000, 0x3c4, 0x3bf, 0x021, 0x088, 0x020, 0x1b7,
> +    0x000, 0x055, 0x364, 0x026, 0x002, 0x001, 0x031, 0x364,
> +    0x024, 0x002, 0x009, 0x007, 0x364, 0x025, 0x004, 0x009,
> +    0x027, 0x309, 0x01c, 0x003, 0x004, 0x00a, 0x021, 0x364,
> +    0x2cf, 0x011, 0x009, 0x01c, 0x364, 0x33b, 0x007, 0x001,
> +    0x007, 0x364, 0x33b, 0x002, 0x001, 0x012, 0x3c5, 0x010,
> +    0x027, 0x364, 0x234, 0x040, 0x001, 0x005, 0x3c4, 0x37f,
> +    0x024, 0x3c5, 0x008, 0x025, 0x000, 0x010, 0x364, 0x234,
> +    0x040, 0x001, 0x005, 0x3c5, 0x080, 0x024, 0x3c4, 0x3ef,
> +    0x027, 0x3c5, 0x010, 0x026, 0x054, 0x045, 0x364, 0x026,
> +    0x001, 0x001, 0x008, 0x3c5, 0x004, 0x232, 0x044, 0x20d,
> +    0x000, 0x09f, 0x18a, 0x208, 0x244, 0x243, 0x244, 0x250,
> +    0x327, 0x243, 0x326, 0x250, 0x001, 0x308, 0x347, 0x243,
> +    0x250, 0x087, 0x187, 0x208, 0x244, 0x020, 0x364, 0x026,
> +    0x002, 0x001, 0x2fb, 0x3c5, 0x008, 0x232, 0x020, 0x3b5,
> +    0x000, 0x364, 0x233, 0x008, 0x001, 0x004, 0x307, 0x220,
> +    0x3c5, 0x001, 0x00c, 0x247, 0x01b, 0x083, 0x18d, 0x244,
> +    0x01c, 0x044, 0x1c9, 0x001, 0x0a3, 0x1a8, 0x2c5, 0x01f,
> +    0x045, 0x3c4, 0x0ff, 0x01f, 0x085, 0x044, 0x189, 0x000,
> +    0x3d5, 0x100, 0x01f, 0x3b7, 0x300, 0x397, 0x200, 0x044,
> +    0x1a9, 0x000, 0x3c7, 0x07f, 0x252, 0x055, 0x151, 0x252,
> +    0x001, 0x006, 0x140, 0x01e, 0x00b, 0x3fa, 0x397, 0x200,
> +    0x044, 0x1b7, 0x000, 0x3c4, 0x2ff, 0x01f, 0x045, 0x327,
> +    0x22c, 0x307, 0x22d, 0x2e4, 0x004, 0x009, 0x00d, 0x286,
> +    0x384, 0x007, 0x001, 0x00f, 0x2e4, 0x007, 0x001, 0x032,
> +    0x000, 0x039, 0x384, 0x007, 0x3c4, 0x3f8, 0x22c, 0x245,
> +    0x22c, 0x327, 0x22c, 0x307, 0x22d, 0x2e4, 0x040, 0x009,
> +    0x016, 0x286, 0x264, 0x070, 0x001, 0x018, 0x3a4, 0x070,
> +    0x001, 0x029, 0x1aa, 0x002, 0x02e, 0x044, 0x3b5, 0x000,
> +    0x044, 0x3fd, 0x000, 0x000, 0x009, 0x384, 0x070, 0x3c4,
> +    0x38f, 0x22c, 0x245, 0x22c, 0x347, 0x22c, 0x22d, 0x045,
> +    0x227, 0x044, 0x301, 0x000, 0x044, 0x232, 0x000, 0x000,
> +    0x3d2, 0x044, 0x20d, 0x000, 0x044, 0x2f3, 0x000, 0x000,
> +    0x3ca, 0x044, 0x003, 0x001, 0x044, 0x326, 0x000, 0x000,
> +    0x3e5, 0x044, 0x0f2, 0x001, 0x044, 0x3b5, 0x000, 0x044,
> +    0x3f0, 0x000, 0x000, 0x3da, 0x3a7, 0x080, 0x384, 0x001,
> +    0x001, 0x011, 0x082, 0x044, 0x1a9, 0x000, 0x081, 0x044,
> +    0x1b7, 0x000, 0x3c5, 0x004, 0x024, 0x3c5, 0x008, 0x025,
> +    0x045, 0x366, 0x22e, 0x020, 0x001, 0x010, 0x082, 0x044,
> +    0x1b7, 0x000, 0x081, 0x044, 0x1a9, 0x000, 0x3c4, 0x3fb,
> +    0x024, 0x3c4, 0x3f7, 0x025, 0x045, 0x308, 0x248, 0x19e,
> +    0x020, 0x254, 0x001, 0x307, 0x020, 0x384, 0x070, 0x266,
> +    0x010, 0x001, 0x007, 0x0c2, 0x26f, 0x020, 0x1b6, 0x001,
> +    0x3c5, 0x001, 0x00c, 0x0c0, 0x01b, 0x044, 0x1c9, 0x001,
> +    0x3c4, 0x3fe, 0x00c, 0x045, 0x0a1, 0x325, 0x27b, 0x044,
> +    0x192, 0x000, 0x247, 0x24f, 0x397, 0x3e0, 0x044, 0x1a9,
> +    0x000, 0x0a0, 0x325, 0x27b, 0x387, 0x140, 0x044, 0x1a9,
> +    0x000, 0x044, 0x187, 0x000, 0x084, 0x044, 0x1a9, 0x000,
> +    0x044, 0x187, 0x000, 0x387, 0x040, 0x044, 0x1b7, 0x000,
> +    0x387, 0x106, 0x044, 0x189, 0x000, 0x387, 0x100, 0x044,
> +    0x1b7, 0x000, 0x387, 0x099, 0x044, 0x189, 0x000, 0x0a1,
> +    0x325, 0x27b, 0x307, 0x24f, 0x044, 0x1bd, 0x000, 0x0a0,
> +    0x325, 0x27b, 0x084, 0x044, 0x1b7, 0x000, 0x387, 0x099,
> +    0x044, 0x2f6, 0x002, 0x009, 0x004, 0x399, 0x3ff, 0x020,
> +    0x189, 0x000, 0x041, 0x327, 0x236, 0x3a4, 0x00c, 0x134,
> +    0x043, 0x045, 0x055, 0x3d7, 0x071, 0x030, 0x000, 0x006,
> +    0x055, 0x3d7, 0x221, 0x030, 0x347, 0x034, 0x258, 0x0c0,
> +    0x034, 0x140, 0x035, 0x009, 0x3fe, 0x347, 0x032, 0x031,
> +    0x345, 0x21d, 0x030, 0x246, 0x031, 0x374, 0x030, 0x200,
> +    0x001, 0x007, 0x246, 0x031, 0x044, 0x18c, 0x000, 0x131,
> +    0x009, 0x3f3, 0x346, 0x21d, 0x030, 0x347, 0x258, 0x034,
> +    0x054, 0x045, 0x364, 0x233, 0x040, 0x001, 0x006, 0x3b7,
> +    0x200, 0x2a8, 0x284, 0x045, 0x227, 0x055, 0x040, 0x397,
> +    0x203, 0x300, 0x202, 0x04d, 0x141, 0x202, 0x362, 0x202,
> +    0x018, 0x009, 0x004, 0x0c0, 0x202, 0x042, 0x054, 0x045,
> +    0x055, 0x3c7, 0x0f2, 0x030, 0x364, 0x035, 0x001, 0x009,
> +    0x3fd, 0x307, 0x032, 0x045, 0x0a1, 0x1aa, 0x324, 0x233,
> +    0x045, 0x327, 0x222, 0x3a4, 0x07f, 0x001, 0x02c, 0x055,
> +    0x307, 0x034, 0x0c0, 0x034, 0x040, 0x140, 0x035, 0x009,
> +    0x3fe, 0x3c7, 0x071, 0x030, 0x387, 0x0d7, 0x347, 0x032,
> +    0x031, 0x345, 0x21d, 0x030, 0x141, 0x23d, 0x009, 0x007,
> +    0x153, 0x23d, 0x346, 0x21c, 0x031, 0x246, 0x031, 0x131,
> +    0x009, 0x3f4, 0x346, 0x21d, 0x030, 0x042, 0x247, 0x034,
> +    0x054, 0x045, 0x083, 0x18d, 0x345, 0x21d, 0x233, 0x364,
> +    0x2cf, 0x004, 0x001, 0x005, 0x245, 0x305, 0x045, 0x3a7,
> +    0x071, 0x020, 0x1a9, 0x000, 0x083, 0x18d, 0x364, 0x2cf,
> +    0x004, 0x001, 0x006, 0x208, 0x244, 0x305, 0x045, 0x328,
> +    0x21d, 0x2c4, 0x233, 0x3a7, 0x071, 0x020, 0x1b7, 0x000,
> +    0x120, 0x001, 0x027, 0x041, 0x2f4, 0x200, 0x001, 0x00a,
> +    0x3a7, 0x073, 0x082, 0x044, 0x1a9, 0x000, 0x000, 0x009,
> +    0x3a7, 0x073, 0x387, 0x3fd, 0x044, 0x1b8, 0x000, 0x043,
> +    0x2e4, 0x180, 0x001, 0x016, 0x2e4, 0x080, 0x009, 0x017,
> +    0x3c5, 0x002, 0x232, 0x044, 0x382, 0x001, 0x000, 0x012,
> +    0x3c4, 0x3fd, 0x232, 0x044, 0x394, 0x001, 0x000, 0x00a,
> +    0x044, 0x353, 0x001, 0x000, 0x005, 0x081, 0x043, 0x040,
> +    0x020, 0x181, 0x006, 0x3c4, 0x3fe, 0x03a, 0x247, 0x25e,
> +    0x0c5, 0x263, 0x264, 0x100, 0x001, 0x004, 0x148, 0x263,
> +    0x3c4, 0x3bf, 0x00c, 0x384, 0x003, 0x187, 0x247, 0x03a,
> +    0x3c5, 0x040, 0x00c, 0x042, 0x247, 0x25d, 0x043, 0x042,
> +    0x100, 0x00b, 0x008, 0x247, 0x03c, 0x042, 0x247, 0x03b,
> +    0x042, 0x247, 0x039, 0x042, 0x247, 0x038, 0x142, 0x03a,
> +    0x041, 0x307, 0x25d, 0x040, 0x152, 0x03a, 0x345, 0x263,
> +    0x03a, 0x045, 0x3c4, 0x3fe, 0x03d, 0x247, 0x25f, 0x0c5,
> +    0x263, 0x264, 0x100, 0x001, 0x004, 0x148, 0x263, 0x3c4,
> +    0x37f, 0x00c, 0x384, 0x003, 0x187, 0x247, 0x03d, 0x3c5,
> +    0x080, 0x00c, 0x042, 0x247, 0x25d, 0x043, 0x042, 0x100,
> +    0x00b, 0x008, 0x247, 0x03f, 0x042, 0x247, 0x03e, 0x042,
> +    0x247, 0x039, 0x042, 0x247, 0x038, 0x142, 0x03d, 0x041,
> +    0x307, 0x25d, 0x040, 0x152, 0x03d, 0x345, 0x263, 0x03d,
> +    0x045, 0x3c4, 0x3fe, 0x040, 0x0c1, 0x041, 0x3c4, 0x3cf,
> +    0x00c, 0x151, 0x041, 0x0c0, 0x263, 0x247, 0x262, 0x0c0,
> +    0x040, 0x384, 0x003, 0x227, 0x1a0, 0x285, 0x384, 0x3fd,
> +    0x187, 0x245, 0x040, 0x245, 0x041, 0x245, 0x263, 0x3c5,
> +    0x030, 0x00c, 0x3c7, 0x3ff, 0x039, 0x142, 0x040, 0x152,
> +    0x040, 0x144, 0x040, 0x364, 0x262, 0x100, 0x001, 0x004,
> +    0x148, 0x040, 0x042, 0x043, 0x247, 0x261, 0x2c7, 0x260,
> +    0x044, 0x0de, 0x002, 0x0a3, 0x1ab, 0x2a8, 0x2c4, 0x04a,
> +    0x307, 0x262, 0x384, 0x030, 0x187, 0x245, 0x04a, 0x0a1,
> +    0x307, 0x262, 0x384, 0x030, 0x193, 0x262, 0x000, 0x001,
> +    0x008, 0x262, 0x001, 0x001, 0x007, 0x000, 0x006, 0x0a0,
> +    0x000, 0x003, 0x0a2, 0x1ad, 0x2c5, 0x263, 0x0a3, 0x307,
> +    0x262, 0x384, 0x00c, 0x191, 0x262, 0x001, 0x001, 0x008,
> +    0x262, 0x002, 0x001, 0x007, 0x000, 0x006, 0x0a1, 0x000,
> +    0x003, 0x0a2, 0x1a5, 0x2c5, 0x263, 0x374, 0x262, 0x200,
> +    0x001, 0x00e, 0x307, 0x261, 0x327, 0x260, 0x041, 0x040,
> +    0x347, 0x263, 0x041, 0x141, 0x040, 0x045, 0x347, 0x263,
> +    0x041, 0x141, 0x040, 0x020, 0x089, 0x000, 0x042, 0x043,
> +    0x247, 0x25c, 0x042, 0x264, 0x3ff, 0x00b, 0x008, 0x247,
> +    0x043, 0x042, 0x247, 0x042, 0x042, 0x247, 0x039, 0x042,
> +    0x247, 0x038, 0x142, 0x040, 0x152, 0x040, 0x307, 0x25c,
> +    0x041, 0x040, 0x045, 0x055, 0x140, 0x259, 0x001, 0x009,
> +    0x322, 0x259, 0x001, 0x007, 0x0a1, 0x054, 0x045, 0x2c7,
> +    0x259, 0x264, 0x008, 0x009, 0x06e, 0x0c0, 0x012, 0x043,
> +    0x2c7, 0x25a, 0x043, 0x2c7, 0x25b, 0x227, 0x274, 0x200,
> +    0x009, 0x022, 0x3a4, 0x006, 0x2c7, 0x00d, 0x227, 0x3c4,
> +    0x3fd, 0x00c, 0x3c4, 0x3fc, 0x018, 0x384, 0x001, 0x245,
> +    0x018, 0x142, 0x00c, 0x042, 0x247, 0x014, 0x042, 0x247,
> +    0x013, 0x120, 0x00b, 0x008, 0x042, 0x247, 0x011, 0x042,
> +    0x247, 0x010, 0x3c7, 0x050, 0x26e, 0x142, 0x012, 0x141,
> +    0x00d, 0x080, 0x2e4, 0x100, 0x001, 0x003, 0x108, 0x151,
> +    0x26e, 0x001, 0x007, 0x364, 0x012, 0x040, 0x009, 0x3f9,
> +    0x152, 0x012, 0x151, 0x00d, 0x2e4, 0x080, 0x001, 0x003,
> +    0x104, 0x245, 0x012, 0x307, 0x25b, 0x040, 0x307, 0x25a,
> +    0x040, 0x2a9, 0x003, 0x017, 0x151, 0x26e, 0x003, 0x007,
> +    0x364, 0x012, 0x080, 0x009, 0x3f9, 0x364, 0x026, 0x002,
> +    0x001, 0x007, 0x364, 0x025, 0x004, 0x009, 0x007, 0x141,
> +    0x012, 0x0a0, 0x054, 0x045, 0x364, 0x2cf, 0x007, 0x001,
> +    0x3f8, 0x3c4, 0x3fc, 0x2cf, 0x3d5, 0x200, 0x2cf, 0x020,
> +    0x33a, 0x002, 0x247, 0x017, 0x287, 0x00b, 0x006, 0x3a7,
> +    0x3ff, 0x000, 0x003, 0x1bb, 0x384, 0x0ff, 0x264, 0x080,
> +    0x001, 0x004, 0x385, 0x300, 0x380, 0x011, 0x00b, 0x018,
> +    0x041, 0x0a0, 0x131, 0x380, 0x014, 0x003, 0x3fd, 0x041,
> +    0x0bf, 0x1a6, 0x2a8, 0x2c4, 0x018, 0x186, 0x245, 0x018,
> +    0x083, 0x18d, 0x245, 0x017, 0x042, 0x043, 0x103, 0x121,
> +    0x18a, 0x1a7, 0x285, 0x247, 0x01a, 0x387, 0x3ff, 0x247,
> +    0x019, 0x18b, 0x245, 0x018, 0x307, 0x017, 0x19d, 0x262,
> +    0x003, 0x001, 0x00e, 0x262, 0x001, 0x001, 0x013, 0x262,
> +    0x002, 0x009, 0x037, 0x3a7, 0x0aa, 0x000, 0x00d, 0x0c1,
> +    0x019, 0x08f, 0x18b, 0x208, 0x244, 0x018, 0x000, 0x039,
> +    0x3a7, 0x055, 0x041, 0x3a7, 0x071, 0x044, 0x192, 0x000,
> +    0x00b, 0x010, 0x040, 0x3a7, 0x0f2, 0x044, 0x192, 0x000,
> +    0x198, 0x043, 0x3a4, 0x001, 0x009, 0x004, 0x386, 0x001,
> +    0x043, 0x264, 0x001, 0x001, 0x004, 0x3a6, 0x0ff, 0x287,
> +    0x187, 0x285, 0x247, 0x019, 0x18b, 0x103, 0x244, 0x018,
> +    0x364, 0x24d, 0x030, 0x009, 0x00c, 0x08f, 0x18b, 0x208,
> +    0x244, 0x018, 0x397, 0x1fe, 0x182, 0x244, 0x019, 0x327,
> +    0x017, 0x1ba, 0x3a4, 0x007, 0x001, 0x019, 0x2e2, 0x003,
> +    0x001, 0x015, 0x041, 0x3a7, 0x060, 0x044, 0x192, 0x000,
> +    0x043, 0x384, 0x008, 0x001, 0x00a, 0x2e2, 0x003, 0x003,
> +    0x004, 0x3a6, 0x002, 0x3a6, 0x001, 0x387, 0x002, 0x189,
> +    0x395, 0x23f, 0x280, 0x050, 0x245, 0x01a, 0x045, 0x0ff,
> +    0x00c, 0x030, 0x03c, 0x00f, 0x0f0, 0x004, 0x020, 0x307,
> +    0x26f, 0x384, 0x003, 0x229, 0x220, 0x3b0, 0x04b, 0x287,
> +    0x199, 0x390, 0x008, 0x041, 0x040, 0x045, 0x055, 0x329,
> +    0x01f, 0x00b, 0x08b, 0x364, 0x234, 0x080, 0x001, 0x00e,
> +    0x364, 0x024, 0x002, 0x009, 0x009, 0x364, 0x025, 0x004,
> +    0x001, 0x004, 0x000, 0x012, 0x327, 0x01d, 0x009, 0x00a,
> +    0x081, 0x18d, 0x245, 0x020, 0x327, 0x01d, 0x246, 0x020,
> +    0x3a2, 0x020, 0x003, 0x02b, 0x309, 0x01c, 0x003, 0x022,
> +    0x3c4, 0x3ef, 0x027, 0x3c5, 0x010, 0x026, 0x0a0, 0x387,
> +    0x3df, 0x044, 0x1b8, 0x000, 0x081, 0x189, 0x044, 0x1a9,
> +    0x000, 0x140, 0x01c, 0x00b, 0x00d, 0x0a1, 0x044, 0x192,
> +    0x000, 0x247, 0x27f, 0x395, 0x3ff, 0x044, 0x1bd, 0x000,
> +    0x344, 0x21f, 0x01c, 0x000, 0x02a, 0x307, 0x01c, 0x003,
> +    0x026, 0x345, 0x21d, 0x01c, 0x209, 0x003, 0x020, 0x307,
> +    0x020, 0x181, 0x003, 0x01b, 0x364, 0x025, 0x004, 0x009,
> +    0x005, 0x3c5, 0x008, 0x025, 0x0a0, 0x081, 0x189, 0x044,
> +    0x1b7, 0x000, 0x387, 0x020, 0x044, 0x1a9, 0x000, 0x0a1,
> +    0x307, 0x27f, 0x044, 0x1bd, 0x000, 0x055, 0x364, 0x234,
> +    0x002, 0x001, 0x00f, 0x307, 0x020, 0x384, 0x070, 0x266,
> +    0x010, 0x001, 0x007, 0x0c2, 0x26f, 0x044, 0x1b6, 0x001,
> +    0x054, 0x020, 0x0a3, 0x006, 0x346, 0x21d, 0x232, 0x02b,
> +    0x181, 0x006, 0x364, 0x233, 0x001, 0x021, 0x08d, 0x006,
> +    0x3c4, 0x3fe, 0x233, 0x020, 0x0f4, 0x000, 0x327, 0x21d,
> +    0x324, 0x020, 0x045, 0x307, 0x28d, 0x384, 0x07f, 0x22a,
> +    0x286, 0x040, 0x0b0, 0x044, 0x192, 0x000, 0x384, 0x380,
> +    0x043, 0x285, 0x0b0, 0x020, 0x1bd, 0x000, 0x0a2, 0x141,
> +    0x041, 0x141, 0x2f1, 0x397, 0x200, 0x151, 0x041, 0x044,
> +    0x0fb, 0x002, 0x055, 0x364, 0x200, 0x080, 0x009, 0x00e,
> +    0x364, 0x234, 0x002, 0x001, 0x009, 0x054, 0x364, 0x012,
> +    0x040, 0x001, 0x3f1, 0x045, 0x364, 0x2cf, 0x007, 0x009,
> +    0x3fc, 0x044, 0x33f, 0x002, 0x3c4, 0x080, 0x2cf, 0x3c4,
> +    0x2bf, 0x200, 0x080, 0x046, 0x020, 0x0d3, 0x000, 0x0c0,
> +    0x013, 0x0c0, 0x014, 0x0c0, 0x259, 0x045, 0x088, 0x0a2,
> +    0x044, 0x0fb, 0x002, 0x364, 0x259, 0x002, 0x009, 0x007,
> +    0x042, 0x042, 0x020, 0x0d3, 0x000, 0x387, 0x085, 0x187,
> +    0x385, 0x080, 0x247, 0x041, 0x3c5, 0x020, 0x00c, 0x045,
> +    0x387, 0x07f, 0x247, 0x2a1, 0x247, 0x2a2, 0x247, 0x2a3,
> +    0x247, 0x2a4, 0x247, 0x2a7, 0x247, 0x2a8, 0x247, 0x2a5,
> +    0x247, 0x2a6, 0x044, 0x150, 0x003, 0x0c3, 0x2e0, 0x364,
> +    0x02b, 0x010, 0x009, 0x011, 0x044, 0x38c, 0x002, 0x044,
> +    0x39f, 0x002, 0x347, 0x290, 0x2c6, 0x347, 0x28f, 0x2c5,
> +    0x347, 0x28e, 0x2c4, 0x045, 0x0c0, 0x2ce, 0x0c8, 0x2d5,
> +    0x0cf, 0x2ca, 0x0c1, 0x2c7, 0x0c1, 0x2c8, 0x0c5, 0x2cc,
> +    0x0cf, 0x2d1, 0x0c0, 0x2d2, 0x0dd, 0x2cd, 0x045, 0x0c0,
> +    0x2d8, 0x044, 0x3b3, 0x002, 0x3c7, 0x038, 0x290, 0x0cc,
> +    0x28f, 0x0c0, 0x28e, 0x0cd, 0x291, 0x044, 0x034, 0x003,
> +    0x020, 0x06e, 0x003, 0x364, 0x02b, 0x010, 0x009, 0x013,
> +    0x0ca, 0x293, 0x0a0, 0x397, 0x294, 0x04d, 0x101, 0x272,
> +    0x2a0, 0x009, 0x3fc, 0x044, 0x06e, 0x003, 0x044, 0x096,
> +    0x003, 0x090, 0x3a7, 0x022, 0x044, 0x1a9, 0x000, 0x347,
> +    0x2aa, 0x2a1, 0x347, 0x2ab, 0x2a2, 0x347, 0x2ac, 0x2a3,
> +    0x347, 0x2ad, 0x2a4, 0x020, 0x3f0, 0x002, 0x044, 0x034,
> +    0x003, 0x020, 0x096, 0x003, 0x3a7, 0x020, 0x084, 0x020,
> +    0x1b7, 0x000, 0x3a7, 0x020, 0x084, 0x020, 0x1a9, 0x000,
> +    0x307, 0x2a1, 0x187, 0x327, 0x2a3, 0x00b, 0x004, 0x141,
> +    0x2e5, 0x3a4, 0x0ff, 0x285, 0x208, 0x3a7, 0x024, 0x044,
> +    0x1bd, 0x000, 0x307, 0x2a2, 0x187, 0x327, 0x2a4, 0x00b,
> +    0x004, 0x141, 0x2e5, 0x3a4, 0x0ff, 0x285, 0x208, 0x3a7,
> +    0x026, 0x044, 0x1bd, 0x000, 0x307, 0x2a7, 0x187, 0x327,
> +    0x2a5, 0x3a4, 0x0ff, 0x285, 0x208, 0x3a7, 0x025, 0x044,
> +    0x1bd, 0x000, 0x307, 0x2a8, 0x187, 0x327, 0x2a6, 0x3a4,
> +    0x0ff, 0x285, 0x208, 0x3a7, 0x027, 0x020, 0x1bd, 0x000,
> +    0x0c0, 0x28f, 0x000, 0x00d, 0x140, 0x28f, 0x003, 0x3fa,
> +    0x362, 0x28f, 0x00f, 0x00b, 0x004, 0x0cf, 0x28f, 0x140,
> +    0x28e, 0x003, 0x00b, 0x362, 0x28e, 0x00f, 0x00b, 0x008,
> +    0x0cf, 0x28e, 0x000, 0x004, 0x0c0, 0x28e, 0x307, 0x28f,
> +    0x183, 0x305, 0x28e, 0x22a, 0x3a4, 0x3f7, 0x286, 0x327,
> +    0x290, 0x1a7, 0x285, 0x3a7, 0x02b, 0x044, 0x1bd, 0x000,
> +    0x044, 0x2f6, 0x002, 0x009, 0x005, 0x0c2, 0x2fa, 0x045,
> +    0x045, 0x347, 0x2ca, 0x293, 0x000, 0x011, 0x307, 0x2ca,
> +    0x302, 0x293, 0x003, 0x3f7, 0x327, 0x2c9, 0x322, 0x293,
> +    0x003, 0x005, 0x347, 0x2c9, 0x293, 0x307, 0x291, 0x044,
> +    0x106, 0x003, 0x0a1, 0x364, 0x236, 0x100, 0x009, 0x003,
> +    0x0a5, 0x1a3, 0x285, 0x183, 0x305, 0x292, 0x183, 0x305,
> +    0x293, 0x3a7, 0x02c, 0x020, 0x1bd, 0x000, 0x307, 0x296,
> +    0x044, 0x106, 0x003, 0x040, 0x307, 0x295, 0x044, 0x106,
> +    0x003, 0x040, 0x307, 0x294, 0x044, 0x106, 0x003, 0x184,
> +    0x043, 0x285, 0x184, 0x043, 0x285, 0x3a7, 0x028, 0x044,
> +    0x1bd, 0x000, 0x307, 0x299, 0x044, 0x106, 0x003, 0x040,
> +    0x307, 0x298, 0x044, 0x106, 0x003, 0x040, 0x307, 0x297,
> +    0x044, 0x106, 0x003, 0x184, 0x043, 0x285, 0x184, 0x043,
> +    0x285, 0x3a7, 0x029, 0x044, 0x1bd, 0x000, 0x307, 0x29f,
> +    0x044, 0x106, 0x003, 0x040, 0x307, 0x29e, 0x044, 0x106,
> +    0x003, 0x040, 0x307, 0x29d, 0x044, 0x106, 0x003, 0x184,
> +    0x043, 0x285, 0x184, 0x043, 0x285, 0x3a7, 0x031, 0x044,
> +    0x1bd, 0x000, 0x307, 0x29c, 0x044, 0x106, 0x003, 0x040,
> +    0x307, 0x29b, 0x044, 0x106, 0x003, 0x040, 0x307, 0x29a,
> +    0x044, 0x106, 0x003, 0x184, 0x043, 0x285, 0x184, 0x043,
> +    0x285, 0x3a7, 0x02a, 0x020, 0x1bd, 0x000, 0x100, 0x003,
> +    0x005, 0x22a, 0x286, 0x045, 0x228, 0x121, 0x28a, 0x286,
> +    0x385, 0x010, 0x045, 0x083, 0x182, 0x0a1, 0x182, 0x385,
> +    0x001, 0x181, 0x285, 0x181, 0x385, 0x002, 0x181, 0x285,
> +    0x3a7, 0x030, 0x020, 0x1bd, 0x000, 0x044, 0x15b, 0x003,
> +    0x382, 0x081, 0x240, 0x2a5, 0x240, 0x2a6, 0x044, 0x134,
> +    0x003, 0x020, 0x3f0, 0x002, 0x364, 0x2a5, 0x300, 0x001,
> +    0x007, 0x003, 0x010, 0x3c7, 0x0ff, 0x2a5, 0x364, 0x2a6,
> +    0x300, 0x001, 0x007, 0x003, 0x00a, 0x3c7, 0x0ff, 0x2a6,
> +    0x045, 0x0c0, 0x2a5, 0x000, 0x3f3, 0x0c0, 0x2a6, 0x045,
> +    0x397, 0x2a1, 0x04c, 0x109, 0x04d, 0x118, 0x272, 0x2a9,
> +    0x009, 0x3fa, 0x045, 0x347, 0x2ae, 0x2a5, 0x347, 0x2af,
> +    0x2a6, 0x045, 0x342, 0x2fe, 0x00f, 0x003, 0x03f, 0x045,
> +    0x302, 0x2fe, 0x003, 0x019, 0x042, 0x042, 0x045, 0x327,
> +    0x00e, 0x309, 0x00f, 0x002, 0x005, 0x2a8, 0x208, 0x121,
> +    0x20e, 0x040, 0x041, 0x322, 0x2fd, 0x001, 0x3eb, 0x303,
> +    0x2fe, 0x00b, 0x3eb, 0x042, 0x247, 0x2fd, 0x042, 0x247,
> +    0x2fe, 0x000, 0x02e, 0x0c0, 0x2ff, 0x044, 0x30e, 0x002,
> +    0x364, 0x017, 0x004, 0x009, 0x3dc, 0x340, 0x046, 0x047,
> +    0x001, 0x021, 0x342, 0x2fd, 0x00e, 0x001, 0x3c5, 0x343,
> +    0x2fe, 0x00f, 0x00b, 0x017, 0x347, 0x00e, 0x2fd, 0x347,
> +    0x00f, 0x2fe, 0x009, 0x00d, 0x140, 0x2fd, 0x003, 0x009,
> +    0x342, 0x300, 0x2fd, 0x00b, 0x004, 0x0c0, 0x2fd, 0x0c1,
> +    0x2ff, 0x045, 0x30e, 0x21d, 0x102, 0x000, 0x004, 0x30e,
> +    0x21d, 0x327, 0x2c7, 0x041, 0x327, 0x2c8, 0x041, 0x0a2,
> +    0x044, 0x0fb, 0x002, 0x045, 0x366, 0x200, 0x080, 0x009,
> +    0x019, 0x364, 0x026, 0x002, 0x001, 0x014, 0x054, 0x140,
> +    0x2fa, 0x00b, 0x3f3, 0x3c7, 0x3ff, 0x2fa, 0x360, 0x2fa,
> +    0x00a, 0x003, 0x007, 0x054, 0x140, 0x01c, 0x00b, 0x3f8,
> +    0x045, 0x0c0, 0x301, 0x3ce, 0x3ff, 0x2fe, 0x040, 0x044,
> +    0x3f0, 0x002, 0x044, 0x18b, 0x003, 0x042, 0x04c, 0x140,
> +    0x301, 0x001, 0x010, 0x346, 0x301, 0x00f, 0x003, 0x029,
> +    0x320, 0x303, 0x2e4, 0x100, 0x009, 0x02a, 0x04d, 0x000,
> +    0x3e7, 0x0c1, 0x303, 0x347, 0x00f, 0x301, 0x00b, 0x004,
> +    0x152, 0x303, 0x009, 0x004, 0x0c1, 0x301, 0x040, 0x3a7,
> +    0x060, 0x044, 0x192, 0x000, 0x264, 0x008, 0x001, 0x007,
> +    0x348, 0x303, 0x303, 0x141, 0x303, 0x000, 0x3d0, 0x140,
> +    0x2ff, 0x009, 0x005, 0x322, 0x303, 0x04d, 0x045, 0x364,
> +    0x2cf, 0x080, 0x009, 0x019, 0x044, 0x346, 0x002, 0x0a0,
> +    0x397, 0x294, 0x04d, 0x101, 0x272, 0x2a0, 0x009, 0x3fc,
> +    0x044, 0x096, 0x003, 0x0c0, 0x293, 0x044, 0x06e, 0x003,
> +    0x044, 0x2b1, 0x003, 0x140, 0x2d3, 0x009, 0x002, 0x3c4,
> +    0x2fd, 0x00d, 0x044, 0x33f, 0x002, 0x3c4, 0x2ff, 0x200,
> +    0x020, 0x089, 0x000, 0x0cd, 0x2ce, 0x347, 0x2ae, 0x2a5,
> +    0x347, 0x2af, 0x2a6, 0x307, 0x2e3, 0x140, 0x304, 0x009,
> +    0x004, 0x208, 0x101, 0x240, 0x2a6, 0x240, 0x2a5, 0x044,
> +    0x134, 0x003, 0x044, 0x1ba, 0x003, 0x0c0, 0x309, 0x387,
> +    0x071, 0x140, 0x304, 0x001, 0x003, 0x108, 0x364, 0x309,
> +    0x001, 0x001, 0x004, 0x380, 0x040, 0x187, 0x106, 0x0a0,
> +    0x044, 0x18a, 0x002, 0x397, 0x2a5, 0x300, 0x309, 0x044,
> +    0x1e9, 0x003, 0x141, 0x309, 0x362, 0x309, 0x002, 0x009,
> +    0x3e0, 0x044, 0x3f0, 0x002, 0x347, 0x2a5, 0x2e3, 0x342,
> +    0x2ae, 0x2e3, 0x00b, 0x007, 0x348, 0x2e3, 0x2e3, 0x141,
> +    0x2e3, 0x140, 0x307, 0x009, 0x005, 0x347, 0x2e3, 0x307,
> +    0x045, 0x364, 0x2cf, 0x080, 0x009, 0x0ac, 0x0c1, 0x2ce,
> +    0x055, 0x3c5, 0x004, 0x2cf, 0x3a7, 0x071, 0x044, 0x192,
> +    0x000, 0x247, 0x305, 0x054, 0x080, 0x044, 0x1bd, 0x000,
> +    0x3a7, 0x02c, 0x387, 0x30f, 0x044, 0x1b8, 0x000, 0x3a7,
> +    0x022, 0x08a, 0x044, 0x1bd, 0x000, 0x081, 0x189, 0x0a0,
> +    0x044, 0x1a9, 0x000, 0x30e, 0x21d, 0x102, 0x0b0, 0x041,
> +    0x0a0, 0x041, 0x0a2, 0x044, 0x0fb, 0x002, 0x080, 0x0a0,
> +    0x262, 0x001, 0x00b, 0x004, 0x3a7, 0x0ff, 0x040, 0x397,
> +    0x2a1, 0x04d, 0x101, 0x04d, 0x101, 0x04d, 0x101, 0x04d,
> +    0x113, 0x043, 0x280, 0x3a7, 0x080, 0x04d, 0x040, 0x392,
> +    0x2a1, 0x262, 0x005, 0x00b, 0x007, 0x040, 0x044, 0x3e4,
> +    0x002, 0x042, 0x227, 0x3a4, 0x001, 0x121, 0x1a5, 0x191,
> +    0x285, 0x187, 0x106, 0x0a0, 0x044, 0x18a, 0x002, 0x042,
> +    0x044, 0x1e9, 0x003, 0x041, 0x101, 0x392, 0x2a1, 0x264,
> +    0x008, 0x001, 0x3c6, 0x390, 0x2a1, 0x111, 0x043, 0x04d,
> +    0x272, 0x2a1, 0x003, 0x3fb, 0x044, 0x150, 0x003, 0x044,
> +    0x3ea, 0x002, 0x044, 0x06e, 0x003, 0x364, 0x292, 0x008,
> +    0x009, 0x008, 0x080, 0x3a7, 0x022, 0x044, 0x1bd, 0x000,
> +    0x307, 0x020, 0x192, 0x002, 0x013, 0x19a, 0x002, 0x010,
> +    0x081, 0x189, 0x0a0, 0x044, 0x1b7, 0x000, 0x055, 0x3a7,
> +    0x071, 0x307, 0x305, 0x044, 0x1bd, 0x000, 0x044, 0x3f0,
> +    0x002, 0x3c4, 0x3fb, 0x2cf, 0x3c5, 0x080, 0x2cf, 0x054,
> +    0x045, 0x397, 0x36a, 0x247, 0x369, 0x0a0, 0x101, 0x04d,
> +    0x272, 0x38e, 0x009, 0x3fc, 0x045, 0x0c3, 0x34e, 0x1cb,
> +    0x34e, 0x3c5, 0x03f, 0x34e, 0x0c3, 0x362, 0x0c4, 0x363,
> +    0x0c0, 0x33c, 0x0c0, 0x356, 0x0c0, 0x357, 0x3d7, 0x2f9,
> +    0x352, 0x1c2, 0x352, 0x3d7, 0x254, 0x353, 0x1c0, 0x353,
> +    0x08d, 0x18b, 0x385, 0x05e, 0x247, 0x354, 0x3c7, 0x0b2,
> +    0x355, 0x345, 0x21d, 0x355, 0x0c4, 0x341, 0x0c2, 0x33f,
> +    0x0d2, 0x340, 0x0d3, 0x342, 0x0ce, 0x344, 0x0de, 0x343,
> +    0x0c0, 0x348, 0x045, 0x055, 0x3c4, 0x008, 0x33b, 0x144,
> +    0x33b, 0x0c6, 0x33d, 0x3c4, 0x3fb, 0x200, 0x307, 0x027,
> +    0x384, 0x324, 0x101, 0x247, 0x027, 0x045, 0x055, 0x3c4,
> +    0x3ec, 0x052, 0x044, 0x05b, 0x001, 0x3c4, 0x3fb, 0x00c,
> +    0x0c0, 0x359, 0x3c4, 0x1ff, 0x35b, 0x045, 0x055, 0x0c0,
> +    0x33d, 0x3c4, 0x3fe, 0x03d, 0x0df, 0x053, 0x3c4, 0x373,
> +    0x00c, 0x0c0, 0x349, 0x0c0, 0x35a, 0x3c4, 0x330, 0x027,
> +    0x0c0, 0x33b, 0x344, 0x21f, 0x33c, 0x045, 0x044, 0x050,
> +    0x005, 0x307, 0x33c, 0x00b, 0x018, 0x362, 0x33d, 0x003,
> +    0x007, 0x013, 0x009, 0x005, 0x044, 0x073, 0x004, 0x055,
> +    0x364, 0x33c, 0x040, 0x001, 0x008, 0x3c4, 0x3fb, 0x200,
> +    0x044, 0x103, 0x004, 0x044, 0x1bb, 0x005, 0x020, 0x0ad,
> +    0x000, 0x364, 0x33c, 0x002, 0x001, 0x055, 0x3c5, 0x008,
> +    0x00c, 0x364, 0x33c, 0x080, 0x009, 0x023, 0x0c0, 0x392,
> +    0x347, 0x354, 0x03e, 0x347, 0x355, 0x03f, 0x347, 0x352,
> +    0x038, 0x347, 0x353, 0x039, 0x307, 0x352, 0x040, 0x307,
> +    0x353, 0x040, 0x307, 0x354, 0x040, 0x307, 0x355, 0x305,
> +    0x21d, 0x040, 0x397, 0x2a0, 0x044, 0x01a, 0x002, 0x0c0,
> +    0x290, 0x044, 0x034, 0x003, 0x044, 0x361, 0x003, 0x0c7,
> +    0x2d1, 0x0c3, 0x2cc, 0x0c0, 0x2c8, 0x0c1, 0x2c7, 0x1cd,
> +    0x2c7, 0x0c1, 0x33d, 0x142, 0x027, 0x0c0, 0x33e, 0x0c0,
> +    0x365, 0x020, 0x04c, 0x004, 0x085, 0x364, 0x33b, 0x020,
> +    0x001, 0x003, 0x102, 0x18a, 0x385, 0x11f, 0x247, 0x053,
> +    0x045, 0x0c2, 0x33b, 0x0c5, 0x33d, 0x3c5, 0x010, 0x027,
> +    0x0df, 0x053, 0x045, 0x044, 0x3b6, 0x003, 0x044, 0x3c6,
> +    0x003, 0x044, 0x38c, 0x002, 0x044, 0x39f, 0x002, 0x3c4,
> +    0x3fb, 0x200, 0x045, 0x055, 0x364, 0x33c, 0x020, 0x009,
> +    0x007, 0x0c4, 0x33d, 0x044, 0x103, 0x004, 0x0c5, 0x33d,
> +    0x3c4, 0x3fe, 0x03d, 0x3c5, 0x00a, 0x33b, 0x307, 0x027,
> +    0x384, 0x334, 0x305, 0x392, 0x247, 0x027, 0x3c4, 0x2ff,
> +    0x053, 0x3c4, 0x377, 0x00c, 0x020, 0x38c, 0x002, 0x2e4,
> +    0x010, 0x001, 0x005, 0x3c5, 0x080, 0x33c, 0x044, 0x006,
> +    0x005, 0x364, 0x33b, 0x010, 0x3c4, 0x3bf, 0x33c, 0x364,
> +    0x33c, 0x020, 0x009, 0x007, 0x364, 0x33c, 0x002, 0x001,
> +    0x015, 0x3c5, 0x004, 0x00c, 0x364, 0x33c, 0x020, 0x001,
> +    0x005, 0x3c5, 0x080, 0x058, 0x0c0, 0x350, 0x044, 0x0c5,
> +    0x004, 0x3c5, 0x001, 0x052, 0x045, 0x0c0, 0x04c, 0x347,
> +    0x357, 0x04d, 0x347, 0x356, 0x04e, 0x347, 0x357, 0x364,
> +    0x347, 0x356, 0x365, 0x387, 0x067, 0x187, 0x385, 0x080,
> +    0x3c4, 0x04c, 0x052, 0x245, 0x052, 0x309, 0x026, 0x003,
> +    0x00c, 0x0c0, 0x029, 0x3c7, 0x022, 0x029, 0x345, 0x21d,
> +    0x029, 0x000, 0x00f, 0x347, 0x362, 0x02c, 0x399, 0x380,
> +    0x208, 0x244, 0x029, 0x307, 0x363, 0x187, 0x245, 0x029,
> +    0x081, 0x18c, 0x245, 0x053, 0x347, 0x021, 0x35c, 0x3c4,
> +    0x3cf, 0x021, 0x045, 0x055, 0x364, 0x052, 0x001, 0x001,
> +    0x02a, 0x142, 0x052, 0x086, 0x187, 0x385, 0x072, 0x364,
> +    0x33c, 0x020, 0x001, 0x008, 0x044, 0x18d, 0x000, 0x055,
> +    0x000, 0x005, 0x044, 0x189, 0x000, 0x347, 0x35c, 0x021,
> +    0x3c7, 0x080, 0x052, 0x3c4, 0x3fb, 0x00c, 0x364, 0x33c,
> +    0x200, 0x009, 0x008, 0x3c5, 0x020, 0x2cf, 0x3c5, 0x040,
> +    0x200, 0x045, 0x055, 0x140, 0x33d, 0x001, 0x3fc, 0x055,
> +    0x307, 0x368, 0x304, 0x34e, 0x0c0, 0x351, 0x227, 0x1a2,
> +    0x002, 0x071, 0x00b, 0x08b, 0x044, 0x03b, 0x005, 0x044,
> +    0x006, 0x005, 0x141, 0x374, 0x140, 0x346, 0x001, 0x00b,
> +    0x342, 0x342, 0x346, 0x00b, 0x019, 0x0c4, 0x350, 0x000,
> +    0x019, 0x340, 0x347, 0x345, 0x001, 0x00a, 0x342, 0x347,
> +    0x345, 0x364, 0x33c, 0x004, 0x001, 0x3ec, 0x0cc, 0x350,
> +    0x141, 0x384, 0x000, 0x009, 0x0c8, 0x350, 0x141, 0x383,
> +    0x340, 0x342, 0x346, 0x140, 0x345, 0x001, 0x00c, 0x342,
> +    0x344, 0x345, 0x00b, 0x00e, 0x3c5, 0x001, 0x350, 0x000,
> +    0x00e, 0x3c5, 0x003, 0x350, 0x141, 0x37c, 0x000, 0x00a,
> +    0x3c5, 0x002, 0x350, 0x141, 0x37b, 0x340, 0x344, 0x345,
> +    0x140, 0x347, 0x001, 0x00c, 0x342, 0x343, 0x347, 0x00b,
> +    0x00f, 0x3c5, 0x010, 0x350, 0x000, 0x00f, 0x3c5, 0x030,
> +    0x350, 0x141, 0x38c, 0x020, 0x3fa, 0x004, 0x3c5, 0x020,
> +    0x350, 0x141, 0x38b, 0x340, 0x343, 0x347, 0x020, 0x3fa,
> +    0x004, 0x044, 0x03b, 0x005, 0x141, 0x375, 0x0c0, 0x346,
> +    0x0c0, 0x347, 0x0c0, 0x345, 0x044, 0x01e, 0x005, 0x3c7,
> +    0x03f, 0x350, 0x141, 0x37c, 0x141, 0x384, 0x141, 0x38c,
> +    0x0c0, 0x348, 0x020, 0x3fa, 0x004, 0x205, 0x001, 0x182,
> +    0x044, 0x03b, 0x005, 0x227, 0x3a4, 0x00c, 0x1b1, 0x001,
> +    0x013, 0x364, 0x350, 0x00c, 0x009, 0x05c, 0x364, 0x04d,
> +    0x00c, 0x009, 0x057, 0x132, 0x003, 0x00b, 0x001, 0x027,
> +    0x000, 0x050, 0x3c4, 0x3f3, 0x350, 0x000, 0x04b, 0x140,
> +    0x351, 0x009, 0x004, 0x141, 0x37f, 0x140, 0x346, 0x001,
> +    0x00b, 0x151, 0x348, 0x151, 0x346, 0x3c5, 0x004, 0x350,
> +    0x000, 0x038, 0x3c5, 0x00c, 0x350, 0x140, 0x351, 0x001,
> +    0x031, 0x141, 0x384, 0x000, 0x02d, 0x140, 0x351, 0x009,
> +    0x004, 0x141, 0x380, 0x342, 0x23e, 0x348, 0x001, 0x016,
> +    0x342, 0x342, 0x346, 0x001, 0x00e, 0x141, 0x348, 0x141,
> +    0x346, 0x340, 0x342, 0x346, 0x3c5, 0x004, 0x350, 0x000,
> +    0x00e, 0x340, 0x342, 0x346, 0x3c5, 0x008, 0x350, 0x140,
> +    0x351, 0x001, 0x004, 0x141, 0x383, 0x340, 0x23e, 0x348,
> +    0x227, 0x3a4, 0x003, 0x001, 0x013, 0x364, 0x350, 0x003,
> +    0x009, 0x071, 0x364, 0x04d, 0x003, 0x009, 0x06c, 0x132,
> +    0x003, 0x00b, 0x001, 0x036, 0x000, 0x065, 0x3c4, 0x3fc,
> +    0x350, 0x000, 0x060, 0x140, 0x351, 0x009, 0x004, 0x141,
> +    0x377, 0x140, 0x345, 0x009, 0x00d, 0x3c5, 0x003, 0x350,
> +    0x140, 0x351, 0x001, 0x04f, 0x141, 0x37c, 0x000, 0x04b,
> +    0x342, 0x342, 0x346, 0x009, 0x007, 0x340, 0x342, 0x346,
> +    0x000, 0x3ed, 0x340, 0x342, 0x346, 0x151, 0x348, 0x141,
> +    0x346, 0x152, 0x345, 0x3c5, 0x001, 0x350, 0x000, 0x033,
> +    0x140, 0x351, 0x009, 0x004, 0x141, 0x378, 0x342, 0x23e,
> +    0x348, 0x001, 0x01c, 0x342, 0x344, 0x345, 0x001, 0x014,
> +    0x140, 0x346, 0x001, 0x010, 0x141, 0x348, 0x151, 0x346,
> +    0x142, 0x345, 0x340, 0x344, 0x345, 0x3c5, 0x001, 0x350,
> +    0x000, 0x00e, 0x340, 0x344, 0x345, 0x3c5, 0x002, 0x350,
> +    0x140, 0x351, 0x001, 0x004, 0x141, 0x37b, 0x340, 0x23e,
> +    0x348, 0x227, 0x1b3, 0x3a4, 0x003, 0x001, 0x013, 0x364,
> +    0x350, 0x030, 0x009, 0x071, 0x364, 0x04d, 0x030, 0x009,
> +    0x06c, 0x132, 0x003, 0x00b, 0x001, 0x036, 0x000, 0x065,
> +    0x3c4, 0x3cf, 0x350, 0x000, 0x060, 0x140, 0x351, 0x009,
> +    0x004, 0x141, 0x387, 0x140, 0x347, 0x009, 0x00d, 0x3c5,
> +    0x030, 0x350, 0x140, 0x351, 0x001, 0x04f, 0x141, 0x38c,
> +    0x000, 0x04b, 0x342, 0x342, 0x346, 0x009, 0x007, 0x340,
> +    0x342, 0x346, 0x000, 0x3ed, 0x340, 0x342, 0x346, 0x151,
> +    0x348, 0x141, 0x346, 0x152, 0x347, 0x3c5, 0x010, 0x350,
> +    0x000, 0x033, 0x140, 0x351, 0x009, 0x004, 0x141, 0x388,
> +    0x342, 0x23e, 0x348, 0x001, 0x01c, 0x342, 0x343, 0x347,
> +    0x001, 0x014, 0x140, 0x346, 0x001, 0x010, 0x141, 0x348,
> +    0x151, 0x346, 0x142, 0x347, 0x340, 0x343, 0x347, 0x3c5,
> +    0x010, 0x350, 0x000, 0x00e, 0x340, 0x343, 0x347, 0x3c5,
> +    0x020, 0x350, 0x140, 0x351, 0x001, 0x004, 0x141, 0x38b,
> +    0x340, 0x23e, 0x348, 0x328, 0x04d, 0x324, 0x350, 0x2e4,
> +    0x02a, 0x001, 0x026, 0x140, 0x351, 0x009, 0x022, 0x141,
> +    0x351, 0x2e4, 0x020, 0x001, 0x005, 0x3c4, 0x3cf, 0x350,
> +    0x2e4, 0x008, 0x001, 0x005, 0x3c4, 0x3f3, 0x350, 0x2e4,
> +    0x002, 0x001, 0x28a, 0x3c4, 0x3fc, 0x350, 0x000, 0x285,
> +    0x0c0, 0x350, 0x3c4, 0x3bf, 0x027, 0x000, 0x0a8, 0x328,
> +    0x04d, 0x324, 0x350, 0x287, 0x3a4, 0x003, 0x131, 0x009,
> +    0x029, 0x140, 0x345, 0x001, 0x01c, 0x342, 0x344, 0x345,
> +    0x044, 0x030, 0x005, 0x003, 0x006, 0x140, 0x345, 0x009,
> +    0x00b, 0x364, 0x368, 0x002, 0x001, 0x006, 0x141, 0x350,
> +    0x141, 0x37b, 0x340, 0x344, 0x345, 0x000, 0x00b, 0x364,
> +    0x368, 0x001, 0x001, 0x006, 0x142, 0x350, 0x141, 0x37c,
> +    0x227, 0x3a4, 0x00c, 0x134, 0x009, 0x039, 0x140, 0x346,
> +    0x001, 0x01c, 0x342, 0x342, 0x346, 0x044, 0x030, 0x005,
> +    0x003, 0x006, 0x140, 0x346, 0x009, 0x00b, 0x364, 0x368,
> +    0x008, 0x001, 0x006, 0x144, 0x350, 0x141, 0x383, 0x340,
> +    0x342, 0x346, 0x000, 0x01b, 0x364, 0x368, 0x008, 0x009,
> +    0x3e3, 0x364, 0x368, 0x004, 0x001, 0x011, 0x327, 0x345,
> +    0x320, 0x347, 0x001, 0x007, 0x364, 0x33c, 0x004, 0x001,
> +    0x006, 0x148, 0x350, 0x141, 0x384, 0x227, 0x3a4, 0x030,
> +    0x3a2, 0x010, 0x009, 0x02b, 0x140, 0x347, 0x001, 0x01d,
> +    0x342, 0x343, 0x347, 0x044, 0x030, 0x005, 0x003, 0x006,
> +    0x140, 0x347, 0x009, 0x00c, 0x364, 0x368, 0x020, 0x001,
> +    0x007, 0x3c0, 0x010, 0x350, 0x141, 0x38b, 0x340, 0x343,
> +    0x347, 0x000, 0x00c, 0x364, 0x368, 0x010, 0x001, 0x007,
> +    0x3c0, 0x020, 0x350, 0x141, 0x38c, 0x044, 0x3fa, 0x004,
> +    0x000, 0x026, 0x3c5, 0x040, 0x027, 0x307, 0x04d, 0x384,
> +    0x200, 0x305, 0x350, 0x247, 0x04d, 0x045, 0x08f, 0x3b7,
> +    0x211, 0x044, 0x1b8, 0x000, 0x347, 0x33f, 0x346, 0x347,
> +    0x340, 0x347, 0x347, 0x341, 0x345, 0x347, 0x347, 0x348,
> +    0x340, 0x345, 0x348, 0x340, 0x346, 0x348, 0x307, 0x347,
> +    0x183, 0x305, 0x345, 0x184, 0x305, 0x346, 0x32a, 0x346,
> +    0x3a4, 0x008, 0x285, 0x3b7, 0x210, 0x020, 0x1bd, 0x000,
> +    0x364, 0x33c, 0x008, 0x001, 0x007, 0x327, 0x23e, 0x322,
> +    0x348, 0x131, 0x045, 0x040, 0x227, 0x306, 0x373, 0x001,
> +    0x00f, 0x307, 0x369, 0x101, 0x272, 0x372, 0x009, 0x003,
> +    0x118, 0x04d, 0x247, 0x369, 0x2c7, 0x373, 0x042, 0x045,
> +    0x140, 0x35a, 0x00b, 0x0b0, 0x344, 0x21f, 0x35a, 0x0a3,
> +    0x1ad, 0x2a8, 0x2c4, 0x027, 0x055, 0x044, 0x340, 0x001,
> +    0x054, 0x264, 0x002, 0x001, 0x005, 0x0c0, 0x33d, 0x045,
> +    0x083, 0x18b, 0x304, 0x050, 0x305, 0x221, 0x044, 0x0d3,
> +    0x005, 0x001, 0x3f4, 0x308, 0x221, 0x244, 0x027, 0x387,
> +    0x030, 0x304, 0x050, 0x187, 0x044, 0x0d3, 0x005, 0x001,
> +    0x3e6, 0x08c, 0x304, 0x050, 0x189, 0x044, 0x0d3, 0x005,
> +    0x001, 0x3dd, 0x083, 0x304, 0x050, 0x18b, 0x044, 0x0d3,
> +    0x005, 0x001, 0x3d4, 0x083, 0x18b, 0x304, 0x365, 0x044,
> +    0x0d3, 0x005, 0x001, 0x3cb, 0x387, 0x030, 0x304, 0x365,
> +    0x187, 0x044, 0x0d3, 0x005, 0x001, 0x3c1, 0x08c, 0x304,
> +    0x365, 0x189, 0x044, 0x0d3, 0x005, 0x001, 0x3b8, 0x083,
> +    0x304, 0x365, 0x18b, 0x044, 0x0d3, 0x005, 0x001, 0x3af,
> +    0x307, 0x21d, 0x304, 0x364, 0x192, 0x364, 0x052, 0x020,
> +    0x001, 0x00d, 0x327, 0x21d, 0x324, 0x04f, 0x001, 0x005,
> +    0x345, 0x21d, 0x33c, 0x1b1, 0x285, 0x044, 0x0d3, 0x005,
> +    0x001, 0x395, 0x045, 0x364, 0x33b, 0x001, 0x001, 0x02c,
> +    0x0a3, 0x1ab, 0x2a8, 0x2c4, 0x027, 0x245, 0x027, 0x345,
> +    0x21d, 0x027, 0x364, 0x33b, 0x001, 0x001, 0x01d, 0x044,
> +    0x103, 0x005, 0x364, 0x35b, 0x002, 0x001, 0x3f5, 0x344,
> +    0x21f, 0x027, 0x364, 0x33b, 0x001, 0x001, 0x00d, 0x044,
> +    0x103, 0x005, 0x307, 0x35b, 0x264, 0x002, 0x009, 0x3f4,
> +    0x264, 0x001, 0x045, 0x055, 0x364, 0x059, 0x080, 0x001,
> +    0x012, 0x364, 0x24b, 0x080, 0x009, 0x00d, 0x364, 0x001,
> +    0x080, 0x009, 0x008, 0x3c5, 0x080, 0x24b, 0x044, 0x12d,
> +    0x005, 0x044, 0x340, 0x001, 0x247, 0x35b, 0x374, 0x027,
> +    0x200, 0x001, 0x00a, 0x264, 0x080, 0x009, 0x006, 0x3b8,
> +    0x200, 0x2c4, 0x027, 0x054, 0x045, 0x044, 0x340, 0x001,
> +    0x264, 0x080, 0x001, 0x088, 0x3b8, 0x300, 0x2c4, 0x027,
> +    0x264, 0x040, 0x001, 0x00f, 0x140, 0x359, 0x001, 0x00b,
> +    0x0c0, 0x33d, 0x0c0, 0x359, 0x3d5, 0x200, 0x027, 0x000,
> +    0x060, 0x384, 0x030, 0x327, 0x359, 0x2e2, 0x008, 0x003,
> +    0x3f1, 0x2a9, 0x3b0, 0x15a, 0x041, 0x1b9, 0x3b0, 0x005,
> +    0x041, 0x045, 0x000, 0x012, 0x000, 0x015, 0x000, 0x015,
> +    0x000, 0x016, 0x000, 0x017, 0x000, 0x01a, 0x000, 0x01c,
> +    0x000, 0x01f, 0x000, 0x022, 0x187, 0x247, 0x367, 0x000,
> +    0x033, 0x000, 0x02f, 0x191, 0x000, 0x02c, 0x193, 0x000,
> +    0x029, 0x187, 0x247, 0x366, 0x000, 0x026, 0x245, 0x366,
> +    0x000, 0x022, 0x191, 0x245, 0x366, 0x000, 0x01d, 0x193,
> +    0x245, 0x366, 0x000, 0x018, 0x229, 0x3a4, 0x040, 0x2c5,
> +    0x33c, 0x329, 0x04d, 0x18b, 0x2cc, 0x04d, 0x347, 0x367,
> +    0x368, 0x347, 0x366, 0x04e, 0x0c0, 0x359, 0x000, 0x006,
> +    0x245, 0x367, 0x141, 0x359, 0x3d5, 0x300, 0x027, 0x140,
> +    0x359, 0x009, 0x011, 0x140, 0x04d, 0x00b, 0x00a, 0x364,
> +    0x33c, 0x040, 0x001, 0x005, 0x020, 0x103, 0x004, 0x044,
> +    0x137, 0x004, 0x045, 0x362, 0x33e, 0x007, 0x009, 0x003,
> +    0x045, 0x055, 0x362, 0x33d, 0x000, 0x006, 0x077, 0x362,
> +    0x33d, 0x005, 0x00f, 0x072, 0x140, 0x34d, 0x009, 0x007,
> +    0x044, 0x23e, 0x005, 0x000, 0x069, 0x308, 0x356, 0x304,
> +    0x365, 0x001, 0x007, 0x044, 0x36a, 0x005, 0x000, 0x05e,
> +    0x140, 0x349, 0x001, 0x017, 0x364, 0x04f, 0x03f, 0x009,
> +    0x055, 0x0c0, 0x349, 0x362, 0x34f, 0x000, 0x006, 0x04e,
> +    0x307, 0x34f, 0x044, 0x000, 0x006, 0x0c0, 0x34f, 0x000,
> +    0x045, 0x140, 0x33e, 0x009, 0x007, 0x044, 0x23e, 0x005,
> +    0x000, 0x03c, 0x362, 0x33e, 0x001, 0x009, 0x007, 0x044,
> +    0x269, 0x005, 0x000, 0x032, 0x362, 0x33e, 0x002, 0x009,
> +    0x007, 0x044, 0x26f, 0x005, 0x000, 0x028, 0x362, 0x33e,
> +    0x003, 0x009, 0x007, 0x044, 0x27f, 0x005, 0x000, 0x01e,
> +    0x362, 0x33e, 0x004, 0x009, 0x007, 0x044, 0x29a, 0x005,
> +    0x000, 0x014, 0x362, 0x33e, 0x005, 0x009, 0x007, 0x044,
> +    0x2b7, 0x005, 0x000, 0x00a, 0x362, 0x33e, 0x006, 0x009,
> +    0x005, 0x044, 0x34f, 0x005, 0x054, 0x045, 0x081, 0x189,
> +    0x304, 0x053, 0x009, 0x00c, 0x0c1, 0x33d, 0x083, 0x189,
> +    0x395, 0x3f7, 0x244, 0x027, 0x000, 0x01c, 0x0c2, 0x33d,
> +    0x0c1, 0x34d, 0x3c5, 0x008, 0x027, 0x0c0, 0x34b, 0x0c0,
> +    0x34c, 0x140, 0x35d, 0x009, 0x00b, 0x0c0, 0x34f, 0x088,
> +    0x189, 0x245, 0x365, 0x044, 0x3c2, 0x005, 0x0c1, 0x33e,
> +    0x045, 0x347, 0x35e, 0x34a, 0x0c2, 0x33e, 0x045, 0x307,
> +    0x34b, 0x302, 0x360, 0x006, 0x009, 0x141, 0x34b, 0x044,
> +    0x3f3, 0x005, 0x000, 0x004, 0x0c3, 0x33e, 0x045, 0x307,
> +    0x34c, 0x302, 0x361, 0x006, 0x014, 0x141, 0x34c, 0x088,
> +    0x3c7, 0x020, 0x34f, 0x3c7, 0x028, 0x372, 0x141, 0x38a,
> +    0x141, 0x382, 0x044, 0x000, 0x006, 0x000, 0x004, 0x0c4,
> +    0x33e, 0x045, 0x0c5, 0x33e, 0x0c0, 0x2d3, 0x364, 0x02b,
> +    0x080, 0x009, 0x015, 0x3c5, 0x010, 0x2cf, 0x3c5, 0x040,
> +    0x200, 0x362, 0x201, 0x002, 0x001, 0x00a, 0x0c1, 0x244,
> +    0x3c5, 0x004, 0x245, 0x3c4, 0x3fb, 0x200, 0x045, 0x364,
> +    0x2cf, 0x010, 0x009, 0x094, 0x364, 0x34a, 0x001, 0x001,
> +    0x009, 0x0c6, 0x33e, 0x044, 0x33f, 0x002, 0x000, 0x088,
> +    0x140, 0x259, 0x009, 0x009, 0x044, 0x346, 0x002, 0x0c0,
> +    0x330, 0x0c0, 0x331, 0x044, 0x012, 0x006, 0x140, 0x330,
> +    0x009, 0x00c, 0x140, 0x331, 0x009, 0x008, 0x347, 0x32e,
> +    0x330, 0x347, 0x32f, 0x331, 0x362, 0x331, 0x000, 0x00f,
> +    0x00c, 0x362, 0x32f, 0x000, 0x00f, 0x007, 0x044, 0x3f3,
> +    0x005, 0x000, 0x057, 0x362, 0x331, 0x000, 0x007, 0x00c,
> +    0x362, 0x32f, 0x000, 0x007, 0x007, 0x044, 0x3e6, 0x005,
> +    0x000, 0x048, 0x044, 0x33f, 0x002, 0x0c6, 0x33e, 0x362,
> +    0x331, 0x000, 0x00f, 0x021, 0x308, 0x330, 0x348, 0x331,
> +    0x336, 0x101, 0x3c1, 0x000, 0x336, 0x247, 0x330, 0x347,
> +    0x336, 0x331, 0x307, 0x330, 0x347, 0x331, 0x336, 0x302,
> +    0x32e, 0x343, 0x32f, 0x336, 0x002, 0x024, 0x044, 0x3e6,
> +    0x005, 0x000, 0x01f, 0x308, 0x32e, 0x348, 0x32f, 0x336,
> +    0x101, 0x3c1, 0x000, 0x336, 0x247, 0x32e, 0x347, 0x336,
> +    0x32f, 0x307, 0x330, 0x347, 0x331, 0x336, 0x302, 0x32e,
> +    0x343, 0x32f, 0x336, 0x002, 0x005, 0x044, 0x3f3, 0x005,
> +    0x347, 0x32e, 0x330, 0x347, 0x32f, 0x331, 0x045, 0x3c5,
> +    0x008, 0x33b, 0x0c3, 0x33d, 0x3c5, 0x004, 0x027, 0x0c7,
> +    0x33e, 0x364, 0x33c, 0x020, 0x001, 0x00a, 0x345, 0x21d,
> +    0x364, 0x347, 0x21d, 0x35a, 0x000, 0x005, 0x345, 0x21d,
> +    0x04d, 0x045, 0x364, 0x04f, 0x03f, 0x001, 0x054, 0x307,
> +    0x04f, 0x384, 0x003, 0x113, 0x009, 0x007, 0x3c5, 0x001,
> +    0x34a, 0x141, 0x37e, 0x307, 0x04f, 0x384, 0x003, 0x112,
> +    0x009, 0x007, 0x3c5, 0x001, 0x34a, 0x141, 0x37d, 0x307,
> +    0x04f, 0x384, 0x00c, 0x11c, 0x009, 0x007, 0x3c5, 0x002,
> +    0x34a, 0x141, 0x386, 0x307, 0x04f, 0x384, 0x00c, 0x118,
> +    0x009, 0x007, 0x3c5, 0x002, 0x34a, 0x141, 0x385, 0x307,
> +    0x04f, 0x384, 0x030, 0x382, 0x030, 0x009, 0x007, 0x3c5,
> +    0x004, 0x34a, 0x141, 0x38e, 0x307, 0x04f, 0x384, 0x030,
> +    0x382, 0x020, 0x009, 0x007, 0x3c5, 0x004, 0x34a, 0x141,
> +    0x38d, 0x347, 0x356, 0x365, 0x0c1, 0x349, 0x044, 0x3c2,
> +    0x005, 0x045, 0x088, 0x189, 0x304, 0x365, 0x001, 0x004,
> +    0x141, 0x376, 0x364, 0x33c, 0x020, 0x001, 0x007, 0x347,
> +    0x21d, 0x35a, 0x000, 0x013, 0x347, 0x365, 0x04e, 0x307,
> +    0x04e, 0x306, 0x356, 0x001, 0x007, 0x3c5, 0x080, 0x027,
> +    0x000, 0x005, 0x3c4, 0x37f, 0x027, 0x045, 0x081, 0x0c4,
> +    0x34f, 0x0c5, 0x372, 0x141, 0x379, 0x141, 0x381, 0x044,
> +    0x000, 0x006, 0x045, 0x088, 0x0c2, 0x34f, 0x0ca, 0x372,
> +    0x141, 0x37a, 0x141, 0x382, 0x044, 0x000, 0x006, 0x045,
> +    0x364, 0x33c, 0x010, 0x001, 0x009, 0x22a, 0x3a4, 0x015,
> +    0x209, 0x384, 0x02a, 0x285, 0x245, 0x365, 0x044, 0x3c2,
> +    0x005, 0x045, 0x0c2, 0x2ce, 0x0c0, 0x304, 0x044, 0x25b,
> +    0x003, 0x0c1, 0x2c7, 0x0c1, 0x2c8, 0x086, 0x189, 0x395,
> +    0x104, 0x0a2, 0x044, 0x18a, 0x002, 0x044, 0x1bf, 0x003,
> +    0x3c5, 0x100, 0x00d, 0x044, 0x30e, 0x002, 0x347, 0x00e,
> +    0x32e, 0x347, 0x00f, 0x32f, 0x045, 0x307, 0x000, 0x183,
> +    0x247, 0x21b, 0x003, 0x00b, 0x347, 0x21e, 0x008, 0x307,
> +    0x006, 0x327, 0x007, 0x000, 0x009, 0x347, 0x21e, 0x00b,
> +    0x307, 0x009, 0x327, 0x00a, 0x020, 0x1bb, 0x006, 0x347,
> +    0x059, 0x24b, 0x347, 0x248, 0x24a, 0x044, 0x340, 0x001,
> +    0x247, 0x248, 0x054, 0x364, 0x001, 0x080, 0x009, 0x059,
> +    0x347, 0x24a, 0x248, 0x364, 0x001, 0x001, 0x009, 0x171,
> +    0x364, 0x001, 0x002, 0x009, 0x171, 0x364, 0x001, 0x004,
> +    0x009, 0x17c, 0x364, 0x001, 0x008, 0x009, 0x1a4, 0x364,
> +    0x001, 0x010, 0x029, 0x042, 0x008, 0x364, 0x001, 0x020,
> +    0x029, 0x01f, 0x008, 0x364, 0x001, 0x040, 0x009, 0x1b1,
> +    0x364, 0x001, 0x100, 0x009, 0x1ac, 0x327, 0x21c, 0x324,
> +    0x020, 0x029, 0x0ab, 0x006, 0x364, 0x23f, 0x003, 0x001,
> +    0x00c, 0x044, 0x340, 0x001, 0x227, 0x1ba, 0x326, 0x248,
> +    0x054, 0x009, 0x026, 0x307, 0x24b, 0x306, 0x059, 0x384,
> +    0x080, 0x009, 0x01b, 0x055, 0x142, 0x000, 0x047, 0x3c5,
> +    0x020, 0x000, 0x3c5, 0x001, 0x233, 0x000, 0x012, 0x364,
> +    0x233, 0x001, 0x001, 0x00a, 0x3c5, 0x020, 0x000, 0x347,
> +    0x24a, 0x248, 0x000, 0x3e9, 0x044, 0x340, 0x001, 0x247,
> +    0x248, 0x347, 0x059, 0x24b, 0x044, 0x34c, 0x001, 0x009,
> +    0x012, 0x364, 0x33c, 0x020, 0x001, 0x007, 0x364, 0x24b,
> +    0x080, 0x009, 0x008, 0x306, 0x249, 0x19a, 0x001, 0x3cd,
> +    0x054, 0x364, 0x23f, 0x002, 0x001, 0x052, 0x307, 0x248,
> +    0x19e, 0x00a, 0x01c, 0x3c5, 0x084, 0x021, 0x3c4, 0x3fe,
> +    0x026, 0x307, 0x248, 0x306, 0x249, 0x209, 0x00b, 0x022,
> +    0x3b7, 0x210, 0x044, 0x192, 0x000, 0x247, 0x257, 0x080,
> +    0x044, 0x1bd, 0x000, 0x000, 0x015, 0x364, 0x026, 0x001,
> +    0x009, 0x010, 0x3c4, 0x37b, 0x021, 0x364, 0x234, 0x001,
> +    0x001, 0x008, 0x3c5, 0x001, 0x026, 0x044, 0x342, 0x006,
> +    0x307, 0x248, 0x19d, 0x00a, 0x007, 0x3c4, 0x3fd, 0x026,
> +    0x000, 0x00d, 0x364, 0x234, 0x002, 0x001, 0x008, 0x3c5,
> +    0x002, 0x026, 0x044, 0x141, 0x001, 0x327, 0x248, 0x326,
> +    0x249, 0x00b, 0x005, 0x044, 0x27d, 0x001, 0x364, 0x23f,
> +    0x001, 0x001, 0x013, 0x044, 0x34c, 0x001, 0x001, 0x007,
> +    0x2a8, 0x2c4, 0x233, 0x000, 0x00b, 0x327, 0x248, 0x326,
> +    0x249, 0x1ba, 0x3a4, 0x003, 0x001, 0x01f, 0x327, 0x248,
> +    0x1ba, 0x287, 0x190, 0x002, 0x006, 0x3a4, 0x3fb, 0x000,
> +    0x004, 0x3a5, 0x004, 0x3a4, 0x007, 0x307, 0x234, 0x384,
> +    0x3f8, 0x225, 0x344, 0x21f, 0x232, 0x347, 0x248, 0x249,
> +    0x020, 0x022, 0x008, 0x347, 0x248, 0x249, 0x364, 0x33c,
> +    0x020, 0x001, 0x005, 0x044, 0x12d, 0x005, 0x364, 0x233,
> +    0x001, 0x001, 0x314, 0x3c4, 0x3fe, 0x233, 0x020, 0x0f4,
> +    0x000, 0x328, 0x21b, 0x044, 0x32d, 0x001, 0x043, 0x307,
> +    0x21b, 0x009, 0x00e, 0x2c7, 0x005, 0x144, 0x000, 0x364,
> +    0x233, 0x001, 0x001, 0x2fb, 0x020, 0x0a3, 0x006, 0x00b,
> +    0x009, 0x0c0, 0x21b, 0x2c7, 0x00b, 0x148, 0x000, 0x047,
> +    0x0c0, 0x21b, 0x2c7, 0x008, 0x141, 0x000, 0x047, 0x3c4,
> +    0x3df, 0x000, 0x364, 0x000, 0x100, 0x001, 0x2a2, 0x364,
> +    0x233, 0x001, 0x001, 0x005, 0x3c5, 0x020, 0x000, 0x307,
> +    0x003, 0x327, 0x004, 0x041, 0x044, 0x32c, 0x001, 0x043,
> +    0x044, 0x32d, 0x001, 0x040, 0x209, 0x002, 0x083, 0x003,
> +    0x089, 0x188, 0x199, 0x041, 0x229, 0x280, 0x043, 0x390,
> +    0x057, 0x040, 0x199, 0x390, 0x008, 0x040, 0x045, 0x3c4,
> +    0x3f3, 0x012, 0x000, 0x2b3, 0x0af, 0x1a7, 0x2a8, 0x2c4,
> +    0x01f, 0x3c5, 0x001, 0x200, 0x344, 0x21f, 0x232, 0x151,
> +    0x2fa, 0x020, 0x247, 0x002, 0x364, 0x03a, 0x040, 0x009,
> +    0x007, 0x3c4, 0x3f7, 0x03a, 0x000, 0x299, 0x3c4, 0x3f0,
> +    0x03a, 0x364, 0x2cf, 0x001, 0x001, 0x01b, 0x364, 0x2cf,
> +    0x002, 0x009, 0x016, 0x142, 0x03a, 0x141, 0x2e6, 0x3c1,
> +    0x000, 0x2e7, 0x32a, 0x03a, 0x2f4, 0x200, 0x001, 0x3fc,
> +    0x143, 0x03a, 0x374, 0x25e, 0x200, 0x009, 0x002, 0x000,
> +    0x276, 0x364, 0x03d, 0x040, 0x009, 0x007, 0x3c4, 0x3f7,
> +    0x03d, 0x000, 0x26c, 0x3c4, 0x3f0, 0x03d, 0x364, 0x33b,
> +    0x001, 0x001, 0x007, 0x044, 0x3a3, 0x003, 0x000, 0x25f,
> +    0x374, 0x25f, 0x200, 0x009, 0x002, 0x000, 0x258, 0x158,
> +    0x025, 0x044, 0x141, 0x001, 0x020, 0x0a3, 0x006, 0x042,
> +    0x3a7, 0x020, 0x1a7, 0x3a5, 0x055, 0x020, 0x1de, 0x007,
> +    0x042, 0x394, 0x3ff, 0x04d, 0x040, 0x020, 0x181, 0x006,
> +    0x042, 0x394, 0x3ff, 0x04c, 0x020, 0x1de, 0x007, 0x364,
> +    0x2cf, 0x007, 0x029, 0x1dc, 0x007, 0x042, 0x186, 0x003,
> +    0x06b, 0x002, 0x06d, 0x2e4, 0x001, 0x001, 0x059, 0x287,
> +    0x384, 0x00e, 0x190, 0x3a4, 0x370, 0x285, 0x041, 0x0a0,
> +    0x044, 0x18a, 0x002, 0x043, 0x1b3, 0x3c4, 0x3fd, 0x00c,
> +    0x3c4, 0x3fc, 0x018, 0x287, 0x384, 0x070, 0x382, 0x030,
> +    0x001, 0x007, 0x3a4, 0x007, 0x133, 0x009, 0x007, 0x3c4,
> +    0x3ef, 0x021, 0x141, 0x018, 0x142, 0x00c, 0x0a1, 0x1aa,
> +    0x364, 0x026, 0x004, 0x009, 0x004, 0x2c5, 0x02a, 0x2a8,
> +    0x082, 0x044, 0x189, 0x000, 0x2c4, 0x02a, 0x3c4, 0x3f7,
> +    0x00d, 0x3c5, 0x001, 0x00d, 0x3c4, 0x3fe, 0x00d, 0x140,
> +    0x013, 0x009, 0x00b, 0x140, 0x014, 0x009, 0x007, 0x3c5,
> +    0x008, 0x00d, 0x000, 0x014, 0x0c0, 0x012, 0x0c2, 0x012,
> +    0x0c0, 0x012, 0x0c5, 0x012, 0x000, 0x00a, 0x0c0, 0x00d,
> +    0x044, 0x33f, 0x002, 0x3c4, 0x3fd, 0x00c, 0x0a3, 0x020,
> +    0x1de, 0x007, 0x2c7, 0x013, 0x000, 0x3fa, 0x2c7, 0x014,
> +    0x000, 0x3f6, 0x020, 0x181, 0x006, 0x2e4, 0x100, 0x009,
> +    0x042, 0x041, 0x3a4, 0x007, 0x387, 0x006, 0x189, 0x395,
> +    0x321, 0x280, 0x050, 0x0c3, 0x265, 0x262, 0x005, 0x00b,
> +    0x004, 0x0c7, 0x265, 0x043, 0x1b3, 0x2e2, 0x003, 0x009,
> +    0x00b, 0x041, 0x040, 0x084, 0x0b1, 0x044, 0x1b7, 0x000,
> +    0x042, 0x043, 0x2a9, 0x349, 0x265, 0x265, 0x111, 0x00b,
> +    0x3fb, 0x2aa, 0x34a, 0x265, 0x265, 0x348, 0x265, 0x265,
> +    0x041, 0x3a7, 0x030, 0x044, 0x192, 0x000, 0x043, 0x304,
> +    0x265, 0x285, 0x3a7, 0x030, 0x044, 0x1bd, 0x000, 0x000,
> +    0x007, 0x084, 0x0b1, 0x044, 0x1a9, 0x000, 0x020, 0x181,
> +    0x006, 0x000, 0x006, 0x009, 0x002, 0x004, 0x2c7, 0x22c,
> +    0x2f4, 0x100, 0x001, 0x013, 0x044, 0x342, 0x006, 0x364,
> +    0x23f, 0x002, 0x009, 0x005, 0x020, 0x181, 0x006, 0x345,
> +    0x21d, 0x232, 0x020, 0x2ea, 0x002, 0x044, 0x1ef, 0x001,
> +    0x000, 0x3ef, 0x044, 0x1ef, 0x001, 0x091, 0x044, 0x189,
> +    0x000, 0x3b7, 0x210, 0x307, 0x257, 0x020, 0x1bd, 0x000,
> +    0x1ad, 0x1b9, 0x3c4, 0x3cf, 0x232, 0x2c5, 0x232, 0x020,
> +    0x181, 0x006, 0x287, 0x2e4, 0x100, 0x001, 0x016, 0x041,
> +    0x384, 0x001, 0x182, 0x040, 0x3b7, 0x211, 0x044, 0x1a9,
> +    0x000, 0x042, 0x385, 0x3f3, 0x3b7, 0x211, 0x044, 0x1b8,
> +    0x000, 0x043, 0x287, 0x2f4, 0x200, 0x001, 0x016, 0x384,
> +    0x010, 0x190, 0x227, 0x190, 0x285, 0x040, 0x3a7, 0x060,
> +    0x044, 0x1a9, 0x000, 0x042, 0x385, 0x3f3, 0x3a7, 0x060,
> +    0x044, 0x1b8, 0x000, 0x020, 0x181, 0x006, 0x2e4, 0x100,
> +    0x009, 0x059, 0x287, 0x384, 0x0ff, 0x264, 0x080, 0x001,
> +    0x004, 0x385, 0x300, 0x1bd, 0x3a4, 0x003, 0x009, 0x004,
> +    0x247, 0x23a, 0x131, 0x009, 0x006, 0x247, 0x23c, 0x003,
> +    0x036, 0x131, 0x009, 0x004, 0x247, 0x23b, 0x131, 0x009,
> +    0x00a, 0x247, 0x23a, 0x003, 0x02a, 0x247, 0x23c, 0x247,
> +    0x23b, 0x327, 0x23a, 0x00b, 0x004, 0x2a8, 0x121, 0x140,
> +    0x23b, 0x00b, 0x006, 0x322, 0x23b, 0x000, 0x004, 0x320,
> +    0x23b, 0x320, 0x23c, 0x322, 0x23e, 0x007, 0x010, 0x347,
> +    0x23a, 0x237, 0x347, 0x23b, 0x239, 0x347, 0x23c, 0x238,
> +    0x044, 0x05b, 0x001, 0x000, 0x038, 0x347, 0x237, 0x23a,
> +    0x347, 0x239, 0x23b, 0x347, 0x238, 0x23c, 0x020, 0x1dc,
> +    0x007, 0x140, 0x33b, 0x009, 0x015, 0x289, 0x002, 0x00c,
> +    0x003, 0x006, 0x327, 0x237, 0x000, 0x008, 0x327, 0x238,
> +    0x000, 0x004, 0x327, 0x239, 0x042, 0x020, 0x1de, 0x007,
> +    0x289, 0x002, 0x00c, 0x003, 0x006, 0x327, 0x345, 0x000,
> +    0x3f5, 0x327, 0x346, 0x000, 0x3f1, 0x327, 0x347, 0x000,
> +    0x3ed, 0x2c7, 0x01a, 0x020, 0x181, 0x006, 0x327, 0x00c,
> +    0x3c5, 0x002, 0x00c, 0x3c5, 0x001, 0x00d, 0x08f, 0x044,
> +    0x189, 0x000, 0x3c4, 0x3fe, 0x00d, 0x2c7, 0x00c, 0x020,
> +    0x181, 0x006, 0x130, 0x001, 0x013, 0x083, 0x044, 0x189,
> +    0x000, 0x3c6, 0x001, 0x02b, 0x083, 0x044, 0x189, 0x000,
> +    0x3c6, 0x001, 0x02b, 0x131, 0x009, 0x3f1, 0x020, 0x181,
> +    0x006, 0x327, 0x00c, 0x3c5, 0x002, 0x00c, 0x387, 0x07c,
> +    0x187, 0x385, 0x08f, 0x244, 0x02a, 0x088, 0x187, 0x107,
> +    0x245, 0x02a, 0x082, 0x044, 0x189, 0x000, 0x081, 0x18a,
> +    0x208, 0x244, 0x02a, 0x2c7, 0x00c, 0x020, 0x181, 0x006,
> +    0x364, 0x026, 0x002, 0x001, 0x007, 0x364, 0x012, 0x040,
> +    0x001, 0x3f8, 0x020, 0x181, 0x006, 0x042, 0x327, 0x00d,
> +    0x000, 0x16e, 0x042, 0x327, 0x012, 0x000, 0x169, 0x042,
> +    0x197, 0x264, 0x001, 0x009, 0x011, 0x264, 0x002, 0x009,
> +    0x015, 0x264, 0x004, 0x009, 0x017, 0x264, 0x010, 0x009,
> +    0x01b, 0x0a0, 0x000, 0x154, 0x325, 0x21d, 0x2c7, 0x054,
> +    0x384, 0x3fe, 0x000, 0x3e7, 0x0c0, 0x054, 0x384, 0x3fd,
> +    0x000, 0x3e1, 0x324, 0x21f, 0x2c7, 0x054, 0x384, 0x3fb,
> +    0x000, 0x3d9, 0x044, 0x048, 0x008, 0x3c6, 0x100, 0x02b,
> +    0x0c0, 0x000, 0x364, 0x000, 0x020, 0x009, 0x3f5, 0x000,
> +    0x3db, 0x042, 0x040, 0x197, 0x001, 0x00d, 0x111, 0x001,
> +    0x028, 0x111, 0x001, 0x029, 0x111, 0x001, 0x02a, 0x000,
> +    0x041, 0x2c7, 0x254, 0x3b7, 0x241, 0x387, 0x100, 0x044,
> +    0x1a9, 0x000, 0x121, 0x044, 0x192, 0x000, 0x384, 0x030,
> +    0x040, 0x132, 0x044, 0x192, 0x000, 0x3b8, 0x300, 0x284,
> +    0x043, 0x1a3, 0x285, 0x395, 0x080, 0x000, 0x01e, 0x2c7,
> +    0x254, 0x000, 0x01f, 0x2c7, 0x255, 0x000, 0x01b, 0x287,
> +    0x040, 0x3b7, 0x241, 0x044, 0x1bd, 0x000, 0x131, 0x044,
> +    0x192, 0x000, 0x3a7, 0x061, 0x1a6, 0x2a8, 0x284, 0x043,
> +    0x3a4, 0x200, 0x285, 0x3b7, 0x240, 0x044, 0x1bd, 0x000,
> +    0x020, 0x181, 0x006, 0x362, 0x391, 0x001, 0x021, 0x181,
> +    0x006, 0x0c1, 0x391, 0x042, 0x0c0, 0x38f, 0x0c0, 0x390,
> +    0x080, 0x051, 0x2c0, 0x38f, 0x3c1, 0x000, 0x390, 0x3c6,
> +    0x0d8, 0x38f, 0x349, 0x38f, 0x38f, 0x34b, 0x390, 0x390,
> +    0x00a, 0x008, 0x3c0, 0x0e5, 0x38f, 0x3c1, 0x000, 0x390,
> +    0x3b7, 0x00b, 0x1a9, 0x3b5, 0x382, 0x222, 0x001, 0x005,
> +    0x101, 0x000, 0x3e0, 0x101, 0x051, 0x326, 0x38f, 0x3a4,
> +    0x0ff, 0x2e2, 0x0ef, 0x009, 0x029, 0x101, 0x051, 0x040,
> +    0x307, 0x38f, 0x197, 0x226, 0x2e2, 0x0be, 0x009, 0x01e,
> +    0x042, 0x101, 0x051, 0x326, 0x390, 0x3a4, 0x0ff, 0x2e2,
> +    0x0ad, 0x009, 0x013, 0x101, 0x050, 0x327, 0x390, 0x1b7,
> +    0x286, 0x262, 0x0de, 0x009, 0x009, 0x080, 0x040, 0x0c0,
> +    0x391, 0x020, 0x181, 0x006, 0x387, 0x0ff, 0x000, 0x3f8,
> +    0x043, 0x0a0, 0x1a7, 0x3a5, 0x045, 0x000, 0x071, 0x345,
> +    0x221, 0x233, 0x28a, 0x00a, 0x00c, 0x3a4, 0x300, 0x3c4,
> +    0x0ff, 0x027, 0x2c5, 0x027, 0x020, 0x181, 0x006, 0x327,
> +    0x059, 0x1a7, 0x042, 0x000, 0x05b, 0x2e4, 0x020, 0x001,
> +    0x012, 0x081, 0x18c, 0x245, 0x233, 0x2e4, 0x010, 0x009,
> +    0x005, 0x208, 0x244, 0x233, 0x044, 0x11a, 0x001, 0x000,
> +    0x042, 0x041, 0x091, 0x189, 0x2e4, 0x002, 0x001, 0x015,
> +    0x3c5, 0x040, 0x233, 0x245, 0x024, 0x364, 0x026, 0x002,
> +    0x001, 0x01d, 0x3a7, 0x022, 0x397, 0x200, 0x044, 0x1b7,
> +    0x000, 0x000, 0x014, 0x3c4, 0x3bf, 0x233, 0x364, 0x026,
> +    0x002, 0x001, 0x00c, 0x208, 0x244, 0x024, 0x3a7, 0x022,
> +    0x397, 0x200, 0x044, 0x1a9, 0x000, 0x043, 0x081, 0x189,
> +    0x2e4, 0x001, 0x001, 0x009, 0x3a7, 0x020, 0x044, 0x1a9,
> +    0x000, 0x000, 0x008, 0x3a7, 0x020, 0x208, 0x044, 0x1b8,
> +    0x000, 0x020, 0x181, 0x006, 0x043, 0x0a0, 0x041, 0x020,
> +    0x181, 0x006, 0x2e2, 0x00f, 0x001, 0x060, 0x307, 0x2cf,
> +    0x0c0, 0x2d3, 0x120, 0x001, 0x05f, 0x00b, 0x018, 0x0c1,
> +    0x2d3, 0x3c4, 0x00f, 0x2cf, 0x3c5, 0x100, 0x200, 0x000,
> +    0x048, 0x0c0, 0x2d8, 0x3a4, 0x3f7, 0x001, 0x042, 0x0c1,
> +    0x2d8, 0x2c7, 0x2da, 0x000, 0x03c, 0x2e4, 0x008, 0x009,
> +    0x3f2, 0x2e2, 0x004, 0x009, 0x021, 0x364, 0x026, 0x002,
> +    0x001, 0x3cc, 0x364, 0x027, 0x010, 0x001, 0x3c7, 0x140,
> +    0x2f9, 0x009, 0x3c3, 0x140, 0x2d8, 0x001, 0x3bf, 0x327,
> +    0x2da, 0x364, 0x026, 0x002, 0x001, 0x3b8, 0x364, 0x2cf,
> +    0x073, 0x029, 0x1dc, 0x007, 0x3c4, 0x08f, 0x2cf, 0x2e4,
> +    0x003, 0x001, 0x010, 0x287, 0x1b5, 0x2c7, 0x2d4, 0x384,
> +    0x007, 0x183, 0x245, 0x2cf, 0x3c5, 0x040, 0x200, 0x0c0,
> +    0x2f9, 0x020, 0x181, 0x006, 0x30a, 0x2cf, 0x384, 0x020,
> +    0x000, 0x3f2, 0x347, 0x2cf, 0x2f9, 0x3c4, 0x3df, 0x2cf,
> +    0x000, 0x3f1, 0x042, 0x2c7, 0x269, 0x287, 0x384, 0x0ff,
> +    0x1a1, 0x002, 0x00b, 0x00b, 0x014, 0x247, 0x28d, 0x044,
> +    0x2fb, 0x002, 0x000, 0x005, 0x044, 0x125, 0x003, 0x140,
> +    0x269, 0x00b, 0x01b, 0x0a1, 0x044, 0x30f, 0x002, 0x140,
> +    0x269, 0x00b, 0x013, 0x364, 0x012, 0x040, 0x001, 0x3fd,
> +    0x347, 0x00e, 0x266, 0x347, 0x00f, 0x267, 0x397, 0x200,
> +    0x0a1, 0x044, 0x0fb, 0x002, 0x347, 0x28d, 0x268, 0x307,
> +    0x269, 0x197, 0x384, 0x003, 0x390, 0x266, 0x04c, 0x041,
> +    0x020, 0x181, 0x006, 0x042, 0x247, 0x265, 0x041, 0x397,
> +    0x007, 0x189, 0x395, 0x2ca, 0x1bb, 0x3a4, 0x007, 0x280,
> +    0x050, 0x043, 0x041, 0x1b7, 0x3a4, 0x00f, 0x280, 0x043,
> +    0x364, 0x265, 0x100, 0x009, 0x01b, 0x120, 0x00b, 0x008,
> +    0x3a4, 0x0ff, 0x2a8, 0x121, 0x000, 0x004, 0x3a4, 0x0ff,
> +    0x04d, 0x041, 0x044, 0x3f0, 0x002, 0x044, 0x3de, 0x002,
> +    0x044, 0x06e, 0x003, 0x020, 0x181, 0x006, 0x04c, 0x041,
> +    0x000, 0x3fb, 0x2c4, 0x2a1, 0x28e, 0x293, 0x2b2, 0x2d4,
> +    0x2e4, 0x347, 0x22e, 0x22f, 0x2c7, 0x22e, 0x2e4, 0x040,
> +    0x001, 0x01a, 0x3a7, 0x080, 0x044, 0x192, 0x000, 0x384,
> +    0x3c3, 0x327, 0x22e, 0x1b5, 0x3a4, 0x03c, 0x285, 0x3a7,
> +    0x080, 0x044, 0x1bd, 0x000, 0x347, 0x22f, 0x22e, 0x020,
> +    0x181, 0x006, 0x3c5, 0x004, 0x233, 0x364, 0x22e, 0x001,
> +    0x009, 0x005, 0x3c4, 0x3fb, 0x233, 0x364, 0x22e, 0x020,
> +    0x009, 0x005, 0x080, 0x000, 0x003, 0x081, 0x044, 0x254,
> +    0x001, 0x364, 0x22e, 0x001, 0x001, 0x007, 0x0c8, 0x291,
> +    0x044, 0x06e, 0x003, 0x307, 0x22e, 0x20a, 0x384, 0x001,
> +    0x044, 0x045, 0x008, 0x020, 0x181, 0x006, 0x2c7, 0x223,
> +    0x0c0, 0x224, 0x000, 0x01e, 0x309, 0x223, 0x002, 0x01d,
> +    0x003, 0x020, 0x001, 0x030, 0x362, 0x224, 0x001, 0x003,
> +    0x011, 0x112, 0x001, 0x01f, 0x112, 0x001, 0x057, 0x116,
> +    0x001, 0x06a, 0x114, 0x001, 0x055, 0x112, 0x001, 0x060,
> +    0x020, 0x181, 0x006, 0x20e, 0x384, 0x0ff, 0x000, 0x055,
> +    0x041, 0x229, 0x1b1, 0x042, 0x044, 0x1bd, 0x000, 0x000,
> +    0x3f1, 0x344, 0x21f, 0x02a, 0x083, 0x18b, 0x245, 0x02a,
> +    0x000, 0x005, 0x344, 0x21f, 0x029, 0x3b4, 0x3ff, 0x307,
> +    0x224, 0x262, 0x007, 0x00e, 0x3dd, 0x20a, 0x183, 0x247,
> +    0x02d, 0x30a, 0x224, 0x002, 0x006, 0x2c7, 0x02c, 0x000,
> +    0x009, 0x287, 0x189, 0x245, 0x02c, 0x1b5, 0x2c5, 0x02d,
> +    0x307, 0x223, 0x001, 0x00a, 0x3c5, 0x080, 0x02d, 0x3c4,
> +    0x37f, 0x02d, 0x000, 0x030, 0x3c5, 0x040, 0x02d, 0x3c4,
> +    0x3bf, 0x02d, 0x000, 0x028, 0x397, 0x013, 0x000, 0x004,
> +    0x397, 0x2c7, 0x300, 0x224, 0x140, 0x224, 0x009, 0x005,
> +    0x04d, 0x101, 0x0a0, 0x04d, 0x000, 0x016, 0x2c7, 0x2cb,
> +    0x000, 0x3a0, 0x140, 0x224, 0x009, 0x006, 0x2c7, 0x019,
> +    0x000, 0x00a, 0x08f, 0x18b, 0x208, 0x244, 0x018, 0x1ab,
> +    0x2c5, 0x018, 0x141, 0x224, 0x000, 0x38c, 0x042, 0x309,
> +    0x223, 0x002, 0x03e, 0x003, 0x043, 0x116, 0x001, 0x049,
> +    0x112, 0x001, 0x00e, 0x114, 0x029, 0x1dd, 0x007, 0x397,
> +    0x200, 0x300, 0x224, 0x04c, 0x041, 0x000, 0x3e5, 0x307,
> +    0x224, 0x262, 0x007, 0x02e, 0x1dd, 0x007, 0x364, 0x026,
> +    0x004, 0x029, 0x1dd, 0x007, 0x20a, 0x187, 0x0a3, 0x1a7,
> +    0x2a8, 0x2c4, 0x02a, 0x245, 0x02a, 0x327, 0x02e, 0x307,
> +    0x224, 0x20a, 0x00a, 0x009, 0x1b9, 0x307, 0x02f, 0x384,
> +    0x00f, 0x185, 0x225, 0x3b4, 0x3ff, 0x000, 0x022, 0x20a,
> +    0x384, 0x0ff, 0x04c, 0x041, 0x000, 0x344, 0x304, 0x21f,
> +    0x22e, 0x044, 0x192, 0x000, 0x040, 0x000, 0x33b, 0x30a,
> +    0x224, 0x002, 0x011, 0x307, 0x00d, 0x3c4, 0x3f7, 0x00d,
> +    0x347, 0x00f, 0x26a, 0x327, 0x00e, 0x247, 0x00d, 0x041,
> +    0x000, 0x39a, 0x327, 0x26a, 0x000, 0x3fb, 0x04e, 0x020,
> +    0x23b, 0x009, 0x020, 0x28e, 0x00a, 0x020, 0x03a, 0x00a,
> +    0x020, 0x0fe, 0x00a, 0x020, 0x3f3, 0x008, 0x020, 0x013,
> +    0x009, 0x020, 0x075, 0x00a, 0x0c1, 0x244, 0x3c5, 0x040,
> +    0x245, 0x3c4, 0x3bf, 0x200, 0x044, 0x172, 0x000, 0x020,
> +    0x0d3, 0x000, 0x020, 0x2c3, 0x008, 0x020, 0x375, 0x00b,
> +    0x0c1, 0x201, 0x045, 0x020, 0x04a, 0x009, 0x020, 0x04e,
> +    0x009, 0x020, 0x256, 0x002, 0x020, 0x17f, 0x009, 0x020,
> +    0x23f, 0x006, 0x020, 0x285, 0x00a, 0x020, 0x209, 0x00b,
> +    0x020, 0x257, 0x006, 0x020, 0x117, 0x008, 0x020, 0x394,
> +    0x00a, 0x020, 0x048, 0x00b, 0x020, 0x1dc, 0x007, 0x020,
> +    0x27f, 0x00a, 0x020, 0x2d2, 0x006, 0x020, 0x1e2, 0x007,
> +    0x020, 0x295, 0x00b, 0x020, 0x3a8, 0x001, 0x020, 0x277,
> +    0x00b, 0x020, 0x2ba, 0x00b, 0x020, 0x2d5, 0x006, 0x020,
> +    0x326, 0x006, 0x020, 0x350, 0x006, 0x020, 0x1dc, 0x007,
> +    0x020, 0x35a, 0x006, 0x020, 0x0a4, 0x00b, 0x020, 0x38e,
> +    0x006, 0x020, 0x011, 0x007, 0x020, 0x016, 0x007, 0x020,
> +    0x31e, 0x007, 0x020, 0x324, 0x007, 0x020, 0x3b6, 0x007,
> +    0x020, 0x02a, 0x007, 0x020, 0x041, 0x007, 0x020, 0x060,
> +    0x007, 0x020, 0x06d, 0x007, 0x020, 0x072, 0x007, 0x020,
> +    0x2d1, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007,
> +    0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x252,
> +    0x007, 0x020, 0x293, 0x007, 0x020, 0x2d8, 0x00b, 0x020,
> +    0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x16f, 0x007,
> +    0x020, 0x185, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc,
> +    0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020,
> +    0x30e, 0x00b, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007,
> +    0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc,
> +    0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020,
> +    0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x077, 0x007,
> +    0x020, 0x0b1, 0x007, 0x020, 0x103, 0x007, 0x020, 0x1c5,
> +    0x008, 0x020, 0x1dc, 0x007, 0x020, 0x168, 0x007, 0x287,
> +    0x264, 0x004, 0x001, 0x049, 0x3c5, 0x00c, 0x00c, 0x3c5,
> +    0x020, 0x33b, 0x18e, 0x00a, 0x013, 0x044, 0x04c, 0x004,
> +    0x3a4, 0x001, 0x001, 0x014, 0x364, 0x052, 0x001, 0x009,
> +    0x093, 0x044, 0x0bc, 0x004, 0x000, 0x08e, 0x3c4, 0x2ff,
> +    0x053, 0x3c4, 0x030, 0x027, 0x000, 0x3ec, 0x3c4, 0x3fe,
> +    0x052, 0x000, 0x081, 0x043, 0x327, 0x33b, 0x020, 0x1de,
> +    0x007, 0x2e4, 0x080, 0x009, 0x00d, 0x3d5, 0x220, 0x33c,
> +    0x100, 0x009, 0x06e, 0x044, 0x3b6, 0x003, 0x000, 0x06c,
> +    0x3d5, 0x120, 0x33c, 0x100, 0x009, 0x022, 0x044, 0x066,
> +    0x004, 0x000, 0x061, 0x384, 0x003, 0x3c4, 0x3df, 0x33b,
> +    0x262, 0x003, 0x001, 0x3d9, 0x3c4, 0x32d, 0x33c, 0x3c4,
> +    0x3ef, 0x027, 0x2e4, 0x040, 0x009, 0x3d5, 0x100, 0x009,
> +    0x007, 0x044, 0x063, 0x004, 0x000, 0x046, 0x364, 0x200,
> +    0x004, 0x029, 0x1dc, 0x007, 0x0c0, 0x2d8, 0x111, 0x001,
> +    0x028, 0x3c5, 0x002, 0x33c, 0x3c5, 0x001, 0x33b, 0x344,
> +    0x21f, 0x33c, 0x287, 0x19b, 0x247, 0x361, 0x287, 0x183,
> +    0x19b, 0x247, 0x360, 0x0c0, 0x35e, 0x2e4, 0x020, 0x001,
> +    0x004, 0x0c5, 0x35e, 0x2e4, 0x010, 0x001, 0x005, 0x3c5,
> +    0x080, 0x33c, 0x289, 0x384, 0x010, 0x245, 0x33c, 0x044,
> +    0x001, 0x004, 0x364, 0x33c, 0x002, 0x001, 0x005, 0x3c5,
> +    0x004, 0x200, 0x364, 0x33c, 0x020, 0x009, 0x005, 0x044,
> +    0x097, 0x004, 0x020, 0x181, 0x006, 0x287, 0x19b, 0x11d,
> +    0x001, 0x002, 0x287, 0x1a3, 0x1b3, 0x19b, 0x180, 0x390,
> +    0x1d7, 0x040, 0x199, 0x390, 0x008, 0x040, 0x045, 0x000,
> +    0x021, 0x000, 0x073, 0x000, 0x05f, 0x000, 0x023, 0x000,
> +    0x025, 0x000, 0x033, 0x000, 0x035, 0x000, 0x037, 0x000,
> +    0x041, 0x000, 0x01f, 0x000, 0x021, 0x000, 0x023, 0x000,
> +    0x031, 0x000, 0x082, 0x000, 0x002, 0x020, 0x1dc, 0x007,
> +    0x044, 0x378, 0x003, 0x3c4, 0x3fd, 0x233, 0x000, 0x072,
> +    0x2c7, 0x363, 0x000, 0x06e, 0x2c7, 0x362, 0x000, 0x06a,
> +    0x2c7, 0x341, 0x000, 0x066, 0x2c7, 0x33f, 0x000, 0x062,
> +    0x2c7, 0x340, 0x000, 0x05e, 0x2c7, 0x344, 0x000, 0x05a,
> +    0x2c7, 0x342, 0x000, 0x056, 0x2c7, 0x343, 0x000, 0x052,
> +    0x2c7, 0x341, 0x2c7, 0x33f, 0x2c7, 0x340, 0x000, 0x04a,
> +    0x307, 0x340, 0x300, 0x341, 0x300, 0x33f, 0x282, 0x007,
> +    0x006, 0x2c7, 0x23e, 0x000, 0x03d, 0x043, 0x0a1, 0x020,
> +    0x1de, 0x007, 0x287, 0x384, 0x003, 0x181, 0x3c4, 0x3f3,
> +    0x052, 0x245, 0x052, 0x3a4, 0x00c, 0x3c4, 0x3f3, 0x33c,
> +    0x2c5, 0x33c, 0x000, 0x026, 0x3c5, 0x002, 0x233, 0x3c7,
> +    0x3ff, 0x352, 0x3c7, 0x3ff, 0x353, 0x1d3, 0x353, 0x0cf,
> +    0x354, 0x1cb, 0x354, 0x3c5, 0x0c0, 0x354, 0x3c9, 0x222,
> +    0x355, 0x3c5, 0x001, 0x33c, 0x0c0, 0x356, 0x1b0, 0x00a,
> +    0x006, 0x081, 0x18a, 0x247, 0x356, 0x1ab, 0x2c7, 0x357,
> +    0x020, 0x181, 0x006, 0x287, 0x001, 0x025, 0x197, 0x3a4,
> +    0x00f, 0x262, 0x003, 0x001, 0x03d, 0x131, 0x001, 0x020,
> +    0x131, 0x001, 0x021, 0x131, 0x001, 0x022, 0x131, 0x001,
> +    0x025, 0x131, 0x001, 0x026, 0x131, 0x001, 0x027, 0x132,
> +    0x182, 0x390, 0x377, 0x280, 0x04c, 0x042, 0x020, 0x1de,
> +    0x007, 0x044, 0x361, 0x003, 0x000, 0x3d4, 0x327, 0x373,
> +    0x000, 0x3f5, 0x327, 0x372, 0x000, 0x3f1, 0x327, 0x2b3,
> +    0x322, 0x2b2, 0x000, 0x3eb, 0x327, 0x374, 0x000, 0x3e7,
> +    0x327, 0x375, 0x000, 0x3e3, 0x327, 0x376, 0x000, 0x3df,
> +    0x307, 0x369, 0x282, 0x272, 0x369, 0x00e, 0x003, 0x108,
> +    0x04c, 0x000, 0x3d4, 0x364, 0x33c, 0x001, 0x001, 0x01b,
> +    0x364, 0x33b, 0x020, 0x009, 0x016, 0x0a0, 0x307, 0x04f,
> +    0x181, 0x00a, 0x003, 0x0a4, 0x100, 0x00b, 0x004, 0x3a5,
> +    0x080, 0x307, 0x050, 0x194, 0x384, 0x040, 0x225, 0x2c7,
> +    0x392, 0x081, 0x189, 0x314, 0x053, 0x001, 0x007, 0x3c5,
> +    0x008, 0x027, 0x000, 0x005, 0x3c4, 0x3f7, 0x027, 0x364,
> +    0x33c, 0x020, 0x001, 0x007, 0x347, 0x21d, 0x35a, 0x000,
> +    0x018, 0x347, 0x050, 0x368, 0x3b7, 0x201, 0x1a5, 0x140,
> +    0x04f, 0x00b, 0x00b, 0x364, 0x052, 0x020, 0x001, 0x3f3,
> +    0x2c5, 0x33c, 0x000, 0x005, 0x2a8, 0x2c4, 0x33c, 0x081,
> +    0x189, 0x304, 0x053, 0x001, 0x007, 0x3c5, 0x008, 0x027,
> +    0x000, 0x005, 0x3c4, 0x3f7, 0x027, 0x3c5, 0x080, 0x053,
> +    0x3c4, 0x37f, 0x053, 0x364, 0x33b, 0x020, 0x009, 0x00a,
> +    0x364, 0x33c, 0x020, 0x009, 0x005, 0x044, 0x132, 0x004,
> +    0x020, 0x08d, 0x006, 0x2c7, 0x231, 0x2e4, 0x100, 0x001,
> +    0x045, 0x2e4, 0x001, 0x001, 0x020, 0x3b7, 0x213, 0x084,
> +    0x044, 0x1a9, 0x000, 0x3b7, 0x250, 0x084, 0x044, 0x1a9,
> +    0x000, 0x399, 0x305, 0x3a7, 0x022, 0x044, 0x1a9, 0x000,
> +    0x044, 0x322, 0x001, 0x3c5, 0x002, 0x024, 0x3c5, 0x008,
> +    0x292, 0x000, 0x020, 0x3c4, 0x3fd, 0x024, 0x364, 0x234,
> +    0x002, 0x001, 0x009, 0x3a7, 0x022, 0x399, 0x305, 0x044,
> +    0x1b7, 0x000, 0x3b7, 0x213, 0x084, 0x044, 0x1b7, 0x000,
> +    0x3b7, 0x250, 0x084, 0x044, 0x1b7, 0x000, 0x3c4, 0x007,
> +    0x292, 0x044, 0x06e, 0x003, 0x307, 0x231, 0x274, 0x200,
> +    0x001, 0x01b, 0x274, 0x010, 0x001, 0x00b, 0x387, 0x020,
> +    0x245, 0x021, 0x185, 0x245, 0x024, 0x000, 0x00b, 0x387,
> +    0x3df, 0x244, 0x021, 0x185, 0x385, 0x0ff, 0x244, 0x024,
> +    0x044, 0x03a, 0x00a, 0x045, 0x327, 0x230, 0x364, 0x233,
> +    0x004, 0x001, 0x003, 0x045, 0x0c2, 0x22a, 0x347, 0x275,
> +    0x270, 0x0c0, 0x27b, 0x264, 0x010, 0x009, 0x00a, 0x0c1,
> +    0x22a, 0x347, 0x274, 0x270, 0x3d7, 0x200, 0x27b, 0x327,
> +    0x230, 0x264, 0x004, 0x001, 0x012, 0x347, 0x277, 0x270,
> +    0x264, 0x010, 0x009, 0x007, 0x347, 0x276, 0x270, 0x384,
> +    0x00f, 0x112, 0x1b7, 0x000, 0x004, 0x3a4, 0x0ff, 0x2c7,
> +    0x225, 0x384, 0x00f, 0x262, 0x003, 0x001, 0x00b, 0x101,
> +    0x3c2, 0x100, 0x270, 0x34a, 0x225, 0x225, 0x000, 0x3f3,
> +    0x044, 0x237, 0x00a, 0x044, 0x35f, 0x009, 0x364, 0x22a,
> +    0x002, 0x001, 0x006, 0x347, 0x270, 0x272, 0x045, 0x347,
> +    0x270, 0x271, 0x045, 0x044, 0x2f6, 0x002, 0x009, 0x015,
> +    0x307, 0x241, 0x197, 0x384, 0x007, 0x001, 0x008, 0x3c2,
> +    0x100, 0x270, 0x111, 0x009, 0x3fc, 0x3d7, 0x200, 0x27b,
> +    0x044, 0x35f, 0x009, 0x347, 0x241, 0x226, 0x0c1, 0x22a,
> +    0x020, 0x032, 0x009, 0x044, 0x2f6, 0x002, 0x009, 0x014,
> +    0x307, 0x243, 0x197, 0x384, 0x007, 0x001, 0x008, 0x3c2,
> +    0x100, 0x270, 0x111, 0x009, 0x3fc, 0x0c0, 0x27b, 0x044,
> +    0x35f, 0x009, 0x347, 0x243, 0x226, 0x0c2, 0x22a, 0x020,
> +    0x032, 0x009, 0x327, 0x226, 0x2c7, 0x225, 0x3c4, 0x0ff,
> +    0x225, 0x1b7, 0x3a4, 0x007, 0x001, 0x00d, 0x34a, 0x225,
> +    0x225, 0x002, 0x008, 0x131, 0x009, 0x3fa, 0x044, 0x237,
> +    0x00a, 0x045, 0x0c1, 0x26f, 0x000, 0x050, 0x327, 0x01d,
> +    0x2e4, 0x380, 0x009, 0x00a, 0x13a, 0x00b, 0x00a, 0x3c5,
> +    0x008, 0x233, 0x000, 0x005, 0x3c4, 0x3f7, 0x233, 0x327,
> +    0x01d, 0x021, 0x2ed, 0x009, 0x364, 0x020, 0x004, 0x009,
> +    0x01a, 0x309, 0x232, 0x00b, 0x009, 0x347, 0x270, 0x271,
> +    0x308, 0x221, 0x244, 0x232, 0x347, 0x271, 0x270, 0x044,
> +    0x270, 0x009, 0x001, 0x04c, 0x347, 0x270, 0x271, 0x000,
> +    0x018, 0x309, 0x232, 0x001, 0x009, 0x347, 0x270, 0x272,
> +    0x308, 0x221, 0x244, 0x232, 0x347, 0x272, 0x270, 0x044,
> +    0x270, 0x009, 0x001, 0x089, 0x347, 0x270, 0x272, 0x397,
> +    0x200, 0x044, 0x1b1, 0x001, 0x364, 0x26f, 0x002, 0x009,
> +    0x005, 0x3c4, 0x3fe, 0x200, 0x364, 0x020, 0x005, 0x029,
> +    0x2e4, 0x002, 0x364, 0x020, 0x010, 0x009, 0x0e9, 0x364,
> +    0x020, 0x100, 0x009, 0x12b, 0x020, 0x2e4, 0x002, 0x3c4,
> +    0x3f7, 0x233, 0x364, 0x020, 0x001, 0x009, 0x00c, 0x364,
> +    0x020, 0x004, 0x009, 0x05d, 0x000, 0x3d8, 0x3c5, 0x080,
> +    0x020, 0x364, 0x233, 0x006, 0x001, 0x031, 0x081, 0x189,
> +    0x304, 0x232, 0x009, 0x017, 0x347, 0x271, 0x274, 0x080,
> +    0x364, 0x233, 0x004, 0x009, 0x003, 0x085, 0x0c1, 0x22a,
> +    0x044, 0x39c, 0x008, 0x081, 0x189, 0x245, 0x232, 0x000,
> +    0x0c8, 0x347, 0x271, 0x276, 0x081, 0x189, 0x208, 0x244,
> +    0x232, 0x307, 0x22b, 0x197, 0x384, 0x007, 0x0c1, 0x22a,
> +    0x044, 0x39c, 0x008, 0x000, 0x005, 0x044, 0x3f3, 0x008,
> +    0x3b7, 0x200, 0x387, 0x3df, 0x044, 0x1b8, 0x000, 0x3b7,
> +    0x203, 0x387, 0x3f7, 0x044, 0x1b8, 0x000, 0x307, 0x020,
> +    0x385, 0x042, 0x384, 0x3ce, 0x247, 0x020, 0x044, 0x044,
> +    0x001, 0x000, 0x383, 0x0a1, 0x1aa, 0x2c5, 0x020, 0x364,
> +    0x233, 0x006, 0x001, 0x039, 0x081, 0x189, 0x304, 0x232,
> +    0x009, 0x017, 0x347, 0x272, 0x275, 0x080, 0x364, 0x233,
> +    0x004, 0x009, 0x003, 0x095, 0x0c2, 0x22a, 0x044, 0x39c,
> +    0x008, 0x081, 0x189, 0x245, 0x232, 0x000, 0x0ce, 0x347,
> +    0x272, 0x277, 0x081, 0x189, 0x208, 0x244, 0x232, 0x307,
> +    0x22b, 0x197, 0x364, 0x233, 0x002, 0x001, 0x007, 0x193,
> +    0x384, 0x007, 0x385, 0x010, 0x0c2, 0x22a, 0x044, 0x39c,
> +    0x008, 0x000, 0x008, 0x347, 0x272, 0x270, 0x044, 0x013,
> +    0x009, 0x081, 0x18a, 0x208, 0x244, 0x232, 0x0a3, 0x387,
> +    0x3f7, 0x044, 0x1b8, 0x000, 0x307, 0x020, 0x0a4, 0x1a7,
> +    0x3a5, 0x008, 0x285, 0x3b7, 0x304, 0x2a8, 0x284, 0x247,
> +    0x020, 0x0a0, 0x387, 0x3df, 0x044, 0x1b8, 0x000, 0x044,
> +    0x2f6, 0x002, 0x009, 0x00f, 0x364, 0x2cf, 0x080, 0x009,
> +    0x00a, 0x0c3, 0x26f, 0x044, 0x1b6, 0x001, 0x020, 0x2e4,
> +    0x002, 0x044, 0x051, 0x001, 0x000, 0x308, 0x3c4, 0x3f7,
> +    0x233, 0x364, 0x233, 0x006, 0x001, 0x013, 0x044, 0x2f6,
> +    0x002, 0x009, 0x00e, 0x081, 0x364, 0x233, 0x004, 0x009,
> +    0x003, 0x083, 0x0c1, 0x22a, 0x044, 0x39c, 0x008, 0x3d7,
> +    0x200, 0x27b, 0x0c0, 0x271, 0x3b7, 0x300, 0x387, 0x3df,
> +    0x044, 0x1b8, 0x000, 0x3b7, 0x221, 0x091, 0x189, 0x044,
> +    0x1a9, 0x000, 0x3b7, 0x201, 0x387, 0x0a6, 0x044, 0x1bd,
> +    0x000, 0x3c5, 0x021, 0x020, 0x3c4, 0x3ed, 0x020, 0x3b7,
> +    0x200, 0x387, 0x020, 0x044, 0x020, 0x00a, 0x009, 0x32a,
> +    0x347, 0x271, 0x270, 0x000, 0x055, 0x3a7, 0x071, 0x307,
> +    0x21d, 0x044, 0x1b7, 0x000, 0x3c4, 0x3f7, 0x233, 0x044,
> +    0x2f6, 0x002, 0x009, 0x007, 0x0c1, 0x2d3, 0x3c5, 0x100,
> +    0x200, 0x081, 0x18a, 0x245, 0x232, 0x364, 0x233, 0x006,
> +    0x001, 0x013, 0x044, 0x2f6, 0x002, 0x009, 0x00e, 0x081,
> +    0x364, 0x233, 0x004, 0x009, 0x003, 0x093, 0x0c2, 0x22a,
> +    0x044, 0x39c, 0x008, 0x0c0, 0x27b, 0x0c0, 0x272, 0x3b7,
> +    0x300, 0x387, 0x020, 0x044, 0x1a9, 0x000, 0x0a1, 0x397,
> +    0x205, 0x247, 0x27f, 0x044, 0x1bd, 0x000, 0x3d5, 0x204,
> +    0x020, 0x3c4, 0x2ff, 0x020, 0x0a0, 0x387, 0x021, 0x184,
> +    0x044, 0x020, 0x00a, 0x009, 0x336, 0x347, 0x272, 0x270,
> +    0x044, 0x35f, 0x009, 0x397, 0x200, 0x044, 0x1b1, 0x001,
> +    0x020, 0x2e4, 0x002, 0x3c4, 0x3fe, 0x200, 0x3c4, 0x3fe,
> +    0x26f, 0x344, 0x21f, 0x232, 0x0c0, 0x020, 0x0a3, 0x1ab,
> +    0x2c5, 0x020, 0x044, 0x20d, 0x000, 0x044, 0x2f3, 0x000,
> +    0x044, 0x3b5, 0x000, 0x044, 0x3f0, 0x000, 0x0a9, 0x1ab,
> +    0x09f, 0x18a, 0x208, 0x304, 0x055, 0x225, 0x044, 0x394,
> +    0x00a, 0x307, 0x055, 0x19b, 0x384, 0x003, 0x227, 0x1a3,
> +    0x225, 0x044, 0x0a4, 0x00b, 0x0a7, 0x020, 0x022, 0x008,
> +    0x327, 0x220, 0x324, 0x232, 0x001, 0x006, 0x387, 0x07f,
> +    0x000, 0x013, 0x399, 0x240, 0x385, 0x07f, 0x306, 0x270,
> +    0x001, 0x06c, 0x399, 0x240, 0x327, 0x270, 0x3a4, 0x380,
> +    0x226, 0x001, 0x015, 0x327, 0x220, 0x324, 0x232, 0x009,
> +    0x019, 0x364, 0x232, 0x001, 0x001, 0x02b, 0x327, 0x01d,
> +    0x307, 0x01b, 0x190, 0x282, 0x003, 0x041, 0x307, 0x01b,
> +    0x191, 0x380, 0x010, 0x282, 0x003, 0x034, 0x000, 0x019,
> +    0x327, 0x220, 0x324, 0x232, 0x001, 0x00a, 0x327, 0x270,
> +    0x384, 0x07f, 0x3a4, 0x07f, 0x000, 0x008, 0x327, 0x270,
> +    0x3a4, 0x07f, 0x001, 0x005, 0x286, 0x001, 0x02f, 0x307,
> +    0x270, 0x384, 0x07f, 0x386, 0x07f, 0x009, 0x00a, 0x387,
> +    0x080, 0x382, 0x07f, 0x240, 0x270, 0x000, 0x01c, 0x141,
> +    0x270, 0x364, 0x270, 0x07f, 0x009, 0x015, 0x000, 0x013,
> +    0x3c0, 0x040, 0x270, 0x000, 0x00e, 0x307, 0x270, 0x196,
> +    0x384, 0x00f, 0x266, 0x009, 0x001, 0x008, 0x3c0, 0x080,
> +    0x270, 0x044, 0x35f, 0x009, 0x045, 0x309, 0x232, 0x00b,
> +    0x013, 0x347, 0x271, 0x270, 0x374, 0x27b, 0x200, 0x009,
> +    0x005, 0x347, 0x272, 0x270, 0x044, 0x35f, 0x009, 0x020,
> +    0x0b7, 0x009, 0x327, 0x232, 0x1a2, 0x023, 0x0b7, 0x009,
> +    0x307, 0x270, 0x196, 0x119, 0x021, 0x0b7, 0x009, 0x307,
> +    0x232, 0x181, 0x023, 0x0b7, 0x009, 0x364, 0x270, 0x080,
> +    0x029, 0x0b7, 0x009, 0x083, 0x18c, 0x245, 0x232, 0x3c4,
> +    0x3f7, 0x233, 0x3c4, 0x380, 0x270, 0x3c0, 0x080, 0x270,
> +    0x044, 0x35f, 0x009, 0x397, 0x200, 0x044, 0x1b1, 0x001,
> +    0x020, 0x09c, 0x009, 0x000, 0x000, 0x000, 0x002, 0x000,
> +    0x00a, 0x000, 0x02a, 0x000, 0x0aa, 0x002, 0x0aa, 0x00a,
> +    0x0aa, 0x02a, 0x0aa, 0x06a, 0x0aa, 0x07a, 0x0aa, 0x07e,
> +    0x0aa, 0x07f, 0x0aa, 0x07f, 0x0ba, 0x07f, 0x0be, 0x07f,
> +    0x0fe, 0x07f, 0x0ff, 0x007, 0x000, 0x017, 0x001, 0x027,
> +    0x007, 0x037, 0x00f, 0x047, 0x03f, 0x080, 0x0ff, 0x364,
> +    0x270, 0x07f, 0x307, 0x270, 0x384, 0x07f, 0x009, 0x00d,
> +    0x089, 0x186, 0x306, 0x270, 0x001, 0x007, 0x3c5, 0x001,
> +    0x232, 0x000, 0x005, 0x3c4, 0x3fe, 0x232, 0x347, 0x270,
> +    0x27c, 0x3c4, 0x007, 0x27c, 0x374, 0x27b, 0x200, 0x001,
> +    0x00a, 0x364, 0x233, 0x008, 0x001, 0x005, 0x044, 0x0fe,
> +    0x00a, 0x0a3, 0x325, 0x27b, 0x044, 0x192, 0x000, 0x384,
> +    0x3f8, 0x305, 0x27c, 0x044, 0x1bd, 0x000, 0x307, 0x270,
> +    0x192, 0x384, 0x00f, 0x3b9, 0x200, 0x324, 0x233, 0x001,
> +    0x014, 0x229, 0x387, 0x009, 0x189, 0x395, 0x333, 0x280,
> +    0x051, 0x2c7, 0x27d, 0x1c7, 0x27d, 0x101, 0x051, 0x2c5,
> +    0x27d, 0x000, 0x011, 0x0c0, 0x27d, 0x384, 0x00f, 0x001,
> +    0x00b, 0x349, 0x27d, 0x27d, 0x3c5, 0x001, 0x27d, 0x111,
> +    0x000, 0x3f7, 0x0a2, 0x325, 0x27b, 0x307, 0x27d, 0x044,
> +    0x1bd, 0x000, 0x374, 0x27b, 0x200, 0x001, 0x02c, 0x347,
> +    0x270, 0x27a, 0x3c4, 0x07f, 0x27a, 0x0c0, 0x279, 0x387,
> +    0x009, 0x189, 0x395, 0x353, 0x051, 0x041, 0x101, 0x051,
> +    0x2c7, 0x279, 0x101, 0x043, 0x322, 0x27a, 0x00b, 0x004,
> +    0x000, 0x3f4, 0x1c7, 0x279, 0x0a3, 0x325, 0x27b, 0x044,
> +    0x192, 0x000, 0x384, 0x0ff, 0x305, 0x279, 0x044, 0x1bd,
> +    0x000, 0x327, 0x220, 0x324, 0x232, 0x009, 0x022, 0x0c0,
> +    0x27e, 0x307, 0x270, 0x197, 0x00a, 0x004, 0x000, 0x005,
> +    0x3c5, 0x018, 0x27e, 0x0a4, 0x222, 0x2c5, 0x27e, 0x0a4,
> +    0x325, 0x27b, 0x044, 0x192, 0x000, 0x384, 0x3e0, 0x3c4,
> +    0x01f, 0x27e, 0x305, 0x27e, 0x044, 0x1bd, 0x000, 0x045,
> +    0x044, 0x1a9, 0x000, 0x083, 0x18c, 0x208, 0x244, 0x232,
> +    0x3c5, 0x001, 0x00c, 0x0a3, 0x325, 0x27b, 0x088, 0x044,
> +    0x1a9, 0x000, 0x387, 0x3f8, 0x044, 0x1b8, 0x000, 0x020,
> +    0x2f6, 0x002, 0x3c7, 0x020, 0x280, 0x3b7, 0x215, 0x044,
> +    0x192, 0x000, 0x247, 0x247, 0x151, 0x280, 0x001, 0x016,
> +    0x0a1, 0x044, 0x182, 0x000, 0x3b7, 0x215, 0x044, 0x192,
> +    0x000, 0x306, 0x247, 0x001, 0x3f1, 0x0a2, 0x364, 0x22b,
> +    0x003, 0x001, 0x003, 0x0a5, 0x020, 0x182, 0x000, 0x1f6,
> +    0x185, 0x1f5, 0x129, 0x1f4, 0x0d0, 0x1b3, 0x0fc, 0x122,
> +    0x0ff, 0x1f6, 0x189, 0x1f5, 0x11b, 0x1f5, 0x0aa, 0x194,
> +    0x0ce, 0x123, 0x0f3, 0x0d2, 0x0ff, 0x364, 0x233, 0x020,
> +    0x009, 0x051, 0x307, 0x272, 0x196, 0x384, 0x00f, 0x0c9,
> +    0x286, 0x242, 0x286, 0x397, 0x00a, 0x189, 0x395, 0x05f,
> +    0x044, 0x2ea, 0x001, 0x009, 0x004, 0x380, 0x00a, 0x051,
> +    0x2c7, 0x284, 0x101, 0x051, 0x2c7, 0x288, 0x3a4, 0x07f,
> +    0x040, 0x307, 0x272, 0x384, 0x07f, 0x222, 0x042, 0x00b,
> +    0x005, 0x101, 0x000, 0x3ed, 0x347, 0x284, 0x285, 0x3c4,
> +    0x00f, 0x284, 0x1d3, 0x285, 0x1d6, 0x288, 0x342, 0x288,
> +    0x286, 0x003, 0x008, 0x156, 0x285, 0x151, 0x286, 0x00b,
> +    0x3fc, 0x362, 0x285, 0x003, 0x003, 0x004, 0x0c3, 0x285,
> +    0x307, 0x285, 0x0a1, 0x184, 0x305, 0x284, 0x044, 0x1bd,
> +    0x000, 0x045, 0x3db, 0x071, 0x0b9, 0x0ff, 0x089, 0x0e2,
> +    0x12c, 0x176, 0x1bf, 0x00d, 0x007, 0x006, 0x003, 0x002,
> +    0x005, 0x0b3, 0x156, 0x1fa, 0x27f, 0x080, 0x09e, 0x14b,
> +    0x1f0, 0x27f, 0x080, 0x08b, 0x140, 0x1e9, 0x27f, 0x081,
> +    0x138, 0x1e3, 0x27f, 0x00f, 0x0b2, 0x14f, 0x1f0, 0x27f,
> +    0x080, 0x0a3, 0x145, 0x1e7, 0x27f, 0x080, 0x095, 0x13d,
> +    0x1e0, 0x27f, 0x08b, 0x136, 0x1db, 0x27f, 0x0c5, 0x28b,
> +    0x347, 0x271, 0x281, 0x3c4, 0x07f, 0x281, 0x0c5, 0x282,
> +    0x044, 0x2ea, 0x001, 0x009, 0x004, 0x0c2, 0x282, 0x044,
> +    0x1bc, 0x00a, 0x347, 0x283, 0x289, 0x307, 0x241, 0x364,
> +    0x233, 0x002, 0x001, 0x004, 0x307, 0x225, 0x384, 0x0ff,
> +    0x242, 0x283, 0x00b, 0x056, 0x0c3, 0x28b, 0x302, 0x289,
> +    0x397, 0x00a, 0x189, 0x395, 0x0ca, 0x044, 0x2ea, 0x001,
> +    0x009, 0x004, 0x380, 0x004, 0x051, 0x2c7, 0x28c, 0x2a9,
> +    0x121, 0x3a4, 0x07f, 0x040, 0x307, 0x271, 0x384, 0x07f,
> +    0x282, 0x042, 0x003, 0x007, 0x001, 0x005, 0x101, 0x000,
> +    0x3ed, 0x1d5, 0x28c, 0x347, 0x241, 0x281, 0x364, 0x233,
> +    0x002, 0x001, 0x005, 0x347, 0x225, 0x281, 0x3c4, 0x0ff,
> +    0x281, 0x342, 0x289, 0x281, 0x347, 0x28c, 0x282, 0x366,
> +    0x282, 0x00f, 0x009, 0x006, 0x1c0, 0x281, 0x0c1, 0x282,
> +    0x044, 0x1bc, 0x00a, 0x001, 0x00d, 0x141, 0x28b, 0x362,
> +    0x28b, 0x03f, 0x001, 0x00d, 0x151, 0x283, 0x000, 0x3f5,
> +    0x362, 0x28b, 0x00a, 0x003, 0x004, 0x0ca, 0x28b, 0x397,
> +    0x00a, 0x189, 0x395, 0x0d8, 0x044, 0x2ea, 0x001, 0x009,
> +    0x004, 0x380, 0x013, 0x327, 0x24c, 0x131, 0x003, 0x005,
> +    0x105, 0x000, 0x3fc, 0x051, 0x2c7, 0x28a, 0x3a4, 0x07f,
> +    0x121, 0x040, 0x307, 0x271, 0x384, 0x07f, 0x282, 0x042,
> +    0x003, 0x005, 0x101, 0x000, 0x3f0, 0x1d6, 0x28a, 0x387,
> +    0x00a, 0x189, 0x395, 0x0d3, 0x300, 0x28a, 0x050, 0x247,
> +    0x28a, 0x30a, 0x28b, 0x3b7, 0x201, 0x184, 0x305, 0x28a,
> +    0x044, 0x1bd, 0x000, 0x045, 0x0c1, 0x283, 0x342, 0x282,
> +    0x281, 0x003, 0x006, 0x141, 0x283, 0x000, 0x3f9, 0x045,
> +    0x000, 0x301, 0x103, 0x307, 0x006, 0x10e, 0x21e, 0x33e,
> +    0x13c, 0x038, 0x078, 0x1f8, 0x0f0, 0x000, 0x001, 0x003,
> +    0x002, 0x006, 0x187, 0x227, 0x387, 0x00a, 0x189, 0x395,
> +    0x1c8, 0x300, 0x227, 0x111, 0x050, 0x247, 0x24c, 0x1d7,
> +    0x24c, 0x384, 0x0ff, 0x285, 0x044, 0x226, 0x00a, 0x364,
> +    0x22a, 0x001, 0x001, 0x00e, 0x3d5, 0x200, 0x232, 0x040,
> +    0x1aa, 0x285, 0x3b7, 0x220, 0x044, 0x1bd, 0x000, 0x042,
> +    0x364, 0x22a, 0x002, 0x001, 0x022, 0x040, 0x3a7, 0x073,
> +    0x044, 0x192, 0x000, 0x384, 0x31f, 0x044, 0x226, 0x00a,
> +    0x1a4, 0x285, 0x3a7, 0x073, 0x044, 0x1bd, 0x000, 0x3a7,
> +    0x070, 0x044, 0x192, 0x000, 0x19a, 0x18a, 0x043, 0x285,
> +    0x3a7, 0x070, 0x044, 0x1bd, 0x000, 0x045, 0x040, 0x387,
> +    0x00a, 0x189, 0x395, 0x1d5, 0x300, 0x278, 0x051, 0x042,
> +    0x045, 0x00a, 0x058, 0x026, 0x015, 0x044, 0x032, 0x0c0,
> +    0x278, 0x0a0, 0x397, 0x00a, 0x189, 0x395, 0x231, 0x280,
> +    0x050, 0x247, 0x228, 0x3c4, 0x00f, 0x228, 0x347, 0x228,
> +    0x229, 0x040, 0x307, 0x278, 0x001, 0x008, 0x340, 0x229,
> +    0x228, 0x111, 0x000, 0x3fa, 0x042, 0x193, 0x0c0, 0x227,
> +    0x347, 0x225, 0x226, 0x141, 0x227, 0x366, 0x227, 0x00e,
> +    0x001, 0x00b, 0x342, 0x228, 0x226, 0x007, 0x3f6, 0x140,
> +    0x226, 0x001, 0x011, 0x121, 0x2e2, 0x006, 0x009, 0x3cc,
> +    0x141, 0x278, 0x366, 0x278, 0x005, 0x009, 0x3c4, 0x0a1,
> +    0x000, 0x006, 0x044, 0x1da, 0x00a, 0x0a0, 0x045, 0x044,
> +    0x333, 0x008, 0x020, 0x181, 0x006, 0x345, 0x21d, 0x232,
> +    0x364, 0x23f, 0x001, 0x029, 0x2e4, 0x002, 0x2c7, 0x234,
> +    0x399, 0x200, 0x245, 0x233, 0x364, 0x234, 0x020, 0x009,
> +    0x005, 0x208, 0x244, 0x233, 0x083, 0x18c, 0x208, 0x244,
> +    0x036, 0x2e4, 0x008, 0x001, 0x007, 0x345, 0x220, 0x232,
> +    0x000, 0x007, 0x081, 0x18b, 0x208, 0x244, 0x232, 0x307,
> +    0x235, 0x226, 0x3a4, 0x001, 0x001, 0x010, 0x327, 0x234,
> +    0x2e4, 0x001, 0x009, 0x041, 0x041, 0x044, 0x20d, 0x000,
> +    0x044, 0x2f3, 0x000, 0x043, 0x0a3, 0x1ad, 0x3a5, 0x039,
> +    0x326, 0x236, 0x001, 0x02f, 0x3a7, 0x0bf, 0x1a7, 0x3a5,
> +    0x039, 0x326, 0x236, 0x001, 0x026, 0x327, 0x234, 0x307,
> +    0x235, 0x286, 0x384, 0x002, 0x001, 0x01d, 0x2e4, 0x002,
> +    0x009, 0x051, 0x041, 0x0a1, 0x1ad, 0x2c5, 0x024, 0x307,
> +    0x024, 0x19a, 0x002, 0x005, 0x2a8, 0x2c4, 0x024, 0x044,
> +    0x3b5, 0x000, 0x044, 0x0f2, 0x001, 0x044, 0x3f0, 0x000,
> +    0x043, 0x000, 0x067, 0x364, 0x026, 0x001, 0x009, 0x3c6,
> +    0x041, 0x0a0, 0x044, 0x301, 0x000, 0x364, 0x26f, 0x002,
> +    0x021, 0x310, 0x00a, 0x044, 0x290, 0x001, 0x0c1, 0x26f,
> +    0x043, 0x307, 0x020, 0x193, 0x384, 0x007, 0x110, 0x001,
> +    0x00c, 0x364, 0x232, 0x010, 0x009, 0x007, 0x044, 0x044,
> +    0x001, 0x000, 0x3a3, 0x3c4, 0x3fe, 0x26f, 0x3c5, 0x001,
> +    0x200, 0x3c5, 0x010, 0x020, 0x3c4, 0x31f, 0x020, 0x000,
> +    0x395, 0x364, 0x026, 0x002, 0x009, 0x3c5, 0x041, 0x044,
> +    0x003, 0x001, 0x043, 0x307, 0x020, 0x197, 0x384, 0x007,
> +    0x110, 0x001, 0x00f, 0x364, 0x232, 0x020, 0x009, 0x00a,
> +    0x044, 0x051, 0x001, 0x3c5, 0x001, 0x027, 0x000, 0x3ab,
> +    0x3c4, 0x3fc, 0x26f, 0x3c5, 0x001, 0x200, 0x3c5, 0x100,
> +    0x020, 0x087, 0x188, 0x208, 0x244, 0x020, 0x000, 0x39b,
> +    0x044, 0x11a, 0x001, 0x307, 0x234, 0x306, 0x235, 0x384,
> +    0x003, 0x021, 0x2e4, 0x002, 0x347, 0x234, 0x235, 0x366,
> +    0x26f, 0x002, 0x021, 0x2e4, 0x002, 0x364, 0x234, 0x003,
> +    0x021, 0x2e4, 0x002, 0x327, 0x21c, 0x324, 0x020, 0x021,
> +    0x385, 0x00a, 0x020, 0x247, 0x002, 0x364, 0x23f, 0x001,
> +    0x021, 0x38e, 0x00a, 0x020, 0x247, 0x002, 0x345, 0x21d,
> +    0x232, 0x020, 0x247, 0x002, 0x2c7, 0x241, 0x307, 0x242,
> +    0x286, 0x001, 0x092, 0x0c1, 0x22a, 0x327, 0x242, 0x326,
> +    0x241, 0x3a4, 0x0ff, 0x001, 0x005, 0x3c4, 0x38f, 0x020,
> +    0x347, 0x241, 0x242, 0x347, 0x241, 0x226, 0x307, 0x21d,
> +    0x304, 0x241, 0x001, 0x00a, 0x0c3, 0x22a, 0x347, 0x241,
> +    0x243, 0x044, 0x39f, 0x002, 0x327, 0x241, 0x3a4, 0x0ff,
> +    0x2c7, 0x225, 0x3c4, 0x300, 0x230, 0x2c5, 0x230, 0x044,
> +    0x099, 0x00b, 0x081, 0x18b, 0x304, 0x226, 0x009, 0x00d,
> +    0x364, 0x232, 0x100, 0x009, 0x008, 0x081, 0x18a, 0x208,
> +    0x044, 0x1b8, 0x000, 0x044, 0x186, 0x001, 0x327, 0x226,
> +    0x003, 0x032, 0x044, 0x2f6, 0x002, 0x001, 0x019, 0x044,
> +    0x237, 0x00a, 0x347, 0x241, 0x226, 0x081, 0x306, 0x22a,
> +    0x384, 0x003, 0x001, 0x005, 0x347, 0x243, 0x226, 0x044,
> +    0x032, 0x009, 0x002, 0x02d, 0x000, 0x031, 0x044, 0x237,
> +    0x00a, 0x009, 0x01c, 0x044, 0x082, 0x00b, 0x0a2, 0x1ab,
> +    0x324, 0x020, 0x001, 0x023, 0x364, 0x233, 0x001, 0x000,
> +    0x01e, 0x045, 0x044, 0x186, 0x001, 0x3c5, 0x003, 0x22a,
> +    0x347, 0x241, 0x243, 0x000, 0x3c7, 0x3a4, 0x3ff, 0x001,
> +    0x00e, 0x327, 0x21c, 0x324, 0x020, 0x009, 0x006, 0x043,
> +    0x3a7, 0x0ff, 0x041, 0x0c0, 0x270, 0x044, 0x082, 0x00b,
> +    0x3c4, 0x3fc, 0x22a, 0x327, 0x21c, 0x324, 0x020, 0x009,
> +    0x010, 0x307, 0x270, 0x003, 0x005, 0x020, 0x181, 0x006,
> +    0x043, 0x3a7, 0x0ff, 0x041, 0x020, 0x181, 0x006, 0x045,
> +    0x2c7, 0x243, 0x307, 0x250, 0x286, 0x001, 0x3de, 0x0c2,
> +    0x22a, 0x041, 0x044, 0x39f, 0x002, 0x043, 0x2c7, 0x226,
> +    0x3a4, 0x0ff, 0x2c7, 0x225, 0x3c4, 0x0ff, 0x230, 0x1a7,
> +    0x2c5, 0x230, 0x307, 0x21d, 0x304, 0x243, 0x001, 0x013,
> +    0x3c4, 0x0ff, 0x243, 0x347, 0x243, 0x241, 0x347, 0x243,
> +    0x242, 0x3c5, 0x003, 0x22a, 0x044, 0x186, 0x001, 0x000,
> +    0x005, 0x044, 0x191, 0x001, 0x327, 0x243, 0x003, 0x394,
> +    0x000, 0x362, 0x364, 0x232, 0x004, 0x001, 0x008, 0x044,
> +    0x232, 0x000, 0x3c4, 0x3fb, 0x232, 0x364, 0x232, 0x008,
> +    0x001, 0x008, 0x044, 0x326, 0x000, 0x3c4, 0x3f7, 0x232,
> +    0x045, 0x3b7, 0x221, 0x083, 0x189, 0x044, 0x1a9, 0x000,
> +    0x083, 0x020, 0x1b7, 0x000, 0x2c7, 0x24d, 0x364, 0x233,
> +    0x002, 0x001, 0x019, 0x3b9, 0x381, 0x121, 0x081, 0x18a,
> +    0x225, 0x304, 0x24d, 0x001, 0x005, 0x044, 0x1ff, 0x00b,
> +    0x140, 0x24d, 0x00b, 0x008, 0x1a3, 0x044, 0x1ff, 0x00b,
> +    0x000, 0x012, 0x307, 0x220, 0x284, 0x001, 0x00d, 0x3c4,
> +    0x33f, 0x232, 0x1b6, 0x3a4, 0x0c0, 0x2c5, 0x232, 0x020,
> +    0x18a, 0x00b, 0x327, 0x24d, 0x364, 0x020, 0x070, 0x001,
> +    0x00a, 0x399, 0x383, 0x101, 0x326, 0x22b, 0x234, 0x001,
> +    0x02e, 0x3c5, 0x080, 0x233, 0x3d5, 0x200, 0x232, 0x364,
> +    0x026, 0x001, 0x001, 0x00a, 0x3c5, 0x004, 0x232, 0x044,
> +    0x20d, 0x000, 0x307, 0x24d, 0x307, 0x24d, 0x384, 0x007,
> +    0x001, 0x09a, 0x113, 0x001, 0x0a8, 0x3b7, 0x301, 0x044,
> +    0x192, 0x000, 0x384, 0x3f8, 0x103, 0x044, 0x1bd, 0x000,
> +    0x3c4, 0x3f7, 0x021, 0x000, 0x0af, 0x0a7, 0x1a7, 0x324,
> +    0x020, 0x001, 0x014, 0x327, 0x24d, 0x326, 0x22b, 0x397,
> +    0x370, 0x364, 0x233, 0x002, 0x001, 0x006, 0x087, 0x18b,
> +    0x385, 0x070, 0x234, 0x001, 0x02b, 0x3c5, 0x100, 0x233,
> +    0x364, 0x026, 0x002, 0x001, 0x008, 0x3c5, 0x008, 0x232,
> +    0x044, 0x3b5, 0x000, 0x307, 0x24d, 0x384, 0x070, 0x001,
> +    0x091, 0x382, 0x030, 0x001, 0x0a6, 0x3b7, 0x301, 0x044,
> +    0x192, 0x000, 0x384, 0x3c7, 0x385, 0x018, 0x044, 0x1bd,
> +    0x000, 0x3c4, 0x3f7, 0x024, 0x000, 0x0a4, 0x347, 0x24d,
> +    0x22b, 0x364, 0x233, 0x006, 0x001, 0x033, 0x307, 0x22b,
> +    0x364, 0x233, 0x002, 0x001, 0x023, 0x364, 0x233, 0x080,
> +    0x001, 0x00a, 0x307, 0x24d, 0x197, 0x384, 0x007, 0x044,
> +    0x3a4, 0x008, 0x364, 0x233, 0x100, 0x001, 0x00c, 0x307,
> +    0x24d, 0x19b, 0x384, 0x007, 0x385, 0x010, 0x044, 0x3a4,
> +    0x008, 0x3c4, 0x27f, 0x233, 0x000, 0x00b, 0x3c5, 0x003,
> +    0x22a, 0x197, 0x044, 0x39c, 0x008, 0x003, 0x298, 0x044,
> +    0x082, 0x00b, 0x0a2, 0x1ab, 0x324, 0x020, 0x021, 0x181,
> +    0x006, 0x045, 0x3b7, 0x301, 0x087, 0x044, 0x1b7, 0x000,
> +    0x3b7, 0x211, 0x082, 0x044, 0x1b7, 0x000, 0x3c4, 0x3f7,
> +    0x021, 0x000, 0x36c, 0x3b7, 0x301, 0x044, 0x192, 0x000,
> +    0x384, 0x3f8, 0x105, 0x044, 0x1bd, 0x000, 0x3b7, 0x211,
> +    0x082, 0x044, 0x1a9, 0x000, 0x3c5, 0x008, 0x021, 0x344,
> +    0x21f, 0x021, 0x3b7, 0x250, 0x088, 0x044, 0x1a9, 0x000,
> +    0x3b7, 0x211, 0x082, 0x044, 0x1a9, 0x000, 0x000, 0x347,
> +    0x3b7, 0x301, 0x387, 0x3c7, 0x044, 0x1b8, 0x000, 0x3a7,
> +    0x060, 0x083, 0x044, 0x1b7, 0x000, 0x3b7, 0x070, 0x083,
> +    0x18a, 0x044, 0x1b7, 0x000, 0x3c4, 0x3f7, 0x024, 0x000,
> +    0x36f, 0x3b7, 0x301, 0x044, 0x192, 0x000, 0x384, 0x3c7,
> +    0x385, 0x028, 0x044, 0x1bd, 0x000, 0x3c5, 0x048, 0x024,
> +    0x3a7, 0x060, 0x083, 0x044, 0x1a9, 0x000, 0x3b7, 0x070,
> +    0x083, 0x18a, 0x044, 0x1a9, 0x000, 0x000, 0x351, 0x307,
> +    0x22b, 0x284, 0x2a8, 0x2c4, 0x24d, 0x245, 0x24d, 0x2a8,
> +    0x045, 0x2f4, 0x200, 0x001, 0x008, 0x364, 0x2cf, 0x007,
> +    0x029, 0x1dc, 0x007, 0x287, 0x385, 0x300, 0x208, 0x001,
> +    0x04b, 0x364, 0x33b, 0x010, 0x029, 0x1dc, 0x007, 0x3c5,
> +    0x002, 0x00c, 0x287, 0x384, 0x0ff, 0x305, 0x21d, 0x1b7,
> +    0x2e4, 0x001, 0x001, 0x01d, 0x040, 0x384, 0x007, 0x117,
> +    0x001, 0x00c, 0x3c5, 0x040, 0x02d, 0x081, 0x044, 0x189,
> +    0x000, 0x3c4, 0x3bf, 0x02d, 0x042, 0x247, 0x029, 0x364,
> +    0x018, 0x001, 0x009, 0x005, 0x3c5, 0x010, 0x021, 0x2e4,
> +    0x002, 0x001, 0x017, 0x264, 0x080, 0x001, 0x005, 0x0a4,
> +    0x1a7, 0x285, 0x040, 0x3c5, 0x080, 0x02d, 0x081, 0x044,
> +    0x189, 0x000, 0x3c4, 0x37f, 0x02d, 0x042, 0x247, 0x02a,
> +    0x000, 0x014, 0x38e, 0x3ff, 0x1b8, 0x00a, 0x00a, 0x244,
> +    0x029, 0x3c4, 0x3ef, 0x021, 0x3c4, 0x3fd, 0x00c, 0x120,
> +    0x001, 0x004, 0x244, 0x02a, 0x020, 0x181, 0x006, 0x289,
> +    0x00a, 0x004, 0x2c7, 0x251, 0x22e, 0x364, 0x026, 0x001,
> +    0x021, 0x181, 0x006, 0x041, 0x3a4, 0x01f, 0x001, 0x005,
> +    0x044, 0x0d9, 0x001, 0x043, 0x1b7, 0x001, 0x005, 0x044,
> +    0x182, 0x000, 0x020, 0x181, 0x006, 0x2e4, 0x002, 0x009,
> +    0x01b, 0x3c4, 0x2ff, 0x232, 0x120, 0x001, 0x012, 0x3d5,
> +    0x300, 0x232, 0x044, 0x099, 0x00b, 0x32a, 0x026, 0x00a,
> +    0x008, 0x044, 0x20d, 0x000, 0x044, 0x232, 0x000, 0x020,
> +    0x181, 0x006, 0x042, 0x307, 0x240, 0x20a, 0x040, 0x020,
> +    0x181, 0x006, 0x289, 0x00a, 0x004, 0x2c7, 0x256, 0x22e,
> +    0x364, 0x026, 0x002, 0x021, 0x181, 0x006, 0x041, 0x3a4,
> +    0x01f, 0x001, 0x005, 0x044, 0x0de, 0x001, 0x043, 0x1b7,
> +    0x001, 0x005, 0x044, 0x0e2, 0x001, 0x020, 0x181, 0x006,
> +    0x364, 0x23f, 0x003, 0x009, 0x007, 0x044, 0x340, 0x001,
> +    0x247, 0x249, 0x054, 0x347, 0x249, 0x248, 0x2c7, 0x23f,
> +    0x083, 0x18a, 0x385, 0x018, 0x364, 0x23f, 0x001, 0x001,
> +    0x006, 0x245, 0x057, 0x000, 0x005, 0x208, 0x244, 0x057,
> +    0x087, 0x18c, 0x385, 0x0e0, 0x364, 0x23f, 0x002, 0x001,
> +    0x009, 0x245, 0x057, 0x044, 0x27d, 0x001, 0x000, 0x005,
> +    0x208, 0x244, 0x057, 0x020, 0x181, 0x006, 0x2c7, 0x246,
> +    0x3b7, 0x300, 0x044, 0x192, 0x000, 0x384, 0x33f, 0x327,
> +    0x246, 0x3a4, 0x0c0, 0x285, 0x3b7, 0x300, 0x044, 0x1bd,
> +    0x000, 0x3b7, 0x200, 0x044, 0x192, 0x000, 0x0a3, 0x1a9,
> +    0x2a8, 0x284, 0x040, 0x307, 0x246, 0x384, 0x030, 0x264,
> +    0x010, 0x001, 0x012, 0x040, 0x041, 0x3b7, 0x201, 0x044,
> +    0x192, 0x000, 0x384, 0x3e0, 0x385, 0x006, 0x044, 0x1bd,
> +    0x000, 0x043, 0x042, 0x185, 0x2a8, 0x284, 0x227, 0x042,
> +    0x285, 0x3b7, 0x200, 0x044, 0x1bd, 0x000, 0x307, 0x246,
> +    0x384, 0x007, 0x044, 0x375, 0x00b, 0x3a7, 0x073, 0x307,
> +    0x246, 0x184, 0x00a, 0x014, 0x044, 0x192, 0x000, 0x384,
> +    0x3e2, 0x327, 0x246, 0x1b5, 0x3a4, 0x01c, 0x285, 0x3a7,
> +    0x073, 0x044, 0x1bd, 0x000, 0x000, 0x006, 0x081, 0x044,
> +    0x1a9, 0x000, 0x020, 0x181, 0x006, 0x3c5, 0x001, 0x00c,
> +    0x187, 0x0a7, 0x1a7, 0x2a8, 0x324, 0x00c, 0x225, 0x2c7,
> +    0x00c, 0x045, 0x04e, 0x087, 0x011, 0x054, 0x084
> +
> +};  /* end fm10000_serdes_spico_code_prd2 */
> +
> +
> +
> +/* Spico Swap code (production version 2)
> + *  source file:   serdes.0x2055_0045.swap
> + *
> + *  Note: if swap code exists, if must be loaded on top of
> + *  the sbus master image. */
> +
> +const uint32_t fm10000_serdes_swap_code_versionBuildId_prd2 =
> 0x20550045;
> +const uint32_t fm10000_serdes_swap_code_size_prd2           = 7842;
> +
> +const uint16_t fm10000_serdes_swap_code_prd2[] = {
> +    0x01e, 0x09d, 0x002, 0x000, 0x000, 0x008, 0x00f, 0x07b,
> +    0x020, 0x01e, 0x00f, 0x069, 0x01d, 0x029, 0x00b, 0x01d,
> +    0x02c, 0x382, 0x04e, 0x020, 0x23b, 0x009, 0x020, 0x28e,
> +    0x00a, 0x020, 0x03a, 0x00a, 0x020, 0x0fe, 0x00a, 0x020,
> +    0x3f3, 0x008, 0x020, 0x013, 0x009, 0x020, 0x075, 0x00a,
> +    0x0c1, 0x244, 0x3c5, 0x040, 0x245, 0x3c4, 0x3bf, 0x200,
> +    0x044, 0x172, 0x000, 0x020, 0x0d3, 0x000, 0x020, 0x2c3,
> +    0x008, 0x020, 0x375, 0x00b, 0x0c1, 0x201, 0x045, 0x020,
> +    0x04a, 0x009, 0x020, 0x04e, 0x009, 0x020, 0x256, 0x002,
> +    0x020, 0x17f, 0x009, 0x020, 0x23f, 0x006, 0x020, 0x285,
> +    0x00a, 0x020, 0x209, 0x00b, 0x020, 0x257, 0x006, 0x020,
> +    0x117, 0x008, 0x020, 0x394, 0x00a, 0x020, 0x048, 0x00b,
> +    0x020, 0x1dc, 0x007, 0x020, 0x27f, 0x00a, 0x020, 0x2d2,
> +    0x006, 0x020, 0x1e2, 0x007, 0x020, 0x295, 0x00b, 0x020,
> +    0x3a8, 0x001, 0x020, 0x277, 0x00b, 0x020, 0x2ba, 0x00b,
> +    0x020, 0x2d5, 0x006, 0x020, 0x326, 0x006, 0x020, 0x350,
> +    0x006, 0x020, 0x1dc, 0x007, 0x020, 0x35a, 0x006, 0x020,
> +    0x0a4, 0x00b, 0x020, 0x38e, 0x006, 0x020, 0x011, 0x007,
> +    0x020, 0x016, 0x007, 0x020, 0x31e, 0x007, 0x020, 0x324,
> +    0x007, 0x020, 0x3b6, 0x007, 0x020, 0x02a, 0x007, 0x020,
> +    0x041, 0x007, 0x020, 0x060, 0x007, 0x020, 0x06d, 0x007,
> +    0x020, 0x072, 0x007, 0x020, 0x2d1, 0x007, 0x020, 0x1dc,
> +    0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020,
> +    0x1dc, 0x007, 0x020, 0x252, 0x007, 0x020, 0x293, 0x007,
> +    0x020, 0x2d8, 0x00b, 0x020, 0x1dc, 0x007, 0x020, 0x1dc,
> +    0x007, 0x020, 0x16f, 0x007, 0x020, 0x185, 0x007, 0x020,
> +    0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007,
> +    0x020, 0x1dc, 0x007, 0x020, 0x30e, 0x00b, 0x020, 0x1dc,
> +    0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020,
> +    0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007,
> +    0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc,
> +    0x007, 0x020, 0x077, 0x007, 0x020, 0x0b1, 0x007, 0x020,
> +    0x103, 0x007, 0x020, 0x1c5, 0x008, 0x020, 0x1dc, 0x007,
> +    0x020, 0x168, 0x007, 0x287, 0x264, 0x004, 0x001, 0x049,
> +    0x3c5, 0x00c, 0x00c, 0x3c5, 0x020, 0x33b, 0x18e, 0x00a,
> +    0x013, 0x044, 0x04c, 0x004, 0x3a4, 0x001, 0x001, 0x014,
> +    0x364, 0x052, 0x001, 0x009, 0x093, 0x044, 0x0bc, 0x004,
> +    0x000, 0x08e, 0x3c4, 0x2ff, 0x053, 0x3c4, 0x030, 0x027,
> +    0x000, 0x3ec, 0x3c4, 0x3fe, 0x052, 0x000, 0x081, 0x043,
> +    0x327, 0x33b, 0x020, 0x1de, 0x007, 0x2e4, 0x080, 0x009,
> +    0x00d, 0x3d5, 0x220, 0x33c, 0x100, 0x009, 0x06e, 0x044,
> +    0x3b6, 0x003, 0x000, 0x06c, 0x3d5, 0x120, 0x33c, 0x100,
> +    0x009, 0x022, 0x044, 0x066, 0x004, 0x000, 0x061, 0x384,
> +    0x003, 0x3c4, 0x3df, 0x33b, 0x262, 0x003, 0x001, 0x3d9,
> +    0x3c4, 0x32d, 0x33c, 0x3c4, 0x3ef, 0x027, 0x2e4, 0x040,
> +    0x009, 0x3d5, 0x100, 0x009, 0x007, 0x044, 0x063, 0x004,
> +    0x000, 0x046, 0x364, 0x200, 0x004, 0x029, 0x1dc, 0x007,
> +    0x0c0, 0x2d8, 0x111, 0x001, 0x028, 0x3c5, 0x002, 0x33c,
> +    0x3c5, 0x001, 0x33b, 0x344, 0x21f, 0x33c, 0x287, 0x19b,
> +    0x247, 0x361, 0x287, 0x183, 0x19b, 0x247, 0x360, 0x0c0,
> +    0x35e, 0x2e4, 0x020, 0x001, 0x004, 0x0c5, 0x35e, 0x2e4,
> +    0x010, 0x001, 0x005, 0x3c5, 0x080, 0x33c, 0x289, 0x384,
> +    0x010, 0x245, 0x33c, 0x044, 0x001, 0x004, 0x364, 0x33c,
> +    0x002, 0x001, 0x005, 0x3c5, 0x004, 0x200, 0x364, 0x33c,
> +    0x020, 0x009, 0x005, 0x044, 0x097, 0x004, 0x020, 0x181,
> +    0x006, 0x287, 0x19b, 0x11d, 0x001, 0x002, 0x287, 0x1a3,
> +    0x1b3, 0x19b, 0x180, 0x390, 0x1d7, 0x040, 0x199, 0x390,
> +    0x008, 0x040, 0x045, 0x000, 0x021, 0x000, 0x073, 0x000,
> +    0x05f, 0x000, 0x023, 0x000, 0x025, 0x000, 0x033, 0x000,
> +    0x035, 0x000, 0x037, 0x000, 0x041, 0x000, 0x01f, 0x000,
> +    0x021, 0x000, 0x023, 0x000, 0x031, 0x000, 0x082, 0x000,
> +    0x002, 0x020, 0x1dc, 0x007, 0x044, 0x378, 0x003, 0x3c4,
> +    0x3fd, 0x233, 0x000, 0x072, 0x2c7, 0x363, 0x000, 0x06e,
> +    0x2c7, 0x362, 0x000, 0x06a, 0x2c7, 0x341, 0x000, 0x066,
> +    0x2c7, 0x33f, 0x000, 0x062, 0x2c7, 0x340, 0x000, 0x05e,
> +    0x2c7, 0x344, 0x000, 0x05a, 0x2c7, 0x342, 0x000, 0x056,
> +    0x2c7, 0x343, 0x000, 0x052, 0x2c7, 0x341, 0x2c7, 0x33f,
> +    0x2c7, 0x340, 0x000, 0x04a, 0x307, 0x340, 0x300, 0x341,
> +    0x300, 0x33f, 0x282, 0x007, 0x006, 0x2c7, 0x23e, 0x000,
> +    0x03d, 0x043, 0x0a1, 0x020, 0x1de, 0x007, 0x287, 0x384,
> +    0x003, 0x181, 0x3c4, 0x3f3, 0x052, 0x245, 0x052, 0x3a4,
> +    0x00c, 0x3c4, 0x3f3, 0x33c, 0x2c5, 0x33c, 0x000, 0x026,
> +    0x3c5, 0x002, 0x233, 0x3c7, 0x3ff, 0x352, 0x3c7, 0x3ff,
> +    0x353, 0x1d3, 0x353, 0x0cf, 0x354, 0x1cb, 0x354, 0x3c5,
> +    0x0c0, 0x354, 0x3c9, 0x222, 0x355, 0x3c5, 0x001, 0x33c,
> +    0x0c0, 0x356, 0x1b0, 0x00a, 0x006, 0x081, 0x18a, 0x247,
> +    0x356, 0x1ab, 0x2c7, 0x357, 0x020, 0x181, 0x006, 0x287,
> +    0x001, 0x025, 0x197, 0x3a4, 0x00f, 0x262, 0x003, 0x001,
> +    0x03d, 0x131, 0x001, 0x020, 0x131, 0x001, 0x021, 0x131,
> +    0x001, 0x022, 0x131, 0x001, 0x025, 0x131, 0x001, 0x026,
> +    0x131, 0x001, 0x027, 0x132, 0x182, 0x390, 0x377, 0x280,
> +    0x04c, 0x042, 0x020, 0x1de, 0x007, 0x044, 0x361, 0x003,
> +    0x000, 0x3d4, 0x327, 0x373, 0x000, 0x3f5, 0x327, 0x372,
> +    0x000, 0x3f1, 0x327, 0x2b3, 0x322, 0x2b2, 0x000, 0x3eb,
> +    0x327, 0x374, 0x000, 0x3e7, 0x327, 0x375, 0x000, 0x3e3,
> +    0x327, 0x376, 0x000, 0x3df, 0x307, 0x369, 0x282, 0x272,
> +    0x369, 0x00e, 0x003, 0x108, 0x04c, 0x000, 0x3d4, 0x364,
> +    0x33c, 0x001, 0x001, 0x01b, 0x364, 0x33b, 0x020, 0x009,
> +    0x016, 0x0a0, 0x307, 0x04f, 0x181, 0x00a, 0x003, 0x0a4,
> +    0x100, 0x00b, 0x004, 0x3a5, 0x080, 0x307, 0x050, 0x194,
> +    0x384, 0x040, 0x225, 0x2c7, 0x392, 0x081, 0x189, 0x314,
> +    0x053, 0x001, 0x007, 0x3c5, 0x008, 0x027, 0x000, 0x005,
> +    0x3c4, 0x3f7, 0x027, 0x364, 0x33c, 0x020, 0x001, 0x007,
> +    0x347, 0x21d, 0x35a, 0x000, 0x018, 0x347, 0x050, 0x368,
> +    0x3b7, 0x201, 0x1a5, 0x140, 0x04f, 0x00b, 0x00b, 0x364,
> +    0x052, 0x020, 0x001, 0x3f3, 0x2c5, 0x33c, 0x000, 0x005,
> +    0x2a8, 0x2c4, 0x33c, 0x081, 0x189, 0x304, 0x053, 0x001,
> +    0x007, 0x3c5, 0x008, 0x027, 0x000, 0x005, 0x3c4, 0x3f7,
> +    0x027, 0x3c5, 0x080, 0x053, 0x3c4, 0x37f, 0x053, 0x364,
> +    0x33b, 0x020, 0x009, 0x00a, 0x364, 0x33c, 0x020, 0x009,
> +    0x005, 0x044, 0x132, 0x004, 0x020, 0x08d, 0x006, 0x2c7,
> +    0x231, 0x2e4, 0x100, 0x001, 0x045, 0x2e4, 0x001, 0x001,
> +    0x020, 0x3b7, 0x213, 0x084, 0x044, 0x1a9, 0x000, 0x3b7,
> +    0x250, 0x084, 0x044, 0x1a9, 0x000, 0x399, 0x305, 0x3a7,
> +    0x022, 0x044, 0x1a9, 0x000, 0x044, 0x322, 0x001, 0x3c5,
> +    0x002, 0x024, 0x3c5, 0x008, 0x292, 0x000, 0x020, 0x3c4,
> +    0x3fd, 0x024, 0x364, 0x234, 0x002, 0x001, 0x009, 0x3a7,
> +    0x022, 0x399, 0x305, 0x044, 0x1b7, 0x000, 0x3b7, 0x213,
> +    0x084, 0x044, 0x1b7, 0x000, 0x3b7, 0x250, 0x084, 0x044,
> +    0x1b7, 0x000, 0x3c4, 0x007, 0x292, 0x044, 0x06e, 0x003,
> +    0x307, 0x231, 0x274, 0x200, 0x001, 0x01b, 0x274, 0x010,
> +    0x001, 0x00b, 0x387, 0x020, 0x245, 0x021, 0x185, 0x245,
> +    0x024, 0x000, 0x00b, 0x387, 0x3df, 0x244, 0x021, 0x185,
> +    0x385, 0x0ff, 0x244, 0x024, 0x044, 0x03a, 0x00a, 0x045,
> +    0x327, 0x230, 0x364, 0x233, 0x004, 0x001, 0x003, 0x045,
> +    0x0c2, 0x22a, 0x347, 0x275, 0x270, 0x0c0, 0x27b, 0x264,
> +    0x010, 0x009, 0x00a, 0x0c1, 0x22a, 0x347, 0x274, 0x270,
> +    0x3d7, 0x200, 0x27b, 0x327, 0x230, 0x264, 0x004, 0x001,
> +    0x012, 0x347, 0x277, 0x270, 0x264, 0x010, 0x009, 0x007,
> +    0x347, 0x276, 0x270, 0x384, 0x00f, 0x112, 0x1b7, 0x000,
> +    0x004, 0x3a4, 0x0ff, 0x2c7, 0x225, 0x384, 0x00f, 0x262,
> +    0x003, 0x001, 0x00b, 0x101, 0x3c2, 0x100, 0x270, 0x34a,
> +    0x225, 0x225, 0x000, 0x3f3, 0x044, 0x237, 0x00a, 0x044,
> +    0x35f, 0x009, 0x364, 0x22a, 0x002, 0x001, 0x006, 0x347,
> +    0x270, 0x272, 0x045, 0x347, 0x270, 0x271, 0x045, 0x044,
> +    0x2f6, 0x002, 0x009, 0x015, 0x307, 0x241, 0x197, 0x384,
> +    0x007, 0x001, 0x008, 0x3c2, 0x100, 0x270, 0x111, 0x009,
> +    0x3fc, 0x3d7, 0x200, 0x27b, 0x044, 0x35f, 0x009, 0x347,
> +    0x241, 0x226, 0x0c1, 0x22a, 0x020, 0x032, 0x009, 0x044,
> +    0x2f6, 0x002, 0x009, 0x014, 0x307, 0x243, 0x197, 0x384,
> +    0x007, 0x001, 0x008, 0x3c2, 0x100, 0x270, 0x111, 0x009,
> +    0x3fc, 0x0c0, 0x27b, 0x044, 0x35f, 0x009, 0x347, 0x243,
> +    0x226, 0x0c2, 0x22a, 0x020, 0x032, 0x009, 0x327, 0x226,
> +    0x2c7, 0x225, 0x3c4, 0x0ff, 0x225, 0x1b7, 0x3a4, 0x007,
> +    0x001, 0x00d, 0x34a, 0x225, 0x225, 0x002, 0x008, 0x131,
> +    0x009, 0x3fa, 0x044, 0x237, 0x00a, 0x045, 0x0c1, 0x26f,
> +    0x000, 0x050, 0x327, 0x01d, 0x2e4, 0x380, 0x009, 0x00a,
> +    0x13a, 0x00b, 0x00a, 0x3c5, 0x008, 0x233, 0x000, 0x005,
> +    0x3c4, 0x3f7, 0x233, 0x327, 0x01d, 0x021, 0x2ed, 0x009,
> +    0x364, 0x020, 0x004, 0x009, 0x01a, 0x309, 0x232, 0x00b,
> +    0x009, 0x347, 0x270, 0x271, 0x308, 0x221, 0x244, 0x232,
> +    0x347, 0x271, 0x270, 0x044, 0x270, 0x009, 0x001, 0x04c,
> +    0x347, 0x270, 0x271, 0x000, 0x018, 0x309, 0x232, 0x001,
> +    0x009, 0x347, 0x270, 0x272, 0x308, 0x221, 0x244, 0x232,
> +    0x347, 0x272, 0x270, 0x044, 0x270, 0x009, 0x001, 0x089,
> +    0x347, 0x270, 0x272, 0x397, 0x200, 0x044, 0x1b1, 0x001,
> +    0x364, 0x26f, 0x002, 0x009, 0x005, 0x3c4, 0x3fe, 0x200,
> +    0x364, 0x020, 0x005, 0x029, 0x2e4, 0x002, 0x364, 0x020,
> +    0x010, 0x009, 0x0e9, 0x364, 0x020, 0x100, 0x009, 0x12b,
> +    0x020, 0x2e4, 0x002, 0x3c4, 0x3f7, 0x233, 0x364, 0x020,
> +    0x001, 0x009, 0x00c, 0x364, 0x020, 0x004, 0x009, 0x05d,
> +    0x000, 0x3d8, 0x3c5, 0x080, 0x020, 0x364, 0x233, 0x006,
> +    0x001, 0x031, 0x081, 0x189, 0x304, 0x232, 0x009, 0x017,
> +    0x347, 0x271, 0x274, 0x080, 0x364, 0x233, 0x004, 0x009,
> +    0x003, 0x085, 0x0c1, 0x22a, 0x044, 0x39c, 0x008, 0x081,
> +    0x189, 0x245, 0x232, 0x000, 0x0c8, 0x347, 0x271, 0x276,
> +    0x081, 0x189, 0x208, 0x244, 0x232, 0x307, 0x22b, 0x197,
> +    0x384, 0x007, 0x0c1, 0x22a, 0x044, 0x39c, 0x008, 0x000,
> +    0x005, 0x044, 0x3f3, 0x008, 0x3b7, 0x200, 0x387, 0x3df,
> +    0x044, 0x1b8, 0x000, 0x3b7, 0x203, 0x387, 0x3f7, 0x044,
> +    0x1b8, 0x000, 0x307, 0x020, 0x385, 0x042, 0x384, 0x3ce,
> +    0x247, 0x020, 0x044, 0x044, 0x001, 0x000, 0x383, 0x0a1,
> +    0x1aa, 0x2c5, 0x020, 0x364, 0x233, 0x006, 0x001, 0x039,
> +    0x081, 0x189, 0x304, 0x232, 0x009, 0x017, 0x347, 0x272,
> +    0x275, 0x080, 0x364, 0x233, 0x004, 0x009, 0x003, 0x095,
> +    0x0c2, 0x22a, 0x044, 0x39c, 0x008, 0x081, 0x189, 0x245,
> +    0x232, 0x000, 0x0ce, 0x347, 0x272, 0x277, 0x081, 0x189,
> +    0x208, 0x244, 0x232, 0x307, 0x22b, 0x197, 0x364, 0x233,
> +    0x002, 0x001, 0x007, 0x193, 0x384, 0x007, 0x385, 0x010,
> +    0x0c2, 0x22a, 0x044, 0x39c, 0x008, 0x000, 0x008, 0x347,
> +    0x272, 0x270, 0x044, 0x013, 0x009, 0x081, 0x18a, 0x208,
> +    0x244, 0x232, 0x0a3, 0x387, 0x3f7, 0x044, 0x1b8, 0x000,
> +    0x307, 0x020, 0x0a4, 0x1a7, 0x3a5, 0x008, 0x285, 0x3b7,
> +    0x304, 0x2a8, 0x284, 0x247, 0x020, 0x0a0, 0x387, 0x3df,
> +    0x044, 0x1b8, 0x000, 0x044, 0x2f6, 0x002, 0x009, 0x00f,
> +    0x364, 0x2cf, 0x080, 0x009, 0x00a, 0x0c3, 0x26f, 0x044,
> +    0x1b6, 0x001, 0x020, 0x2e4, 0x002, 0x044, 0x051, 0x001,
> +    0x000, 0x308, 0x3c4, 0x3f7, 0x233, 0x364, 0x233, 0x006,
> +    0x001, 0x013, 0x044, 0x2f6, 0x002, 0x009, 0x00e, 0x081,
> +    0x364, 0x233, 0x004, 0x009, 0x003, 0x083, 0x0c1, 0x22a,
> +    0x044, 0x39c, 0x008, 0x3d7, 0x200, 0x27b, 0x0c0, 0x271,
> +    0x3b7, 0x300, 0x387, 0x3df, 0x044, 0x1b8, 0x000, 0x3b7,
> +    0x221, 0x091, 0x189, 0x044, 0x1a9, 0x000, 0x3b7, 0x201,
> +    0x387, 0x0a6, 0x044, 0x1bd, 0x000, 0x3c5, 0x021, 0x020,
> +    0x3c4, 0x3ed, 0x020, 0x3b7, 0x200, 0x387, 0x020, 0x044,
> +    0x020, 0x00a, 0x009, 0x32a, 0x347, 0x271, 0x270, 0x000,
> +    0x055, 0x3a7, 0x071, 0x307, 0x21d, 0x044, 0x1b7, 0x000,
> +    0x3c4, 0x3f7, 0x233, 0x044, 0x2f6, 0x002, 0x009, 0x007,
> +    0x0c1, 0x2d3, 0x3c5, 0x100, 0x200, 0x081, 0x18a, 0x245,
> +    0x232, 0x364, 0x233, 0x006, 0x001, 0x013, 0x044, 0x2f6,
> +    0x002, 0x009, 0x00e, 0x081, 0x364, 0x233, 0x004, 0x009,
> +    0x003, 0x093, 0x0c2, 0x22a, 0x044, 0x39c, 0x008, 0x0c0,
> +    0x27b, 0x0c0, 0x272, 0x3b7, 0x300, 0x387, 0x020, 0x044,
> +    0x1a9, 0x000, 0x0a1, 0x397, 0x205, 0x247, 0x27f, 0x044,
> +    0x1bd, 0x000, 0x3d5, 0x204, 0x020, 0x3c4, 0x2ff, 0x020,
> +    0x0a0, 0x387, 0x021, 0x184, 0x044, 0x020, 0x00a, 0x009,
> +    0x336, 0x347, 0x272, 0x270, 0x044, 0x35f, 0x009, 0x397,
> +    0x200, 0x044, 0x1b1, 0x001, 0x020, 0x2e4, 0x002, 0x3c4,
> +    0x3fe, 0x200, 0x3c4, 0x3fe, 0x26f, 0x344, 0x21f, 0x232,
> +    0x0c0, 0x020, 0x0a3, 0x1ab, 0x2c5, 0x020, 0x044, 0x20d,
> +    0x000, 0x044, 0x2f3, 0x000, 0x044, 0x3b5, 0x000, 0x044,
> +    0x3f0, 0x000, 0x0a9, 0x1ab, 0x09f, 0x18a, 0x208, 0x304,
> +    0x055, 0x225, 0x044, 0x394, 0x00a, 0x307, 0x055, 0x19b,
> +    0x384, 0x003, 0x227, 0x1a3, 0x225, 0x044, 0x0a4, 0x00b,
> +    0x0a7, 0x020, 0x022, 0x008, 0x327, 0x220, 0x324, 0x232,
> +    0x001, 0x006, 0x387, 0x07f, 0x000, 0x013, 0x399, 0x240,
> +    0x385, 0x07f, 0x306, 0x270, 0x001, 0x06c, 0x399, 0x240,
> +    0x327, 0x270, 0x3a4, 0x380, 0x226, 0x001, 0x015, 0x327,
> +    0x220, 0x324, 0x232, 0x009, 0x019, 0x364, 0x232, 0x001,
> +    0x001, 0x02b, 0x327, 0x01d, 0x307, 0x01b, 0x190, 0x282,
> +    0x003, 0x041, 0x307, 0x01b, 0x191, 0x380, 0x010, 0x282,
> +    0x003, 0x034, 0x000, 0x019, 0x327, 0x220, 0x324, 0x232,
> +    0x001, 0x00a, 0x327, 0x270, 0x384, 0x07f, 0x3a4, 0x07f,
> +    0x000, 0x008, 0x327, 0x270, 0x3a4, 0x07f, 0x001, 0x005,
> +    0x286, 0x001, 0x02f, 0x307, 0x270, 0x384, 0x07f, 0x386,
> +    0x07f, 0x009, 0x00a, 0x387, 0x080, 0x382, 0x07f, 0x240,
> +    0x270, 0x000, 0x01c, 0x141, 0x270, 0x364, 0x270, 0x07f,
> +    0x009, 0x015, 0x000, 0x013, 0x3c0, 0x040, 0x270, 0x000,
> +    0x00e, 0x307, 0x270, 0x196, 0x384, 0x00f, 0x266, 0x009,
> +    0x001, 0x008, 0x3c0, 0x080, 0x270, 0x044, 0x35f, 0x009,
> +    0x045, 0x309, 0x232, 0x00b, 0x013, 0x347, 0x271, 0x270,
> +    0x374, 0x27b, 0x200, 0x009, 0x005, 0x347, 0x272, 0x270,
> +    0x044, 0x35f, 0x009, 0x020, 0x0b7, 0x009, 0x327, 0x232,
> +    0x1a2, 0x023, 0x0b7, 0x009, 0x307, 0x270, 0x196, 0x119,
> +    0x021, 0x0b7, 0x009, 0x307, 0x232, 0x181, 0x023, 0x0b7,
> +    0x009, 0x364, 0x270, 0x080, 0x029, 0x0b7, 0x009, 0x083,
> +    0x18c, 0x245, 0x232, 0x3c4, 0x3f7, 0x233, 0x3c4, 0x380,
> +    0x270, 0x3c0, 0x080, 0x270, 0x044, 0x35f, 0x009, 0x397,
> +    0x200, 0x044, 0x1b1, 0x001, 0x020, 0x09c, 0x009, 0x000,
> +    0x000, 0x000, 0x002, 0x000, 0x00a, 0x000, 0x02a, 0x000,
> +    0x0aa, 0x002, 0x0aa, 0x00a, 0x0aa, 0x02a, 0x0aa, 0x06a,
> +    0x0aa, 0x07a, 0x0aa, 0x07e, 0x0aa, 0x07f, 0x0aa, 0x07f,
> +    0x0ba, 0x07f, 0x0be, 0x07f, 0x0fe, 0x07f, 0x0ff, 0x007,
> +    0x000, 0x017, 0x001, 0x027, 0x007, 0x037, 0x00f, 0x047,
> +    0x03f, 0x080, 0x0ff, 0x364, 0x270, 0x07f, 0x307, 0x270,
> +    0x384, 0x07f, 0x009, 0x00d, 0x089, 0x186, 0x306, 0x270,
> +    0x001, 0x007, 0x3c5, 0x001, 0x232, 0x000, 0x005, 0x3c4,
> +    0x3fe, 0x232, 0x347, 0x270, 0x27c, 0x3c4, 0x007, 0x27c,
> +    0x374, 0x27b, 0x200, 0x001, 0x00a, 0x364, 0x233, 0x008,
> +    0x001, 0x005, 0x044, 0x0fe, 0x00a, 0x0a3, 0x325, 0x27b,
> +    0x044, 0x192, 0x000, 0x384, 0x3f8, 0x305, 0x27c, 0x044,
> +    0x1bd, 0x000, 0x307, 0x270, 0x192, 0x384, 0x00f, 0x3b9,
> +    0x200, 0x324, 0x233, 0x001, 0x014, 0x229, 0x387, 0x009,
> +    0x189, 0x395, 0x333, 0x280, 0x051, 0x2c7, 0x27d, 0x1c7,
> +    0x27d, 0x101, 0x051, 0x2c5, 0x27d, 0x000, 0x011, 0x0c0,
> +    0x27d, 0x384, 0x00f, 0x001, 0x00b, 0x349, 0x27d, 0x27d,
> +    0x3c5, 0x001, 0x27d, 0x111, 0x000, 0x3f7, 0x0a2, 0x325,
> +    0x27b, 0x307, 0x27d, 0x044, 0x1bd, 0x000, 0x374, 0x27b,
> +    0x200, 0x001, 0x02c, 0x347, 0x270, 0x27a, 0x3c4, 0x07f,
> +    0x27a, 0x0c0, 0x279, 0x387, 0x009, 0x189, 0x395, 0x353,
> +    0x051, 0x041, 0x101, 0x051, 0x2c7, 0x279, 0x101, 0x043,
> +    0x322, 0x27a, 0x00b, 0x004, 0x000, 0x3f4, 0x1c7, 0x279,
> +    0x0a3, 0x325, 0x27b, 0x044, 0x192, 0x000, 0x384, 0x0ff,
> +    0x305, 0x279, 0x044, 0x1bd, 0x000, 0x327, 0x220, 0x324,
> +    0x232, 0x009, 0x022, 0x0c0, 0x27e, 0x307, 0x270, 0x197,
> +    0x00a, 0x004, 0x000, 0x005, 0x3c5, 0x018, 0x27e, 0x0a4,
> +    0x222, 0x2c5, 0x27e, 0x0a4, 0x325, 0x27b, 0x044, 0x192,
> +    0x000, 0x384, 0x3e0, 0x3c4, 0x01f, 0x27e, 0x305, 0x27e,
> +    0x044, 0x1bd, 0x000, 0x045, 0x044, 0x1a9, 0x000, 0x083,
> +    0x18c, 0x208, 0x244, 0x232, 0x3c5, 0x001, 0x00c, 0x0a3,
> +    0x325, 0x27b, 0x088, 0x044, 0x1a9, 0x000, 0x387, 0x3f8,
> +    0x044, 0x1b8, 0x000, 0x020, 0x2f6, 0x002, 0x3c7, 0x020,
> +    0x280, 0x3b7, 0x215, 0x044, 0x192, 0x000, 0x247, 0x247,
> +    0x151, 0x280, 0x001, 0x016, 0x0a1, 0x044, 0x182, 0x000,
> +    0x3b7, 0x215, 0x044, 0x192, 0x000, 0x306, 0x247, 0x001,
> +    0x3f1, 0x0a2, 0x364, 0x22b, 0x003, 0x001, 0x003, 0x0a5,
> +    0x020, 0x182, 0x000, 0x1f6, 0x185, 0x1f5, 0x129, 0x1f4,
> +    0x0d0, 0x1b3, 0x0fc, 0x122, 0x0ff, 0x1f6, 0x189, 0x1f5,
> +    0x11b, 0x1f5, 0x0aa, 0x194, 0x0ce, 0x123, 0x0f3, 0x0d2,
> +    0x0ff, 0x364, 0x233, 0x020, 0x009, 0x051, 0x307, 0x272,
> +    0x196, 0x384, 0x00f, 0x0c9, 0x286, 0x242, 0x286, 0x397,
> +    0x00a, 0x189, 0x395, 0x05f, 0x044, 0x2ea, 0x001, 0x009,
> +    0x004, 0x380, 0x00a, 0x051, 0x2c7, 0x284, 0x101, 0x051,
> +    0x2c7, 0x288, 0x3a4, 0x07f, 0x040, 0x307, 0x272, 0x384,
> +    0x07f, 0x222, 0x042, 0x00b, 0x005, 0x101, 0x000, 0x3ed,
> +    0x347, 0x284, 0x285, 0x3c4, 0x00f, 0x284, 0x1d3, 0x285,
> +    0x1d6, 0x288, 0x342, 0x288, 0x286, 0x003, 0x008, 0x156,
> +    0x285, 0x151, 0x286, 0x00b, 0x3fc, 0x362, 0x285, 0x003,
> +    0x003, 0x004, 0x0c3, 0x285, 0x307, 0x285, 0x0a1, 0x184,
> +    0x305, 0x284, 0x044, 0x1bd, 0x000, 0x045, 0x3db, 0x071,
> +    0x0b9, 0x0ff, 0x089, 0x0e2, 0x12c, 0x176, 0x1bf, 0x00d,
> +    0x007, 0x006, 0x003, 0x002, 0x005, 0x0b3, 0x156, 0x1fa,
> +    0x27f, 0x080, 0x09e, 0x14b, 0x1f0, 0x27f, 0x080, 0x08b,
> +    0x140, 0x1e9, 0x27f, 0x081, 0x138, 0x1e3, 0x27f, 0x00f,
> +    0x0b2, 0x14f, 0x1f0, 0x27f, 0x080, 0x0a3, 0x145, 0x1e7,
> +    0x27f, 0x080, 0x095, 0x13d, 0x1e0, 0x27f, 0x08b, 0x136,
> +    0x1db, 0x27f, 0x0c5, 0x28b, 0x347, 0x271, 0x281, 0x3c4,
> +    0x07f, 0x281, 0x0c5, 0x282, 0x044, 0x2ea, 0x001, 0x009,
> +    0x004, 0x0c2, 0x282, 0x044, 0x1bc, 0x00a, 0x347, 0x283,
> +    0x289, 0x307, 0x241, 0x364, 0x233, 0x002, 0x001, 0x004,
> +    0x307, 0x225, 0x384, 0x0ff, 0x242, 0x283, 0x00b, 0x056,
> +    0x0c3, 0x28b, 0x302, 0x289, 0x397, 0x00a, 0x189, 0x395,
> +    0x0ca, 0x044, 0x2ea, 0x001, 0x009, 0x004, 0x380, 0x004,
> +    0x051, 0x2c7, 0x28c, 0x2a9, 0x121, 0x3a4, 0x07f, 0x040,
> +    0x307, 0x271, 0x384, 0x07f, 0x282, 0x042, 0x003, 0x007,
> +    0x001, 0x005, 0x101, 0x000, 0x3ed, 0x1d5, 0x28c, 0x347,
> +    0x241, 0x281, 0x364, 0x233, 0x002, 0x001, 0x005, 0x347,
> +    0x225, 0x281, 0x3c4, 0x0ff, 0x281, 0x342, 0x289, 0x281,
> +    0x347, 0x28c, 0x282, 0x366, 0x282, 0x00f, 0x009, 0x006,
> +    0x1c0, 0x281, 0x0c1, 0x282, 0x044, 0x1bc, 0x00a, 0x001,
> +    0x00d, 0x141, 0x28b, 0x362, 0x28b, 0x03f, 0x001, 0x00d,
> +    0x151, 0x283, 0x000, 0x3f5, 0x362, 0x28b, 0x00a, 0x003,
> +    0x004, 0x0ca, 0x28b, 0x397, 0x00a, 0x189, 0x395, 0x0d8,
> +    0x044, 0x2ea, 0x001, 0x009, 0x004, 0x380, 0x013, 0x327,
> +    0x24c, 0x131, 0x003, 0x005, 0x105, 0x000, 0x3fc, 0x051,
> +    0x2c7, 0x28a, 0x3a4, 0x07f, 0x121, 0x040, 0x307, 0x271,
> +    0x384, 0x07f, 0x282, 0x042, 0x003, 0x005, 0x101, 0x000,
> +    0x3f0, 0x1d6, 0x28a, 0x387, 0x00a, 0x189, 0x395, 0x0d3,
> +    0x300, 0x28a, 0x050, 0x247, 0x28a, 0x30a, 0x28b, 0x3b7,
> +    0x201, 0x184, 0x305, 0x28a, 0x044, 0x1bd, 0x000, 0x045,
> +    0x0c1, 0x283, 0x342, 0x282, 0x281, 0x003, 0x006, 0x141,
> +    0x283, 0x000, 0x3f9, 0x045, 0x000, 0x301, 0x103, 0x307,
> +    0x006, 0x10e, 0x21e, 0x33e, 0x13c, 0x038, 0x078, 0x1f8,
> +    0x0f0, 0x000, 0x001, 0x003, 0x002, 0x006, 0x187, 0x227,
> +    0x387, 0x00a, 0x189, 0x395, 0x1c8, 0x300, 0x227, 0x111,
> +    0x050, 0x247, 0x24c, 0x1d7, 0x24c, 0x384, 0x0ff, 0x285,
> +    0x044, 0x226, 0x00a, 0x364, 0x22a, 0x001, 0x001, 0x00e,
> +    0x3d5, 0x200, 0x232, 0x040, 0x1aa, 0x285, 0x3b7, 0x220,
> +    0x044, 0x1bd, 0x000, 0x042, 0x364, 0x22a, 0x002, 0x001,
> +    0x022, 0x040, 0x3a7, 0x073, 0x044, 0x192, 0x000, 0x384,
> +    0x31f, 0x044, 0x226, 0x00a, 0x1a4, 0x285, 0x3a7, 0x073,
> +    0x044, 0x1bd, 0x000, 0x3a7, 0x070, 0x044, 0x192, 0x000,
> +    0x19a, 0x18a, 0x043, 0x285, 0x3a7, 0x070, 0x044, 0x1bd,
> +    0x000, 0x045, 0x040, 0x387, 0x00a, 0x189, 0x395, 0x1d5,
> +    0x300, 0x278, 0x051, 0x042, 0x045, 0x00a, 0x058, 0x026,
> +    0x015, 0x044, 0x032, 0x0c0, 0x278, 0x0a0, 0x397, 0x00a,
> +    0x189, 0x395, 0x231, 0x280, 0x050, 0x247, 0x228, 0x3c4,
> +    0x00f, 0x228, 0x347, 0x228, 0x229, 0x040, 0x307, 0x278,
> +    0x001, 0x008, 0x340, 0x229, 0x228, 0x111, 0x000, 0x3fa,
> +    0x042, 0x193, 0x0c0, 0x227, 0x347, 0x225, 0x226, 0x141,
> +    0x227, 0x366, 0x227, 0x00e, 0x001, 0x00b, 0x342, 0x228,
> +    0x226, 0x007, 0x3f6, 0x140, 0x226, 0x001, 0x011, 0x121,
> +    0x2e2, 0x006, 0x009, 0x3cc, 0x141, 0x278, 0x366, 0x278,
> +    0x005, 0x009, 0x3c4, 0x0a1, 0x000, 0x006, 0x044, 0x1da,
> +    0x00a, 0x0a0, 0x045, 0x044, 0x333, 0x008, 0x020, 0x181,
> +    0x006, 0x345, 0x21d, 0x232, 0x364, 0x23f, 0x001, 0x029,
> +    0x2e4, 0x002, 0x2c7, 0x234, 0x399, 0x200, 0x245, 0x233,
> +    0x364, 0x234, 0x020, 0x009, 0x005, 0x208, 0x244, 0x233,
> +    0x083, 0x18c, 0x208, 0x244, 0x036, 0x2e4, 0x008, 0x001,
> +    0x007, 0x345, 0x220, 0x232, 0x000, 0x007, 0x081, 0x18b,
> +    0x208, 0x244, 0x232, 0x307, 0x235, 0x226, 0x3a4, 0x001,
> +    0x001, 0x010, 0x327, 0x234, 0x2e4, 0x001, 0x009, 0x041,
> +    0x041, 0x044, 0x20d, 0x000, 0x044, 0x2f3, 0x000, 0x043,
> +    0x0a3, 0x1ad, 0x3a5, 0x039, 0x326, 0x236, 0x001, 0x02f,
> +    0x3a7, 0x0bf, 0x1a7, 0x3a5, 0x039, 0x326, 0x236, 0x001,
> +    0x026, 0x327, 0x234, 0x307, 0x235, 0x286, 0x384, 0x002,
> +    0x001, 0x01d, 0x2e4, 0x002, 0x009, 0x051, 0x041, 0x0a1,
> +    0x1ad, 0x2c5, 0x024, 0x307, 0x024, 0x19a, 0x002, 0x005,
> +    0x2a8, 0x2c4, 0x024, 0x044, 0x3b5, 0x000, 0x044, 0x0f2,
> +    0x001, 0x044, 0x3f0, 0x000, 0x043, 0x000, 0x067, 0x364,
> +    0x026, 0x001, 0x009, 0x3c6, 0x041, 0x0a0, 0x044, 0x301,
> +    0x000, 0x364, 0x26f, 0x002, 0x021, 0x310, 0x00a, 0x044,
> +    0x290, 0x001, 0x0c1, 0x26f, 0x043, 0x307, 0x020, 0x193,
> +    0x384, 0x007, 0x110, 0x001, 0x00c, 0x364, 0x232, 0x010,
> +    0x009, 0x007, 0x044, 0x044, 0x001, 0x000, 0x3a3, 0x3c4,
> +    0x3fe, 0x26f, 0x3c5, 0x001, 0x200, 0x3c5, 0x010, 0x020,
> +    0x3c4, 0x31f, 0x020, 0x000, 0x395, 0x364, 0x026, 0x002,
> +    0x009, 0x3c5, 0x041, 0x044, 0x003, 0x001, 0x043, 0x307,
> +    0x020, 0x197, 0x384, 0x007, 0x110, 0x001, 0x00f, 0x364,
> +    0x232, 0x020, 0x009, 0x00a, 0x044, 0x051, 0x001, 0x3c5,
> +    0x001, 0x027, 0x000, 0x3ab, 0x3c4, 0x3fc, 0x26f, 0x3c5,
> +    0x001, 0x200, 0x3c5, 0x100, 0x020, 0x087, 0x188, 0x208,
> +    0x244, 0x020, 0x000, 0x39b, 0x044, 0x11a, 0x001, 0x307,
> +    0x234, 0x306, 0x235, 0x384, 0x003, 0x021, 0x2e4, 0x002,
> +    0x347, 0x234, 0x235, 0x366, 0x26f, 0x002, 0x021, 0x2e4,
> +    0x002, 0x364, 0x234, 0x003, 0x021, 0x2e4, 0x002, 0x327,
> +    0x21c, 0x324, 0x020, 0x021, 0x385, 0x00a, 0x020, 0x247,
> +    0x002, 0x364, 0x23f, 0x001, 0x021, 0x38e, 0x00a, 0x020,
> +    0x247, 0x002, 0x345, 0x21d, 0x232, 0x020, 0x247, 0x002,
> +    0x2c7, 0x241, 0x307, 0x242, 0x286, 0x001, 0x092, 0x0c1,
> +    0x22a, 0x327, 0x242, 0x326, 0x241, 0x3a4, 0x0ff, 0x001,
> +    0x005, 0x3c4, 0x38f, 0x020, 0x347, 0x241, 0x242, 0x347,
> +    0x241, 0x226, 0x307, 0x21d, 0x304, 0x241, 0x001, 0x00a,
> +    0x0c3, 0x22a, 0x347, 0x241, 0x243, 0x044, 0x39f, 0x002,
> +    0x327, 0x241, 0x3a4, 0x0ff, 0x2c7, 0x225, 0x3c4, 0x300,
> +    0x230, 0x2c5, 0x230, 0x044, 0x099, 0x00b, 0x081, 0x18b,
> +    0x304, 0x226, 0x009, 0x00d, 0x364, 0x232, 0x100, 0x009,
> +    0x008, 0x081, 0x18a, 0x208, 0x044, 0x1b8, 0x000, 0x044,
> +    0x186, 0x001, 0x327, 0x226, 0x003, 0x032, 0x044, 0x2f6,
> +    0x002, 0x001, 0x019, 0x044, 0x237, 0x00a, 0x347, 0x241,
> +    0x226, 0x081, 0x306, 0x22a, 0x384, 0x003, 0x001, 0x005,
> +    0x347, 0x243, 0x226, 0x044, 0x032, 0x009, 0x002, 0x02d,
> +    0x000, 0x031, 0x044, 0x237, 0x00a, 0x009, 0x01c, 0x044,
> +    0x082, 0x00b, 0x0a2, 0x1ab, 0x324, 0x020, 0x001, 0x023,
> +    0x364, 0x233, 0x001, 0x000, 0x01e, 0x045, 0x044, 0x186,
> +    0x001, 0x3c5, 0x003, 0x22a, 0x347, 0x241, 0x243, 0x000,
> +    0x3c7, 0x3a4, 0x3ff, 0x001, 0x00e, 0x327, 0x21c, 0x324,
> +    0x020, 0x009, 0x006, 0x043, 0x3a7, 0x0ff, 0x041, 0x0c0,
> +    0x270, 0x044, 0x082, 0x00b, 0x3c4, 0x3fc, 0x22a, 0x327,
> +    0x21c, 0x324, 0x020, 0x009, 0x010, 0x307, 0x270, 0x003,
> +    0x005, 0x020, 0x181, 0x006, 0x043, 0x3a7, 0x0ff, 0x041,
> +    0x020, 0x181, 0x006, 0x045, 0x2c7, 0x243, 0x307, 0x250,
> +    0x286, 0x001, 0x3de, 0x0c2, 0x22a, 0x041, 0x044, 0x39f,
> +    0x002, 0x043, 0x2c7, 0x226, 0x3a4, 0x0ff, 0x2c7, 0x225,
> +    0x3c4, 0x0ff, 0x230, 0x1a7, 0x2c5, 0x230, 0x307, 0x21d,
> +    0x304, 0x243, 0x001, 0x013, 0x3c4, 0x0ff, 0x243, 0x347,
> +    0x243, 0x241, 0x347, 0x243, 0x242, 0x3c5, 0x003, 0x22a,
> +    0x044, 0x186, 0x001, 0x000, 0x005, 0x044, 0x191, 0x001,
> +    0x327, 0x243, 0x003, 0x394, 0x000, 0x362, 0x364, 0x232,
> +    0x004, 0x001, 0x008, 0x044, 0x232, 0x000, 0x3c4, 0x3fb,
> +    0x232, 0x364, 0x232, 0x008, 0x001, 0x008, 0x044, 0x326,
> +    0x000, 0x3c4, 0x3f7, 0x232, 0x045, 0x3b7, 0x221, 0x083,
> +    0x189, 0x044, 0x1a9, 0x000, 0x083, 0x020, 0x1b7, 0x000,
> +    0x2c7, 0x24d, 0x364, 0x233, 0x002, 0x001, 0x019, 0x3b9,
> +    0x381, 0x121, 0x081, 0x18a, 0x225, 0x304, 0x24d, 0x001,
> +    0x005, 0x044, 0x1ff, 0x00b, 0x140, 0x24d, 0x00b, 0x008,
> +    0x1a3, 0x044, 0x1ff, 0x00b, 0x000, 0x012, 0x307, 0x220,
> +    0x284, 0x001, 0x00d, 0x3c4, 0x33f, 0x232, 0x1b6, 0x3a4,
> +    0x0c0, 0x2c5, 0x232, 0x020, 0x18a, 0x00b, 0x327, 0x24d,
> +    0x364, 0x020, 0x070, 0x001, 0x00a, 0x399, 0x383, 0x101,
> +    0x326, 0x22b, 0x234, 0x001, 0x02e, 0x3c5, 0x080, 0x233,
> +    0x3d5, 0x200, 0x232, 0x364, 0x026, 0x001, 0x001, 0x00a,
> +    0x3c5, 0x004, 0x232, 0x044, 0x20d, 0x000, 0x307, 0x24d,
> +    0x307, 0x24d, 0x384, 0x007, 0x001, 0x09a, 0x113, 0x001,
> +    0x0a8, 0x3b7, 0x301, 0x044, 0x192, 0x000, 0x384, 0x3f8,
> +    0x103, 0x044, 0x1bd, 0x000, 0x3c4, 0x3f7, 0x021, 0x000,
> +    0x0af, 0x0a7, 0x1a7, 0x324, 0x020, 0x001, 0x014, 0x327,
> +    0x24d, 0x326, 0x22b, 0x397, 0x370, 0x364, 0x233, 0x002,
> +    0x001, 0x006, 0x087, 0x18b, 0x385, 0x070, 0x234, 0x001,
> +    0x02b, 0x3c5, 0x100, 0x233, 0x364, 0x026, 0x002, 0x001,
> +    0x008, 0x3c5, 0x008, 0x232, 0x044, 0x3b5, 0x000, 0x307,
> +    0x24d, 0x384, 0x070, 0x001, 0x091, 0x382, 0x030, 0x001,
> +    0x0a6, 0x3b7, 0x301, 0x044, 0x192, 0x000, 0x384, 0x3c7,
> +    0x385, 0x018, 0x044, 0x1bd, 0x000, 0x3c4, 0x3f7, 0x024,
> +    0x000, 0x0a4, 0x347, 0x24d, 0x22b, 0x364, 0x233, 0x006,
> +    0x001, 0x033, 0x307, 0x22b, 0x364, 0x233, 0x002, 0x001,
> +    0x023, 0x364, 0x233, 0x080, 0x001, 0x00a, 0x307, 0x24d,
> +    0x197, 0x384, 0x007, 0x044, 0x3a4, 0x008, 0x364, 0x233,
> +    0x100, 0x001, 0x00c, 0x307, 0x24d, 0x19b, 0x384, 0x007,
> +    0x385, 0x010, 0x044, 0x3a4, 0x008, 0x3c4, 0x27f, 0x233,
> +    0x000, 0x00b, 0x3c5, 0x003, 0x22a, 0x197, 0x044, 0x39c,
> +    0x008, 0x003, 0x298, 0x044, 0x082, 0x00b, 0x0a2, 0x1ab,
> +    0x324, 0x020, 0x021, 0x181, 0x006, 0x045, 0x3b7, 0x301,
> +    0x087, 0x044, 0x1b7, 0x000, 0x3b7, 0x211, 0x082, 0x044,
> +    0x1b7, 0x000, 0x3c4, 0x3f7, 0x021, 0x000, 0x36c, 0x3b7,
> +    0x301, 0x044, 0x192, 0x000, 0x384, 0x3f8, 0x105, 0x044,
> +    0x1bd, 0x000, 0x3b7, 0x211, 0x082, 0x044, 0x1a9, 0x000,
> +    0x3c5, 0x008, 0x021, 0x344, 0x21f, 0x021, 0x3b7, 0x250,
> +    0x088, 0x044, 0x1a9, 0x000, 0x3b7, 0x211, 0x082, 0x044,
> +    0x1a9, 0x000, 0x000, 0x347, 0x3b7, 0x301, 0x387, 0x3c7,
> +    0x044, 0x1b8, 0x000, 0x3a7, 0x060, 0x083, 0x044, 0x1b7,
> +    0x000, 0x3b7, 0x070, 0x083, 0x18a, 0x044, 0x1b7, 0x000,
> +    0x3c4, 0x3f7, 0x024, 0x000, 0x36f, 0x3b7, 0x301, 0x044,
> +    0x192, 0x000, 0x384, 0x3c7, 0x385, 0x028, 0x044, 0x1bd,
> +    0x000, 0x3c5, 0x048, 0x024, 0x3a7, 0x060, 0x083, 0x044,
> +    0x1a9, 0x000, 0x3b7, 0x070, 0x083, 0x18a, 0x044, 0x1a9,
> +    0x000, 0x000, 0x351, 0x307, 0x22b, 0x284, 0x2a8, 0x2c4,
> +    0x24d, 0x245, 0x24d, 0x2a8, 0x045, 0x2f4, 0x200, 0x001,
> +    0x008, 0x364, 0x2cf, 0x007, 0x029, 0x1dc, 0x007, 0x287,
> +    0x385, 0x300, 0x208, 0x001, 0x04b, 0x364, 0x33b, 0x010,
> +    0x029, 0x1dc, 0x007, 0x3c5, 0x002, 0x00c, 0x287, 0x384,
> +    0x0ff, 0x305, 0x21d, 0x1b7, 0x2e4, 0x001, 0x001, 0x01d,
> +    0x040, 0x384, 0x007, 0x117, 0x001, 0x00c, 0x3c5, 0x040,
> +    0x02d, 0x081, 0x044, 0x189, 0x000, 0x3c4, 0x3bf, 0x02d,
> +    0x042, 0x247, 0x029, 0x364, 0x018, 0x001, 0x009, 0x005,
> +    0x3c5, 0x010, 0x021, 0x2e4, 0x002, 0x001, 0x017, 0x264,
> +    0x080, 0x001, 0x005, 0x0a4, 0x1a7, 0x285, 0x040, 0x3c5,
> +    0x080, 0x02d, 0x081, 0x044, 0x189, 0x000, 0x3c4, 0x37f,
> +    0x02d, 0x042, 0x247, 0x02a, 0x000, 0x014, 0x38e, 0x3ff,
> +    0x1b8, 0x00a, 0x00a, 0x244, 0x029, 0x3c4, 0x3ef, 0x021,
> +    0x3c4, 0x3fd, 0x00c, 0x120, 0x001, 0x004, 0x244, 0x02a,
> +    0x020, 0x181, 0x006, 0x289, 0x00a, 0x004, 0x2c7, 0x251,
> +    0x22e, 0x364, 0x026, 0x001, 0x021, 0x181, 0x006, 0x041,
> +    0x3a4, 0x01f, 0x001, 0x005, 0x044, 0x0d9, 0x001, 0x043,
> +    0x1b7, 0x001, 0x005, 0x044, 0x182, 0x000, 0x020, 0x181,
> +    0x006, 0x2e4, 0x002, 0x009, 0x01b, 0x3c4, 0x2ff, 0x232,
> +    0x120, 0x001, 0x012, 0x3d5, 0x300, 0x232, 0x044, 0x099,
> +    0x00b, 0x32a, 0x026, 0x00a, 0x008, 0x044, 0x20d, 0x000,
> +    0x044, 0x232, 0x000, 0x020, 0x181, 0x006, 0x042, 0x307,
> +    0x240, 0x20a, 0x040, 0x020, 0x181, 0x006, 0x289, 0x00a,
> +    0x004, 0x2c7, 0x256, 0x22e, 0x364, 0x026, 0x002, 0x021,
> +    0x181, 0x006, 0x041, 0x3a4, 0x01f, 0x001, 0x005, 0x044,
> +    0x0de, 0x001, 0x043, 0x1b7, 0x001, 0x005, 0x044, 0x0e2,
> +    0x001, 0x020, 0x181, 0x006, 0x364, 0x23f, 0x003, 0x009,
> +    0x007, 0x044, 0x340, 0x001, 0x247, 0x249, 0x054, 0x347,
> +    0x249, 0x248, 0x2c7, 0x23f, 0x083, 0x18a, 0x385, 0x018,
> +    0x364, 0x23f, 0x001, 0x001, 0x006, 0x245, 0x057, 0x000,
> +    0x005, 0x208, 0x244, 0x057, 0x087, 0x18c, 0x385, 0x0e0,
> +    0x364, 0x23f, 0x002, 0x001, 0x009, 0x245, 0x057, 0x044,
> +    0x27d, 0x001, 0x000, 0x005, 0x208, 0x244, 0x057, 0x020,
> +    0x181, 0x006, 0x2c7, 0x246, 0x3b7, 0x300, 0x044, 0x192,
> +    0x000, 0x384, 0x33f, 0x327, 0x246, 0x3a4, 0x0c0, 0x285,
> +    0x3b7, 0x300, 0x044, 0x1bd, 0x000, 0x3b7, 0x200, 0x044,
> +    0x192, 0x000, 0x0a3, 0x1a9, 0x2a8, 0x284, 0x040, 0x307,
> +    0x246, 0x384, 0x030, 0x264, 0x010, 0x001, 0x012, 0x040,
> +    0x041, 0x3b7, 0x201, 0x044, 0x192, 0x000, 0x384, 0x3e0,
> +    0x385, 0x006, 0x044, 0x1bd, 0x000, 0x043, 0x042, 0x185,
> +    0x2a8, 0x284, 0x227, 0x042, 0x285, 0x3b7, 0x200, 0x044,
> +    0x1bd, 0x000, 0x307, 0x246, 0x384, 0x007, 0x044, 0x375,
> +    0x00b, 0x3a7, 0x073, 0x307, 0x246, 0x184, 0x00a, 0x014,
> +    0x044, 0x192, 0x000, 0x384, 0x3e2, 0x327, 0x246, 0x1b5,
> +    0x3a4, 0x01c, 0x285, 0x3a7, 0x073, 0x044, 0x1bd, 0x000,
> +    0x000, 0x006, 0x081, 0x044, 0x1a9, 0x000, 0x020, 0x181,
> +    0x006, 0x3c5, 0x001, 0x00c, 0x187, 0x0a7, 0x1a7, 0x2a8,
> +    0x324, 0x00c, 0x225, 0x2c7, 0x00c, 0x045, 0x04e, 0x087,
> +    0x011, 0x054, 0x084, 0x020, 0x01e, 0x00f, 0x018, 0x01d,
> +    0x029, 0x00b, 0x01d, 0x02c, 0x331, 0x04e, 0x020, 0x0d3,
> +    0x000, 0x020, 0x167, 0x00b, 0x020, 0x3f6, 0x00a, 0x020,
> +    0x096, 0x00b, 0x020, 0x0d3, 0x000, 0x020, 0x0d3, 0x000,
> +    0x020, 0x00d, 0x00b, 0x020, 0x179, 0x00b, 0x0c1, 0x244,
> +    0x3c5, 0x040, 0x245, 0x3c4, 0x3bf, 0x200, 0x020, 0x0d3,
> +    0x000, 0x020, 0x2c3, 0x008, 0x04e, 0x04e, 0x045, 0x0c2,
> +    0x201, 0x045, 0x020, 0x3ed, 0x00a, 0x020, 0x256, 0x002,
> +    0x020, 0x256, 0x002, 0x020, 0x256, 0x002, 0x020, 0x23f,
> +    0x006, 0x020, 0x160, 0x00b, 0x020, 0x28d, 0x00b, 0x020,
> +    0x257, 0x006, 0x020, 0x117, 0x008, 0x020, 0x160, 0x00b,
> +    0x020, 0x160, 0x00b, 0x020, 0x1dc, 0x007, 0x020, 0x160,
> +    0x00b, 0x020, 0x2d2, 0x006, 0x020, 0x1e2, 0x007, 0x020,
> +    0x160, 0x00b, 0x020, 0x3a8, 0x001, 0x020, 0x160, 0x00b,
> +    0x020, 0x160, 0x00b, 0x020, 0x2d5, 0x006, 0x020, 0x326,
> +    0x006, 0x020, 0x350, 0x006, 0x020, 0x1dc, 0x007, 0x020,
> +    0x35a, 0x006, 0x020, 0x177, 0x00b, 0x020, 0x38e, 0x006,
> +    0x020, 0x011, 0x007, 0x020, 0x016, 0x007, 0x020, 0x31e,
> +    0x007, 0x020, 0x324, 0x007, 0x020, 0x3b6, 0x007, 0x020,
> +    0x02a, 0x007, 0x020, 0x041, 0x007, 0x020, 0x060, 0x007,
> +    0x020, 0x06d, 0x007, 0x020, 0x072, 0x007, 0x020, 0x2d1,
> +    0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020,
> +    0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x252, 0x007,
> +    0x020, 0x293, 0x007, 0x020, 0x2fb, 0x00b, 0x020, 0x1dc,
> +    0x007, 0x020, 0x1dc, 0x007, 0x020, 0x16f, 0x007, 0x020,
> +    0x185, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007,
> +    0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x160,
> +    0x00b, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020,
> +    0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007,
> +    0x020, 0x1dc, 0x007, 0x020, 0x1dc, 0x007, 0x020, 0x1dc,
> +    0x007, 0x020, 0x1dc, 0x007, 0x020, 0x077, 0x007, 0x020,
> +    0x0b1, 0x007, 0x020, 0x103, 0x007, 0x020, 0x1c5, 0x008,
> +    0x020, 0x1dc, 0x007, 0x020, 0x168, 0x007, 0x287, 0x264,
> +    0x004, 0x001, 0x049, 0x3c5, 0x00c, 0x00c, 0x3c5, 0x020,
> +    0x33b, 0x18e, 0x00a, 0x013, 0x044, 0x04c, 0x004, 0x3a4,
> +    0x001, 0x001, 0x014, 0x364, 0x052, 0x001, 0x009, 0x093,
> +    0x044, 0x0bc, 0x004, 0x000, 0x08e, 0x3c4, 0x2ff, 0x053,
> +    0x3c4, 0x030, 0x027, 0x000, 0x3ec, 0x3c4, 0x3fe, 0x052,
> +    0x000, 0x081, 0x043, 0x327, 0x33b, 0x020, 0x1de, 0x007,
> +    0x2e4, 0x080, 0x009, 0x00d, 0x3d5, 0x220, 0x33c, 0x100,
> +    0x009, 0x06e, 0x044, 0x3b6, 0x003, 0x000, 0x06c, 0x3d5,
> +    0x120, 0x33c, 0x100, 0x009, 0x022, 0x044, 0x066, 0x004,
> +    0x000, 0x061, 0x384, 0x003, 0x3c4, 0x3df, 0x33b, 0x262,
> +    0x003, 0x001, 0x3d9, 0x3c4, 0x32d, 0x33c, 0x3c4, 0x3ef,
> +    0x027, 0x2e4, 0x040, 0x009, 0x3d5, 0x100, 0x009, 0x007,
> +    0x044, 0x063, 0x004, 0x000, 0x046, 0x364, 0x200, 0x004,
> +    0x029, 0x1dc, 0x007, 0x0c0, 0x2d8, 0x111, 0x001, 0x028,
> +    0x3c5, 0x002, 0x33c, 0x3c5, 0x001, 0x33b, 0x344, 0x21f,
> +    0x33c, 0x287, 0x19b, 0x247, 0x361, 0x287, 0x183, 0x19b,
> +    0x247, 0x360, 0x0c0, 0x35e, 0x2e4, 0x020, 0x001, 0x004,
> +    0x0c5, 0x35e, 0x2e4, 0x010, 0x001, 0x005, 0x3c5, 0x080,
> +    0x33c, 0x289, 0x384, 0x010, 0x245, 0x33c, 0x044, 0x001,
> +    0x004, 0x364, 0x33c, 0x002, 0x001, 0x005, 0x3c5, 0x004,
> +    0x200, 0x364, 0x33c, 0x020, 0x009, 0x005, 0x044, 0x097,
> +    0x004, 0x020, 0x181, 0x006, 0x287, 0x19b, 0x11d, 0x001,
> +    0x002, 0x287, 0x1a3, 0x1b3, 0x19b, 0x180, 0x390, 0x1d7,
> +    0x040, 0x199, 0x390, 0x008, 0x040, 0x045, 0x000, 0x021,
> +    0x000, 0x073, 0x000, 0x05f, 0x000, 0x023, 0x000, 0x025,
> +    0x000, 0x033, 0x000, 0x035, 0x000, 0x037, 0x000, 0x041,
> +    0x000, 0x01f, 0x000, 0x021, 0x000, 0x023, 0x000, 0x031,
> +    0x000, 0x082, 0x000, 0x002, 0x020, 0x1dc, 0x007, 0x044,
> +    0x378, 0x003, 0x3c4, 0x3fd, 0x233, 0x000, 0x072, 0x2c7,
> +    0x363, 0x000, 0x06e, 0x2c7, 0x362, 0x000, 0x06a, 0x2c7,
> +    0x341, 0x000, 0x066, 0x2c7, 0x33f, 0x000, 0x062, 0x2c7,
> +    0x340, 0x000, 0x05e, 0x2c7, 0x344, 0x000, 0x05a, 0x2c7,
> +    0x342, 0x000, 0x056, 0x2c7, 0x343, 0x000, 0x052, 0x2c7,
> +    0x341, 0x2c7, 0x33f, 0x2c7, 0x340, 0x000, 0x04a, 0x307,
> +    0x340, 0x300, 0x341, 0x300, 0x33f, 0x282, 0x007, 0x006,
> +    0x2c7, 0x23e, 0x000, 0x03d, 0x043, 0x0a1, 0x020, 0x1de,
> +    0x007, 0x287, 0x384, 0x003, 0x181, 0x3c4, 0x3f3, 0x052,
> +    0x245, 0x052, 0x3a4, 0x00c, 0x3c4, 0x3f3, 0x33c, 0x2c5,
> +    0x33c, 0x000, 0x026, 0x3c5, 0x002, 0x233, 0x3c7, 0x3ff,
> +    0x352, 0x3c7, 0x3ff, 0x353, 0x1d3, 0x353, 0x0cf, 0x354,
> +    0x1cb, 0x354, 0x3c5, 0x0c0, 0x354, 0x3c9, 0x222, 0x355,
> +    0x3c5, 0x001, 0x33c, 0x0c0, 0x356, 0x1b0, 0x00a, 0x006,
> +    0x081, 0x18a, 0x247, 0x356, 0x1ab, 0x2c7, 0x357, 0x020,
> +    0x181, 0x006, 0x287, 0x001, 0x025, 0x197, 0x3a4, 0x00f,
> +    0x262, 0x003, 0x001, 0x03d, 0x131, 0x001, 0x020, 0x131,
> +    0x001, 0x021, 0x131, 0x001, 0x022, 0x131, 0x001, 0x025,
> +    0x131, 0x001, 0x026, 0x131, 0x001, 0x027, 0x132, 0x182,
> +    0x390, 0x377, 0x280, 0x04c, 0x042, 0x020, 0x1de, 0x007,
> +    0x044, 0x361, 0x003, 0x000, 0x3d4, 0x327, 0x373, 0x000,
> +    0x3f5, 0x327, 0x372, 0x000, 0x3f1, 0x327, 0x2b3, 0x322,
> +    0x2b2, 0x000, 0x3eb, 0x327, 0x374, 0x000, 0x3e7, 0x327,
> +    0x375, 0x000, 0x3e3, 0x327, 0x376, 0x000, 0x3df, 0x307,
> +    0x369, 0x282, 0x272, 0x369, 0x00e, 0x003, 0x108, 0x04c,
> +    0x000, 0x3d4, 0x364, 0x33c, 0x001, 0x001, 0x01b, 0x364,
> +    0x33b, 0x020, 0x009, 0x016, 0x0a0, 0x307, 0x04f, 0x181,
> +    0x00a, 0x003, 0x0a4, 0x100, 0x00b, 0x004, 0x3a5, 0x080,
> +    0x307, 0x050, 0x194, 0x384, 0x040, 0x225, 0x2c7, 0x392,
> +    0x081, 0x189, 0x314, 0x053, 0x001, 0x007, 0x3c5, 0x008,
> +    0x027, 0x000, 0x005, 0x3c4, 0x3f7, 0x027, 0x364, 0x33c,
> +    0x020, 0x001, 0x007, 0x347, 0x21d, 0x35a, 0x000, 0x018,
> +    0x347, 0x050, 0x368, 0x3b7, 0x201, 0x1a5, 0x140, 0x04f,
> +    0x00b, 0x00b, 0x364, 0x052, 0x020, 0x001, 0x3f3, 0x2c5,
> +    0x33c, 0x000, 0x005, 0x2a8, 0x2c4, 0x33c, 0x081, 0x189,
> +    0x304, 0x053, 0x001, 0x007, 0x3c5, 0x008, 0x027, 0x000,
> +    0x005, 0x3c4, 0x3f7, 0x027, 0x3c5, 0x080, 0x053, 0x3c4,
> +    0x37f, 0x053, 0x364, 0x33b, 0x020, 0x009, 0x00a, 0x364,
> +    0x33c, 0x020, 0x009, 0x005, 0x044, 0x132, 0x004, 0x020,
> +    0x08d, 0x006, 0x364, 0x026, 0x010, 0x009, 0x0e8, 0x0c9,
> +    0x2ce, 0x0c8, 0x30f, 0x362, 0x2d2, 0x002, 0x009, 0x004,
> +    0x0ce, 0x30f, 0x362, 0x30f, 0x010, 0x00f, 0x0af, 0x0c4,
> +    0x303, 0x364, 0x30f, 0x002, 0x001, 0x004, 0x141, 0x303,
> +    0x0c1, 0x310, 0x364, 0x30f, 0x001, 0x009, 0x004, 0x152,
> +    0x310, 0x397, 0x2b2, 0x300, 0x30f, 0x04c, 0x2c7, 0x305,
> +    0x397, 0x2aa, 0x300, 0x303, 0x04c, 0x2c0, 0x305, 0x342,
> +    0x310, 0x305, 0x397, 0x2a1, 0x300, 0x303, 0x327, 0x305,
> +    0x04d, 0x044, 0x1bf, 0x003, 0x08c, 0x364, 0x30f, 0x002,
> +    0x001, 0x003, 0x108, 0x364, 0x30f, 0x004, 0x001, 0x003,
> +    0x101, 0x18a, 0x385, 0x101, 0x0a0, 0x044, 0x18a, 0x002,
> +    0x364, 0x2cf, 0x002, 0x001, 0x014, 0x309, 0x013, 0x34b,
> +    0x014, 0x336, 0x209, 0x34b, 0x336, 0x336, 0x209, 0x34b,
> +    0x336, 0x336, 0x249, 0x013, 0x34b, 0x336, 0x014, 0x397,
> +    0x2a1, 0x300, 0x303, 0x04c, 0x320, 0x310, 0x04d, 0x2e4,
> +    0x100, 0x001, 0x004, 0x000, 0x012, 0x044, 0x3f0, 0x002,
> +    0x044, 0x30e, 0x002, 0x140, 0x00f, 0x009, 0x008, 0x307,
> +    0x00e, 0x302, 0x2cd, 0x00a, 0x3e4, 0x0c4, 0x303, 0x364,
> +    0x30f, 0x002, 0x001, 0x004, 0x141, 0x303, 0x397, 0x2a1,
> +    0x300, 0x303, 0x04c, 0x2c7, 0x305, 0x397, 0x2aa, 0x300,
> +    0x303, 0x04c, 0x2c2, 0x305, 0x342, 0x310, 0x305, 0x397,
> +    0x2b2, 0x300, 0x30f, 0x327, 0x305, 0x04d, 0x362, 0x2d2,
> +    0x002, 0x001, 0x00f, 0x364, 0x2cb, 0x002, 0x009, 0x00a,
> +    0x307, 0x30f, 0x118, 0x390, 0x2b2, 0x327, 0x305, 0x04d,
> +    0x141, 0x30f, 0x000, 0x350, 0x044, 0x275, 0x00b, 0x0c0,
> +    0x2a9, 0x0c0, 0x303, 0x362, 0x303, 0x008, 0x00f, 0x017,
> +    0x397, 0x2b2, 0x300, 0x303, 0x04c, 0x2a7, 0x362, 0x303,
> +    0x004, 0x00f, 0x006, 0x2c0, 0x2a9, 0x000, 0x004, 0x2c2,
> +    0x2a9, 0x141, 0x303, 0x000, 0x3e8, 0x30a, 0x2a9, 0x20a,
> +    0x24a, 0x2a9, 0x044, 0x022, 0x009, 0x3c4, 0x3ef, 0x026,
> +    0x045, 0x307, 0x2b2, 0x300, 0x2b3, 0x247, 0x2a1, 0x362,
> +    0x2a1, 0x000, 0x006, 0x004, 0x141, 0x2a1, 0x30a, 0x2a1,
> +    0x300, 0x2aa, 0x247, 0x2a1, 0x307, 0x2b4, 0x300, 0x2b5,
> +    0x247, 0x2a2, 0x362, 0x2a2, 0x000, 0x006, 0x004, 0x141,
> +    0x2a2, 0x30a, 0x2a2, 0x300, 0x2ab, 0x247, 0x2a2, 0x307,
> +    0x2b6, 0x300, 0x2b7, 0x247, 0x2a3, 0x362, 0x2a3, 0x000,
> +    0x006, 0x004, 0x141, 0x2a3, 0x30a, 0x2a3, 0x300, 0x2ac,
> +    0x247, 0x2a3, 0x307, 0x2b8, 0x300, 0x2b9, 0x247, 0x2a4,
> +    0x362, 0x2a4, 0x000, 0x006, 0x004, 0x141, 0x2a4, 0x30a,
> +    0x2a4, 0x300, 0x2ad, 0x247, 0x2a4, 0x347, 0x2ae, 0x2a5,
> +    0x347, 0x2af, 0x2a6, 0x044, 0x3f0, 0x002, 0x045, 0x0c0,
> +    0x30f, 0x362, 0x30f, 0x010, 0x00f, 0x00c, 0x397, 0x2b2,
> +    0x300, 0x30f, 0x0a0, 0x04d, 0x141, 0x30f, 0x000, 0x3f3,
> +    0x045, 0x364, 0x2d4, 0x002, 0x001, 0x003, 0x045, 0x0c7,
> +    0x2ce, 0x347, 0x290, 0x2fb, 0x088, 0x189, 0x395, 0x101,
> +    0x0a0, 0x044, 0x18a, 0x002, 0x044, 0x1bf, 0x003, 0x309,
> +    0x013, 0x34b, 0x014, 0x336, 0x209, 0x34b, 0x336, 0x336,
> +    0x209, 0x34b, 0x336, 0x336, 0x209, 0x34b, 0x336, 0x336,
> +    0x209, 0x34b, 0x336, 0x336, 0x249, 0x013, 0x34b, 0x336,
> +    0x014, 0x307, 0x2ae, 0x300, 0x2ba, 0x114, 0x247, 0x2a5,
> +    0x307, 0x2af, 0x300, 0x2bd, 0x104, 0x247, 0x2a6, 0x3c7,
> +    0x3ff, 0x301, 0x151, 0x2a6, 0x141, 0x2a5, 0x364, 0x2a6,
> +    0x100, 0x001, 0x004, 0x000, 0x01a, 0x364, 0x2a5, 0x100,
> +    0x001, 0x004, 0x000, 0x013, 0x044, 0x014, 0x003, 0x044,
> +    0x30e, 0x002, 0x307, 0x2cd, 0x0c0, 0x336, 0x302, 0x00e,
> +    0x343, 0x00f, 0x336, 0x00a, 0x3df, 0x3ce, 0x3ff, 0x2fe,
> +    0x141, 0x2a6, 0x00b, 0x004, 0x0c0, 0x2a6, 0x151, 0x2a5,
> +    0x00b, 0x004, 0x0c0, 0x2a5, 0x362, 0x2a6, 0x0ff, 0x006,
> +    0x005, 0x3c7, 0x0ff, 0x2a6, 0x362, 0x2a5, 0x0ff, 0x006,
> +    0x005, 0x3c7, 0x0ff, 0x2a5, 0x044, 0x014, 0x003, 0x309,
> +    0x303, 0x242, 0x290, 0x0c0, 0x304, 0x362, 0x304, 0x003,
> +    0x00f, 0x02c, 0x340, 0x303, 0x290, 0x362, 0x290, 0x000,
> +    0x00f, 0x004, 0x0c0, 0x290, 0x362, 0x290, 0x0ff, 0x006,
> +    0x004, 0x000, 0x01b, 0x044, 0x034, 0x003, 0x044, 0x1cc,
> +    0x003, 0x044, 0x30e, 0x002, 0x0c0, 0x2ff, 0x044, 0x195,
> +    0x003, 0x140, 0x2ff, 0x001, 0x005, 0x347, 0x290, 0x305,
> +    0x141, 0x304, 0x000, 0x3d3, 0x362, 0x301, 0x000, 0x00f,
> +    0x01b, 0x347, 0x305, 0x301, 0x347, 0x2fb, 0x290, 0x3c6,
> +    0x0ff, 0x01a, 0x307, 0x2ae, 0x300, 0x2be, 0x114, 0x247,
> +    0x2a5, 0x307, 0x2af, 0x300, 0x2c1, 0x104, 0x247, 0x2a6,
> +    0x000, 0x36a, 0x307, 0x305, 0x300, 0x301, 0x24a, 0x290,
> +    0x044, 0x034, 0x003, 0x045, 0x0c0, 0x2e4, 0x0c3, 0x2ce,
> +    0x044, 0x1bf, 0x003, 0x0c0, 0x2ea, 0x044, 0x078, 0x009,
> +    0x347, 0x28f, 0x318, 0x347, 0x28e, 0x319, 0x0c0, 0x31b,
> +    0x0c0, 0x31c, 0x3c7, 0x038, 0x317, 0x364, 0x2d4, 0x020,
> +    0x001, 0x005, 0x347, 0x2c6, 0x317, 0x364, 0x2d4, 0x002,
> +    0x001, 0x005, 0x347, 0x290, 0x317, 0x0c0, 0x31e, 0x0cf,
> +    0x324, 0x364, 0x2d4, 0x004, 0x001, 0x008, 0x347, 0x28f,
> +    0x31e, 0x347, 0x28f, 0x324, 0x0c0, 0x31f, 0x0cf, 0x325,
> +    0x364, 0x2d4, 0x008, 0x001, 0x008, 0x347, 0x28e, 0x31f,
> +    0x347, 0x28e, 0x325, 0x364, 0x2d4, 0x010, 0x001, 0x00d,
> +    0x347, 0x291, 0x320, 0x347, 0x291, 0x326, 0x347, 0x291,
> +    0x31a, 0x000, 0x00a, 0x0cd, 0x291, 0x0cd, 0x31a, 0x0c0,
> +    0x320, 0x0cd, 0x326, 0x044, 0x1bf, 0x00a, 0x364, 0x24d,
> +    0x030, 0x009, 0x028, 0x309, 0x2c7, 0x34b, 0x2c8, 0x336,
> +    0x209, 0x34b, 0x336, 0x336, 0x34e, 0x2c8, 0x337, 0x32c,
> +    0x2c7, 0x282, 0x343, 0x337, 0x336, 0x247, 0x332, 0x347,
> +    0x336, 0x333, 0x307, 0x332, 0x347, 0x333, 0x336, 0x300,
> +    0x2c7, 0x341, 0x2c8, 0x336, 0x247, 0x334, 0x347, 0x336,
> +    0x335, 0x0c0, 0x398, 0x364, 0x2df, 0x002, 0x001, 0x006,
> +    0x0c1, 0x39a, 0x000, 0x004, 0x0c4, 0x39a, 0x347, 0x2cd,
> +    0x397, 0x0c0, 0x399, 0x307, 0x399, 0x302, 0x39a, 0x006,
> +    0x076, 0x044, 0x16d, 0x00a, 0x0cf, 0x28f, 0x362, 0x28f,
> +    0x000, 0x007, 0x065, 0x362, 0x28f, 0x00f, 0x00f, 0x009,
> +    0x08f, 0x302, 0x28f, 0x247, 0x28e, 0x000, 0x004, 0x0c0,
> +    0x28e, 0x362, 0x28f, 0x006, 0x00f, 0x004, 0x0cf, 0x28e,
> +    0x0c1, 0x394, 0x362, 0x28e, 0x00a, 0x006, 0x004, 0x0d1,
> +    0x394, 0x0c0, 0x2a9, 0x307, 0x2a9, 0x302, 0x394, 0x006,
> +    0x03b, 0x347, 0x2a9, 0x313, 0x307, 0x2aa, 0x300, 0x2a9,
> +    0x247, 0x2a1, 0x307, 0x2ab, 0x300, 0x2a9, 0x247, 0x2a2,
> +    0x307, 0x2ac, 0x302, 0x2a9, 0x247, 0x2a3, 0x307, 0x2ad,
> +    0x302, 0x2a9, 0x247, 0x2a4, 0x044, 0x12e, 0x00a, 0x347,
> +    0x31d, 0x290, 0x307, 0x290, 0x302, 0x323, 0x007, 0x00a,
> +    0x044, 0x015, 0x00a, 0x340, 0x329, 0x290, 0x000, 0x3f4,
> +    0x307, 0x314, 0x300, 0x315, 0x247, 0x316, 0x141, 0x2a9,
> +    0x000, 0x3c3, 0x151, 0x28f, 0x000, 0x39a, 0x340, 0x317,
> +    0x398, 0x141, 0x399, 0x000, 0x388, 0x347, 0x398, 0x317,
> +    0x362, 0x39a, 0x004, 0x009, 0x007, 0x307, 0x398, 0x191,
> +    0x247, 0x317, 0x044, 0x177, 0x00a, 0x347, 0x317, 0x2e9,
> +    0x347, 0x31b, 0x2a9, 0x347, 0x2a9, 0x313, 0x347, 0x316,
> +    0x2ea, 0x0c0, 0x395, 0x347, 0x31e, 0x28f, 0x307, 0x28f,
> +    0x302, 0x324, 0x007, 0x093, 0x0c3, 0x2ce, 0x347, 0x325,
> +    0x28e, 0x347, 0x326, 0x291, 0x044, 0x3ad, 0x002, 0x0c3,
> +    0x303, 0x044, 0x3d4, 0x009, 0x347, 0x2a5, 0x2e2, 0x364,
> +    0x2d4, 0x008, 0x001, 0x007, 0x364, 0x2d4, 0x010, 0x009,
> +    0x05d, 0x0cf, 0x32e, 0x362, 0x32e, 0x000, 0x007, 0x02d,
> +    0x364, 0x2d4, 0x008, 0x009, 0x00c, 0x347, 0x32e, 0x28e,
> +    0x362, 0x28e, 0x00f, 0x006, 0x004, 0x0cf, 0x28e, 0x364,
> +    0x2d4, 0x010, 0x009, 0x005, 0x347, 0x32e, 0x291, 0x044,
> +    0x3ad, 0x002, 0x0c0, 0x303, 0x044, 0x3d4, 0x009, 0x307,
> +    0x2a5, 0x302, 0x2e2, 0x00e, 0x004, 0x000, 0x006, 0x151,
> +    0x32e, 0x000, 0x3d2, 0x364, 0x2d4, 0x008, 0x001, 0x006,
> +    0x141, 0x291, 0x000, 0x022, 0x307, 0x28e, 0x302, 0x325,
> +    0x006, 0x01c, 0x307, 0x2a5, 0x302, 0x2e2, 0x00e, 0x016,
> +    0x141, 0x28e, 0x307, 0x28e, 0x302, 0x325, 0x009, 0x004,
> +    0x000, 0x00c, 0x044, 0x034, 0x003, 0x0c0, 0x303, 0x044,
> +    0x3d4, 0x009, 0x000, 0x3e2, 0x362, 0x291, 0x00d, 0x006,
> +    0x004, 0x0cd, 0x291, 0x397, 0x39b, 0x300, 0x28f, 0x327,
> +    0x28e, 0x04d, 0x397, 0x3ab, 0x300, 0x28f, 0x327, 0x291,
> +    0x04d, 0x141, 0x28f, 0x000, 0x36b, 0x044, 0x16d, 0x00a,
> +    0x347, 0x2c7, 0x2c2, 0x347, 0x2c8, 0x2c3, 0x0c4, 0x397,
> +    0x0c0, 0x399, 0x307, 0x399, 0x302, 0x2e0, 0x006, 0x00f,
> +    0x349, 0x2c7, 0x2c7, 0x34b, 0x2c8, 0x2c8, 0x349, 0x397,
> +    0x397, 0x141, 0x399, 0x000, 0x3ef, 0x044, 0x1bf, 0x00a,
> +    0x347, 0x31e, 0x28f, 0x307, 0x28f, 0x302, 0x324, 0x007,
> +    0x055, 0x0c3, 0x2ce, 0x397, 0x39b, 0x300, 0x28f, 0x04c,
> +    0x2c7, 0x28e, 0x397, 0x3ab, 0x300, 0x28f, 0x04c, 0x2c7,
> +    0x291, 0x347, 0x317, 0x290, 0x044, 0x3ad, 0x002, 0x0c0,
> +    0x32e, 0x362, 0x32e, 0x010, 0x00f, 0x023, 0x0c1, 0x30a,
> +    0x0c0, 0x330, 0x362, 0x330, 0x004, 0x00f, 0x013, 0x364,
> +    0x026, 0x010, 0x009, 0x00a, 0x362, 0x32e, 0x002, 0x006,
> +    0x005, 0x044, 0x1e6, 0x00a, 0x141, 0x330, 0x000, 0x3ec,
> +    0x3c4, 0x3ef, 0x026, 0x141, 0x32e, 0x000, 0x3dc, 0x0c3,
> +    0x2ce, 0x044, 0x1bf, 0x003, 0x044, 0x30e, 0x002, 0x044,
> +    0x015, 0x00a, 0x307, 0x314, 0x300, 0x315, 0x247, 0x316,
> +    0x141, 0x28f, 0x000, 0x3a9, 0x044, 0x3b3, 0x002, 0x362,
> +    0x316, 0x006, 0x00f, 0x004, 0x0c0, 0x396, 0x044, 0x177,
> +    0x00a, 0x347, 0x316, 0x2ec, 0x347, 0x2c2, 0x2c7, 0x347,
> +    0x2c3, 0x2c8, 0x045, 0x3a7, 0x060, 0x044, 0x192, 0x000,
> +    0x207, 0x384, 0x008, 0x247, 0x304, 0x09c, 0x189, 0x395,
> +    0x106, 0x0a0, 0x044, 0x18a, 0x002, 0x3c4, 0x300, 0x01a,
> +    0x140, 0x303, 0x009, 0x010, 0x140, 0x304, 0x009, 0x007,
> +    0x3c5, 0x004, 0x01a, 0x000, 0x013, 0x3c5, 0x020, 0x01a,
> +    0x000, 0x00e, 0x140, 0x304, 0x009, 0x007, 0x3c5, 0x080,
> +    0x01a, 0x000, 0x005, 0x3c5, 0x001, 0x01a, 0x044, 0x1ba,
> +    0x003, 0x3d7, 0x200, 0x013, 0x0c0, 0x014, 0x397, 0x2a5,
> +    0x044, 0x1e9, 0x003, 0x045, 0x0c0, 0x303, 0x0c0, 0x330,
> +    0x0c0, 0x331, 0x0c0, 0x32e, 0x0c0, 0x32f, 0x044, 0x3ad,
> +    0x002, 0x0c0, 0x303, 0x307, 0x303, 0x302, 0x2d1, 0x006,
> +    0x0bb, 0x364, 0x303, 0x001, 0x001, 0x016, 0x307, 0x2ae,
> +    0x302, 0x313, 0x114, 0x302, 0x315, 0x247, 0x2a5, 0x307,
> +    0x2af, 0x302, 0x313, 0x104, 0x300, 0x315, 0x247, 0x2a6,
> +    0x000, 0x014, 0x307, 0x2ae, 0x300, 0x2a9, 0x114, 0x302,
> +    0x314, 0x247, 0x2a5, 0x307, 0x2af, 0x300, 0x2a9, 0x104,
> +    0x300, 0x314, 0x247, 0x2a6, 0x362, 0x2a5, 0x000, 0x00f,
> +    0x003, 0x045, 0x362, 0x2a6, 0x0ff, 0x006, 0x003, 0x045,
> +    0x044, 0x3f0, 0x002, 0x362, 0x303, 0x002, 0x00f, 0x02c,
> +    0x083, 0x18a, 0x385, 0x101, 0x0a0, 0x044, 0x18a, 0x002,
> +    0x044, 0x1cc, 0x003, 0x044, 0x30e, 0x002, 0x307, 0x334,
> +    0x347, 0x335, 0x336, 0x302, 0x046, 0x343, 0x047, 0x336,
> +    0x00a, 0x00e, 0x307, 0x046, 0x347, 0x047, 0x336, 0x302,
> +    0x332, 0x343, 0x333, 0x336, 0x002, 0x006, 0x347, 0x323,
> +    0x290, 0x045, 0x307, 0x303, 0x384, 0x001, 0x104, 0x18a,
> +    0x385, 0x101, 0x207, 0x0a0, 0x044, 0x18a, 0x002, 0x044,
> +    0x1cc, 0x003, 0x044, 0x30e, 0x002, 0x307, 0x046, 0x347,
> +    0x047, 0x336, 0x302, 0x332, 0x343, 0x333, 0x336, 0x002,
> +    0x006, 0x347, 0x323, 0x290, 0x045, 0x364, 0x303, 0x001,
> +    0x001, 0x00a, 0x340, 0x00e, 0x330, 0x341, 0x00f, 0x331,
> +    0x000, 0x008, 0x340, 0x00e, 0x32e, 0x341, 0x00f, 0x32f,
> +    0x307, 0x2fd, 0x347, 0x2fe, 0x336, 0x327, 0x32e, 0x347,
> +    0x32f, 0x337, 0x320, 0x330, 0x341, 0x331, 0x337, 0x282,
> +    0x343, 0x337, 0x336, 0x002, 0x003, 0x045, 0x141, 0x303,
> +    0x000, 0x343, 0x347, 0x290, 0x317, 0x347, 0x28f, 0x318,
> +    0x347, 0x28e, 0x319, 0x347, 0x291, 0x31a, 0x347, 0x2a9,
> +    0x31b, 0x347, 0x313, 0x31c, 0x347, 0x293, 0x396, 0x307,
> +    0x32e, 0x347, 0x32f, 0x336, 0x300, 0x330, 0x341, 0x331,
> +    0x336, 0x247, 0x2fd, 0x347, 0x336, 0x2fe, 0x307, 0x2fd,
> +    0x347, 0x2fe, 0x336, 0x327, 0x397, 0x0c0, 0x337, 0x282,
> +    0x343, 0x337, 0x336, 0x002, 0x019, 0x30a, 0x397, 0x327,
> +    0x330, 0x282, 0x00a, 0x004, 0x141, 0x315, 0x30a, 0x397,
> +    0x327, 0x32e, 0x282, 0x00a, 0x004, 0x141, 0x314, 0x3ce,
> +    0x3ff, 0x2fe, 0x000, 0x2ea, 0x045, 0x364, 0x2d4, 0x002,
> +    0x001, 0x00c, 0x347, 0x317, 0x31d, 0x347, 0x317, 0x323,
> +    0x0c1, 0x329, 0x000, 0x031, 0x362, 0x316, 0x000, 0x00e,
> +    0x007, 0x364, 0x2d4, 0x020, 0x001, 0x01f, 0x307, 0x317,
> +    0x114, 0x247, 0x31d, 0x307, 0x317, 0x104, 0x247, 0x323,
> +    0x0c4, 0x329, 0x362, 0x31d, 0x000, 0x00f, 0x004, 0x0c0,
> +    0x31d, 0x362, 0x323, 0x0b8, 0x006, 0x00f, 0x3c7, 0x0b8,
> +    0x323, 0x000, 0x00a, 0x3c7, 0x038, 0x31d, 0x3c7, 0x0b8,
> +    0x323, 0x0c4, 0x329, 0x045, 0x0c0, 0x314, 0x0c0, 0x315,
> +    0x0c0, 0x316, 0x3ce, 0x3ff, 0x2fe, 0x045, 0x347, 0x319,
> +    0x28e, 0x347, 0x318, 0x28f, 0x347, 0x317, 0x290, 0x347,
> +    0x31a, 0x291, 0x347, 0x396, 0x293, 0x347, 0x31b, 0x2bd,
> +    0x347, 0x2bd, 0x2bc, 0x347, 0x2bc, 0x2bb, 0x347, 0x2bb,
> +    0x2ba, 0x347, 0x2ba, 0x2b5, 0x347, 0x2b5, 0x2b4, 0x347,
> +    0x2b4, 0x2b3, 0x347, 0x2b3, 0x2b2, 0x080, 0x302, 0x31c,
> +    0x247, 0x2c1, 0x347, 0x2c1, 0x2c0, 0x347, 0x2c0, 0x2bf,
> +    0x347, 0x2bf, 0x2be, 0x347, 0x2be, 0x2b9, 0x347, 0x2b9,
> +    0x2b8, 0x347, 0x2b8, 0x2b7, 0x347, 0x2b7, 0x2b6, 0x044,
> +    0x3ad, 0x002, 0x044, 0x022, 0x009, 0x045, 0x309, 0x2c7,
> +    0x34b, 0x2c8, 0x336, 0x209, 0x34b, 0x336, 0x336, 0x209,
> +    0x34b, 0x336, 0x336, 0x300, 0x2c7, 0x341, 0x2c8, 0x336,
> +    0x247, 0x332, 0x347, 0x336, 0x333, 0x309, 0x2c7, 0x34b,
> +    0x2c8, 0x336, 0x300, 0x332, 0x341, 0x333, 0x336, 0x247,
> +    0x334, 0x347, 0x336, 0x335, 0x045, 0x3a7, 0x022, 0x090,
> +    0x364, 0x2d4, 0x001, 0x001, 0x00b, 0x364, 0x2cf, 0x001,
> +    0x001, 0x005, 0x044, 0x1a9, 0x000, 0x045, 0x044, 0x1b7,
> +    0x000, 0x362, 0x2f6, 0x002, 0x00f, 0x02b, 0x0c0, 0x304,
> +    0x044, 0x25b, 0x003, 0x347, 0x2a5, 0x2e2, 0x001, 0x007,
> +    0x347, 0x2a6, 0x2e1, 0x009, 0x005, 0x141, 0x2ee, 0x045,
> +    0x364, 0x2f6, 0x001, 0x001, 0x037, 0x0c1, 0x304, 0x044,
> +    0x25b, 0x003, 0x362, 0x2a5, 0x0ff, 0x001, 0x007, 0x362,
> +    0x2a6, 0x0ff, 0x009, 0x028, 0x141, 0x2ee, 0x045, 0x307,
> +    0x2bb, 0x300, 0x2ae, 0x247, 0x2a5, 0x307, 0x2bd, 0x300,
> +    0x2af, 0x247, 0x2a6, 0x347, 0x2a5, 0x2e2, 0x347, 0x2a6,
> +    0x2e1, 0x364, 0x2f6, 0x001, 0x001, 0x00e, 0x307, 0x2be,
> +    0x300, 0x2ae, 0x247, 0x2a5, 0x307, 0x2c0, 0x300, 0x2af,
> +    0x247, 0x2a6, 0x044, 0x1bf, 0x003, 0x362, 0x2f6, 0x002,
> +    0x00f, 0x00f, 0x364, 0x2cf, 0x001, 0x001, 0x007, 0x3d7,
> +    0x200, 0x013, 0x0c0, 0x014, 0x3c5, 0x100, 0x00d, 0x0c6,
> +    0x2ce, 0x34e, 0x306, 0x306, 0x0c2, 0x308, 0x362, 0x308,
> +    0x00d, 0x00e, 0x019, 0x307, 0x308, 0x112, 0x390, 0x294,
> +    0x04c, 0x2c7, 0x303, 0x34e, 0x306, 0x306, 0x364, 0x306,
> +    0x001, 0x009, 0x005, 0x044, 0x2fa, 0x00a, 0x141, 0x308,
> +    0x000, 0x3e6, 0x140, 0x30a, 0x001, 0x05c, 0x0c0, 0x303,
> +    0x0c0, 0x304, 0x362, 0x304, 0x00b, 0x00e, 0x048, 0x397,
> +    0x294, 0x300, 0x304, 0x04c, 0x2c7, 0x305, 0x362, 0x305,
> +    0x000, 0x00f, 0x007, 0x308, 0x305, 0x101, 0x247, 0x305,
> +    0x307, 0x305, 0x302, 0x303, 0x00f, 0x005, 0x347, 0x305,
> +    0x303, 0x362, 0x305, 0x00f, 0x009, 0x025, 0x141, 0x293,
> +    0x0c0, 0x30a, 0x0c4, 0x2f7, 0x0c0, 0x304, 0x362, 0x304,
> +    0x00b, 0x00e, 0x01c, 0x397, 0x294, 0x300, 0x304, 0x04c,
> +    0x2c7, 0x305, 0x397, 0x294, 0x300, 0x304, 0x329, 0x305,
> +    0x320, 0x305, 0x2aa, 0x2aa, 0x04d, 0x141, 0x304, 0x000,
> +    0x3e7, 0x141, 0x304, 0x000, 0x3b7, 0x362, 0x303, 0x00a,
> +    0x00f, 0x008, 0x151, 0x293, 0x0c0, 0x30a, 0x0c4, 0x2f7,
> +    0x044, 0x06e, 0x003, 0x044, 0x096, 0x003, 0x045, 0x307,
> +    0x2a5, 0x347, 0x2e2, 0x2a5, 0x247, 0x2e2, 0x307, 0x2a6,
> +    0x347, 0x2e1, 0x2a6, 0x247, 0x2e1, 0x044, 0x014, 0x003,
> +    0x045, 0x347, 0x303, 0x304, 0x347, 0x304, 0x30e, 0x3ce,
> +    0x3ff, 0x2fe, 0x152, 0x303, 0x0c0, 0x305, 0x362, 0x305,
> +    0x003, 0x00f, 0x0b9, 0x141, 0x303, 0x362, 0x303, 0x3f1,
> +    0x00f, 0x004, 0x000, 0x0ac, 0x362, 0x303, 0x00f, 0x006,
> +    0x007, 0x347, 0x30c, 0x30d, 0x000, 0x0a6, 0x307, 0x308,
> +    0x112, 0x390, 0x294, 0x327, 0x303, 0x04d, 0x044, 0x096,
> +    0x003, 0x044, 0x2e8, 0x00a, 0x362, 0x2f6, 0x002, 0x00f,
> +    0x00d, 0x08c, 0x189, 0x395, 0x104, 0x328, 0x308, 0x121,
> +    0x3a4, 0x0ff, 0x000, 0x007, 0x088, 0x189, 0x395, 0x101,
> +    0x0a0, 0x044, 0x18a, 0x002, 0x044, 0x30e, 0x002, 0x347,
> +    0x00e, 0x32e, 0x347, 0x00f, 0x32f, 0x364, 0x2f6, 0x001,
> +    0x001, 0x024, 0x044, 0x2e8, 0x00a, 0x362, 0x2f6, 0x002,
> +    0x00f, 0x010, 0x08e, 0x189, 0x395, 0x104, 0x328, 0x308,
> +    0x121, 0x3a4, 0x0ff, 0x044, 0x18a, 0x002, 0x000, 0x005,
> +    0x3c6, 0x0ff, 0x01a, 0x044, 0x30e, 0x002, 0x340, 0x00e,
> +    0x32e, 0x341, 0x00f, 0x32f, 0x140, 0x305, 0x001, 0x007,
> +    0x362, 0x303, 0x3f1, 0x009, 0x005, 0x347, 0x32f, 0x30b,
> +    0x362, 0x305, 0x001, 0x009, 0x005, 0x347, 0x32f, 0x30c,
> +    0x362, 0x305, 0x002, 0x009, 0x005, 0x347, 0x32f, 0x30d,
> +    0x362, 0x32f, 0x000, 0x00f, 0x00d, 0x348, 0x32e, 0x32e,
> +    0x348, 0x32f, 0x32f, 0x141, 0x32e, 0x3c1, 0x000, 0x32f,
> +    0x307, 0x32e, 0x347, 0x32f, 0x336, 0x302, 0x2fd, 0x343,
> +    0x2fe, 0x336, 0x002, 0x00b, 0x347, 0x303, 0x304, 0x347,
> +    0x32e, 0x2fd, 0x347, 0x32f, 0x2fe, 0x140, 0x305, 0x009,
> +    0x007, 0x141, 0x2fd, 0x3c1, 0x000, 0x2fe, 0x141, 0x305,
> +    0x000, 0x346, 0x307, 0x30b, 0x306, 0x30d, 0x003, 0x01d,
> +    0x307, 0x30e, 0x111, 0x247, 0x304, 0x362, 0x30c, 0x000,
> +    0x00f, 0x004, 0x142, 0x304, 0x362, 0x304, 0x3f1, 0x00f,
> +    0x005, 0x3c7, 0x3f1, 0x304, 0x362, 0x304, 0x00f, 0x006,
> +    0x004, 0x0cf, 0x304, 0x307, 0x308, 0x112, 0x390, 0x294,
> +    0x327, 0x304, 0x04d, 0x045, 0x044, 0x290, 0x001, 0x3c4,
> +    0x3fe, 0x200, 0x020, 0x2e0, 0x002, 0x045, 0x1f6, 0x185,
> +    0x1f5, 0x129, 0x1f4, 0x0d0, 0x1b3, 0x0fc, 0x122, 0x0ff,
> +    0x1f6, 0x189, 0x1f5, 0x11b, 0x1f5, 0x0aa, 0x194, 0x0ce,
> +    0x123, 0x0f3, 0x0d2, 0x0ff, 0x364, 0x233, 0x020, 0x009,
> +    0x051, 0x307, 0x272, 0x196, 0x384, 0x00f, 0x0c9, 0x286,
> +    0x242, 0x286, 0x397, 0x00a, 0x189, 0x395, 0x3f7, 0x044,
> +    0x2ea, 0x001, 0x009, 0x004, 0x380, 0x00a, 0x051, 0x2c7,
> +    0x284, 0x101, 0x051, 0x2c7, 0x288, 0x3a4, 0x07f, 0x040,
> +    0x307, 0x272, 0x384, 0x07f, 0x222, 0x042, 0x00b, 0x005,
> +    0x101, 0x000, 0x3ed, 0x347, 0x284, 0x285, 0x3c4, 0x00f,
> +    0x284, 0x1d3, 0x285, 0x1d6, 0x288, 0x342, 0x288, 0x286,
> +    0x003, 0x008, 0x156, 0x285, 0x151, 0x286, 0x00b, 0x3fc,
> +    0x362, 0x285, 0x003, 0x003, 0x004, 0x0c3, 0x285, 0x307,
> +    0x285, 0x0a1, 0x184, 0x305, 0x284, 0x044, 0x1bd, 0x000,
> +    0x045, 0x3db, 0x071, 0x0b9, 0x0ff, 0x089, 0x0e2, 0x12c,
> +    0x176, 0x1bf, 0x00d, 0x007, 0x006, 0x003, 0x002, 0x005,
> +    0x0b3, 0x156, 0x1fa, 0x27f, 0x080, 0x09e, 0x14b, 0x1f0,
> +    0x27f, 0x080, 0x08b, 0x140, 0x1e9, 0x27f, 0x081, 0x138,
> +    0x1e3, 0x27f, 0x00f, 0x0b2, 0x14f, 0x1f0, 0x27f, 0x080,
> +    0x0a3, 0x145, 0x1e7, 0x27f, 0x080, 0x095, 0x13d, 0x1e0,
> +    0x27f, 0x08b, 0x136, 0x1db, 0x27f, 0x0c5, 0x28b, 0x347,
> +    0x271, 0x281, 0x3c4, 0x07f, 0x281, 0x0c5, 0x282, 0x044,
> +    0x2ea, 0x001, 0x009, 0x004, 0x0c2, 0x282, 0x044, 0x154,
> +    0x00b, 0x347, 0x283, 0x289, 0x307, 0x241, 0x364, 0x233,
> +    0x002, 0x001, 0x004, 0x307, 0x225, 0x384, 0x0ff, 0x242,
> +    0x283, 0x00b, 0x056, 0x0c3, 0x28b, 0x302, 0x289, 0x397,
> +    0x00b, 0x189, 0x395, 0x062, 0x044, 0x2ea, 0x001, 0x009,
> +    0x004, 0x380, 0x004, 0x051, 0x2c7, 0x28c, 0x2a9, 0x121,
> +    0x3a4, 0x07f, 0x040, 0x307, 0x271, 0x384, 0x07f, 0x282,
> +    0x042, 0x003, 0x007, 0x001, 0x005, 0x101, 0x000, 0x3ed,
> +    0x1d5, 0x28c, 0x347, 0x241, 0x281, 0x364, 0x233, 0x002,
> +    0x001, 0x005, 0x347, 0x225, 0x281, 0x3c4, 0x0ff, 0x281,
> +    0x342, 0x289, 0x281, 0x347, 0x28c, 0x282, 0x366, 0x282,
> +    0x00f, 0x009, 0x006, 0x1c0, 0x281, 0x0c1, 0x282, 0x044,
> +    0x154, 0x00b, 0x001, 0x00d, 0x141, 0x28b, 0x362, 0x28b,
> +    0x03f, 0x001, 0x00d, 0x151, 0x283, 0x000, 0x3f5, 0x362,
> +    0x28b, 0x00a, 0x003, 0x004, 0x0ca, 0x28b, 0x397, 0x00b,
> +    0x189, 0x395, 0x070, 0x044, 0x2ea, 0x001, 0x009, 0x004,
> +    0x380, 0x013, 0x327, 0x24c, 0x131, 0x003, 0x005, 0x105,
> +    0x000, 0x3fc, 0x051, 0x2c7, 0x28a, 0x3a4, 0x07f, 0x121,
> +    0x040, 0x307, 0x271, 0x384, 0x07f, 0x282, 0x042, 0x003,
> +    0x005, 0x101, 0x000, 0x3f0, 0x1d6, 0x28a, 0x387, 0x00b,
> +    0x189, 0x395, 0x06b, 0x300, 0x28a, 0x050, 0x247, 0x28a,
> +    0x30a, 0x28b, 0x3b7, 0x201, 0x184, 0x305, 0x28a, 0x044,
> +    0x1bd, 0x000, 0x045, 0x0c1, 0x283, 0x342, 0x282, 0x281,
> +    0x003, 0x006, 0x141, 0x283, 0x000, 0x3f9, 0x045, 0x0c0,
> +    0x244, 0x044, 0x172, 0x000, 0x043, 0x047, 0x0a1, 0x1aa,
> +    0x2c5, 0x233, 0x0c0, 0x244, 0x044, 0x172, 0x000, 0x364,
> +    0x233, 0x001, 0x029, 0x0f4, 0x000, 0x047, 0x000, 0x3e9,
> +    0x364, 0x025, 0x004, 0x009, 0x0d4, 0x307, 0x2cf, 0x18a,
> +    0x003, 0x006, 0x002, 0x08c, 0x000, 0x0bd, 0x364, 0x200,
> +    0x100, 0x009, 0x0c0, 0x0c0, 0x2e6, 0x0c0, 0x2e7, 0x08d,
> +    0x18b, 0x385, 0x090, 0x040, 0x083, 0x040, 0x387, 0x080,
> +    0x044, 0x3e3, 0x001, 0x044, 0x346, 0x002, 0x3c5, 0x001,
> +    0x2cf, 0x0c0, 0x2d8, 0x0c0, 0x2f1, 0x3c4, 0x3ef, 0x027,
> +    0x387, 0x085, 0x187, 0x385, 0x080, 0x247, 0x041, 0x3c5,
> +    0x020, 0x00c, 0x0c0, 0x2f6, 0x044, 0x3b3, 0x002, 0x140,
> +    0x2d3, 0x009, 0x026, 0x364, 0x292, 0x008, 0x009, 0x021,
> +    0x044, 0x16d, 0x009, 0x0d0, 0x312, 0x0c0, 0x30a, 0x0c0,
> +    0x2ee, 0x0d0, 0x2f7, 0x044, 0x253, 0x00b, 0x342, 0x293,
> +    0x312, 0x001, 0x00e, 0x0c1, 0x30a, 0x347, 0x293, 0x312,
> +    0x0c8, 0x2f7, 0x044, 0x253, 0x00b, 0x000, 0x3f1, 0x3c4,
> +    0x1ff, 0x2cf, 0x0c0, 0x30a, 0x307, 0x290, 0x183, 0x305,
> +    0x28f, 0x183, 0x305, 0x28e, 0x247, 0x2f2, 0x0cf, 0x2ce,
> +    0x044, 0x113, 0x003, 0x044, 0x33f, 0x002, 0x055, 0x364,
> +    0x2cf, 0x020, 0x009, 0x005, 0x3c4, 0x3bf, 0x200, 0x3c4,
> +    0x3ee, 0x2cf, 0x364, 0x2df, 0x001, 0x009, 0x04a, 0x364,
> +    0x33c, 0x002, 0x009, 0x045, 0x141, 0x2cf, 0x044, 0x346,
> +    0x002, 0x3c5, 0x002, 0x2cf, 0x347, 0x2d5, 0x2f7, 0x0c4,
> +    0x303, 0x044, 0x08a, 0x009, 0x044, 0x333, 0x008, 0x151,
> +    0x2f7, 0x00b, 0x3f6, 0x347, 0x2d5, 0x2f7, 0x044, 0x253,
> +    0x00b, 0x055, 0x3c4, 0x3fc, 0x2cf, 0x364, 0x2cf, 0x040,
> +    0x009, 0x019, 0x3c4, 0x39d, 0x2cf, 0x0ce, 0x2ce, 0x364,
> +    0x2cf, 0x001, 0x009, 0x007, 0x0cf, 0x2ce, 0x3c4, 0x3fe,
> +    0x2cf, 0x364, 0x2cf, 0x010, 0x009, 0x005, 0x3c4, 0x3bf,
> +    0x200, 0x3c4, 0x1ff, 0x2cf, 0x044, 0x33f, 0x002, 0x020,
> +    0x0d3, 0x000, 0x347, 0x2cb, 0x306, 0x044, 0x1e6, 0x00a,
> +    0x044, 0x333, 0x008, 0x151, 0x2f7, 0x009, 0x3f5, 0x045,
> +    0x397, 0x201, 0x0a0, 0x044, 0x18a, 0x002, 0x020, 0x1bf,
> +    0x003, 0x397, 0x2ba, 0x04c, 0x118, 0x04d, 0x109, 0x272,
> +    0x2c1, 0x00b, 0x3fa, 0x045, 0x397, 0x2b2, 0x04c, 0x2c7,
> +    0x303, 0x101, 0x04c, 0x322, 0x303, 0x00b, 0x009, 0x04c,
> +    0x111, 0x04d, 0x101, 0x327, 0x303, 0x04d, 0x101, 0x272,
> +    0x2c1, 0x00b, 0x3ed, 0x045, 0x2f4, 0x200, 0x001, 0x008,
> +    0x364, 0x2cf, 0x007, 0x029, 0x1dc, 0x007, 0x287, 0x385,
> +    0x300, 0x208, 0x001, 0x04b, 0x364, 0x33b, 0x010, 0x029,
> +    0x1dc, 0x007, 0x3c5, 0x002, 0x00c, 0x287, 0x384, 0x0ff,
> +    0x305, 0x21d, 0x1b7, 0x2e4, 0x001, 0x001, 0x01d, 0x040,
> +    0x384, 0x007, 0x117, 0x001, 0x00c, 0x3c5, 0x040, 0x02d,
> +    0x081, 0x044, 0x189, 0x000, 0x3c4, 0x3bf, 0x02d, 0x042,
> +    0x247, 0x029, 0x364, 0x018, 0x001, 0x009, 0x005, 0x3c5,
> +    0x010, 0x021, 0x2e4, 0x002, 0x001, 0x017, 0x264, 0x080,
> +    0x001, 0x005, 0x0a4, 0x1a7, 0x285, 0x040, 0x3c5, 0x080,
> +    0x02d, 0x081, 0x044, 0x189, 0x000, 0x3c4, 0x37f, 0x02d,
> +    0x042, 0x247, 0x02a, 0x000, 0x014, 0x38e, 0x3ff, 0x1b8,
> +    0x00a, 0x00a, 0x244, 0x029, 0x3c4, 0x3ef, 0x021, 0x3c4,
> +    0x3fd, 0x00c, 0x120, 0x001, 0x004, 0x244, 0x02a, 0x020,
> +    0x181, 0x006, 0x364, 0x23f, 0x003, 0x009, 0x007, 0x044,
> +    0x340, 0x001, 0x247, 0x249, 0x054, 0x347, 0x249, 0x248,
> +    0x2c7, 0x23f, 0x083, 0x18a, 0x385, 0x018, 0x364, 0x23f,
> +    0x001, 0x001, 0x006, 0x245, 0x057, 0x000, 0x005, 0x208,
> +    0x244, 0x057, 0x087, 0x18c, 0x385, 0x0e0, 0x364, 0x23f,
> +    0x002, 0x001, 0x009, 0x245, 0x057, 0x044, 0x27d, 0x001,
> +    0x000, 0x005, 0x208, 0x244, 0x057, 0x020, 0x181, 0x006,
> +    0x04e, 0x0ce, 0x045, 0x03c, 0x0f5, 0x04e, 0x0fd, 0x07e,
> +    0x00a, 0x0f9
> +
> +};  /* end fm10000_serdes_swap_code_prd2 */
> diff --git a/drivers/net/fm10k/switch/fm10k_spico_code.h
> b/drivers/net/fm10k/switch/fm10k_spico_code.h
> new file mode 100644
> index 0000000..c57a169
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_spico_code.h
> @@ -0,0 +1,34 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_SPICO_CODE_H_
> +#define _FM10K_SPICO_CODE_H_
> +#include <stdint.h>
> +
> +extern const uint32_t fm10000_sbus_master_code_versionBuildId_prd;
> +extern const uint32_t fm10000_sbus_master_code_size_prd;
> +extern const uint16_t fm10000_sbus_master_code_prd[];
> +
> +extern const uint32_t fm10000_serdes_spico_code_versionBuildId_prd2;
> +extern const uint32_t fm10000_serdes_spico_code_size_prd2;
> +extern const uint16_t fm10000_serdes_spico_code_prd2[];
> +
> +extern const uint32_t fm10000_serdes_swap_code_versionBuildId_prd2;
> +extern const uint32_t fm10000_serdes_swap_code_size_prd2;
> +extern const uint16_t fm10000_serdes_swap_code_prd2[];
> +
> +#endif /* _FM10K_SPICO_CODE_H_ */
> diff --git a/drivers/net/fm10k/switch/fm10k_stats.c
> b/drivers/net/fm10k/switch/fm10k_stats.c
> new file mode 100644
> index 0000000..848b6a6
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_stats.c
> @@ -0,0 +1,911 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#include "../base/fm10k_type.h"
> +#include "../base/fm10k_osdep.h"
> +
> +#include "../fm10k.h"
> +#include "../fm10k_logs.h"
> +#include "fm10k_debug.h"
> +#include "fm10k_regs.h"
> +#include "fm10k_ext_port.h"
> +#include "fm10k_stats.h"
> +#include "fm10k_switch.h"
> +#include "fm10k_config.h"
> +#include "fm10k_ffu.h"
> +
> +
> +#define FM10K_MAX_VLAN_COUNTER				63
> +#define FM10K_NB_RX_STATS_BANKS				6
> +#define FM10K_BINS_PER_RX_STATS_BANK		16
> +#define FM10K_WORDS_PER_RX_STATS_COUNTER	4
> +
> +/* Max expected entries in read stats scatter gather list */
> +#define MAX_STATS_SGLIST 128
> +#define FM10K_RX_STATS_BASE
> 	(0xE00000)
> +#define FM10K_MOD_BASE
> 	(0xE80000)
> +#define FM10K_CM_APPLY_BASE
> 	(0xD40000)
> +#define FM10K_EPL_BASE
> 	(0x0E0000)
> +
> +#define FM10K_RX_STATS_BANK(index1, index0, word)			\
> +	((0x001000) * ((index1) - 0) + (0x000004) * ((index0) - 0) + (word) +
> (0x000000) + (FM10K_RX_STATS_BASE))
> +#define FM10K_MOD_STATS_BANK_FRAME(index1, index0, word)	\
> +	((0x000800) * ((index1) - 0) + (0x000002) * ((index0) - 0) + (word) +
> (0x025000) + (FM10K_MOD_BASE))
> +#define FM10K_MOD_STATS_BANK_BYTE(index1, index0, word)		\
> +	((0x000800) * ((index1) - 0) + (0x000002) * ((index0) - 0) + (word) +
> (0x026000) + (FM10K_MOD_BASE))
> +#define FM10K_CM_APPLY_DROP_COUNT(index, word)
> 		\
> +	((0x000002) * ((index) - 0) + (word) + (0x000880) +
> (FM10K_CM_APPLY_BASE))
> +#define FM10K_MAC_OVERSIZE_COUNTER(index1, index0)
> 	\
> +	((0x000400) * ((index1) - 0) + (0x000080) * ((index0) - 0) + (0x000021) +
> (FM10K_EPL_BASE))
> +#define FM10K_MAC_JABBER_COUNTER(index1, index0)
> 	\
> +	((0x000400) * ((index1) - 0) + (0x000080) * ((index0) - 0) + (0x000022) +
> (FM10K_EPL_BASE))
> +#define FM10K_MAC_UNDERSIZE_COUNTER(index1, index0) 		\
> +	((0x000400) * ((index1) - 0) + (0x000080) * ((index0) - 0) + (0x000023) +
> (FM10K_EPL_BASE))
> +#define FM10K_MAC_RUNT_COUNTER(index1, index0)
> 	\
> +	((0x000400) * ((index1) - 0) + (0x000080) * ((index0) - 0) + (0x000024) +
> (FM10K_EPL_BASE))
> +#define FM10K_MAC_OVERRUN_COUNTER(index1, index0)
> 	\
> +	((0x000400) * ((index1) - 0) + (0x000080) * ((index0) - 0) + (0x000025) +
> (FM10K_EPL_BASE))
> +#define FM10K_MAC_UNDERRUN_COUNTER(index1, index0)
> 	\
> +	((0x000400) * ((index1) - 0) + (0x000080) * ((index0) - 0) + (0x000026) +
> (FM10K_EPL_BASE))
> +#define FM10K_MAC_CODE_ERROR_COUNTER(index1, index0) 		\
> +	((0x000400) * ((index1) - 0) + (0x000080) * ((index0) - 0) + (0x000027) +
> (FM10K_EPL_BASE))
> +
> +
> +/*
> + * Get a 32bit EPL counter by adding it to the scatter gather
> + * list.
> + * Depends on the existence of the variables:
> + * sgList [out] - scatter gather array to hold the reads
> + * sgListCnt [out] - number of entry in the sgList
> + */
> +#define FM10K_GET_EPL_PORT_STAT_32(reg, var)		do { 	\
> +	sgList[sgListCnt].addr = reg(epl, lane);				\
> +	sgList[sgListCnt].data = (uint32_t*)&counters->var;		\
> +	sgList[sgListCnt].count = 1;
> 		\
> +	sgListCnt++;
> 				\
> +} while(0)
> +
> +/*
> + * Clear a 32bit EPL counter by adding it to the scatter gather
> + * list.
> + * Depends on the existence of the variables:
> + * sgList [out] - scatter gather array to hold the reads
> + * sgListCnt [out] - number of entry in the sgList
> + */
> +#define FM10K_SET_EPL_PORT_STAT_32(reg, varPtr)		do {	\
> +    sgList[sgListCnt].addr = reg(epl, lane);				\
> +    sgList[sgListCnt].data = (uint32_t*)varPtr;				\
> +    sgList[sgListCnt].count = 1;
> 	\
> +    sgListCnt++;
> 			\
> +} while(0)
> +
> +/*
> + * Add a 64bit read of a tx counter to the scatter gather list.
> + * Depends on the existence of the variables:
> + * sgList [out] - scatter gather array to hold the reads
> + * sgListCnt [out] - number of entry in the sgList
> + */
> +#define FM10K_GET_TX_PORT_STAT_64(bank, bin, frameOffset, byteOffset)
> 	do {				\
> +    sgList[sgListCnt].addr = FM10K_MOD_STATS_BANK_FRAME(bank, (physPort
> << 4 | bin), 0);	\
> +    sgList[sgListCnt].data = (uint32_t*)(((uint8_t*)counters)+frameOffset);
> 				\
> +    sgList[sgListCnt].count = 2;
> 									\
> +    sgListCnt++;
> 
> 		\
> +    sgList[sgListCnt].addr = FM10K_MOD_STATS_BANK_BYTE(bank, (physPort <<
> 4 | bin), 0);		\
> +    sgList[sgListCnt].data = (uint32_t*)(((uint8_t*)counters)+byteOffset);
> 				\
> +    sgList[sgListCnt].count = 2;
> 									\
> +    sgListCnt++;
> 
> 		\
> +} while(0)
> +
> +/*
> + * Add a 128bit read of an rx counter to the scatter gather
> + * list.
> + * NOTE: Read values will be stored in the temporary
> + *       array switchExt->cntRxPortStatsBank;
> + * Depends on the existence of the variables:
> + * switchExt->cntRxPortStatsBank [out] - Array to store the
> + * 128bit values sgList
> + * [out] - scatter gather array to hold the reads sgListCnt
> + * [out] - number of entry in the sgList
> + */
> +#define FM10K_GET_RX_PORT_STAT_128(bank, bin)
> 	do {					\
> +    sgList[sgListCnt].addr = FM10K_RX_STATS_BANK(bank, (physPort << 4 | bin),
> 0);	\
> +    sgList[sgListCnt].data = cntRxPortStatsBank[bank][bin];
> 					\
> +    sgList[sgListCnt].count = 4;
> 							\
> +    sgListCnt++;
> 									\
> +} while(0)
> +
> +/*
> + * Update the counter variable related to a 128bit HW counter
> + * NOTE: Read values will be retrieved from the temporary
> + *       array switchExt->cntRxPortStatsBank;
> + * Depends on the existence of the variables:
> + * switchExt->cntRxPortStatsBank [in] - Array to read the
> + * 128bit values from
> + */
> +#define FM10K_UPD_RX_PORT_STAT_128(bank, bin, frameOffset, byteOffset)
> 	do {	\
> +    *( (uint64_t*) (((uint8_t*)counters)+frameOffset) ) = (uint64_t) (
> 		\
> +        ((uint64_t)(cntRxPortStatsBank[bank][bin][1]) << 32) |
> 			\
> +        ((uint64_t)(cntRxPortStatsBank[bank][bin][0]) ) );
> 			\
> +    *( (uint64_t*) (((uint8_t*)counters)+byteOffset) ) = (uint64_t) (
> 	\
> +        ((uint64_t)(cntRxPortStatsBank[bank][bin][3]) << 32) |
> 			\
> +        ((uint64_t)(cntRxPortStatsBank[bank][bin][2]) ) );
> 			\
> +} while(0)
> +
> +
> +/* Rx Bank Definitions */
> +#define FM10K_RX_STAT_BANK_TYPE                       0
> +#define FM10K_RX_STAT_BANK_SIZE                       1
> +#define FM10K_RX_STAT_BANK_PRI                        2
> +#define FM10K_RX_STAT_BANK_FWD_1                      3
> +#define FM10K_RX_STAT_BANK_FWD_2                      4
> +#define FM10K_RX_STAT_BANK_VLAN                       5
> +
> +/* FM10K_RX_STAT_BANK_TYPE Bin Definitions */
> +#define FM10K_RX_STAT_NONIP_L2UCAST                   0
> +#define FM10K_RX_STAT_NONIP_L2MCAST                   1
> +#define FM10K_RX_STAT_NONIP_L2BCAST                   2
> +#define FM10K_RX_STAT_IPV4_L2UCAST                    3
> +#define FM10K_RX_STAT_IPV4_L2MCAST                    4
> +#define FM10K_RX_STAT_IPV4_L2BCAST                    5
> +#define FM10K_RX_STAT_IPV6_L2UCAST                    6
> +#define FM10K_RX_STAT_IPV6_L2MCAST                    7
> +#define FM10K_RX_STAT_IPV6_L2BCAST                    8
> +#define FM10K_RX_STAT_IEEE802_3_PAUSE                 9
> +#define FM10K_RX_STAT_CLASS_BASED_PAUSE               10
> +#define FM10K_RX_STAT_FRAMING_ERR                     11
> +#define FM10K_RX_STAT_FCS_ERR                         12
> +
> +/* FM10K_RX_STAT_BANK_SIZE Bin Definitions */
> +#define FM10K_RX_STAT_LEN_LT_64                       0
> +#define FM10K_RX_STAT_LEN_EQ_64                       1
> +#define FM10K_RX_STAT_LEN_65_127                      2
> +#define FM10K_RX_STAT_LEN_128_255                     3
> +#define FM10K_RX_STAT_LEN_256_511                     4
> +#define FM10K_RX_STAT_LEN_512_1023                    5
> +#define FM10K_RX_STAT_LEN_1024_1522                   6
> +#define FM10K_RX_STAT_LEN_1523_2047                   7
> +#define FM10K_RX_STAT_LEN_2048_4095                   8
> +#define FM10K_RX_STAT_LEN_4096_8191                   9
> +#define FM10K_RX_STAT_LEN_8192_10239                  10
> +#define FM10K_RX_STAT_LEN_GE_10240                    11
> +
> +/* FM10K_RX_STAT_BANK_PRI Bin Definitions */
> +#define FM10K_RX_STAT_PRI_0                           0
> +#define FM10K_RX_STAT_PRI_1                           1
> +#define FM10K_RX_STAT_PRI_2                           2
> +#define FM10K_RX_STAT_PRI_3                           3
> +#define FM10K_RX_STAT_PRI_4                           4
> +#define FM10K_RX_STAT_PRI_5                           5
> +#define FM10K_RX_STAT_PRI_6                           6
> +#define FM10K_RX_STAT_PRI_7                           7
> +#define FM10K_RX_STAT_PRI_8                           8
> +#define FM10K_RX_STAT_PRI_9                           9
> +#define FM10K_RX_STAT_PRI_10                          10
> +#define FM10K_RX_STAT_PRI_11                          11
> +#define FM10K_RX_STAT_PRI_12                          12
> +#define FM10K_RX_STAT_PRI_13                          13
> +#define FM10K_RX_STAT_PRI_14                          14
> +#define FM10K_RX_STAT_PRI_15                          15
> +
> +/* FM10K_RX_STAT_BANK_FWD_1 Bin Definitions */
> +#define FM10K_RX_STAT_FID_FORWARDED                   0
> +#define FM10K_RX_STAT_FLOOD_FORWARDED                 1
> +#define FM10K_RX_STAT_SPECIALLY_HANDLED               2
> +#define FM10K_RX_STAT_PARSER_ERROR_DROP               3
> +#define FM10K_RX_STAT_ECC_ERROR_DROP                  4
> +#define FM10K_RX_STAT_TRAPPED                         5
> +#define FM10K_RX_STAT_PAUSE_DROPS                     6
> +#define FM10K_RX_STAT_STP_DROPS                       7
> +#define FM10K_RX_STAT_SECURITY_VIOLATIONS             8
> +#define FM10K_RX_STAT_VLAN_TAG_DROPS                  9
> +#define FM10K_RX_STAT_VLAN_INGRESS_DROPS              10
> +#define FM10K_RX_STAT_VLAN_EGRESS_DROPS               11
> +#define FM10K_RX_STAT_GLORT_MISS_DROPS                12
> +#define FM10K_RX_STAT_FFU_DROPS                       13
> +#define FM10K_RX_STAT_TRIGGER_DROPS                   14
> +#define FM10K_RX_STAT_OVERFLOW4                       15
> +
> +/* FM10K_RX_STAT_BANK_FWD_2 Bin Definitions */
> +#define FM10K_RX_STAT_POLICER_DROPS                   0
> +#define FM10K_RX_STAT_TTL_DROPS                       1
> +#define FM10K_RX_STAT_CM_PRIV_DROPS                   2
> +#define FM10K_RX_STAT_CM_SMP0_DROPS                   3
> +#define FM10K_RX_STAT_CM_SMP1_DROPS                   4
> +#define FM10K_RX_STAT_CM_RX_HOG_0_DROPS               5
> +#define FM10K_RX_STAT_CM_RX_HOG_1_DROPS               6
> +#define FM10K_RX_STAT_CM_TX_HOG_0_DROPS               7
> +#define FM10K_RX_STAT_CM_TX_HOG_1_DROPS               8
> +/* Bin 9 reserved */
> +#define FM10K_RX_STAT_TRIGGER_REDIRECTS               10
> +#define FM10K_RX_STAT_FLOOD_CONTROL_DROPS             11
> +#define FM10K_RX_STAT_GLORT_FORWARDED                 12
> +#define FM10K_RX_STAT_LOOPBACK_SUPPRESS               13
> +#define FM10K_RX_STAT_OTHERS                          14
> +#define FM10K_RX_STAT_OVERFLOW5                       15
> +
> +/* FM10K_RX_STAT_BANK_VLAN Bin definitions */
> +#define FM10K_RX_STAT_VLAN_UCAST                      0
> +#define FM10K_RX_STAT_VLAN_MCAST                      1
> +#define FM10K_RX_STAT_VLAN_BCAST                      2
> +
> +/* Tx Bank Definitions */
> +#define FM10K_TX_STAT_BANK_TYPE                       0
> +#define FM10K_TX_STAT_BANK_SIZE                       1
> +
> +/* FM10K_TX_STAT_BANK_TYPE Bin Definitions */
> +#define FM10K_TX_STAT_L2UCAST                         0
> +#define FM10K_TX_STAT_L2MCAST                         1
> +#define FM10K_TX_STAT_L2BCAST                         2
> +#define FM10K_TX_STAT_ERR_SENT                        3
> +#define FM10K_TX_STAT_TIMEOUT_DROP                    4
> +#define FM10K_TX_STAT_ERR_DROP                        5
> +#define FM10K_TX_STAT_ECC_DROP                        6
> +#define FM10K_TX_STAT_LOOPBACK_DROP                   7
> +#define FM10K_TX_STAT_TTL1_DROP                       8
> +#define FM10K_TX_STAT_IEEE802_3_PAUSE                 9
> +#define FM10K_TX_STAT_CLASS_BASED_PAUSE               10
> +
> +/* FM10K_TX_STAT_BANK_SIZE Bin Definitions */
> +#define FM10K_TX_STAT_LEN_LT_64                       0
> +#define FM10K_TX_STAT_LEN_EQ_64                       1
> +#define FM10K_TX_STAT_LEN_65_127                      2
> +#define FM10K_TX_STAT_LEN_128_255                     3
> +#define FM10K_TX_STAT_LEN_256_511                     4
> +#define FM10K_TX_STAT_LEN_512_1023                    5
> +#define FM10K_TX_STAT_LEN_1024_1522                   6
> +#define FM10K_TX_STAT_LEN_1523_2047                   7
> +#define FM10K_TX_STAT_LEN_2048_4095                   8
> +#define FM10K_TX_STAT_LEN_4096_8191                   9
> +#define FM10K_TX_STAT_LEN_8192_10239                  10
> +#define FM10K_TX_STAT_LEN_GE_10240                    11
> +
> +
> +/* This structure is used to build a table of all rx / tx counters */
> +struct fm10k_port_count_mapping
> +{
> +   /* Bank in which the counter is located */
> +   uint32_t bank;
> +
> +   /* Bin  in which the counter is located */
> +   uint32_t bin;
> +
> +   /*
> +    * Offset (in bytes) of a the frame counter in
> +    * the fm10k_counters structure
> +    */
> +   uint32_t frameOffset;
> +
> +   /*
> +    * Offset (in bytes) of a the byte counter in
> +    * the fm10k_counters structure
> +    */
> +   uint32_t byteOffset;
> +};
> +
> +#ifndef offsetof
> +#define offsetof(type, field)  ((size_t) &( ((type *)0)->field) )
> +#endif
> +
> +/*
> + * Table of all RX port counters in the RX banks
> + * This table is used for retrieving counters as
> + * well as reseting them
> + */
> +static struct fm10k_port_count_mapping rxPortCntMapTable[] = {
> +    /* Bank                        Bin                                  frameOffset
> byteOffset                                            */
> +    /* --------------------------  ------------------------------       ----------------------------
> -----------------        ---------------------------------------------------   */
> +    /* Type Bank */
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_NONIP_L2UCAST,
> offsetof(struct fm10k_port_counters, cntRxUcstPktsNonIP),       offsetof(struct
> fm10k_port_counters, cntRxUcstOctetsNonIP)    },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_NONIP_L2MCAST,
> offsetof(struct fm10k_port_counters, cntRxMcstPktsNonIP),       offsetof(struct
> fm10k_port_counters, cntRxMcstOctetsNonIP)    },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_NONIP_L2BCAST,
> offsetof(struct fm10k_port_counters, cntRxBcstPktsNonIP),       offsetof(struct
> fm10k_port_counters, cntRxBcstOctetsNonIP)    },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV4_L2UCAST,
> offsetof(struct fm10k_port_counters, cntRxUcstPktsIPv4),        offsetof(struct
> fm10k_port_counters, cntRxUcstOctetsIPv4)     },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV4_L2MCAST,
> offsetof(struct fm10k_port_counters, cntRxMcstPktsIPv4),        offsetof(struct
> fm10k_port_counters, cntRxMcstOctetsIPv4)     },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV4_L2BCAST,
> offsetof(struct fm10k_port_counters, cntRxBcstPktsIPv4),        offsetof(struct
> fm10k_port_counters, cntRxBcstOctetsIPv4)     },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV6_L2UCAST,
> offsetof(struct fm10k_port_counters, cntRxUcstPktsIPv6),        offsetof(struct
> fm10k_port_counters, cntRxUcstOctetsIPv6)     },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV6_L2MCAST,
> offsetof(struct fm10k_port_counters, cntRxMcstPktsIPv6),        offsetof(struct
> fm10k_port_counters, cntRxMcstOctetsIPv6)     },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV6_L2BCAST,
> offsetof(struct fm10k_port_counters, cntRxBcstPktsIPv6),        offsetof(struct
> fm10k_port_counters, cntRxBcstOctetsIPv6)     },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IEEE802_3_PAUSE,
> offsetof(struct fm10k_port_counters, cntRxPausePkts),           offsetof(struct
> fm10k_port_counters, cntRxPauseOctets)        },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_CLASS_BASED_PAUSE,
> offsetof(struct fm10k_port_counters, cntRxCBPausePkts),         offsetof(struct
> fm10k_port_counters, cntRxCBPauseOctets)      },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_FRAMING_ERR,
> offsetof(struct fm10k_port_counters, cntRxFramingErrorPkts),    offsetof(struct
> fm10k_port_counters, cntRxFramingErrorOctets) },
> +    {  FM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_FCS_ERR,
> offsetof(struct fm10k_port_counters, cntRxFCSErrors),           offsetof(struct
> fm10k_port_counters, cntRxFCSErrorsOctets)    },
> +
> +    /* Size Bank */
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_LT_64,
> offsetof(struct fm10k_port_counters, cntRxMinTo63Pkts),         offsetof(struct
> fm10k_port_counters, cntRxMinTo63octets)     },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_EQ_64,
> offsetof(struct fm10k_port_counters, cntRx64Pkts),              offsetof(struct
> fm10k_port_counters, cntRx64octets)          },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_65_127,
> offsetof(struct fm10k_port_counters, cntRx65to127Pkts),         offsetof(struct
> fm10k_port_counters, cntRx65to127octets)     },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_128_255,
> offsetof(struct fm10k_port_counters, cntRx128to255Pkts),        offsetof(struct
> fm10k_port_counters, cntRx128to255octets)    },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_256_511,
> offsetof(struct fm10k_port_counters, cntRx256to511Pkts),        offsetof(struct
> fm10k_port_counters, cntRx256to511octets)    },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_512_1023,
> offsetof(struct fm10k_port_counters, cntRx512to1023Pkts),       offsetof(struct
> fm10k_port_counters, cntRx512to1023octets)   },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_1024_1522,
> offsetof(struct fm10k_port_counters, cntRx1024to1522Pkts),      offsetof(struct
> fm10k_port_counters, cntRx1024to1522octets)  },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_1523_2047,
> offsetof(struct fm10k_port_counters, cntRx1523to2047Pkts),      offsetof(struct
> fm10k_port_counters, cntRx1523to2047octets)  },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_2048_4095,
> offsetof(struct fm10k_port_counters, cntRx2048to4095Pkts),      offsetof(struct
> fm10k_port_counters, cntRx2048to4095octets)  },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_4096_8191,
> offsetof(struct fm10k_port_counters, cntRx4096to8191Pkts),      offsetof(struct
> fm10k_port_counters, cntRx4096to8191octets)  },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_8192_10239,
> offsetof(struct fm10k_port_counters, cntRx8192to10239Pkts),     offsetof(struct
> fm10k_port_counters, cntRx8192to10239octets) },
> +    {  FM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_GE_10240,
> offsetof(struct fm10k_port_counters, cntRx10240toMaxPkts),      offsetof(struct
> fm10k_port_counters, cntRx10240toMaxOctets)  },
> +
> +    /* Priority Bank */
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_0,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[0]),     offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[0])  },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_1,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[1]),     offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[1])  },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_2,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[2]),     offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[2])  },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_3,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[3]),     offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[3])  },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_4,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[4]),     offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[4])  },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_5,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[5]),     offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[5])  },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_6,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[6]),     offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[6])  },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_7,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[7]),     offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[7])  },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_8,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[8]),     offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[8])  },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_9,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[9]),     offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[9])  },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_10,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[10]),    offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[10]) },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_11,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[11]),    offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[11]) },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_12,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[12]),    offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[12]) },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_13,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[13]),    offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[13]) },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_14,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[14]),    offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[14]) },
> +    {  FM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_15,
> offsetof(struct fm10k_port_counters, cntRxPriorityPkts[15]),    offsetof(struct
> fm10k_port_counters, cntRxPriorityOctets[15]) },
> +
> +    /* Forwarding Bank */
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_FID_FORWARDED,
> offsetof(struct fm10k_port_counters, cntFIDForwardedPkts),      offsetof(struct
> fm10k_port_counters, cntFIDForwardedOctets)       },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_FLOOD_FORWARDED,
> offsetof(struct fm10k_port_counters, cntFloodForwardedPkts),    offsetof(struct
> fm10k_port_counters, cntFloodForwardedOctets)     },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_SPECIALLY_HANDLED,
> offsetof(struct fm10k_port_counters, cntSpeciallyHandledPkts),  offsetof(struct
> fm10k_port_counters, cntSpeciallyHandledOctets)   },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_PARSER_ERROR_DROP,
> offsetof(struct fm10k_port_counters, cntParseErrDropPkts),      offsetof(struct
> fm10k_port_counters, cntParseErrDropOctets)       },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_ECC_ERROR_DROP,
> offsetof(struct fm10k_port_counters, cntParityErrorPkts),       offsetof(struct
> fm10k_port_counters, cntParityErrorOctets)        },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_TRAPPED,
> offsetof(struct fm10k_port_counters, cntTrappedPkts),           offsetof(struct
> fm10k_port_counters, cntTrappedOctets)            },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_PAUSE_DROPS,
> offsetof(struct fm10k_port_counters, cntPauseDropPkts),         offsetof(struct
> fm10k_port_counters, cntPauseDropOctets)          },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_STP_DROPS,
> offsetof(struct fm10k_port_counters, cntSTPDropPkts),           offsetof(struct
> fm10k_port_counters, cntSTPDropOctets)            },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_SECURITY_VIOLATIONS,
> offsetof(struct fm10k_port_counters, cntSecurityViolationPkts), offsetof(struct
> fm10k_port_counters, cntSecurityViolationOctets)  },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_VLAN_TAG_DROPS,
> offsetof(struct fm10k_port_counters, cntVLANTagDropPkts),       offsetof(struct
> fm10k_port_counters, cntVLANTagDropOctets)        },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_VLAN_INGRESS_DROPS,
> offsetof(struct fm10k_port_counters, cntVLANIngressBVPkts),     offsetof(struct
> fm10k_port_counters, cntVLANIngressBVOctets)      },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_VLAN_EGRESS_DROPS,
> offsetof(struct fm10k_port_counters, cntVLANEgressBVPkts),      offsetof(struct
> fm10k_port_counters, cntVLANEgressBVOctets)       },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_GLORT_MISS_DROPS,
> offsetof(struct fm10k_port_counters, cntGlortMissDropPkts),     offsetof(struct
> fm10k_port_counters, cntGlortMissDropOctets)      },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_FFU_DROPS,
> offsetof(struct fm10k_port_counters, cntFFUDropPkts),           offsetof(struct
> fm10k_port_counters, cntFFUDropOctets)            },
> +    {  FM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_TRIGGER_DROPS,
> offsetof(struct fm10k_port_counters, cntTriggerDropPkts),       offsetof(struct
> fm10k_port_counters, cntTriggerDropOctets)        },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_POLICER_DROPS,
> offsetof(struct fm10k_port_counters, cntPolicerDropPkts),       offsetof(struct
> fm10k_port_counters, cntPolicerDropOctets)        },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_TTL_DROPS,
> offsetof(struct fm10k_port_counters, cntTTLDropPkts),           offsetof(struct
> fm10k_port_counters, cntTTLDropOctets)            },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_PRIV_DROPS,
> offsetof(struct fm10k_port_counters, cntCmPrivDropPkts),        offsetof(struct
> fm10k_port_counters, cntCmPrivDropOctets)         },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_SMP0_DROPS,
> offsetof(struct fm10k_port_counters, cntSmp0DropPkts),          offsetof(struct
> fm10k_port_counters, cntSmp0DropOctets)           },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_SMP1_DROPS,
> offsetof(struct fm10k_port_counters, cntSmp1DropPkts),          offsetof(struct
> fm10k_port_counters, cntSmp1DropOctets)           },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_RX_HOG_0_DROPS,
> offsetof(struct fm10k_port_counters, cntRxHog0DropPkts),        offsetof(struct
> fm10k_port_counters, cntRxHog0DropOctets)         },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_RX_HOG_1_DROPS,
> offsetof(struct fm10k_port_counters, cntRxHog1DropPkts),        offsetof(struct
> fm10k_port_counters, cntRxHog1DropOctets)         },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_TX_HOG_0_DROPS,
> offsetof(struct fm10k_port_counters, cntTxHog0DropPkts),        offsetof(struct
> fm10k_port_counters, cntTxHog0DropOctets)         },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_TX_HOG_1_DROPS,
> offsetof(struct fm10k_port_counters, cntTxHog1DropPkts),        offsetof(struct
> fm10k_port_counters, cntTxHog1DropOctets)         },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_TRIGGER_REDIRECTS,
> offsetof(struct fm10k_port_counters, cntTriggerRedirPkts),      offsetof(struct
> fm10k_port_counters, cntTriggerRedirOctets)       },
> +    {  FM10K_RX_STAT_BANK_FWD_2,
> FM10K_RX_STAT_FLOOD_CONTROL_DROPS, offsetof(struct
> fm10k_port_counters, cntFloodControlDropPkts),  offsetof(struct
> fm10k_port_counters, cntFloodControlDropOctets)   },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_GLORT_FORWARDED,
> offsetof(struct fm10k_port_counters, cntGlortForwardedPkts),    offsetof(struct
> fm10k_port_counters, cntGlortForwardedOctets)     },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_LOOPBACK_SUPPRESS,
> offsetof(struct fm10k_port_counters, cntLoopbackDropsPkts),     offsetof(struct
> fm10k_port_counters, cntLoopbackDropOctets)       },
> +    {  FM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_OTHERS,
> offsetof(struct fm10k_port_counters, cntOtherPkts),             offsetof(struct
> fm10k_port_counters, cntOtherOctets)              },
> +
> + }; /* end rxPortCntMapTable */
> +
> +
> +/*
> + * Table of all TX port counters in the TX banks
> + * This table is used for retrieving counters as
> + * well as reseting them
> + */
> +static struct fm10k_port_count_mapping txPortCntMapTable[] = {
> +    /* Bank                        Bin                                  frameOffset
> byteOffset                                            */
> +    /* --------------------------  ------------------------------       ----------------------------
> -----------------        ---------------------------------------------------   */
> +    /* Type Bank */
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_L2UCAST,
> offsetof(struct fm10k_port_counters, cntTxUcstPkts),            offsetof(struct
> fm10k_port_counters, cntTxUcstOctets)        },
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_L2MCAST,
> offsetof(struct fm10k_port_counters, cntTxMcstPkts),            offsetof(struct
> fm10k_port_counters, cntTxMcstOctets)        },
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_L2BCAST,
> offsetof(struct fm10k_port_counters, cntTxBcstPkts),            offsetof(struct
> fm10k_port_counters, cntTxBcstOctets)        },
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_ERR_SENT,
> offsetof(struct fm10k_port_counters, cntTxErrorSentPkts),       offsetof(struct
> fm10k_port_counters, cntTxErrorSentOctets)   },
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_TIMEOUT_DROP,
> offsetof(struct fm10k_port_counters, cntTxTimeOutPkts),         offsetof(struct
> fm10k_port_counters, cntTxTimeOutOctets)     },
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_ERR_DROP,
> offsetof(struct fm10k_port_counters, cntTxErrorDropPkts),       offsetof(struct
> fm10k_port_counters, cntTxErrorOctets)       },
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_ECC_DROP,
> offsetof(struct fm10k_port_counters, cntTxUnrepairEccPkts),     offsetof(struct
> fm10k_port_counters, cntTxUnrepairEccOctets) },
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_LOOPBACK_DROP,
> offsetof(struct fm10k_port_counters, cntTxLoopbackPkts),        offsetof(struct
> fm10k_port_counters, cntTxLoopbackOctets)    },
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_TTL1_DROP,
> offsetof(struct fm10k_port_counters, cntTxTTLDropPkts),         offsetof(struct
> fm10k_port_counters, cntTxTTLDropOctets)     },
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_IEEE802_3_PAUSE,
> offsetof(struct fm10k_port_counters, cntTxPausePkts),           offsetof(struct
> fm10k_port_counters, cntTxPauseOctets)       },
> +    {  FM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_CLASS_BASED_PAUSE,
> offsetof(struct fm10k_port_counters, cntTxCBPausePkts),         offsetof(struct
> fm10k_port_counters, cntTxCBPauseOctets)     },
> +
> +    /* Size Bank */
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_LT_64,
> offsetof(struct fm10k_port_counters, cntTxMinTo63Pkts),          offsetof(struct
> fm10k_port_counters, cntTxMinTo63octets)        },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_EQ_64,
> offsetof(struct fm10k_port_counters, cntTx64Pkts),               offsetof(struct
> fm10k_port_counters, cntTx64octets)             },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_65_127,
> offsetof(struct fm10k_port_counters, cntTx65to127Pkts),          offsetof(struct
> fm10k_port_counters, cntTx65to127octets)        },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_128_255,
> offsetof(struct fm10k_port_counters, cntTx128to255Pkts),         offsetof(struct
> fm10k_port_counters, cntTx128to255octets)       },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_256_511,
> offsetof(struct fm10k_port_counters, cntTx256to511Pkts),         offsetof(struct
> fm10k_port_counters, cntTx256to511octets)       },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_512_1023,
> offsetof(struct fm10k_port_counters, cntTx512to1023Pkts),        offsetof(struct
> fm10k_port_counters, cntTx512to1023octets)      },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_1024_1522,
> offsetof(struct fm10k_port_counters, cntTx1024to1522Pkts),       offsetof(struct
> fm10k_port_counters, cntTx1024to1522octets)     },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_1523_2047,
> offsetof(struct fm10k_port_counters, cntTx1523to2047Pkts),       offsetof(struct
> fm10k_port_counters, cntTx1523to2047octets)     },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_2048_4095,
> offsetof(struct fm10k_port_counters, cntTx2048to4095Pkts),       offsetof(struct
> fm10k_port_counters, cntTx2048to4095octets)     },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_4096_8191,
> offsetof(struct fm10k_port_counters, cntTx4096to8191Pkts),       offsetof(struct
> fm10k_port_counters, cntTx4096to8191octets)     },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_8192_10239,
> offsetof(struct fm10k_port_counters, cntTx8192to10239Pkts),      offsetof(struct
> fm10k_port_counters, cntTx8192to10239octets)    },
> +    {  FM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_GE_10240,
> offsetof(struct fm10k_port_counters, cntTx10240toMaxPkts),       offsetof(struct
> fm10k_port_counters, cntTx10240toMaxOctets)     },
> +
> +};  /* end txPortCntMapTable */
> +
> +
> +static void
> +fm10k_read_scatter_gather(struct fm10k_switch *sw,
> +		int nEntries,
> +		struct fm10k_scatter_gather_entry *sgList)
> +{
> +    int  err = 0;
> +    int     i;
> +
> +    for (i = 0 ; err == 0 && i < nEntries ; i++)
> +    {
> +        uint32_t  addr  = sgList[i].addr;
> +        uint32_t  count = sgList[i].count;
> +        uint32_t *data  = sgList[i].data;
> +
> +        fm10k_read_switch_array(sw, addr, data, count);
> +    }
> +}
> +
> +
> +static int
> +fm10k_get_port_counters(struct fm10k_switch *sw,
> +		struct fm10k_ext_port* ext_port,
> +		struct fm10k_port_counters *counters)
> +{
> +    int physPort;
> +    int epl;
> +    int lane;
> +    struct timeval ts;
> +    bool validIpStats = true;
> +    uint32_t i;
> +    struct fm10k_scatter_gather_entry sgList[MAX_STATS_SGLIST];
> +    int sgListCnt = 0;
> +    /* Temporary bin array to retrieve 128bit port counters (frame + bytes). */
> +    uint32_t cntRxPortStatsBank[FM10K_NB_RX_STATS_BANKS]
> +                               [FM10K_BINS_PER_RX_STATS_BANK]
> +                               [FM10K_WORDS_PER_RX_STATS_COUNTER];
> +    /*
> +     * Fill the counters structure with 0 to assure all fields not explicitly
> +     * set below, which will be the fields not supported by the FM10000,
> +     * will be 0 on return.
> +     */
> +    memset(counters, 0, sizeof(*counters));
> +
> +    physPort = ext_port->portno;
> +    epl = ext_port->eplno;
> +    lane = ext_port->first_lane;
> +
> +    counters->cntVersion = FM10K_STATS_VERSION;
> +
> +    /*
> +     * Reading counters for each RX bank
> +     *
> +     * Because the RX_STATS_BANK register contains
> +     * both, frame count and byte count in a 128bit
> +     * register, we first store the data in a temporary
> +     * array.
> +     * 1. Fill Scatter Gather to retrieve each bin
> +     *    counter from the rx bank and store in a temp
> +     *    array.
> +     */
> +    for (i = 0; i < FM10K_SW_NITEMS(rxPortCntMapTable); i++) {
> +        FM10K_GET_RX_PORT_STAT_128(rxPortCntMapTable[i].bank,
> +        						   rxPortCntMapTable[i].bin);
> +    }
> +
> +    /*
> +     * 2. Fill in the scatter gather for tx bank
> +     *    counters. They will directly be stored
> +     *    in the fm10k_counters structure upon
> +     *    scatter gather read.
> +     */
> +    for (i = 0; i < FM10K_SW_NITEMS(txPortCntMapTable); i++) {
> +        FM10K_GET_TX_PORT_STAT_64(txPortCntMapTable[i].bank,
> +                                  txPortCntMapTable[i].bin,
> +                                  txPortCntMapTable[i].frameOffset,
> +                                  txPortCntMapTable[i].byteOffset);
> +    }
> +
> +    /*
> +     * 3. Fill in the scatter gather for TX CM DROP
> +     *    and for EPL counters. They will directly be
> +     *    stored in the fm10k_counters structure upon
> +     *    scatter gather read.
> +     */
> +    sgList[sgListCnt].addr = FM10K_CM_APPLY_DROP_COUNT(physPort, 0);
> +    sgList[sgListCnt].data = (uint32_t*) &counters->cntTxCMDropPkts;
> +    sgList[sgListCnt].count = 2;
> +    sgListCnt++;
> +	/* EPL Counters */
> +	FM10K_GET_EPL_PORT_STAT_32(FM10K_MAC_OVERSIZE_COUNTER,
> cntRxOversizedPkts);
> +	FM10K_GET_EPL_PORT_STAT_32(FM10K_MAC_JABBER_COUNTER,
> cntRxJabberPkts);
> +	FM10K_GET_EPL_PORT_STAT_32(FM10K_MAC_UNDERSIZE_COUNTER,
> cntRxUndersizedPkts);
> +	FM10K_GET_EPL_PORT_STAT_32(FM10K_MAC_RUNT_COUNTER,
> cntRxFragmentPkts);
> +	FM10K_GET_EPL_PORT_STAT_32(FM10K_MAC_OVERRUN_COUNTER,
> cntOverrunPkts);
> +	FM10K_GET_EPL_PORT_STAT_32(FM10K_MAC_UNDERRUN_COUNTER,
> cntUnderrunPkts);
> +
> 	FM10K_GET_EPL_PORT_STAT_32(FM10K_MAC_CODE_ERROR_COUNTE
> R, cntCodeErrors);
> +    /*
> +     * 4. Execute scatter gather read.
> +     */
> +    if (sgListCnt >= MAX_STATS_SGLIST) {
> +        /*
> +         * Pretty static. Mainly to warn if something new added,
> +         * but the array size is not adjust accordingly
> +         */
> +    	FM10K_SW_ERR("Scatter list array %d for port %d overflow.\n",
> sgListCnt, physPort);
> +    	return -1;
> +    }
> +
> +    /*
> +     * Taking lock to protect temporary structures used to
> +     * store 128b counters
> +     */
> +    FM10K_SW_SWITCH_LOCK(sw);
> +
> +    /* now get the stats in one shot, optimized for fibm */
> +    fm10k_read_scatter_gather(sw, sgListCnt, sgList);
> +    FM10K_SW_SWITCH_UNLOCK(sw);
> +
> +    counters->timestamp = ts.tv_sec * 1000000 + ts.tv_usec;
> +
> +    /*
> +     * 5. Retrieve the frame/byte counts from 128bit
> +     *    registers stored in temporary array and set
> +     *    the proper fm_portCounter structure members.
> +     */
> +    for (i = 0; i < FM10K_SW_NITEMS(rxPortCntMapTable); i++) {
> +        FM10K_UPD_RX_PORT_STAT_128(rxPortCntMapTable[i].bank,
> +                                   rxPortCntMapTable[i].bin,
> +                                   rxPortCntMapTable[i].frameOffset,
> +                                   rxPortCntMapTable[i].byteOffset);
> +    }
> +
> +    /*
> +     * 6. Set some counters that are not available
> +     *    in HW but can be computed from two or more
> +     *    HW counters.
> +     */
> +    /*
> +     * If IP parsing is enabled then the IP stats will be read and will be
> +     * valid. Else all traffic, whether IP or not, is counted as NonIP.
> +     */
> +    if (validIpStats) {
> +        /*
> +         * RX counters.
> +         */
> +        counters->cntRxUcstPkts = counters->cntRxUcstPktsNonIP +
> +                                  counters->cntRxUcstPktsIPv4 +
> +                                  counters->cntRxUcstPktsIPv6;
> +
> +        counters->cntRxMcstPkts = counters->cntRxMcstPktsNonIP +
> +                                  counters->cntRxMcstPktsIPv4 +
> +                                  counters->cntRxMcstPktsIPv6;
> +
> +        counters->cntRxBcstPkts = counters->cntRxBcstPktsNonIP +
> +                                  counters->cntRxBcstPktsIPv4 +
> +                                  counters->cntRxBcstPktsIPv6;
> +
> +        /*
> +         * Misc. counters.
> +         */
> +        counters->cntRxOctetsNonIp  = counters->cntRxUcstOctetsNonIP +
> +                                      counters->cntRxMcstOctetsNonIP +
> +                                      counters->cntRxBcstOctetsNonIP;
> +
> +        counters->cntRxOctetsIPv4  = counters->cntRxUcstOctetsIPv4 +
> +                                     counters->cntRxMcstOctetsIPv4 +
> +                                     counters->cntRxBcstOctetsIPv4;
> +
> +        counters->cntRxOctetsIPv6  = counters->cntRxUcstOctetsIPv6 +
> +                                     counters->cntRxMcstOctetsIPv6 +
> +                                     counters->cntRxBcstOctetsIPv6;
> +
> +        counters->cntRxGoodOctets = counters->cntRxOctetsNonIp +
> +                                    counters->cntRxOctetsIPv4 +
> +                                    counters->cntRxOctetsIPv6;
> +    } else {
> +        /*
> +         * RX counters.
> +         */
> +        counters->cntRxUcstPkts     = counters->cntRxUcstPktsNonIP;
> +        counters->cntRxMcstPkts     = counters->cntRxMcstPktsNonIP;
> +        counters->cntRxBcstPkts     = counters->cntRxBcstPktsNonIP;
> +
> +        /*
> +         * Misc. counters.
> +         */
> +        counters->cntRxOctetsNonIp  = counters->cntRxUcstOctetsNonIP +
> +                                      counters->cntRxMcstOctetsNonIP +
> +                                      counters->cntRxBcstOctetsNonIP;
> +
> +        counters->cntRxGoodOctets = counters->cntRxOctetsNonIp;
> +    }
> +
> +    counters->cntTriggerDropRedirPkts = counters->cntTriggerRedirPkts +
> +                                        counters->cntTriggerDropPkts;
> +
> +    /* Emulate Tx Octets counter using the sum of all size bins. */
> +    counters->cntTxOctets += counters->cntTxMinTo63octets;
> +    counters->cntTxOctets += counters->cntTx64octets;
> +    counters->cntTxOctets += counters->cntTx65to127octets;
> +    counters->cntTxOctets += counters->cntTx128to255octets;
> +    counters->cntTxOctets += counters->cntTx256to511octets;
> +    counters->cntTxOctets += counters->cntTx512to1023octets;
> +    counters->cntTxOctets += counters->cntTx1024to1522octets;
> +    counters->cntTxOctets += counters->cntTx1523to2047octets;
> +    counters->cntTxOctets += counters->cntTx2048to4095octets;
> +    counters->cntTxOctets += counters->cntTx4096to8191octets;
> +    counters->cntTxOctets += counters->cntTx8192to10239octets;
> +    counters->cntTxOctets += counters->cntTx10240toMaxOctets;
> +
> +    return 0;
> +}   /* end fm10k_get_port_counters */
> +
> +
> +struct fm10k_stats_data {
> +	uint64_t rx_pkts;
> +	uint64_t tx_pkts;
> +	uint64_t rx_drop;
> +};
> +
> +
> +static uint64_t
> +fm10k_stats_ffu_count_get(struct fm10k_switch *sw, int table_id)
> +{
> +	uint64_t data;
> +
> +	if (FM10K_SW_FFU_CNT_BANK < 2) {
> +		data = fm10k_read_switch_reg64(sw,
> +				0xE40000 +
> 0x4000*FM10K_SW_FFU_CNT_BANK +
> 0x4*(table_id+FM10K_SW_FFU_CNT_START) + 0x8000);
> +	} else {
> +		data = fm10k_read_switch_reg64(sw,
> +				0xE40000 +
> 0x800*(FM10K_SW_FFU_CNT_BANK-2) +
> 0x4*(table_id+FM10K_SW_FFU_CNT_START) + 0x10000);
> +	}
> +	return data;
> +}
> +
> +static void
> +fm10k_stats_epl_ffu_print(struct fm10k_switch *sw, int epl)
> +{
> +	int table_id;
> +	uint64_t data;
> +
> +	table_id = FM10K_FFU_EXT_PORT_RULE_INGRESS(epl);
> +	data = fm10k_stats_ffu_count_get(sw, table_id);
> +	printf("             FFU[%d] ingress        %-12llu\n",
> +			table_id, (long long unsigned int)(data));
> +
> +	table_id = FM10K_FFU_EXT_PORT_RULE_EGRESS(epl);
> +	data = fm10k_stats_ffu_count_get(sw, table_id);
> +	printf("             FFU[%d]  egress        %-12llu\n",
> +			table_id, (long long unsigned int)(data));
> +}
> +
> +#define FM10K_STATS_RULE_NUM_MAX	100
> +static uint16_t fm10k_stats_rule_list[FM10K_STATS_RULE_NUM_MAX];
> +void
> +fm10k_stats_rule_count_reg(uint16_t rule_id)
> +{
> +	int i;
> +
> +	for (i = 0; i < FM10K_STATS_RULE_NUM_MAX; i++) {
> +		if (fm10k_stats_rule_list[i] == 0) {
> +			fm10k_stats_rule_list[i] = rule_id;
> +			break;
> +		}
> +	}
> +}
> +
> +void
> +fm10k_stats_ffu_count_print(struct fm10k_switch *sw)
> +{
> +	int i, rule_id;
> +	uint64_t data;
> +	static uint64_t ffu_count[FM10K_STATS_RULE_NUM_MAX];
> +
> +	for (i = 0; i < FM10K_STATS_RULE_NUM_MAX; i++) {
> +		if (fm10k_stats_rule_list[i] == 0)
> +			continue;
> +
> +		rule_id = fm10k_stats_rule_list[i];
> +		data = fm10k_stats_ffu_count_get(sw, rule_id);
> +		printf("FFU[%d] count         %-12llu \n",
> +				rule_id, (long long unsigned int)(data-
> ffu_count[rule_id]));
> +		ffu_count[rule_id] = data;
> +	}
> +}
> +
> +void
> +fm10k_stats_epl_port_print(struct fm10k_switch *sw)
> +{
> +	int i, lport;
> +	struct fm10k_port_counters counters;
> +	struct fm10k_ext_port ext_port;
> +	static struct fm10k_stats_data last_data[FM10K_SW_EXT_PORTS_MAX];
> +	struct fm10k_stats_data data;
> +
> +	for (i = 0; i < FM10K_SW_EPLS_SUPPORTED; i++) {
> +		lport = sw->epl_map[i].logical_port;
> +		ext_port.portno = lport;
> +		fm10k_get_port_counters(sw, &ext_port, &counters);
> +
> +		data.rx_pkts = counters.cntRxBcstPkts +
> counters.cntRxUcstPkts;
> +		data.tx_pkts = counters.cntTxBcstPkts + counters.cntTxUcstPkts;
> +		data.rx_drop = counters.cntCmPrivDropPkts;
> +		printf("EPL  port %-2d lport %-5d tx_pkt %-12llu rx_pkt %-12llu
> drop_pkt %-12llu\n",
> +				i, lport, (long long unsigned int)(data.tx_pkts-
> last_data[i].tx_pkts),
> +				(long long unsigned int)(data.rx_pkts-
> last_data[i].rx_pkts),
> +				(long long unsigned int)(data.rx_drop-
> last_data[i].rx_drop));
> +		last_data[i] = data;
> +
> +		if (FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_STATS_FFU))
> +			fm10k_stats_epl_ffu_print(sw, i);
> +	}
> +}
> +
> +
> +void
> +fm10k_stats_dpdk_port_print(struct fm10k_switch *sw)
> +{
> +	int i, j, lport, pf_no;
> +	struct fm10k_port_counters counters;
> +	struct fm10k_ext_port ext_port;
> +	static struct fm10k_stats_data last_data[FM10K_SW_PEPS_MAX];
> +	static struct fm10k_stats_data
> last_queue_data[FM10K_SW_PEPS_MAX][4];
> +	struct fm10k_stats_data data, mydata;
> +	char pf_ports[10];
> +
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		if (sw->dpdk_cfg->ports[i].hw == NULL)
> +			continue;
> +		if (sw->dpdk_cfg->ports[i].type != FM10K_CONFIG_DPDK_PF)
> +			continue;
> +		if (sw->dpdk_cfg->dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_NULL)
> +			continue;
> +
> +		memset(&mydata, 0, sizeof(mydata));
> +		if (sw->dpdk_cfg->dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PFS) {
> +			for (j = 0; j < 2; j++) {
> +				pf_no = sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[j];
> +				lport = sw->pep_map[pf_no].logical_port;
> +				memset(&ext_port, 0, sizeof(ext_port));
> +				ext_port.portno = lport;
> +				fm10k_get_port_counters(sw, &ext_port,
> &counters);
> +				data.rx_pkts = counters.cntRxBcstPkts +
> counters.cntRxUcstPkts;
> +				data.tx_pkts = counters.cntTxBcstPkts +
> counters.cntTxUcstPkts;
> +				data.rx_drop = counters.cntCmPrivDropPkts;
> +				mydata.rx_pkts += data.rx_pkts-
> last_data[pf_no].rx_pkts;
> +				mydata.tx_pkts += data.tx_pkts-
> last_data[pf_no].tx_pkts;
> +				mydata.rx_drop += data.rx_drop-
> last_data[pf_no].rx_drop;
> +				last_data[pf_no] = data;
> +			}
> +		} else if (sw->dpdk_cfg->dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PF) {
> +			pf_no = sw->dpdk_cfg->dpdk_port_map[i].map_no[0];
> +			lport = sw->pep_map[pf_no].logical_port;
> +			memset(&ext_port, 0, sizeof(ext_port));
> +			ext_port.portno = lport;
> +			fm10k_get_port_counters(sw, &ext_port, &counters);
> +			data.rx_pkts = counters.cntRxBcstPkts +
> counters.cntRxUcstPkts;
> +			data.tx_pkts = counters.cntTxBcstPkts +
> counters.cntTxUcstPkts;
> +			data.rx_drop = counters.cntCmPrivDropPkts;
> +			mydata.rx_pkts += data.rx_pkts-
> last_data[pf_no].rx_pkts;
> +			mydata.tx_pkts += data.tx_pkts-
> last_data[pf_no].tx_pkts;
> +			mydata.rx_drop += data.rx_drop-
> last_data[pf_no].rx_drop;
> +			last_data[pf_no] = data;
> +		} else
> +			continue;
> +
> +		if (sw->dpdk_cfg->dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PF)
> +			sprintf(pf_ports, "%d", sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[0]);
> +		else {
> +			sprintf(pf_ports, "%d/%d", sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[0],
> +					sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[1]);
> +		}
> +		printf("DPDK port %-2d  pf %-5s   tx_pkt %-12llu rx_pkt %-12llu
> drop_pkt %-12llu\n",
> +				i, pf_ports, (long long unsigned
> int)mydata.tx_pkts,
> +				(long long unsigned int)mydata.rx_pkts,
> +				(long long unsigned int)mydata.rx_drop);
> +
> +		if (!FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_STATS_QUEUE))
> +			continue;
> +		memset(&mydata, 0, sizeof(mydata));
> +		for (j = 0; j < sw->dpdk_cfg->ports[i].tx_queue_num; j++)
> +		{
> +			struct fm10k_hw *hw = sw->dpdk_cfg->ports[i].hw;
> +			uint16_t queue_id = j, pf_no;
> +
> +			fm10k_switch_dpdk_hw_queue_map(hw, queue_id,
> sw->dpdk_cfg->ports[i].tx_queue_num, &hw, &queue_id);
> +			pf_no = fm10k_switch_dpdk_pf_no_get(hw);
> +			data.tx_pkts = FM10K_READ_REG(hw,
> FM10K_QPTC(queue_id));
> +			data.rx_pkts = FM10K_READ_REG(hw,
> FM10K_QPRC(queue_id));
> +			data.rx_drop = FM10K_READ_REG(hw,
> FM10K_QPRDC(queue_id));
> +			mydata.tx_pkts += data.tx_pkts -
> last_queue_data[pf_no][queue_id].tx_pkts;
> +			mydata.rx_pkts += data.rx_pkts -
> last_queue_data[pf_no][queue_id].rx_pkts;
> +			mydata.rx_drop += data.rx_drop -
> last_queue_data[pf_no][queue_id].rx_drop;
> +			printf("            queue %d(%d:%d) tx_pkt %-12llu
> rx_pkt %-12llu drop_pkt %-12llu\n", j, pf_no, queue_id,
> +					(long long unsigned int)(data.tx_pkts -
> last_queue_data[pf_no][queue_id].tx_pkts),
> +					(long long unsigned int)(data.rx_pkts -
> last_queue_data[pf_no][queue_id].rx_pkts),
> +					(long long unsigned int)(data.rx_drop -
> last_queue_data[pf_no][queue_id].rx_drop));
> +			last_queue_data[pf_no][queue_id] = data;
> +		}
> +		printf("                   total tx_pkt %-12llu rx_pkt %-12llu
> drop_pkt %-12llu\n",
> +				(long long unsigned int)mydata.tx_pkts,
> +				(long long unsigned int)mydata.rx_pkts,
> +				(long long unsigned int)mydata.rx_drop);
> +	}
> +}
> +
> +
> +static void
> +fm10k_stats_port_counter_print(struct fm10k_switch *sw, int lport)
> +{
> +	unsigned int i;
> +	struct fm10k_port_counters counters;
> +	struct fm10k_ext_port ext_port;
> +	uint64_t *pdata;
> +
> +	memset(&ext_port, 0, sizeof(ext_port));
> +	ext_port.portno = lport;
> +	fm10k_get_port_counters(sw, &ext_port, &counters);
> +
> +	for (i = 0; i < FM10K_SW_NITEMS(rxPortCntMapTable); i++) {
> +		pdata =
> (uint64_t*)((uint8_t*)(&counters)+rxPortCntMapTable[i].frameOffset);
> +    	if (*pdata != 0)	{
> +    		printf("port %d rx bank %d idx %d pkt %llu\n", lport,
> +    				rxPortCntMapTable[i].bank,
> rxPortCntMapTable[i].bin, (unsigned long long)*pdata);
> +    	}
> +    }
> +	for (i = 0; i < FM10K_SW_NITEMS(txPortCntMapTable); i++) {
> +		pdata =
> (uint64_t*)((uint8_t*)(&counters)+txPortCntMapTable[i].frameOffset);
> +    	if (*pdata != 0)	{
> +    		printf("port %d tx bank %d idx %d pkt %llu\n", lport,
> +    				txPortCntMapTable[i].bank,
> txPortCntMapTable[i].bin, (unsigned long long)*pdata);
> +    	}
> +	}
> +}
> +
> +void
> +fm10k_stats_port_bank_print(struct fm10k_switch *sw)
> +{
> +	int i;
> +
> +	for (i = 0; i < FM10K_SW_EPLS_SUPPORTED; i++) {
> +		fm10k_stats_port_counter_print(sw, sw-
> >epl_map[i].logical_port);
> +	}
> +	for (i = 0; i < FM10K_SW_PEPS_SUPPORTED; i++) {
> +		fm10k_stats_port_counter_print(sw, sw-
> >pep_map[i].logical_port);
> +	}
> +}
> +
> +
> +void *
> +fm10k_switch_process_stats(void *ctx)
> +{
> +	struct fm10k_switch *sw = ctx;
> +
> +	usec_delay(5000000);
> +
> +	if (!FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_ENABLE))
> +		return NULL;
> +
> +	if (!sw->dpdk_cfg->stats_interval)
> +		return NULL;
> +
> +	while (1) {
> +		if (FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_STATS_PORT)) {
> +			printf("--- port statistic ---\n");
> +			fm10k_stats_epl_port_print(sw);
> +			fm10k_stats_dpdk_port_print(sw);
> +		}
> +		if (FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_STATS_FFU)) {
> +			printf("--- ffu statistic ---\n");
> +			fm10k_stats_ffu_count_print(sw);
> +		}
> +		if (FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_STATS_MORE)) {
> +			printf("--- detail statistic ---\n");
> +			fm10k_stats_port_bank_print(sw);
> +		}
> +		usec_delay(1000000 * sw->dpdk_cfg->stats_interval);
> +	}
> +	return NULL;
> +}
> +
> diff --git a/drivers/net/fm10k/switch/fm10k_stats.h
> b/drivers/net/fm10k/switch/fm10k_stats.h
> new file mode 100644
> index 0000000..674173e
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_stats.h
> @@ -0,0 +1,270 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_STATS_H_
> +#define _FM10K_STATS_H_
> +
> +
> +#include <stdint.h>
> +
> +
> +#define FM10K_STATS_VERSION      (1 << 4)
> +
> +
> +struct fm10k_scatter_gather_entry {
> +    uint32_t  addr;
> +    uint32_t  count;
> +    uint32_t *data;
> +
> +};
> +
> +
> +struct fm10k_port_counters {
> +    uint64_t cntVersion;
> +    uint64_t cntRxUcstPkts;
> +    uint64_t cntRxUcstPktsNonIP;
> +    uint64_t cntRxUcstPktsIPv4;
> +    uint64_t cntRxUcstPktsIPv6;
> +    uint64_t cntRxBcstPkts;
> +    uint64_t cntRxBcstPktsNonIP;
> +    uint64_t cntRxBcstPktsIPv4;
> +    uint64_t cntRxBcstPktsIPv6;
> +    uint64_t cntRxMcstPkts;
> +    uint64_t cntRxMcstPktsNonIP;
> +    uint64_t cntRxMcstPktsIPv4;
> +    uint64_t cntRxMcstPktsIPv6;
> +    uint64_t cntRxPausePkts;
> +    uint64_t cntRxCBPausePkts;
> +    uint64_t cntRxFCSErrors;
> +    uint64_t cntRxSymbolErrors;
> +    uint64_t cntRxFrameSizeErrors;
> +    uint64_t cntRxFramingErrorPkts;
> +    uint64_t cntRxMinTo63Pkts;
> +    uint64_t cntRx64Pkts;
> +    uint64_t cntRx65to127Pkts;
> +    uint64_t cntRx128to255Pkts;
> +    uint64_t cntRx256to511Pkts;
> +    uint64_t cntRx512to1023Pkts;
> +    uint64_t cntRx1024to1522Pkts;
> +    uint64_t cntRx1523to2047Pkts;
> +    uint64_t cntRx2048to4095Pkts;
> +    uint64_t cntRx4096to8191Pkts;
> +    uint64_t cntRx8192to10239Pkts;
> +    uint64_t cntRx10240toMaxPkts;
> +    uint64_t cntRxMinTo63octets;
> +    uint64_t cntRx64octets;
> +    uint64_t cntRx65to127octets;
> +    uint64_t cntRx128to255octets;
> +    uint64_t cntRx256to511octets;
> +    uint64_t cntRx512to1023octets;
> +    uint64_t cntRx1024to1522octets;
> +    uint64_t cntRx1523to2047octets;
> +    uint64_t cntRx2048to4095octets;
> +    uint64_t cntRx4096to8191octets;
> +    uint64_t cntRx8192to10239octets;
> +    uint64_t cntRx10240toMaxOctets;
> +    uint64_t cntRxOctetsNonIp;
> +    uint64_t cntRxOctetsIPv4;
> +    uint64_t cntRxOctetsIPv6;
> +    uint64_t cntRxUcstOctetsNonIP;
> +    uint64_t cntRxUcstOctetsIPv4;
> +    uint64_t cntRxUcstOctetsIPv6;
> +    uint64_t cntRxBcstOctetsNonIP;
> +    uint64_t cntRxBcstOctetsIPv4;
> +    uint64_t cntRxBcstOctetsIPv6;
> +    uint64_t cntRxMcstOctetsNonIP;
> +    uint64_t cntRxMcstOctetsIPv4;
> +    uint64_t cntRxMcstOctetsIPv6;
> +    uint64_t cntRxPauseOctets;
> +    uint64_t cntRxCBPauseOctets;
> +    uint64_t cntRxFCSErrorsOctets;
> +    uint64_t cntRxFramingErrorOctets;
> +    uint64_t cntRxGoodOctets;
> +    uint64_t cntRxBadOctets;
> +    uint64_t cntRxPriorityPkts[16];
> +    uint64_t cntRxInvalidPriorityPkts;
> +    uint64_t cntRxPriorityOctets[16];
> +    uint64_t cntRxInvalidPriorityOctets;
> +    uint64_t cntFIDForwardedPkts;
> +    uint64_t cntFloodForwardedPkts;
> +    uint64_t cntGlortSwitchedPkts;
> +    uint64_t cntGlortRoutedPkts;
> +    uint64_t cntSpeciallyHandledPkts;
> +    uint64_t cntParseErrDropPkts;
> +    uint64_t cntParityErrorPkts;
> +    uint64_t cntTrappedPkts;
> +    uint64_t cntPauseDropPkts;
> +    uint64_t cntSTPDropPkts;
> +    uint64_t cntSTPIngressDropsPkts;
> +    uint64_t cntSTPEgressDropsPkts;
> +    uint64_t cntReservedTrapPkts;
> +    uint64_t cntSecurityViolationPkts;
> +    uint64_t cntVLANTagDropPkts;
> +    uint64_t cntVLANIngressBVPkts;
> +    uint64_t cntVLANEgressBVPkts;
> +    uint64_t cntLoopbackDropsPkts;
> +    uint64_t cntGlortMissDropPkts;
> +    uint64_t cntFFUDropPkts;
> +    uint64_t cntInvalidDropPkts;
> +    uint64_t cntPolicerDropPkts;
> +    uint64_t cntTTLDropPkts;
> +    uint64_t cntGlobalWMDropPkts;
> +    uint64_t cntRXMPDropPkts;
> +    uint64_t cntRxHogDropPkts;
> +    uint64_t cntTxHogDropPkts;
> +    uint64_t cntOtherPkts;
> +    uint64_t cntFloodControlDropPkts;
> +    uint64_t cntCmPrivDropPkts;
> +    uint64_t cntSmp0DropPkts;
> +    uint64_t cntSmp1DropPkts;
> +    uint64_t cntRxHog0DropPkts;
> +    uint64_t cntRxHog1DropPkts;
> +    uint64_t cntTxHog0DropPkts;
> +    uint64_t cntTxHog1DropPkts;
> +    uint64_t cntRateLimit0DropPkts;
> +    uint64_t cntRateLimit1DropPkts;
> +    uint64_t cntBadSmpDropPkts;
> +    uint64_t cntTriggerDropRedirPkts;
> +    uint64_t cntTriggerDropPkts;
> +    uint64_t cntTriggerRedirPkts;
> +    uint64_t cntGlortForwardedPkts;
> +    uint64_t cntTriggerMirroredPkts;
> +    uint64_t cntBroadcastDropPkts;
> +    uint64_t cntDLFDropPkts;
> +    uint64_t cntRxCMDropPkts;
> +    uint64_t cntFIDForwardedOctets;
> +    uint64_t cntFloodForwardedOctets;
> +    uint64_t cntSpeciallyHandledOctets;
> +    uint64_t cntParseErrDropOctets;
> +    uint64_t cntParityErrorOctets;
> +    uint64_t cntTrappedOctets;
> +    uint64_t cntPauseDropOctets;
> +    uint64_t cntSTPDropOctets;
> +    uint64_t cntSecurityViolationOctets;
> +    uint64_t cntVLANTagDropOctets;
> +    uint64_t cntVLANIngressBVOctets;
> +    uint64_t cntVLANEgressBVOctets;
> +    uint64_t cntLoopbackDropOctets;
> +    uint64_t cntGlortMissDropOctets;
> +    uint64_t cntFFUDropOctets;
> +    uint64_t cntPolicerDropOctets;
> +    uint64_t cntTTLDropOctets;
> +    uint64_t cntOtherOctets;
> +    uint64_t cntFloodControlDropOctets;
> +    uint64_t cntCmPrivDropOctets;
> +    uint64_t cntSmp0DropOctets;
> +    uint64_t cntSmp1DropOctets;
> +    uint64_t cntRxHog0DropOctets;
> +    uint64_t cntRxHog1DropOctets;
> +    uint64_t cntTxHog0DropOctets;
> +    uint64_t cntTxHog1DropOctets;
> +    uint64_t cntTriggerDropOctets;
> +    uint64_t cntTriggerRedirOctets;
> +    uint64_t cntGlortForwardedOctets;
> +    uint64_t cntTxUcstPkts;
> +    uint64_t cntTxBcstPkts;
> +    uint64_t cntTxMcstPkts;
> +    uint64_t cntTxUcstPktsNonIP;
> +    uint64_t cntTxBcstPktsNonIP;
> +    uint64_t cntTxMcstPktsNonIP;
> +    uint64_t cntTxUcstPktsIP;
> +    uint64_t cntTxBcstPktsIP;
> +    uint64_t cntTxMcstPktsIP;
> +    uint64_t cntTxPausePkts;
> +    uint64_t cntTxCBPausePkts;
> +    uint64_t cntTxFCSErrDropPkts;
> +    uint64_t cntTxFramingErrorPkts;
> +    uint64_t cntTxErrorSentPkts;
> +    uint64_t cntTxErrorDropPkts;
> +    uint64_t cntTxTimeOutPkts;
> +    uint64_t cntTxOutOfMemErrPkts;
> +    uint64_t cntTxUnrepairEccPkts;
> +    uint64_t cntTxLoopbackPkts;
> +    uint64_t cntTxTTLDropPkts;
> +    uint64_t cntTxMinTo63Pkts;
> +    uint64_t cntTx64Pkts;
> +    uint64_t cntTx65to127Pkts;
> +    uint64_t cntTx128to255Pkts;
> +    uint64_t cntTx256to511Pkts;
> +    uint64_t cntTx512to1023Pkts;
> +    uint64_t cntTx1024to1522Pkts;
> +    uint64_t cntTx1523to2047Pkts;
> +    uint64_t cntTx2048to4095Pkts;
> +    uint64_t cntTx4096to8191Pkts;
> +    uint64_t cntTx8192to10239Pkts;
> +    uint64_t cntTx10240toMaxPkts;
> +    uint64_t cntTxMinTo63octets;
> +    uint64_t cntTx64octets;
> +    uint64_t cntTx65to127octets;
> +    uint64_t cntTx128to255octets;
> +    uint64_t cntTx256to511octets;
> +    uint64_t cntTx512to1023octets;
> +    uint64_t cntTx1024to1522octets;
> +    uint64_t cntTx1523to2047octets;
> +    uint64_t cntTx2048to4095octets;
> +    uint64_t cntTx4096to8191octets;
> +    uint64_t cntTx8192to10239octets;
> +    uint64_t cntTx10240toMaxOctets;
> +    uint64_t cntTxUcstOctetsNonIP;
> +    uint64_t cntTxBcstOctetsNonIP;
> +    uint64_t cntTxMcstOctetsNonIP;
> +    uint64_t cntTxUcstOctetsIP;
> +    uint64_t cntTxBcstOctetsIP;
> +    uint64_t cntTxMcstOctetsIP;
> +    uint64_t cntTxUcstOctets;
> +    uint64_t cntTxMcstOctets;
> +    uint64_t cntTxBcstOctets;
> +    uint64_t cntTxFCSErrDropOctets;
> +    uint64_t cntTxOctets;
> +    uint64_t cntTxErrorOctets;
> +    uint64_t cntTxFramingErrorOctets;
> +    uint64_t cntTxPauseOctets;
> +    uint64_t cntTxCBPauseOctets;
> +    uint64_t cntTxFCSErroredOctets;
> +    uint64_t cntTxErrorSentOctets;
> +    uint64_t cntTxTimeOutOctets;
> +    uint64_t cntTxOutOfMemErrOctets;
> +    uint64_t cntTxUnrepairEccOctets;
> +    uint64_t cntTxLoopbackOctets;
> +    uint64_t cntTxTTLDropOctets;
> +    uint64_t cntTxPriorityOctets[16];
> +    uint64_t cntUnderrunPkts;
> +    uint64_t cntOverrunPkts;
> +    uint64_t cntRxFragmentPkts;
> +    uint64_t cntRxUndersizedPkts;
> +    uint64_t cntRxJabberPkts;
> +    uint64_t cntCorruptedPkts;
> +    uint64_t cntCodeErrors;
> +    uint64_t cntRxOversizedPkts;
> +    uint64_t cntTxFCSErroredPkts;
> +    uint64_t cntStatsDropCountTx;
> +    uint64_t cntStatsDropCountRx;
> +    uint64_t cntTxMirrorPkts;
> +    uint64_t cntTxMirrorOctets;
> +    uint64_t cntTxCMDropPkts;
> +    uint64_t timestamp;
> +};
> +
> +void fm10k_stats_rule_count_reg(uint16_t rule_id);
> +void *fm10k_switch_process_stats(void *ctx);
> +
> +void fm10k_stats_epl_port_print(struct fm10k_switch *sw);
> +void fm10k_stats_dpdk_port_print(struct fm10k_switch *sw);
> +void fm10k_stats_ffu_count_print(struct fm10k_switch *sw);
> +void fm10k_stats_port_bank_print(struct fm10k_switch *sw);
> +
> +#endif /* _FM10K_STATS_H */
> diff --git a/drivers/net/fm10k/switch/fm10k_switch.c
> b/drivers/net/fm10k/switch/fm10k_switch.c
> new file mode 100644
> index 0000000..9bb8a99
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_switch.c
> @@ -0,0 +1,2422 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#include <rte_ethdev.h>
> +#include <rte_ethdev_pci.h>
> +
> +#include <rte_malloc.h>
> +
> +#include "../base/fm10k_type.h"
> +#include "../base/fm10k_osdep.h"
> +
> +#include "../fm10k.h"
> +#include "../fm10k_logs.h"
> +#include "fm10k_debug.h"
> +#include "fm10k_regs.h"
> +#include "fm10k_switch.h"
> +#include "fm10k_ext_port.h"
> +#include "fm10k_serdes.h"
> +#include "fm10k_i2c.h"
> +#include "fm10k_ffu.h"
> +#include "fm10k_stats.h"
> +#include "fm10k_config.h"
> +
> +static struct fm10k_device_info fm10k_device_table[] = {
> +	{ FM10K_SW_VENDOR_ID_SILICOM,
> 	FM10K_SW_DEV_ID_PE3100G2DQIR_QXSL4, "Silicom PE3100G2DQiR-
> QX4/QS4/QL4",		2, 100, 2, 2 },
> +	{ FM10K_SW_VENDOR_ID_SILICOM,
> 	FM10K_SW_DEV_ID_PE3100G2DQIRL_QXSL4, "Silicom PE3100G2DQiRL-
> QX4/QS4/QL4",	2, 100, 2, 2 },
> +	{ FM10K_SW_VENDOR_ID_SILICOM,
> 	FM10K_SW_DEV_ID_PE3100G2DQIRM_QXSL4, "Silicom
> PE3100G2DQiRM-QX4/QS4/QL4",	2, 100, 2, 4 },
> +};
> +
> +
> +static struct fm10k_switch fm10k_sw;
> +
> +#define FM10K_AM_TIMEOUT		16384
> +#define FM10K_COMP_PPM_SCALE		1000000
> +
> +#define FM10K_LED_POLL_INTERVAL_MS	500
> +#define FM10K_LED_BLINKS_PER_SECOND	2
> +
> +/*
> + * GLORT MAP
> + */
> +#define FM10K_SW_EPLA_GLORT			0x10
> +#define FM10K_SW_EPLB_GLORT			0x20
> +#define FM10K_SW_PEP01_GLORT		0x30
> +#define FM10K_SW_PEP23_GLORT		0x40
> +#define FM10K_SW_PEP45_GLORT		0x50
> +#define FM10K_SW_PEP67_GLORT		0x60
> +
> +/*
> + * logical port number
> + */
> +#define FM10K_SW_EPLA_LOGICAL_PORT		1
> +#define FM10K_SW_EPLB_LOGICAL_PORT		2
> +
> +#define FM10K_SW_PEP01_LOGICAL_PORT		3
> +#define FM10K_SW_PEP23_LOGICAL_PORT		4
> +#define FM10K_SW_PEP45_LOGICAL_PORT		5
> +#define FM10K_SW_PEP67_LOGICAL_PORT		6
> +
> +/*
> + * physical port number
> + */
> +#define FM10K_SW_EPLA_PHYSICAL_PORT		0
> +#define FM10K_SW_EPLB_PHYSICAL_PORT		4
> +
> +#define FM10K_SW_PEP01_PHYSICAL_PORT	36
> +#define FM10K_SW_PEP23_PHYSICAL_PORT	40
> +#define FM10K_SW_PEP45_PHYSICAL_PORT	44
> +#define FM10K_SW_PEP67_PHYSICAL_PORT	48
> +
> +static struct fm10k_sw_port_map
> fm10k_pep_port_map[FM10K_SW_PEPS_SUPPORTED] = {
> +		{FM10K_SW_PEP01_GLORT,
> FM10K_SW_PEP01_LOGICAL_PORT, FM10K_SW_PEP01_PHYSICAL_PORT},
> +		{FM10K_SW_PEP23_GLORT,
> FM10K_SW_PEP23_LOGICAL_PORT, FM10K_SW_PEP23_PHYSICAL_PORT},
> +		{FM10K_SW_PEP45_GLORT,
> FM10K_SW_PEP45_LOGICAL_PORT, FM10K_SW_PEP45_PHYSICAL_PORT},
> +		{FM10K_SW_PEP67_GLORT,
> FM10K_SW_PEP67_LOGICAL_PORT, FM10K_SW_PEP67_PHYSICAL_PORT},
> +};
> +
> +static struct fm10k_sw_port_map
> fm10k_epl_port_map[FM10K_SW_EPLS_SUPPORTED] = {
> +		{FM10K_SW_EPLA_GLORT, FM10K_SW_EPLA_LOGICAL_PORT,
> FM10K_SW_EPLA_PHYSICAL_PORT},
> +		{FM10K_SW_EPLB_GLORT, FM10K_SW_EPLB_LOGICAL_PORT,
> FM10K_SW_EPLB_PHYSICAL_PORT},
> +};
> +
> +/*
> + * use epl as external port map, only support QUAD_ON
> + */
> +struct fm10k_sched_prog {
> +	uint8_t idle;
> +	uint8_t phys; 	/* physical port */
> +	uint8_t log; 	/* logical port */
> +	uint8_t quad;	/* now, only support QUAD_ON */
> +#define FM10K_SW_QUAD_OFF		0 /* convert entry to idle if EPL
> in quad port mode */
> +#define FM10K_SW_QUAD_ON		1 /* always use quad port mode */
> +#define FM10K_SW_QUAD_40_100	2 /* use quad port mode if link speed is
> 40/100G */
> +};
> +
> +static struct fm10k_sched_prog
> fm10k_sched_prog[FM10K_SW_PEPS_SUPPORTED+FM10K_SW_EPLS_SUPPORT
> ED+1];
> +
> +uint32_t
> +fm10k_switch_pf_logical_get(uint8_t pf_no)
> +{
> +	return fm10k_pep_port_map[pf_no].logical_port;
> +}
> +
> +uint32_t
> +fm10k_switch_epl_logical_get(uint8_t epl_no)
> +{
> +	return fm10k_epl_port_map[epl_no].logical_port;
> +}
> +
> +uint32_t
> +fm10k_switch_vf_glort_get(uint8_t vf_no)
> +{
> +	return FM10K_SW_VF_GLORT_START + vf_no;
> +}
> +
> +uint32_t
> +fm10k_switch_pf_glort_get(uint8_t pf_no)
> +{
> +	return fm10k_pep_port_map[pf_no].glort;
> +}
> +
> +uint32_t
> +fm10k_switch_epl_glort_get(uint8_t epl_no)
> +{
> +	return fm10k_epl_port_map[epl_no].glort;
> +}
> +
> +uint32_t
> +fm10k_switch_pfs_glort_get(uint8_t pf1, uint8_t pf2)
> +{
> +	uint8_t idx;
> +	if(pf1 > pf2)
> +		idx = (pf2 & 0xf) | (pf1<<4 & 0xf0);
> +	else
> +		idx = (pf1 & 0xf) | (pf2<<4 & 0xf0);
> +	return FM10K_SW_PFS_GLORT_START + idx;
> +}
> +
> +struct fm10k_multi_glort {
> +	uint8_t lport1;
> +	uint8_t lport2;
> +	uint16_t vlan1;
> +	uint16_t vlan2;
> +} fm10k_multi_glorts[FM10K_SW_FFU_RULE_MAX];
> +
> +uint32_t
> +fm10k_switch_multi_glort_get(uint8_t lport1, uint8_t lport2,
> +		uint16_t vlan1, uint16_t vlan2, bool *p_new)
> +{
> +	int i;
> +
> +	for (i = 0; i < FM10K_SW_FFU_RULE_MAX; i++) {
> +		if (lport1 == fm10k_multi_glorts[i].lport1 &&
> +		   lport2 == fm10k_multi_glorts[i].lport2 &&
> +		   vlan1 == fm10k_multi_glorts[i].vlan1 &&
> +		   vlan2 == fm10k_multi_glorts[i].vlan2) {
> +			if(p_new != NULL)
> +				*p_new = false;
> +			return FM10K_SW_MULTI_GLORT_START + i;
> +		}
> +	}
> +
> +	for (i = 0; i < FM10K_SW_FFU_RULE_MAX; i++) {
> +		if (fm10k_multi_glorts[i].lport1 == 0 &&
> +		   fm10k_multi_glorts[i].lport2 == 0 &&
> +		   fm10k_multi_glorts[i].vlan1 == 0 &&
> +		   fm10k_multi_glorts[i].vlan2 == 0) {
> +			fm10k_multi_glorts[i].lport1 = lport1;
> +			fm10k_multi_glorts[i].lport2 = lport2;
> +			fm10k_multi_glorts[i].vlan1 = vlan1;
> +			fm10k_multi_glorts[i].vlan2 = vlan2;
> +			if(p_new != NULL)
> +				*p_new = true;
> +			return FM10K_SW_MULTI_GLORT_START + i;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +
> +/*
> + * Note that for physical port numbers, the initial values used for
> + * the EPL entries assume EPL[A] is EPL[0] and EPL[B] is EPL[1].
> + * fm10k_switch_determine_epls() will update these physical port
> + * numbers based on the actual A and B indicies.
> + */
> +static void
> +fm10k_switch_set_sched_prog(void)
> +{
> +	int i;
> +	int start = 0;
> +
> +	for (i = 0; i < FM10K_SW_EPLS_SUPPORTED; i++) {
> +		fm10k_sched_prog[i].idle = 0;
> +		fm10k_sched_prog[i].phys =
> fm10k_epl_port_map[i].physical_port;
> +		fm10k_sched_prog[i].log = fm10k_epl_port_map[i].logical_port;
> +		fm10k_sched_prog[i].quad = FM10K_SW_QUAD_ON;
> +	}
> +	start += FM10K_SW_EPLS_SUPPORTED;
> +	for (i = 0; i < FM10K_SW_PEPS_SUPPORTED; i++) {
> +		fm10k_sched_prog[start+i].idle = 0;
> +		fm10k_sched_prog[start+i].phys =
> fm10k_pep_port_map[i].physical_port;
> +		fm10k_sched_prog[start+i].log =
> fm10k_pep_port_map[i].logical_port;
> +		fm10k_sched_prog[start+i].quad = FM10K_SW_QUAD_40_100;
> +	}
> +	start += FM10K_SW_PEPS_SUPPORTED;
> +	fm10k_sched_prog[start].idle = 1;
> +}
> +
> +struct fm10k_device_info*
> +fm10k_get_device_info(struct fm10k_hw *hw)
> +{
> +	unsigned int i;
> +	struct fm10k_device_info *info;
> +	uint16_t pci_vendor = hw->vendor_id;
> +	uint16_t pci_device = hw->device_id;
> +	uint16_t pci_subvendor = hw->subsystem_vendor_id;
> +	uint16_t pci_subdevice = hw->subsystem_device_id;
> +
> +	if ((pci_vendor != FM10K_SW_VENDOR_ID_INTEL) ||
> +	    (pci_device != FM10K_SW_DEV_ID_FM10K))
> +		return (NULL);
> +
> +	for (i = 0; i < FM10K_SW_NITEMS(fm10k_device_table); i++) {
> +		info = &fm10k_device_table[i];
> +		if ((pci_subvendor == info->subvendor) &&
> +		    (pci_subdevice == info->subdevice)) {
> +			return (info);
> +		}
> +	}
> +
> +	return (NULL);
> +}
> +
> +
> +static void
> +fm10k_switch_determine_epls(struct fm10k_switch *sw)
> +{
> +	struct fm10k_device_info *cfg = sw->info;
> +	unsigned int i;
> +	uint8_t phys;
> +
> +	sw->epla_no = 0;
> +	sw->eplb_no = 6;
> +
> +	switch (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice)) {
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4_REV_2):
> +		sw->epla_no = 1;
> +		sw->eplb_no = 6;
> +		break;
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRL_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE325G2DSIR):
> +		sw->epla_no = 1;
> +		sw->eplb_no = 7;
> +		break;
> +	}
> +
> +	for (i = 0; i < FM10K_SW_NITEMS(fm10k_sched_prog); i++) {
> +		if (fm10k_sched_prog[i].idle)
> +			continue;
> +
> +		phys = fm10k_sched_prog[i].phys;
> +		if (phys <= 3) {
> +			/* Substitute actual epla phys port number */
> +			fm10k_sched_prog[i].phys = sw->epla_no * 4 + phys;
> +		} else if (phys >= 4 && phys <= 7) {
> +			/* Substitute actual eplb phys port number */
> +			fm10k_sched_prog[i].phys = sw->eplb_no * 4 + (phys -
> 4);
> +		}
> +	}
> +}
> +
> +static void
> +fm10k_hw_eicr_disable_source(struct fm10k_switch *sw, unsigned int source)
> +{
> +	unsigned int shift;
> +
> +	switch (source) {
> +	case FM10K_SW_EICR_PCA_FAULT:
> +		shift = FM10K_SW_EICR_PCA_FAULT_SHIFT;
> +		break;
> +	case FM10K_SW_EICR_THI_FAULT:
> +		shift = FM10K_SW_EICR_THI_FAULT_SHIFT;
> +		break;
> +	case FM10K_SW_EICR_FUM_FAULT:
> +		shift = FM10K_SW_EICR_FUM_FAULT_SHIFT;
> +		break;
> +	case FM10K_SW_EICR_MAILBOX:
> +		shift = FM10K_SW_EICR_MAILBOX_SHIFT;
> +		break;
> +	case FM10K_SW_EICR_SWITCH_READY:
> +		shift = FM10K_SW_EICR_SWITCH_READY_SHIFT;
> +		break;
> +	case FM10K_SW_EICR_SWITCH_NREADY:
> +		shift = FM10K_SW_EICR_SWITCH_NREADY_SHIFT;
> +		break;
> +	case FM10K_SW_EICR_SWITCH_INT:
> +		shift = FM10K_SW_EICR_SWITCH_INT_SHIFT;
> +		break;
> +	case FM10K_SW_EICR_SRAM_ERROR:
> +		shift = FM10K_SW_EICR_SRAM_ERROR_SHIFT;
> +		break;
> +	case FM10K_SW_EICR_VFLR:
> +		shift = FM10K_SW_EICR_VFLR_SHIFT;
> +		break;
> +	case FM10K_SW_EICR_MAX_HOLD_TIME:
> +		shift = FM10K_SW_EICR_MAX_HOLD_TIME_SHIFT;
> +		break;
> +	default:
> +		return;
> +	}
> +
> +	fm10k_write_switch_reg(sw, FM10K_SW_EIMR,
> FM10K_SW_EIMR_DISABLE << (shift * 2));
> +	fm10k_write_flush(sw);
> +}
> +
> +
> +unsigned int
> +fm10k_switch_eplidx_to_eplno(struct fm10k_switch *sw, unsigned int eplidx)
> +{
> +	return (eplidx ? sw->eplb_no : sw->epla_no);
> +}
> +
> +
> +static uint16_t
> +fm10k_switch_ppm_to_tx_clk_compensation_timeout(uint32_t pcs, uint32_t
> num_ppm)
> +{
> +	unsigned int scale;
> +	unsigned int ppm;
> +	unsigned int timeout;
> +	unsigned int am_ppm;
> +
> +	if (num_ppm == 0 || pcs == FM10K_SW_EPL_PCS_SEL_DISABLE) {
> +		if (pcs == FM10K_SW_EPL_PCS_SEL_40GBASER ||
> +		    pcs == FM10K_SW_EPL_PCS_SEL_100GBASER)
> +			return (FM10K_AM_TIMEOUT / 2);
> +		else
> +			return (0);
> +	}
> +
> +	if (pcs == FM10K_SW_EPL_PCS_SEL_40GBASER ||
> +	    pcs == FM10K_SW_EPL_PCS_SEL_100GBASER) {
> +		am_ppm = 1000000 / FM10K_AM_TIMEOUT;
> +		scale = FM10K_COMP_PPM_SCALE / 2;
> +	} else {
> +		am_ppm = 0;
> +		scale = FM10K_COMP_PPM_SCALE;
> +	}
> +
> +	ppm = num_ppm + am_ppm;
> +	timeout = scale / ppm;
> +
> +	if(timeout >= 0xffff)
> +		return 0xffff;
> +	else
> +		return timeout;
> +}
> +
> +
> +static int
> +fm10k_switch_configure_epls(struct fm10k_hw *hw, struct fm10k_switch *sw)
> +{
> +	struct fm10k_ext_ports *ext_ports = sw->ext_ports;
> +	struct fm10k_ext_port *port;
> +	struct fm10k_device_info *cfg = sw->info;
> +	u32 mac_cfg[FM10K_SW_MAC_CFG_ARRAY_SIZE];
> +	u32 data, pcs, qpl;
> +	u32 pcstmp;
> +	unsigned int i, j;
> +	unsigned int dic_enable;
> +	unsigned int anti_bubble_wm;
> +	unsigned int rate_fifo_wm;
> +	unsigned int rate_fifo_slow_inc, rate_fifo_fast_inc;
> +	int error;
> +	u16 timeout;
> +
> +	cfg = fm10k_get_device_info(hw);
> +	if (cfg == NULL)
> +	{
> +		return -1;
> +	}
> +
> +	/*
> +	 * Assumptions:
> +	 *   - All external interfaces are the same speed
> +	 *   - 1G/10G ports are packed into the minimum number of EPLs
> +	 *   - quad-mode EPLs use lane 0 as master
> +	 *   - The lowest numbered PEPs are used
> +	 *   - PEPs are always used in x8 mode.
> +	 */
> +	switch (cfg->ext_port_speed) {
> +	case 10:
> +		pcs = FM10K_SW_EPL_PCS_SEL_10GBASER;
> +		qpl = FM10K_SW_EPL_QPL_MODE_L1_L1_L1_L1;
> +		dic_enable = 1;
> +		anti_bubble_wm = 5;
> +		rate_fifo_wm = 3;
> +		rate_fifo_slow_inc = 12;
> +		rate_fifo_fast_inc = 13;
> +		break;
> +		/* XXX	what is the physical config for 25G? */
> +	case 25:
> +		pcs = FM10K_SW_EPL_PCS_SEL_100GBASER;
> +		qpl = FM10K_SW_EPL_QPL_MODE_L1_L1_L1_L1;
> +		dic_enable = 0;
> +		anti_bubble_wm = 6;
> +		rate_fifo_wm = 3;
> +		rate_fifo_slow_inc = 32;
> +		rate_fifo_fast_inc = 33;
> +		break;
> +	case 40:
> +		pcs = FM10K_SW_EPL_PCS_SEL_40GBASER;
> +		qpl = FM10K_SW_EPL_QPL_MODE_L4_XX_XX_XX;
> +		dic_enable = 1;
> +		anti_bubble_wm = 4;
> +		rate_fifo_wm = 5;
> +		rate_fifo_slow_inc = 51;
> +		rate_fifo_fast_inc = 52;
> +		break;
> +	case 100:
> +		pcs = FM10K_SW_EPL_PCS_SEL_100GBASER;
> +		qpl = FM10K_SW_EPL_QPL_MODE_L4_XX_XX_XX;
> +		dic_enable = 1;
> +		anti_bubble_wm = 4;
> +		rate_fifo_wm = 3;
> +		rate_fifo_slow_inc = 129;
> +		rate_fifo_fast_inc = 130;
> +		break;
> +	default:
> +		error = -1;
> +		goto done;
> +	}
> +
> +	/*
> +	 * EPL_CFG_A
> +	 *
> +	 * Mark all used lanes as active and all unused lanes as
> +	 * inactive. Adjust timeout and skew tolerance values for EPLs that
> +	 * are used.
> +	 */
> +	for (i = 0; i < FM10K_SW_EPLS_MAX; i++) {
> +		data = fm10k_read_switch_reg(sw, FM10K_SW_EPL_CFG_A(i));
> +		data &= ~FM10K_SW_EPL_CFG_A_ACTIVE_QUAD;
> +		if (FM10K_SW_EXT_PORTS_EPL_USED(ext_ports, i)) {
> +			for (j = 0; j < ext_ports->num_ports; j++) {
> +				port = &ext_ports->ports[j];
> +				if (port->eplno == i)
> +					data |= port->is_quad ?
> +
> FM10K_SW_EPL_CFG_A_ACTIVE_QUAD :
> +					    FM10K_SW_EPL_CFG_A_ACTIVE(
> +						port->first_lane);
> +			}
> +			FM10K_SW_REPLACE_REG_FIELD(data,
> EPL_CFG_A_TIMEOUT, 19);
> +			FM10K_SW_REPLACE_REG_FIELD(data,
> EPL_CFG_A_SKEW_TOLERANCE, 38);
> +		}
> +		fm10k_write_switch_reg(sw, FM10K_SW_EPL_CFG_A(i), data);
> +	}
> +
> +	/*
> +	 * EPL_CFG_B
> +	 *
> +	 * Disable all unused lanes and configure all used ones
> +	 * appropriately.  For EPLs used in quad port mode, the master lane
> +	 * is the only one that gets configured.
> +	 */
> +	data = 0;
> +	for (i = 0; i < FM10K_SW_EPLS_MAX; i++) {
> +		if (FM10K_SW_EXT_PORTS_EPL_USED(ext_ports, i)) {
> +			for (j = 0; j < FM10K_SW_EPL_LANES; j++) {
> +				if (j < ext_ports->ports_per_epl)
> +					pcstmp = pcs;
> +				else
> +					pcstmp =
> FM10K_SW_EPL_PCS_SEL_DISABLE;
> +				data |=
> +				    FM10K_SW_MAKE_REG_FIELD_IDX(
> +					EPL_CFG_B_PCS_SEL,
> +					j,
> +					pcstmp);
> +			}
> +			data |=
> +			    FM10K_SW_MAKE_REG_FIELD(
> +				EPL_CFG_B_QPL_MODE,
> +				qpl);
> +		} else {
> +			for (j = 0; j < FM10K_SW_EPL_LANES; j++)
> +				data |=
> +				    FM10K_SW_MAKE_REG_FIELD_IDX(
> +					EPL_CFG_B_PCS_SEL,
> +					j,
> +					FM10K_SW_EPL_PCS_SEL_DISABLE);
> +			data |=
> +			    FM10K_SW_MAKE_REG_FIELD(
> +				EPL_CFG_B_QPL_MODE,
> +				FM10K_SW_EPL_QPL_MODE_XX_XX_XX_XX);
> +		}
> +		fm10k_write_switch_reg(sw, FM10K_SW_EPL_CFG_B(i), data);
> +	}
> +
> +	/*
> +	 * MAC_CFG, LINK_RULES and PCS_ML_BASER_CFG
> +	 *
> +	 * Only EPLs/lanes that are being used are initialized. All others
> +	 * are left at their defaults.
> +	 */
> +	for (i = 0; i < FM10K_SW_EPLS_MAX; i++) {
> +		if (!FM10K_SW_EXT_PORTS_EPL_USED(ext_ports, i))
> +			continue;
> +		for (j = 0; j < ext_ports->ports_per_epl; j++) {
> +			fm10k_read_switch_array(sw, FM10K_SW_MAC_CFG(i,
> j),
> +			    mac_cfg, FM10K_SW_MAC_CFG_ARRAY_SIZE);
> +
> +			/* dic enable */
> +			FM10K_SW_SET_ARRAY_BIT(mac_cfg,
> +			    MAC_CFG_TX_IDLE_ENABLE_DIC,
> +			    dic_enable);
> +
> +			/* ifg */
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_IDLE_MIN_IFG_BYTES,
> +			    12);
> +
> +			/* tx pad size: (64 bytes + 8 preamble) / 4 */
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_MIN_COLUMNS,
> +			    18);
> +
> +			/* tx clock compensation */
> +			timeout =
> +
> fm10k_switch_ppm_to_tx_clk_compensation_timeout(pcs,
> +				100);
> +			FM10K_SW_SET_ARRAY_BIT(mac_cfg,
> +			    MAC_CFG_TX_CLOCK_COMPENSATION_ENABLE,
> +			    (timeout > 0));
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_CLOCK_COMPENSATION_TIMEOUT,
> +			    timeout);
> +
> +			FM10K_SW_SET_ARRAY_BIT(mac_cfg,
> +			    MAC_CFG_PREAMBLE_MODE,
> +			    0);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_RX_MIN_FRAME_LENGTH,
> +			    64);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_RX_MAX_FRAME_LENGTH,
> +			    FM10K_SW_PACKET_SIZE_MAX);
> +			FM10K_SW_SET_ARRAY_BIT(mac_cfg,
> +			    MAC_CFG_RX_IGNORE_IFG_ERRORS,
> +			    0);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_FCS_MODE,
> +
> FM10K_SW_TX_MAX_FCS_MODE_REPLACE_NORMAL);
> +
> +			FM10K_SW_SET_ARRAY_BIT(mac_cfg,
> +			    MAC_CFG_IEEE_1588_ENABLE,
> +			    0);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_DRAIN_MODE,
> +
> FM10K_SW_TX_MAC_DRAIN_MODE_DRAIN_NORMAL);
> +
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_PC_ACT_TIMEOUT,
> +			    100);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_PC_ACT_TIME_SCALE,
> +			    3);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_LPI_TIMEOUT,
> +			    180);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_LPI_TIME_SCALE,
> +			    1);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_LPI_HOLD_TIMEOUT,
> +			    20);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_LPI_HOLD_TIME_SCALE,
> +			    1);
> +
> +			FM10K_SW_SET_ARRAY_BIT(mac_cfg,
> +			    MAC_CFG_TX_LPI_AUTOMATIC,
> +			    1);
> +			FM10K_SW_SET_ARRAY_BIT(mac_cfg,
> +			    MAC_CFG_TX_LP_IDLE_REQUEST,
> +			    0);
> +
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_FAULT_MODE,
> +			    FM10K_SW_TX_MAC_FAULT_MODE_NORMAL);
> +
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_ANTI_BUBBLE_WATERMARK,
> +			    anti_bubble_wm);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_RATE_FIFO_WATERMARK,
> +			    rate_fifo_wm);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_RATE_FIFO_FAST_INC,
> +			    rate_fifo_fast_inc);
> +			FM10K_SW_REPLACE_ARRAY_FIELD(mac_cfg,
> +			    MAC_CFG_TX_RATE_FIFO_SLOW_INC,
> +			    rate_fifo_slow_inc);
> +
> +			fm10k_write_switch_array(sw, FM10K_SW_MAC_CFG(i,
> j),
> +			    mac_cfg, FM10K_SW_MAC_CFG_ARRAY_SIZE);
> +
> +			data = fm10k_read_switch_reg(sw,
> FM10K_SW_LINK_RULES(i, j));
> +
> +			/* link-up debounce params */
> +			FM10K_SW_REPLACE_REG_FIELD(data,
> +			    LINK_RULES_FAULT_TIME_SCALE_UP,
> +			    4);
> +			FM10K_SW_REPLACE_REG_FIELD(data,
> +			    LINK_RULES_FAULT_TICKS_UP,
> +			    30);
> +
> +			/* link-down debounce params */
> +			FM10K_SW_REPLACE_REG_FIELD(data,
> +			    LINK_RULES_FAULT_TIME_SCALE_DOWN,
> +			    4);
> +			FM10K_SW_REPLACE_REG_FIELD(data,
> +			    LINK_RULES_FAULT_TICKS_DOWN,
> +			    5);
> +
> +			FM10K_SW_REPLACE_REG_FIELD(data,
> +			    LINK_RULES_HEARTBEAT_TIME_SCALE,
> +			    cfg->ext_port_speed == 10 ? 4 : 0);
> +			fm10k_write_switch_reg(sw, FM10K_SW_LINK_RULES(i,
> j), data);
> +
> +			/* XXX add 10GBASER config */
> +		}
> +
> +		if (cfg->ext_port_speed != 10)
> +			fm10k_write_switch_reg(sw,
> FM10K_SW_PCS_ML_BASER_CFG(i), 0x00003fff);
> +	}
> +
> +
> +	/*
> +	 * LANE_CFG, LANE_SERDES_CFG, LANE_ENERGY_DETECT_CFG,
> +	 * LANE_SIGNAL_DETECT_CFG, and EPL_FIFO_ERROR_STATUS
> +	 *
> +	 * Only EPLs/lanes that are being used are initialized. All others
> +	 * are left at their defaults.
> +	 */
> +	for (i = 0; i < FM10K_SW_EPLS_MAX; i++) {
> +		if (!FM10K_SW_EXT_PORTS_EPL_USED(ext_ports, i))
> +			continue;
> +		for (j = 0; j < ext_ports->ports_per_epl; j++) {
> +			fm10k_write_switch_reg(sw, FM10K_SW_LANE_CFG(i,
> j), 0);
> +
> +			fm10k_write_switch_reg(sw,
> FM10K_SW_LANE_SERDES_CFG(i, j),
> +			    0x1106);
> +
> +			data = fm10k_read_switch_reg(sw,
> +			    FM10K_SW_LANE_ENERGY_DETECT_CFG(i, j));
> +			data |=
> +
> FM10K_SW_LANE_ENERGY_DETECT_CFG_ED_MASK_RX_SIGNAL_OK |
> +
> FM10K_SW_LANE_ENERGY_DETECT_CFG_ED_MASK_RX_RDY |
> +
> FM10K_SW_LANE_ENERGY_DETECT_CFG_ED_MASK_RX_ACTIVITY;
> +			data &=
> +
> ~FM10K_SW_LANE_ENERGY_DETECT_CFG_ED_MASK_ENERGY_DETECT;
> +			fm10k_write_switch_reg(sw,
> +			    FM10K_SW_LANE_ENERGY_DETECT_CFG(i, j), data);
> +
> +			data = fm10k_read_switch_reg(sw,
> +			    FM10K_SW_LANE_SIGNAL_DETECT_CFG(i, j));
> +			data &=
> +
> ~(FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_MASK_RX_SIGNAL_OK |
> +
> 	FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_MASK_RX_RDY);
> +			data |=
> +
> FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_MASK_RX_ACTIVITY |
> +
> FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_MASK_ENERGY_DETECT;
> +			fm10k_write_switch_reg(sw,
> +			    FM10K_SW_LANE_SIGNAL_DETECT_CFG(i, j), data);
> +
> +			data = 0;
> +			data |= ((1 << j) << 4) | (1 << j);
> +			fm10k_write_switch_reg(sw,
> +			    FM10K_SW_EPL_FIFO_ERROR_STATUS(i), data);
> +		}
> +	}
> +
> +	error = fm10k_epl_serdes_reset_and_load_all(sw);
> +	if (error)
> +		goto done;
> +
> +	/*
> +	 * EPL_FIFO_ERROR_STATUS LINK_IP
> +	 */
> +	for (i = 0; i < FM10K_SW_EPLS_MAX; i++) {
> +		if (!FM10K_SW_EXT_PORTS_EPL_USED(ext_ports, i))
> +			continue;
> +		for (j = 0; j < ext_ports->ports_per_epl; j++) {
> +			fm10k_write_switch_reg(sw,
> +			    FM10K_SW_LINK_IP(i, j), FM10K_SW_MASK32(31, 0));
> +		}
> +
> +		data = 0;
> +		data |= ((1 << j) << 4) | (1 << j);
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_EPL_FIFO_ERROR_STATUS(i), data);
> +	}
> +done:
> +	return (error);
> +}
> +
> +int fm10k_switch_dpdk_port_no_get(struct fm10k_hw *hw);
> +int fm10k_ffu_mirror_set(struct fm10k_switch *sw,
> +		u16 src_dpdk_port, u16 dest_dpdk_port, u16 vlan);
> +int fm10k_ffu_mirror_reset(struct fm10k_switch *sw, int src_dpdk_port);
> +
> +int
> +fm10k_switch_mirror_set(struct fm10k_hw *hw, u16 dest_port, u16 vlan)
> +{
> +	struct fm10k_switch* sw = &fm10k_sw;
> +	int src_port = fm10k_switch_dpdk_port_no_get(hw);
> +
> +	/* source port is external port number */
> +	if (src_port < 0 || src_port == dest_port)
> +		return -1;
> +
> +	return fm10k_ffu_mirror_set(sw, src_port, dest_port, vlan);
> +}
> +
> +int fm10k_switch_mirror_reset(struct fm10k_hw *hw)
> +{
> +	struct fm10k_switch* sw = &fm10k_sw;
> +	int src_port = fm10k_switch_dpdk_port_no_get(hw);
> +
> +	if (src_port < 0)
> +		return -1;
> +
> +	return fm10k_ffu_mirror_reset(sw, src_port);
> +}
> +
> +
> +typedef struct
> +{
> +	u8 lport;
> +	u8 has_ftag;
> +}fm10k_sw_lport;
> +
> +static int
> +fm10k_switch_init(struct fm10k_hw *hw, struct fm10k_switch *sw)
> +{
> +	u32 data;
> +	unsigned int num_lports = sw->info->num_peps +
> FM10K_SW_EPLS_SUPPORTED;
> +	fm10k_sw_lport all_lports[num_lports];
> +	struct fm10k_device_info *cfg = sw->info;
> +	unsigned int i;
> +	unsigned int is_quad;
> +	unsigned int table_idx;
> +	int error;
> +	u32 watermark;
> +	u64 data64, data64_2;
> +
> +	/*
> +	 * Build list of all logical ports that might appear in the
> +	 * scheduler program.  Note that for any particular card
> +	 * configuration, not all of these logical ports may be used.
> +	 */
> +	table_idx = 0;
> +	for (i = 0; i < sw->info->num_peps; i++, table_idx++) {
> +		all_lports[table_idx].lport = sw->pep_map[i].logical_port;
> +		all_lports[table_idx].has_ftag = 1;
> +	}
> +	for (i = 0; i < FM10K_SW_EPLS_SUPPORTED; i++, table_idx++) {
> +		all_lports[table_idx].lport = sw->epl_map[i].logical_port;
> +		all_lports[table_idx].has_ftag = 0;
> +	}
> +
> +	if (table_idx != num_lports) {
> +		FM10K_SW_ERR("fm10k switch lport table construction error");
> +		return -1;
> +	}
> +
> +	/*
> +	 * Reset the switch to get to the default state
> +	 */
> +	data = fm10k_read_switch_reg(sw, FM10K_SW_SOFT_RESET);
> +	data &= ~FM10K_SW_SOFT_RESET_SWITCH_READY;
> +	fm10k_write_switch_reg(sw, FM10K_SW_SOFT_RESET, data);
> +	fm10k_write_flush(sw);
> +
> +	usec_delay(100);
> +	data = fm10k_read_switch_reg(sw, FM10K_SW_SOFT_RESET);
> +	data |= FM10K_SW_SOFT_RESET_SWITCH_RESET |
> FM10K_SW_SOFT_RESET_EPL_RESET;
> +	fm10k_write_switch_reg(sw, FM10K_SW_SOFT_RESET, data);
> +	fm10k_write_flush(sw);
> +	usec_delay(1000);
> +
> +	/* Clear memories */
> +	fm10k_write_switch_reg64(sw, FM10K_SW_BIST_CTRL,
> +	    FM10K_SW_BIST_CTRL_BIST_MODE_FABRIC |
> +	    FM10K_SW_BIST_CTRL_BIST_MODE_TUNNEL |
> +	    FM10K_SW_BIST_CTRL_BIST_MODE_EPL);
> +	fm10k_write_flush(sw);
> +
> +	fm10k_write_switch_reg64(sw, FM10K_SW_BIST_CTRL,
> +	    FM10K_SW_BIST_CTRL_BIST_MODE_FABRIC |
> +	    FM10K_SW_BIST_CTRL_BIST_MODE_TUNNEL |
> +	    FM10K_SW_BIST_CTRL_BIST_MODE_EPL |
> +	    FM10K_SW_BIST_CTRL_BIST_RUN_FABRIC |
> +	    FM10K_SW_BIST_CTRL_BIST_RUN_TUNNEL |
> +	    FM10K_SW_BIST_CTRL_BIST_RUN_EPL);
> +	fm10k_write_flush(sw);
> +	usec_delay(800);
> +
> +	fm10k_write_switch_reg64(sw, FM10K_SW_BIST_CTRL, 0);
> +	fm10k_write_flush(sw);
> +
> +	data = fm10k_read_switch_reg(sw, FM10K_SW_SOFT_RESET);
> +	data &= ~(FM10K_SW_SOFT_RESET_SWITCH_RESET |
> FM10K_SW_SOFT_RESET_EPL_RESET);
> +	fm10k_write_switch_reg(sw, FM10K_SW_SOFT_RESET, data);
> +	fm10k_write_flush(sw);
> +	/* ensure switch reset is deasserted for at least 100ns */
> +	usec_delay(1);
> +
> +	sw->epl_sbus = fm10k_sbus_attach(sw, "EPL",
> FM10K_SW_SBUS_EPL_CFG);
> +	if (sw->epl_sbus == NULL) {
> +		error = -1;
> +		goto done;
> +	}
> +
> +	/* Clear non-BIST accessible pause state memories */
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		fm10k_write_switch_reg64(sw,
> +		    FM10K_SW_CM_EGRESS_PAUSE_COUNT(i, 0), 0);
> +		fm10k_write_switch_reg64(sw,
> +		    FM10K_SW_CM_EGRESS_PAUSE_COUNT(i, 1), 0);
> +	}
> +
> +	/* Initialize RXQ_MCAST list */
> +	for (i = 0; i < FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_ENTRIES;
> i++) {
> +		fm10k_write_switch_reg64(sw,
> +		    FM10K_SW_SCHED_RXQ_STORAGE_POINTERS(i),
> +		    FM10K_SW_MAKE_REG_FIELD(
> +			SCHED_RXQ_STORAGE_POINTERS_HEAD_PAGE, i) |
> +		    FM10K_SW_MAKE_REG_FIELD(
> +			SCHED_RXQ_STORAGE_POINTERS_TAIL_PAGE, i));
> +	}
> +	for (i = 0;
> +	     i < FM10K_SW_SCHED_RXQ_FREELIST_INIT_ENTRIES -
> +		 FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_ENTRIES; i++) {
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_SCHED_RXQ_FREELIST_INIT,
> +		    FM10K_SW_MAKE_REG_FIELD(
> +			SCHED_RXQ_FREELIST_INIT_ADDRESS,
> +			i +
> FM10K_SW_SCHED_RXQ_STORAGE_POINTERS_ENTRIES));
> +	}
> +	/* Initialize TXQ list */
> +	for (i = 0; i < FM10K_SW_SCHED_TXQ_HEAD_PERQ_ENTRIES; i++) {
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_SCHED_TXQ_HEAD_PERQ(i),
> +
> FM10K_SW_MAKE_REG_FIELD(SCHED_TXQ_HEAD_PERQ_HEAD, i));
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_SCHED_TXQ_TAIL0_PERQ(i),
> +
> FM10K_SW_MAKE_REG_FIELD(SCHED_TXQ_TAIL0_PERQ_TAIL, i));
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_SCHED_TXQ_TAIL1_PERQ(i),
> +
> FM10K_SW_MAKE_REG_FIELD(SCHED_TXQ_TAIL1_PERQ_TAIL, i));
> +	}
> +	for (i = 0;
> +	     i < FM10K_SW_SCHED_TXQ_FREELIST_INIT_ENTRIES -
> +		 FM10K_SW_SCHED_TXQ_HEAD_PERQ_ENTRIES; i++) {
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_SCHED_TXQ_FREELIST_INIT,
> +		    FM10K_SW_MAKE_REG_FIELD(
> +			SCHED_TXQ_FREELIST_INIT_ADDRESS,
> +			i + FM10K_SW_SCHED_TXQ_HEAD_PERQ_ENTRIES));
> +	}
> +	/* Initialize free segment list */
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_SCHED_SSCHED_RX_PERPORT(i),
> +
> FM10K_SW_MAKE_REG_FIELD(SCHED_SSCHED_RX_PERPORT_NEXT, i));
> +	}
> +	for (i = 0;
> +	     i < FM10K_SW_SCHED_FREELIST_INIT_ENTRIES -
> +		 FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_SCHED_FREELIST_INIT,
> +		    FM10K_SW_MAKE_REG_FIELD(
> +			SCHED_FREELIST_INIT_ADDRESS,
> +			i + FM10K_SW_LOGICAL_PORTS_MAX));
> +	}
> +	/* Disable switch scan chain */
> +	fm10k_write_switch_reg(sw, FM10K_SW_SCAN_DATA_IN,
> +	    FM10K_SW_SCAN_DATA_IN_UPDATE_NODES |
> FM10K_SW_SCAN_DATA_IN_PASSTHRU);
> +
> +	error = fm10k_switch_configure_epls(hw, sw);
> +	if (error)
> +		goto done;
> +
> +	/*
> +	 * XXX for now configure store-and-forward between PEPs and external
> +	 * ports regardless of relative speeds
> +	 */
> +	for (i = 0; i < num_lports; i++) {
> +		fm10k_write_switch_reg64(sw,
> +		    FM10K_SW_SAF_MATRIX(all_lports[i].lport),
> +		    FM10K_SW_SAF_MATRIX_ENABLE_SNF_ALL_PORTS);
> +	}
> +
> +	/* Disable MTU violation trap */
> +	data = fm10k_read_switch_reg(sw, FM10K_SW_SYS_CFG_1);
> +	data &= ~FM10K_SW_SYS_CFG_1_TRAP_MTU_VIOLATIONS;
> +	fm10k_write_switch_reg(sw, FM10K_SW_SYS_CFG_1, data);
> +
> +	/* Disable ingress VLAN filtering and learning */
> +	for (i = 0; i < num_lports; i++) {
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_PORT_CFG_3(all_lports[i].lport), 0);
> +	}
> +	/*
> +	 * Make all ports members of every VLAN, and configure every VLAN to
> +	 * use MST instance 0.
> +	 */
> +	data64 = 0;
> +	for (i = 0; i < num_lports; i++)
> +		data64 |=
> FM10K_SW_INGRESS_VID_TABLE_MEMBERSHIP(all_lports[i].lport);
> +	for (i = 0; i < FM10K_SW_INGRESS_VID_TABLE_ENTRIES; i++) {
> +		fm10k_write_switch_reg128(sw,
> FM10K_SW_INGRESS_VID_TABLE(i),
> +		    FM10K_SW_INGRESS_VID_TABLE_REFLECT, data64);
> +	}
> +	data64 = 0;
> +	for (i = 0; i < num_lports; i++)
> +		data64 |=
> FM10K_SW_EGRESS_VID_TABLE_MEMBERSHIP(all_lports[i].lport);
> +	for (i = 0; i < FM10K_SW_EGRESS_VID_TABLE_ENTRIES; i++)
> +		fm10k_write_switch_reg128(sw,
> FM10K_SW_EGRESS_VID_TABLE(i), 0, data64);
> +
> +	// Init MOD_VLAN_TAG_VID1_MAP
> +	for (i = 0; i < FM10K_SW_INGRESS_VID_TABLE_ENTRIES; i++) {
> +		data64 = i;
> +		data64 = data64<<48;
> +		fm10k_write_switch_reg64(sw, 0xE80000+0x2*i+0x20000,
> data64);
> +	}
> +
> +	/* Configure MST instance 0 to forward for all ports */
> +	data64 = 0;
> +	for (i = 0; i < num_lports; i++)
> +		data64 |=
> FM10K_SW_EGRESS_MST_TABLE_FORWARDING(all_lports[i].lport);
> +	fm10k_write_switch_reg64(sw, FM10K_SW_EGRESS_MST_TABLE(0),
> data64);
> +
> +	data64 = 0;
> +	data64_2 = 0;
> +	for (i = 0; i < num_lports; i++) {
> +		if (all_lports[i].lport <
> +		    FM10K_SW_INGRESS_MST_TABLE_PORTS_PER_TABLE) {
> +			data64 |=
> +			    FM10K_SW_MAKE_REG_FIELD_IDX64(
> +				INGRESS_MST_TABLE_STP_STATE,
> +				all_lports[i].lport,
> +
> 	FM10K_SW_INGRESS_MST_TABLE_STP_STATE_FORWARD);
> +		} else {
> +			data64_2 |=
> +			    FM10K_SW_MAKE_REG_FIELD_IDX64(
> +				INGRESS_MST_TABLE_STP_STATE,
> +				all_lports[i].lport,
> +
> 	FM10K_SW_INGRESS_MST_TABLE_STP_STATE_FORWARD);
> +		}
> +	}
> +	fm10k_write_switch_reg64(sw, FM10K_SW_INGRESS_MST_TABLE(0, 0),
> data64);
> +	fm10k_write_switch_reg64(sw, FM10K_SW_INGRESS_MST_TABLE(1, 0),
> data64_2);
> +
> +	for (i = 0; i < num_lports; i++) {
> +		data64 = fm10k_read_switch_reg64(sw,
> +		    FM10K_SW_PARSER_PORT_CFG_1(all_lports[i].lport));
> +		data64 |= FM10K_SW_PARSER_PORT_CFG_1_VLAN1_TAG(0) |
> +
> FM10K_SW_PARSER_PORT_CFG_1_VLAN2_TAG(0);
> +		fm10k_write_switch_reg64(sw,
> +		    FM10K_SW_PARSER_PORT_CFG_1(all_lports[i].lport), data64);
> +
> +		/*
> +		 * Configure tags for f-tagged lports
> +		 */
> +		if (all_lports[i].has_ftag) {
> +			data64 = fm10k_read_switch_reg64(sw,
> +			    FM10K_SW_PARSER_PORT_CFG_1(all_lports[i].lport));
> +			data64 |= FM10K_SW_PARSER_PORT_CFG_1_FTAG;
> +			fm10k_write_switch_reg64(sw,
> +			    FM10K_SW_PARSER_PORT_CFG_1(all_lports[i].lport),
> +			    data64);
> +
> +			data64 = fm10k_read_switch_reg64(sw,
> +
> FM10K_SW_MOD_PER_PORT_CFG_2(all_lports[i].lport));
> +			data64 |= FM10K_SW_MOD_PER_PORT_CFG_2_FTAG;
> +			fm10k_write_switch_reg64(sw,
> +
> FM10K_SW_MOD_PER_PORT_CFG_2(all_lports[i].lport),
> +			    data64);
> +		}
> +		data64 = fm10k_read_switch_reg64(sw,
> +		    FM10K_SW_PARSER_PORT_CFG_2(all_lports[i].lport));
> +		data64 |= FM10K_SW_PARSER_PORT_CFG_2_PARSE_L3;
> +		data64 |= FM10K_SW_PARSER_PORT_CFG_2_PARSE_L4;
> +		fm10k_write_switch_reg64(sw,
> +		    FM10K_SW_PARSER_PORT_CFG_2(all_lports[i].lport), data64);
> +	}
> +
> +	/*
> +	 * Assign default SGLORTs for the EPL ports in the PARSER config.
> +	 * This isn't necessary for the PEPs as for those, as all frames
> +	 * ingressing from PEPs are tagged with an SGLORT that is derived
> +	 * from a per-tx-queue setting.
> +	 *
> +	 * The PORT_CFG_ISL register offset is determined by logical port
> +	 * number and the register contents determined by the corresponding
> +	 * SGLORT.
> +	 */
> +	for (i = 0; i < FM10K_SW_EPLS_SUPPORTED; i++) {
> +		fm10k_write_switch_reg(sw,
> +
> FM10K_SW_PORT_CFG_ISL(fm10k_sw.epl_map[i].logical_port),
> +			    FM10K_SW_MAKE_REG_FIELD(
> +				PORT_CFG_ISL_SGLORT,
> +				fm10k_sw.epl_map[i].glort));
> +	}
> +
> +	/*
> +	 * FFU counter, 11.10.3.5 POLICER_CFG[0..3]
> +	 */
> +	fm10k_write_switch_reg64(sw, 0xE40000 +
> 0x2*FM10K_SW_FFU_CNT_BANK + 0x11000, FM10K_SW_POLICER_LAST);
> +
> +	/*
> +	 * 11.10.3.1 POLICER_CFG_4K[0..1][0..4095]
> +	 * 11.10.3.2 POLICER_CFG_512[0..1][0..511]
> +	 */
> +	for (i = 0; i < FM10K_SW_FFU_CNT_MAX; i++) {
> +		if (FM10K_SW_FFU_CNT_BANK < 2) {
> +			fm10k_read_switch_reg64(sw,
> +						0xE40000 +
> 0x2000*FM10K_SW_FFU_CNT_BANK + 0x2*(i+FM10K_SW_FFU_CNT_START) +
> 0x0);
> +		} else {
> +			fm10k_read_switch_reg64(sw,
> +						0xE40000 +
> 0x400*(FM10K_SW_FFU_CNT_BANK-2) + 0x2*(i+FM10K_SW_FFU_CNT_START)
> + 0x4000);
> +		}
> +	}
> +
> +	/*
> +	 * FFU
> +	 *
> +	 * The FFU is programmed to match on SGLORT and to set the DGLORT
> to
> +	 * a unique value corresponding to the given SGLORT.  One TCAM entry
> +	 * is required per host port per PEP and one per external interface.
> +	 * Only slice 0 is used.
> +	 */
> +	if (fm10k_ffu_init(sw, sw->dpdk_cfg) < 0)
> +		return -1;
> +
> +	/*
> +	 * Program the segment scheduler (see tables at top)
> +	 *
> +	 * The TX and RX schedules are the same.  Page 0 is used.
> +	 */
> +	if (cfg->ext_port_speed == 40 || cfg->ext_port_speed == 100)
> +		is_quad = 1;
> +	else
> +		is_quad = 0;
> +	for (i = 0; i < FM10K_SW_NITEMS(fm10k_sched_prog); i++) {
> +		/*
> +		 * In addition to explicit idle cycles, non-quad port
> +		 * entries are converted to idle cycles if the interfaces
> +		 * are configured in quad-port mode.
> +		 */
> +		if (fm10k_sched_prog[i].idle ||
> +		    (!fm10k_sched_prog[i].quad && is_quad))
> +			data = FM10K_SW_SCHED_SCHEDULE_IDLE;
> +		else {
> +			data = FM10K_SW_SCHED_SCHEDULE_ENTRY(
> +			    fm10k_sched_prog[i].phys,
> +			    fm10k_sched_prog[i].log,
> +			    (fm10k_sched_prog[i].quad ==
> FM10K_SW_QUAD_40_100) ?
> +			    is_quad : fm10k_sched_prog[i].quad);
> +		}
> +		fm10k_write_switch_reg(sw,
> FM10K_SW_SCHED_RX_SCHEDULE(0, i), data);
> +		fm10k_write_switch_reg(sw,
> FM10K_SW_SCHED_TX_SCHEDULE(0, i), data);
> +	}
> +
> +	fm10k_write_switch_reg(sw, FM10K_SW_SCHED_SCHEDULE_CTRL,
> +	    FM10K_SW_SCHED_SCHEDULE_CTRL_RX_ENABLE |
> +	    FM10K_SW_MAKE_REG_FIELD(
> +		SCHED_SCHEDULE_CTRL_RX_MAX_INDEX,
> +		FM10K_SW_NITEMS(fm10k_sched_prog) - 1) |
> +	    FM10K_SW_SCHED_SCHEDULE_CTRL_TX_ENABLE |
> +	    FM10K_SW_MAKE_REG_FIELD(
> +		SCHED_SCHEDULE_CTRL_TX_MAX_INDEX,
> +		FM10K_SW_NITEMS(fm10k_sched_prog) - 1));
> +
> +	/* Per 5.7.10.4 */
> +	watermark = FM10K_SW_MEM_POOL_SEGS_MAX -
> +	    ((sw->info->num_peps + FM10K_SW_EPLS_SUPPORTED *
> FM10K_SW_EPL_LANES) *
> +	    FM10K_SW_HOWMANY(FM10K_SW_PACKET_SIZE_MAX,
> FM10K_SW_MEM_POOL_SEG_SIZE)) -
> +	    FM10K_SW_MEM_POOL_SEGS_RSVD;
> +	fm10k_write_switch_reg(sw, FM10K_SW_CM_GLOBAL_WM,
> +	    FM10K_SW_MAKE_REG_FIELD(CM_GLOBAL_WM_WATERMARK,
> watermark));
> +	fm10k_write_switch_reg(sw, FM10K_SW_CM_GLOBAL_CFG,
> +	    FM10K_SW_CM_GLOBAL_CFG_WM_SWEEP_EN |
> +	    FM10K_SW_CM_GLOBAL_CFG_PAUSE_GEN_SWEEP_EN |
> +	    FM10K_SW_CM_GLOBAL_CFG_PAUSE_REC_SWEEP_EN |
> +	    FM10K_SW_MAKE_REG_FIELD(
> +		CM_GLOBAL_CFG_NUM_SWEEPER_PORTS,
> +		FM10K_SW_LOGICAL_PORTS_MAX));
> +
> +	/* Configure stats counters */
> +	data = FM10K_SW_RX_STATS_CFG_ENABLE_ALL_BANKS;
> +	data64 =
> +	    FM10K_SW_MOD_STATS_CFG_ENABLE_GROUP_7 |
> +	    FM10K_SW_MOD_STATS_CFG_ENABLE_GROUP_8;
> +	for (i = 0; i < num_lports; i++) {
> +		fm10k_write_switch_reg(sw,
> +		    FM10K_SW_RX_STATS_CFG(all_lports[i].lport),
> +		    data |
> +		    ((all_lports[i].has_ftag) ?
> +			FM10K_SW_MAKE_REG_FIELD(
> +			    RX_STATS_CFG_PER_FRAME_ADJUSTMENT,
> +			    FM10K_SW_FTAG_SIZE) :
> +			0));
> +		fm10k_write_switch_reg64(sw,
> +		    FM10K_SW_MOD_STATS_CFG(all_lports[i].lport),
> +		    data64);
> +	}
> +
> +	/* Transition switch to ready */
> +	data = fm10k_read_switch_reg(sw, FM10K_SW_SOFT_RESET);
> +	data |= FM10K_SW_SOFT_RESET_SWITCH_READY;
> +	fm10k_write_switch_reg(sw, FM10K_SW_SOFT_RESET, data);
> +
> + done:
> +	return (error);
> +}
> +
> +
> +static void
> +fm10k_switch_leds_init(struct fm10k_switch *sw)
> +{
> +	struct fm10k_device_info *cfg = sw->info;
> +	unsigned int i;
> +	uint8_t addr;
> +	uint32_t data;
> +	int max;
> +
> +	switch (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice)) {
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QS41):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QS41):
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QS43):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QS43):
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QL4):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QL4):
> +		FM10K_SW_I2C_REQ_LOCK(sw->i2c);
> +		/*
> +		 * Set up the first PCA9545 mux so we can get at the PCA9635
> +		 * that the LED control lines are connected to.
> +		 */
> +		fm10k_i2c_write8(sw->i2c, 0x70, 0x04);
> +
> +		/*
> +		 * PCA9635 initialization
> +		 * only differences from defaults are noted
> +		 */
> +
> +		/* MODE1 - put into sleep mode to ensure it is brought out
> +		 * of sleep without violating the oscillator startup wait
> +		 */
> +		fm10k_i2c_write16(sw->i2c, 0x6a, 0x00, 0x10);
> +		fm10k_udelay(10);
> +
> +		/* MODE1 - normal mode, disable all call */
> +		fm10k_i2c_write16(sw->i2c, 0x6a, 0x00, 0x00);
> +
> +		/* Wait for oscillator to stabilize after coming out of sleep */
> +		fm10k_udelay(500);
> +
> +		/* MODE2 - group control is blinking, open drain outputs,
> +		 * OE high -> LEDn = 0
> +		 */
> +		fm10k_i2c_write16(sw->i2c, 0x6a, 0x01, 0x20);
> +
> +		/* PWM0 - 100% duty cycle */
> +		fm10k_i2c_write16(sw->i2c, 0x6a, 0x02, 0xff);
> +
> +		/* PWM1 - 100% duty cycle */
> +		fm10k_i2c_write16(sw->i2c, 0x6a, 0x03, 0xff);
> +
> +		/* GRPPWM - 50% blink duty cycle */
> +		fm10k_i2c_write16(sw->i2c, 0x6a, 0x12, 0x80);
> +
> +		/* GRPFREQ - FM10K_LED_BLINKS_PER_SECOND */
> +		if(24/FM10K_LED_BLINKS_PER_SECOND > 1)
> +			max = 24/FM10K_LED_BLINKS_PER_SECOND;
> +		else
> +			max = 1;
> +		fm10k_i2c_write16(sw->i2c, 0x6a, 0x13, max-1);
> +
> +		FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +		break;
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4_REV_2):
> +		FM10K_SW_I2C_REQ_LOCK(sw->i2c);
> +		/*
> +		 * Set up the first PCA9545 mux so we can get at the PCA9635s
> +		 * that the LED control lines are connected to.
> +		 */
> +		fm10k_i2c_write8(sw->i2c, 0x70, 0x01);
> +
> +		/*
> +		 * PCA9635 initialization
> +		 * only differences from defaults are noted
> +		 */
> +
> +		addr = 0x6a;
> +		for (i = 0; i < 2; i++) {
> +			/* MODE1 - put into sleep mode to ensure it is
> +			 * brought out of sleep without violating the
> +			 * oscillator startup wait
> +			 */
> +			fm10k_i2c_write16(sw->i2c, addr, 0x00, 0x10);
> +			fm10k_udelay(10);
> +
> +			/* MODE1 - normal mode, disable all call */
> +			fm10k_i2c_write16(sw->i2c, addr, 0x00, 0x00);
> +
> +			/* MODE2 - group control is blinking, open drain
> +			 * outputs, OE high -> LEDn = 0
> +			 */
> +			fm10k_i2c_write16(sw->i2c, addr, 0x01, 0x20);
> +
> +			/* Wait for oscillator to stabilize after coming out of
> sleep */
> +			fm10k_udelay(500);
> +
> +			/* PWM0 - 100% duty cycle */
> +			fm10k_i2c_write16(sw->i2c, addr, 0x02, 0xff);
> +
> +			/* PWM3 - 100% duty cycle */
> +			fm10k_i2c_write16(sw->i2c, addr, 0x05, 0xff);
> +
> +			/* GRPPWM - 50% blink duty cycle */
> +			fm10k_i2c_write16(sw->i2c, addr, 0x12, 0x80);
> +
> +			/* GRPFREQ - FM10K_LED_BLINKS_PER_SECOND */
> +			if(24/FM10K_LED_BLINKS_PER_SECOND > 1)
> +				max = 24/FM10K_LED_BLINKS_PER_SECOND;
> +			else
> +				max = 1;
> +			fm10k_i2c_write16(sw->i2c, addr, 0x13, max - 1);
> +
> +			addr = 0x69;
> +		}
> +		FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +		break;
> +
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRL_QXSL4):
> +		FM10K_SW_I2C_REQ_LOCK(sw->i2c);
> +		addr = 0x62;
> +		fm10k_i2c_write16(sw->i2c, addr, 0x03, 0x88);
> +		fm10k_i2c_write16(sw->i2c, addr, 0x01, 0x0);
> +
> +		data = fm10k_read_switch_reg(sw, 0xc2b);
> +		data |= 1<<24;
> +		fm10k_write_switch_reg(sw, 0xc2b, data);
> +		FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +		break;
> +
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4):
> +		FM10K_SW_I2C_REQ_LOCK(sw->i2c);
> +		/*
> +		 * PCA9538 initialization
> +		 * only differences from defaults are noted
> +		 */
> +		/*
> +		 *	00000000: No link
> +		 *	00000001: 10G Port 0
> +		 *  00000010: 40G Port 0
> +		 *  00000100: 25G Port 0
> +		 *  00001000: 100G Port 0
> +		 */
> +		addr = 0x62;
> +		fm10k_i2c_write16(sw->i2c, addr, 0x03, 0x0);
> +		fm10k_i2c_write16(sw->i2c, addr, 0x01, 0x0);
> +
> +		addr = 0x65;
> +		fm10k_i2c_write16(sw->i2c, addr, 0x03, 0xf0);
> +		fm10k_i2c_write16(sw->i2c, addr, 0x01, 0x0);
> +
> +		addr = 0x66;
> +		fm10k_i2c_write16(sw->i2c, addr, 0x03, 0x0);
> +		fm10k_i2c_write16(sw->i2c, addr, 0x01, 0x0);
> +
> +		/* set LEC_CFG */
> +		data = fm10k_read_switch_reg(sw, 0xc2b);
> +		data |= 1<<24;
> +		fm10k_write_switch_reg(sw, 0xc2b, data);
> +
> +		/* port from rdifd, LED */
> +		fm10k_gpio_output_set(sw, 4, 0);
> +		FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +		break;
> +
> +	default:
> +		FM10K_SW_ERR("don't know how to operate LEDs for this card
> "
> +		    "(subvendor=0x%04x subdevice=0x%04x)",
> +		    cfg->subvendor, cfg->subdevice);
> +		break;
> +	}
> +}
> +
> +
> +static unsigned int
> +fm10k_switch_pca9635_led_bits(uint8_t led_flags)
> +{
> +	unsigned int bits;
> +
> +	if (led_flags & FM10K_SW_EXT_PORT_LED_FLAG_UP) {
> +		if (led_flags & FM10K_SW_EXT_PORT_LED_FLAG_ACTIVE)
> +			bits = 0x3; /* group blink */
> +		else
> +			bits = 0x1; /* full on */
> +	} else
> +		bits = 0; /* off */
> +
> +	return (bits);
> +}
> +
> +static void
> +fm10k_switch_process_leds(void *ctx)
> +{
> +	struct fm10k_switch *sw = ctx;
> +	struct fm10k_device_info *cfg = sw->info;
> +	struct fm10k_ext_ports *ports = sw->ext_ports;
> +	struct fm10k_ext_port *port;
> +	unsigned int i;
> +	unsigned int num_ports = ports->num_ports;
> +	uint32_t data;
> +	uint8_t update_port[num_ports];
> +	uint8_t led_flags = 0, read;
> +	uint8_t addr;
> +
> +	FM10K_SW_SWITCH_LOCK(sw);
> +
> +	if (sw->master_hw->sw_addr == NULL) {
> +		FM10K_SW_SWITCH_UNLOCK(sw);
> +		return;
> +	}
> +
> +	for (i = 0; i < num_ports; i++) {
> +		port = &ports->ports[i];
> +		data = fm10k_read_switch_reg(sw,
> +		    FM10K_SW_EPL_LED_STATUS(port->eplno));
> +		led_flags =
> +		    ((data & FM10K_SW_EPL_LED_STATUS_PORT_LINK_UP(port-
> >first_lane)) ?
> +			FM10K_SW_EXT_PORT_LED_FLAG_UP : 0) |
> +		    ((data &
> +
> 	(FM10K_SW_EPL_LED_STATUS_PORT_TRANSMITTING(port->first_lane)
> |
> +
> FM10K_SW_EPL_LED_STATUS_PORT_RECEIVING(port->first_lane))) ?
> +			FM10K_SW_EXT_PORT_LED_FLAG_ACTIVE : 0);
> +		update_port[i] = (led_flags != port->last_led_flags);
> +		port->last_led_flags = led_flags;
> +	}
> +	FM10K_SW_SWITCH_UNLOCK(sw);
> +
> +	switch (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice)) {
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QS41):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QS41):
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QS43):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QS43):
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QL4):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QL4):
> +		FM10K_SW_I2C_REQ_LOCK(sw->i2c);
> +		/*
> +		 * Set up the first PCA9545 mux so we can get at the PCA9635
> +		 * that the LED control lines are connected to.
> +		 */
> +		fm10k_i2c_write8(sw->i2c, 0x70, 0x04);
> +
> +		if (!(update_port[0] || update_port[1])) {
> +			FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +			break;
> +		}
> +
> +		led_flags =
> +		    fm10k_switch_pca9635_led_bits(ports-
> >ports[0].last_led_flags) |
> +		    (fm10k_switch_pca9635_led_bits(ports-
> >ports[1].last_led_flags) << 2);
> +
> +		fm10k_i2c_write16(sw->i2c, 0x6a, 0x14, led_flags);
> +		FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +		break;
> +
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4_REV_2):
> +		FM10K_SW_I2C_REQ_LOCK(sw->i2c);
> +		/*
> +		 * Set up the first PCA9545 mux so we can get at the PCA9635s
> +		 * that the LED control lines are connected to.
> +		 */
> +		fm10k_i2c_write8(sw->i2c, 0x70, 0x01);
> +
> +		/* XXX will need to update for QSFPs operating as four
> independent lanes/ports */
> +		for (i = 0; i < 2; i++) {
> +			if (update_port[i] == 0)
> +				continue;
> +
> +			addr = (i == 0) ? 0x6a : 0x69;
> +
> +			port = &ports->ports[i];
> +			led_flags = fm10k_switch_pca9635_led_bits(port-
> >last_led_flags);
> +
> +			switch (port->lane_speed * port->num_lanes) {
> +			case 100:
> +				fm10k_i2c_write16(sw->i2c, addr, 0x14,
> led_flags);
> +				break;
> +			case 40:
> +				fm10k_i2c_write16(sw->i2c, addr, 0x14,
> led_flags << 6);
> +				break;
> +			}
> +		}
> +		FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +		break;
> +
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRL_QXSL4):
> +		FM10K_SW_I2C_REQ_LOCK(sw->i2c);
> +		led_flags = 0;
> +		addr = 0x62;
> +		for (i = 0; i < 2; i++) {
> +			if (!update_port[i])
> +				continue;
> +			port = &ports->ports[i];
> +			if (port->last_led_flags &
> FM10K_SW_EXT_PORT_LED_FLAG_UP) {
> +				switch (port->lane_speed * port->num_lanes) {
> +				case 100:
> +				case 25:
> +					led_flags |= 0x6<<(4*i); /* 100G */
> +					break;
> +				case 40:
> +				case 10:
> +					led_flags |= 0x4<<(4*i); /* 40G */
> +					break;
> +				default:
> +					led_flags = 0;
> +				}
> +			} else
> +				led_flags = 0; /* off */
> +		}
> +
> +		if (update_port[0] || update_port[1]) {
> +			fm10k_i2c_read8_ext(sw->i2c, addr, 0x1, &read);
> +			if(update_port[0])
> +				led_flags |= read&0xf0;
> +			else
> +				led_flags |= read&0xf;
> +			fm10k_i2c_write16(sw->i2c, addr, 0x1, led_flags);
> +			fm10k_i2c_read8_ext(sw->i2c, addr, 0x1, &read);
> +		}
> +		FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +		break;
> +
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4):
> +		FM10K_SW_I2C_REQ_LOCK(sw->i2c);
> +		/* XXX will need to update for QSFPs operating as four
> independent lanes/ports */
> +		for (i = 0; i < 2; i++) {
> +			if (!update_port[i])
> +				continue;
> +			/*
> +			 *	00000000: No link
> +			 *	00000001: 10G Port 0
> +			 *  00000010: 40G Port 0
> +			 *  00000100: 25G Port 0
> +			 *  00001000: 100G Port 0
> +			 */
> +			addr = (i == 0) ? 0x62 : 0x66;
> +			port = &ports->ports[i];
> +			if (port->last_led_flags &
> FM10K_SW_EXT_PORT_LED_FLAG_UP) {
> +				switch (port->lane_speed * port->num_lanes) {
> +				case 100:
> +					led_flags = 0x08; /* 100G */
> +					break;
> +				case 40:
> +					led_flags = 0x02; /* 40G */
> +					break;
> +				}
> +			} else
> +				led_flags = 0; /* off */
> +			fm10k_i2c_write16(sw->i2c, addr, 0x1, led_flags);
> +		}
> +		FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +		break;
> +	}
> +}
> +
> +static void *
> +fm10k_switch_leds_update(void *ctx)
> +{
> +	struct fm10k_switch *sw = ctx;
> +
> +	while (sw->detaching == 0) {
> +		fm10k_switch_process_leds(ctx);
> +		usec_delay(FM10K_LED_POLL_INTERVAL_MS * 1000);
> +	}
> +	return NULL;
> +}
> +
> +static void
> +fm10k_switch_leds_off(struct fm10k_switch *sw, struct fm10k_ext_ports
> *ports)
> +{
> +	struct fm10k_device_info *cfg = sw->info;
> +	struct fm10k_ext_port *port;
> +	unsigned int i;
> +	uint8_t led_flags;
> +	uint8_t addr;
> +
> +	switch (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice)) {
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QS41):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QS41):
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QS43):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QS43):
> +	case FM10K_SW_CARD(SILICOM, PE340G2DBIR_QL4):
> +	case FM10K_SW_CARD(SILICOM_RB, PE340G2DBIR_QL4):
> +		FM10K_SW_I2C_REQ_LOCK(sw->i2c);
> +		/*
> +		 * Set up the first PCA9545 mux so we can get at the PCA9635
> +		 * that the LED control lines are connected to.
> +		 */
> +		fm10k_i2c_write8(sw->i2c, 0x70, 0x04);
> +
> +		led_flags =
> +		    fm10k_switch_pca9635_led_bits(0) |
> +		    (fm10k_switch_pca9635_led_bits(0) << 2);
> +
> +		fm10k_i2c_write16(sw->i2c, 0x6a, 0x14, led_flags);
> +		FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +		break;
> +
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIR_QXSL4_REV_2):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRL_QXSL4):
> +	case FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4):
> +		FM10K_SW_I2C_REQ_LOCK(sw->i2c);
> +		/*
> +		 * Set up the first PCA9545 mux so we can get at the PCA9635s
> +		 * that the LED control lines are connected to.
> +		 */
> +		fm10k_i2c_write8(sw->i2c, 0x70, 0x01);
> +
> +		/* XXX will need to update for QSFPs operating as four
> independent lanes/ports */
> +		addr = 0x6a;
> +		led_flags = fm10k_switch_pca9635_led_bits(0);
> +		for (i = 0; i < 2; i++) {
> +			port = &ports->ports[i];
> +			switch (port->lane_speed * port->num_lanes) {
> +			case 100:
> +				fm10k_i2c_write16(sw->i2c, addr, 0x14,
> led_flags);
> +				break;
> +			case 40:
> +				fm10k_i2c_write16(sw->i2c, addr, 0x14,
> led_flags << 6);
> +				break;
> +			}
> +
> +			addr = 0x69;
> +		}
> +		FM10K_SW_I2C_REQ_UNLOCK(sw->i2c);
> +		break;
> +	}
> +}
> +
> +
> +static void *
> +fm10k_switch_process_intr(void *ctx)
> +{
> +	struct fm10k_switch *sw = ctx;
> +	struct fm10k_ext_ports *ports;
> +	uint64_t gid;
> +	uint64_t reenable_mask;
> +	uint16_t epl_mask;
> +
> +	while (1) {
> +		sem_wait(&sw->intr_tq);
> +
> +		/*
> +		 * Mask off all global interrupt detect interrupts toward PCIe to
> +		 * ensure that the PEP sees the interrupt condition clear so that
> +		 * all subsequent events will be recognized.  The same result
> could
> +		 * be achieved by masking off all block-internal interrupt
> sources
> +		 * in all blocks prior to handling any global interrupt detect
> +		 * interrupts, but the approach taken here makes the interrupt
> +		 * processing easier to decompose and increases the likelihood
> that
> +		 * more work will be coalesced into fewer interrupts.
> +		 */
> +		FM10K_SW_TRACE("masking off PCIe gid interrupts");
> +		FM10K_SW_SWITCH_LOCK(sw);
> +		/*
> +		 * sw->ext_ports will be set to NULL during detach to indicate
> that
> +		 * we are to no longer process EPL interrupts.
> +		 */
> +		ports = sw->ext_ports;
> +		/*
> +		 * sw->sm_mailbox_enabled will be set to 0 during detach to
> indicate
> +		 * that we are to no longer process PEP interrupts.
> +		 */
> +		fm10k_write_switch_reg64(sw,
> FM10K_SW_INTERRUPT_MASK_PCIE(sw->pepno),
> +			FM10K_SW_INTERRUPT_MASK_PCIE_ALL);
> +		gid = fm10k_read_switch_reg64(sw,
> FM10K_SW_GLOBAL_INTERRUPT_DETECT);
> +		FM10K_SW_SWITCH_UNLOCK(sw);
> +
> +		reenable_mask = 0;
> +		if (ports) {
> +			epl_mask = fm10k_ext_ports_epl_intrs(ports, gid);
> +			reenable_mask |=
> +
> 	FM10K_SW_MAKE_REG_FIELD64(INTERRUPT_MASK_PCIE_EPL,
> epl_mask);
> +		}
> +
> +		if (gid & FM10K_SW_GLOBAL_INTERRUPT_DETECT_I2C)
> +			fm10k_i2c_intr(sw->i2c);
> +
> +		reenable_mask |= FM10K_SW_INTERRUPT_MASK_PCIE_I2C;
> +
> +		FM10K_SW_TRACE("re-enabling PCIe gid interrupts");
> +		FM10K_SW_SWITCH_LOCK(sw);
> +		fm10k_write_switch_reg64(sw,
> FM10K_SW_INTERRUPT_MASK_PCIE(sw->pepno),
> +			~reenable_mask);
> +		FM10K_SW_SWITCH_UNLOCK(sw);
> +	}
> +	return NULL;
> +}
> +
> +void
> +fm10k_switch_intr(struct fm10k_hw* hw)
> +{
> +	if (hw)
> +		sem_post(&fm10k_sw.intr_tq);
> +}
> +
> +
> +static void
> +fm10k_switch_enable_interrupts(struct fm10k_switch *sw)
> +{
> +	uint64_t data64;
> +	unsigned int i;
> +
> +	data64 =
> +	    fm10k_read_switch_reg64(sw,
> FM10K_SW_INTERRUPT_MASK_PCIE(sw->pepno));
> +
> +	/* enable interrupts from all EPLs in use */
> +	FM10K_SW_REPLACE_REG_FIELD64(data64,
> INTERRUPT_MASK_PCIE_EPL,
> +	    ~sw->ext_ports->epl_mask);
> +
> +	/* enable interrupts from all non-master PEPs in use */
> +	FM10K_SW_REPLACE_REG_FIELD64(data64,
> INTERRUPT_MASK_PCIE_PCIE,
> +	    ~sw->pep_mask);
> +
> +	/* enable I2C interrupt */
> +	data64 &= ~FM10K_SW_INTERRUPT_MASK_PCIE_I2C;
> +	fm10k_write_switch_reg64(sw,
> FM10K_SW_INTERRUPT_MASK_PCIE(sw->pepno), data64);
> +
> +	/* enable outbound mailbox interrupts from all non-master PEPs */
> +	for (i = 0; i < FM10K_SW_PEPS_MAX; i++) {
> +		if (sw->pep_mask & (1 << i))
> +			fm10k_write_switch_reg(sw,
> FM10K_SW_PCIE_GLOBAL(i, IM),
> +			    ~FM10K_SW_IM_MAILBOX);
> +	}
> +	FM10K_WRITE_REG(sw->master_hw, FM10K_SW_EIMR,
> FM10K_SW_EIMR_FIELD(SWITCH_INT, ENABLE));
> +}
> +
> +
> +static void
> +fm10k_switch_detach(struct fm10k_hw *hw)
> +{
> +	struct fm10k_ext_ports *ports;
> +	struct fm10k_switch* sw = &fm10k_sw;
> +
> +	if (hw == NULL || sw == NULL)
> +		return;
> +
> +	FM10K_SW_SWITCH_LOCK(sw);
> +	sw->detaching = 1;
> +	FM10K_SW_SWITCH_UNLOCK(sw);
> +
> +	if (sw->ext_ports) {
> +		ports = sw->ext_ports;
> +		/*
> +		 * Ensure that any further switch interrupts will not
> +		 * process sw->ext_ports before detaching them.
> +		 */
> +		FM10K_SW_SWITCH_LOCK(sw);
> +		sw->ext_ports = NULL;
> +		FM10K_SW_SWITCH_UNLOCK(sw);
> +		fm10k_switch_leds_off(sw, ports);
> +		fm10k_ext_ports_detach(ports);
> +	}
> +
> +	if (sw->epl_sbus)
> +		fm10k_sbus_detach(sw->epl_sbus);
> +
> +	/*
> +	 * Detach i2c after ext_ports so ext_ports can use i2c to disable
> +	 * phys.
> +	 */
> +	if (sw->i2c)
> +		fm10k_i2c_detach(sw->i2c);
> +
> +	fm10k_hw_eicr_disable_source(sw, FM10K_SW_EICR_SWITCH_INT);
> +}
> +
> +
> +static unsigned int
> +fm10k_switch_get_fabric_clock(struct fm10k_switch *sw)
> +{
> +	uint32_t pll_fabric;
> +	unsigned int freq;
> +
> +	pll_fabric = fm10k_read_switch_reg(sw, FM10K_SW_PLL_FABRIC_LOCK);
> +
> +	switch (FM10K_SW_REG_FIELD(pll_fabric, PLL_FABRIC_FREQSEL)) {
> +	case FM10K_SW_PLL_FABRIC_FREQSEL_CTRL: {
> +		uint32_t ctrl;
> +		unsigned int refdiv, fbdiv4, fbdiv255;
> +
> +		ctrl = fm10k_read_switch_reg(sw,
> FM10K_SW_PLL_FABRIC_CTRL);
> +		refdiv = FM10K_SW_REG_FIELD(ctrl, PLL_FABRIC_REFDIV);
> +		fbdiv4 = FM10K_SW_REG_FIELD(ctrl, PLL_FABRIC_FBDIV4);
> +		fbdiv255 = FM10K_SW_REG_FIELD(ctrl, PLL_FABRIC_FBDIV255);
> +
> +		freq = (15625 * 4 * fbdiv255 * (1 + fbdiv4)) / (refdiv * 100);
> +		break;
> +	}
> +	case FM10K_SW_PLL_FABRIC_FREQSEL_F600: freq = 600; break;
> +	case FM10K_SW_PLL_FABRIC_FREQSEL_F500: freq = 500; break;
> +	case FM10K_SW_PLL_FABRIC_FREQSEL_F400: freq = 400; break;
> +	case FM10K_SW_PLL_FABRIC_FREQSEL_F300: freq = 300; break;
> +	default:
> +		freq = 0;
> +		break;
> +	}
> +
> +	return (freq);
> +}
> +
> +static unsigned int
> +fm10k_switch_get_sku(struct fm10k_switch *sw)
> +{
> +	uint32_t fuse_data;
> +
> +	fuse_data = fm10k_read_switch_reg(sw, FM10K_SW_FUSE_DATA_0);
> +	return (FM10K_SW_REG_FIELD(fuse_data, FUSE_SKU));
> +}
> +
> +static const char *
> +fm10k_switch_get_sku_name(unsigned int sku)
> +{
> +	const char *name;
> +
> +	switch (sku) {
> +	case FM10K_SW_FUSE_SKU_FM10840: name = "FM10840"; break;
> +	case FM10K_SW_FUSE_SKU_FM10420: name = "FM10420"; break;
> +	case FM10K_SW_FUSE_SKU_FM10064: name = "FM10064"; break;
> +	default: name = "FM10xxx-unknown"; break;
> +	}
> +
> +	return (name);
> +}
> +
> +
> +static void
> +fm10k_switch_describe(struct fm10k_switch *sw)
> +{
> +	unsigned int i, pair;
> +	unsigned int reset_state, active_state;
> +	uint32_t device_cfg, resets;
> +
> +	if (!FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_CONFIG))
> +		return;
> +
> +	FM10K_SW_INFO("switch: device is %s, fabric clock %u MHz",
> +	    fm10k_switch_get_sku_name(fm10k_switch_get_sku(sw)),
> +	    fm10k_switch_get_fabric_clock(sw));
> +
> +	device_cfg = fm10k_read_switch_reg(sw, FM10K_SW_DEVICE_CFG);
> +	FM10K_SW_INFO("switch: 100G Ethernet is %s",
> +	    (device_cfg & FM10K_SW_DEVICE_CFG_PCIE_100G_DIS) ?
> +	    "disabled" : "enabled");
> +	switch (FM10K_SW_REG_FIELD(device_cfg, DEVICE_CFG_FEATURE)) {
> +	case FM10K_SW_DEVICE_CFG_PCIE_FULL:
> +		FM10K_SW_INFO("switch: PEPs 0-7 support 2x4 and 1x8 "
> +		    "modes, PEP 8 is x1");
> +		break;
> +	case FM10K_SW_DEVICE_CFG_PCIE_HALF:
> +		FM10K_SW_INFO("switch: PEPs 0-3 support 2x4 and 1x8 "
> +		    "modes, PEPs 4 and 6 are 1x4, PEP 8 is x1");
> +		break;
> +	case FM10K_SW_DEVICE_CFG_PCIE_BASIC:
> +		FM10K_SW_INFO("switch: PEP 0 supports, PEP 8 is x1, "
> +		    "only one can be used");
> +		break;
> +	}
> +
> +	resets = fm10k_read_switch_reg(sw, FM10K_SW_SOFT_RESET);
> +	for (i = 0; i < FM10K_SW_PEPS_MAX; i++) {
> +		if (!(device_cfg & FM10K_SW_DEVICE_CFG_PCIE_EN(i)))
> +			continue;
> +
> +		pair = i / 2;
> +		reset_state = !!(resets &
> FM10K_SW_SOFT_RESET_PCIE_RESET(i));
> +		active_state = !!(resets &
> FM10K_SW_SOFT_RESET_PCIE_ACTIVE(i));
> +		if ((pair < FM10K_SW_DEVICE_CFG_PCIE_MODE_PAIRS) &&
> +		    !(device_cfg &
> FM10K_SW_DEVICE_CFG_PCIE_MODE_2X4(pair))) {
> +			if (i % 2 == 0)
> +				FM10K_SW_INFO("switch: PEP[%u,%u] is
> enabled in 1x8 "
> +				    "mode (Reset=%u, Active=%u)", i, i + 1,
> +				    reset_state, active_state);
> +			else
> +				FM10K_SW_INFO("switch: PEP[%u]
> unexpectedly enabled when "
> +				    "PEP[%u,%u] is in 1x8 mode (Reset=%u, "
> +				    "Active=%u)", i, i - 1, i, reset_state,
> +				    active_state);
> +		} else {
> +			FM10K_SW_INFO("switch: PEP[%u] is enabled in 1x4 "
> +			    "mode (Reset=%u, Active=%u)", i, reset_state,
> +			    active_state);
> +		}
> +	}
> +}
> +
> +
> +static struct fm10k_switch *
> +fm10k_switch_attach(struct fm10k_hw *hw, struct fm10k_switch* sw)
> +{
> +	int i;
> +	int error = 0;
> +
> +	/*
> +	 * XXX apparently no way to determine one's own PEP number.
> +	 */
> +	switch (sw->info->num_peps) {
> +	case 1:
> +		sw->pepno = 0;
> +		break;
> +
> +	case 2:
> +		/*
> +		 * XXX assumption is using even numbered PEPs starting with 0,
> and
> +		 * the highest numbered PEP is the master
> +		 */
> +		sw->pepno = 2;
> +		for (i = 0; i < sw->info->num_peps - 1; i++) {
> +			sw->pep_mask |= (1 << (i * 2));
> +		}
> +		break;
> +
> +	case 4:
> +		sw->pepno = 6;
> +		sw->pep_mask = 0x7f;
> +		break;
> +
> +	default:
> +		sw->pepno = 0;
> +	}
> +
> +	/* When not zero, initialize serdes in 'near loopback' mode */
> +	sw->serdes_loopback = 0;
> +
> +	pthread_mutex_init(&sw->lock, NULL);
> +
> +	fm10k_switch_determine_epls(sw);
> +
> +	sw->ext_ports = fm10k_ext_ports_attach(sw);
> +	if (sw->ext_ports == NULL)
> +		goto fail;
> +
> +	/* label all external ports with their logical port numbers */
> +	for (i = 0; i < sw->ext_ports->num_ports; i++)
> +		sw->ext_ports->ports[i].lport = sw->epl_map[i].logical_port;
> +
> +	/* interrupt */
> +	sem_init(&sw->intr_tq, 0, 0);
> +	pthread_create(&sw->intr_task, NULL, fm10k_switch_process_intr, sw);
> +
> +	fm10k_switch_enable_interrupts(sw);
> +	fm10k_switch_describe(sw);
> +
> +	sw->i2c = fm10k_i2c_attach(sw);
> +	if (sw->i2c == NULL)
> +		goto fail;
> +
> +	error = fm10k_switch_init(hw, sw);
> +	if (error)
> +		goto fail;
> +
> +	for (i = 0; i < sw->ext_ports->num_ports; i++) {
> +		fm10k_ext_port_up(&sw->ext_ports->ports[i]);
> +	}
> +
> +	usec_delay(10000);
> +	fm10k_switch_leds_init(sw);
> +
> +	pthread_create(&sw->led_task, NULL, &fm10k_switch_leds_update,
> sw);
> +	pthread_create(&sw->stats_task, NULL, &fm10k_switch_process_stats,
> sw);
> +	sw->inited = 1;
> +	return (sw);
> +fail:
> +	if (sw != NULL)
> +		fm10k_switch_detach(hw);
> +	return (NULL);
> +}
> +
> +struct fm10k_switch*
> +fm10k_switch_get(void)
> +{
> +	return &fm10k_sw;
> +}
> +
> +static int
> +fm10k_switch_dpdk_port_get(struct fm10k_switch *sw, int pf_no)
> +{
> +	int i;
> +
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		if (sw->dpdk_cfg->ports[i].pf_no == pf_no)
> +			return i;
> +	}
> +	return -1;
> +}
> +#if 0
> +static int
> +fm10k_switch_mapped_dpdk_port_get(struct fm10k_switch *sw, int pf_no)
> +{
> +	int i, j;
> +
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		if (sw->dpdk_cfg->dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PF) {
> +			if (sw->dpdk_cfg->dpdk_port_map[i].map_no[0] ==
> pf_no)
> +				return i;
> +		} else if (sw->dpdk_cfg->dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PFS ||
> +				sw->dpdk_cfg->dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PFSS) {
> +			if (sw->dpdk_cfg->dpdk_port_map[i].map_no[0] ==
> pf_no ||
> +					sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[1] == pf_no)
> +				return i;
> +		}
> +	}
> +	return -1;
> +}
> +#endif
> +static int
> +fm10k_switch_mapped_ext_port_get(struct fm10k_switch *sw, int pf_no)
> +{
> +	int i;
> +
> +	for (i = 0; i < FM10K_SW_EXT_PORTS_MAX; i++) {
> +		if (sw->dpdk_cfg->ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PF) {
> +			if (sw->dpdk_cfg->ext_port_map[i].map_no[0] ==
> pf_no)
> +				return i;
> +		} else if (sw->dpdk_cfg->ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PFS) {
> +			if (sw->dpdk_cfg->ext_port_map[i].map_no[0] ==
> pf_no ||
> +					sw->dpdk_cfg-
> >ext_port_map[i].map_no[1] == pf_no)
> +				return i;
> +		}
> +	}
> +	return -1;
> +}
> +
> +static int
> +fm10k_switch_start(struct fm10k_switch *sw,
> +		struct fm10k_hw* master_hw, eth_fm10k_dev_init_half_func
> *func)
> +{
> +	int i, j;
> +	struct fm10k_dpdk_port *port;
> +	int dpdk_port_no, ext_port_no = 0;
> +	int pf_no;
> +
> +	sw->info = fm10k_get_device_info(master_hw);
> +	sw->master_hw = master_hw;
> +	sw->pep_map = fm10k_pep_port_map;
> +	sw->epl_map = fm10k_epl_port_map;
> +
> +	sw->info->ext_port_speed = sw->dpdk_cfg->ext_port_speed;
> +	fm10k_switch_set_sched_prog();
> +	fm10k_switch_attach(master_hw, &fm10k_sw);
> +
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		port = &sw->dpdk_cfg->ports[i];
> +		if (port->type == FM10K_CONFIG_DPDK_PF &&
> +				sw->dpdk_cfg->dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PFS) {
> +			for (j = 0; j< 2; j++) {
> +				pf_no = sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[j];
> +				dpdk_port_no =
> fm10k_switch_dpdk_port_get(sw, pf_no);
> +				if (sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].type == FM10K_CONFIG_PORT_MAP_PF) {
> +					sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].type = FM10K_CONFIG_PORT_MAP_PFSS;
> +					sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].map_no[0] = sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[0];
> +					sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].map_no[1] = sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[1];
> +				}
> +			}
> +		}
> +	}
> +
> +	/* do initialze all ports, after switch is ready */
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		uint32_t sglort;
> +		struct fm10k_dpdk_port *port = &sw->dpdk_cfg->ports[i];
> +		struct fm10k_hw *hw = port->hw;
> +
> +		if (hw == NULL)
> +			break;
> +
> +		if (port->type == FM10K_CONFIG_DPDK_PF)	{
> +			pf_no = fm10k_switch_dpdk_pf_no_get(hw);
> +			if (sw->dpdk_cfg->ext_port_map[ext_port_no].type ==
> FM10K_CONFIG_PORT_MAP_PF) {
> +				sglort = fm10k_switch_pf_glort_get(pf_no);
> +			} else if (sw->dpdk_cfg-
> >ext_port_map[ext_port_no].type == FM10K_CONFIG_PORT_MAP_PFS) {
> +				ext_port_no =
> fm10k_switch_mapped_ext_port_get(sw, pf_no);
> +				sglort = fm10k_switch_pfs_glort_get(
> +					sw->dpdk_cfg-
> >ext_port_map[ext_port_no].map_no[0],
> +					sw->dpdk_cfg-
> >ext_port_map[ext_port_no].map_no[1]);
> +			} else {
> +				FM10K_SW_ERR("Unknown mapped port
> type %d!", port->type);
> +				return -1;
> +			}
> +			hw->mac.dglort_map = sglort | 0xffff0000;
> +		}
> +		func(hw);
> +	}
> +	return 0;
> +}
> +
> +
> +static int
> +fm10k_switch_dpdk_port_reg(struct fm10k_switch *sw,
> +		struct fm10k_hw* hw, uint8_t is_pf, bool master)
> +{
> +	int i;
> +	struct fm10k_dpdk_port* port;
> +
> +	if (sw->dpdk_cfg == NULL && is_pf) {
> +		if (fm10k_config_init(sw, hw) < 0)
> +			return -1;
> +	}
> +
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		port = &sw->dpdk_cfg->ports[i];
> +		if (master && port->hw &&
> +				port->type == FM10K_CONFIG_DPDK_PF) {
> +			port->pf_no = sw->dpdk_cfg->pf_max - 1 -
> +					(hw->mac.addr[5] - port->hw-
> >mac.addr[5]);
> +			sw->dpdk_cfg->pf_hw[port->pf_no] = port->hw;
> +		}
> +
> +		if (port->hw == NULL) {
> +			port->hw = hw;
> +			if (is_pf) {
> +				sw->dpdk_cfg->pf_bind ++;
> +				port->type = FM10K_CONFIG_DPDK_PF;
> +				if (sw->dpdk_cfg->dpdk_port_map[i].type
> +						==
> FM10K_CONFIG_PORT_MAP_NULL) {
> +					sw->dpdk_cfg->dpdk_port_map[i].type
> = FM10K_CONFIG_PORT_MAP_PF;
> +					sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[0] = i;
> +				}
> +			} else
> +				port->type = FM10K_CONFIG_DPDK_VF;
> +			if (master)
> +				sw->dpdk_cfg->master_hw = hw;
> +			if (sw->dpdk_cfg->master_hw) {
> +				port->pf_no = sw->dpdk_cfg->pf_max - 1 -
> +						(sw->dpdk_cfg->master_hw-
> >mac.addr[5] - hw->mac.addr[5]);
> +				sw->dpdk_cfg->pf_hw[port->pf_no] = port-
> >hw;
> +			}
> +
> +			return 0;
> +		}
> +	}
> +	return -1;
> +}
> +
> +int
> +fm10k_switch_dpdk_port_no_get(struct fm10k_hw *hw)
> +{
> +	int i;
> +
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		if (fm10k_sw.dpdk_cfg->ports[i].hw == NULL)
> +			break;
> +
> +		if (fm10k_sw.dpdk_cfg->ports[i].hw == hw)
> +			return i;
> +	}
> +	return -1;
> +}
> +
> +
> +static int
> +fm10k_switch_dpdk_cfg_check(struct fm10k_switch *sw)
> +{
> +	int i;
> +	bool need_default = true;
> +	struct fm10k_dpdk_port* port;
> +
> +	if (sw->dpdk_cfg->master_hw == NULL) {
> +		FM10K_SW_ERR("Master PF is not bound!!!");
> +		return -1;
> +	}
> +
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		port = &sw->dpdk_cfg->ports[i];
> +		if (port->type == FM10K_CONFIG_DPDK_PF &&
> +				sw->dpdk_cfg->dpdk_port_map[i].type !=
> FM10K_CONFIG_PORT_MAP_NULL) {
> +			need_default = false;
> +			break;
> +		}
> +	}
> +
> +	if (need_default) {
> +		for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +			if (port->type == FM10K_CONFIG_DPDK_PF) {
> +				sw->dpdk_cfg->dpdk_port_map[i].type =
> FM10K_CONFIG_PORT_MAP_PF;
> +				sw->dpdk_cfg->dpdk_port_map[i].map_no[0] =
> i;
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +
> +static void
> +fm10k_switch_dpdk_cfg_describe(struct fm10k_switch* sw)
> +{
> +	int i;
> +
> +	if (!FM10K_CONFIG_CHECK_DEBUG(sw->dpdk_cfg,
> FM10K_CONFIG_DEBUG_CONFIG))
> +		return;
> +
> +	printf("--- FM10K DYNAMIC CONFIG ---\n");
> +	printf("  PF Bind  : %d\n", sw->dpdk_cfg->pf_bind);
> +
> +	printf("--- PF ---\n");
> +	for (i = 0; i < FM10K_SW_PEPS_MAX; i++)	{
> +		uint8_t *mac;
> +		struct rte_eth_dev *dev;
> +		struct rte_pci_device *pdev;
> +
> +		if (sw->dpdk_cfg->pf_hw[i] == NULL)
> +			continue;
> +
> +		dev = (struct rte_eth_dev*)(sw->dpdk_cfg->pf_hw[i]->rte_dev);
> +		pdev = RTE_ETH_DEV_TO_PCI(dev);
> +		mac = sw->dpdk_cfg->pf_hw[i]->mac.addr;
> +		printf("  PF%d : Logical %d Glort %#x PCI Addr %02x:%02x.%x
> MAC Addr %02x:%02x:%02x:%02x:%02x:%02x\n",
> +				i, fm10k_pep_port_map[i].logical_port,
> +				fm10k_switch_pf_glort_get(i), pdev->addr.bus,
> +				pdev->addr.devid,
> +				pdev->addr.function,
> +				mac[0], mac[1], mac[2], mac[3], mac[4],
> mac[5]);
> +	}
> +
> +	printf("--- DPDK PORT ---\n");
> +	for (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {
> +		if (sw->dpdk_cfg->ports[i].type == FM10K_CONFIG_DPDK_NULL)
> +			break;
> +		if (sw->dpdk_cfg->dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_NULL)
> +			break;
> +		if (sw->dpdk_cfg->dpdk_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PF) {
> +			printf("  DPDK PORT%d : Map to PF%d\n", i,
> +					sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[0]);
> +		} else {
> +			printf("  DPDK PORT%d : Map to PF%d&PF%d
> Glort %#x\n", i,
> +					sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[0],
> +					sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[1],
> +					fm10k_switch_pfs_glort_get(sw-
> >dpdk_cfg->dpdk_port_map[i].map_no[0],
> +					sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[1]));
> +		}
> +	}
> +
> +	printf("--- EXT PORT ---\n");
> +	for (i = 0; i < sw->dpdk_cfg->ext_port_num; i++) {
> +		printf("  EXT  PORT%d : Logical %d Glort %#x", i,
> +				fm10k_epl_port_map[i].logical_port,
> +				fm10k_switch_epl_glort_get(i));
> +
> +		if (sw->dpdk_cfg->ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_NULL)
> +			printf("\n");
> +		else if (sw->dpdk_cfg->ext_port_map[i].type ==
> FM10K_CONFIG_PORT_MAP_PF)
> +			printf(" Map to PF%d\n", sw->dpdk_cfg-
> >ext_port_map[i].map_no[0]);
> +		else {
> +			printf(" Map to PF%d&PF%d Glort %#x\n",
> +					sw->dpdk_cfg-
> >ext_port_map[i].map_no[0], sw->dpdk_cfg->ext_port_map[i].map_no[1],
> +					fm10k_switch_pfs_glort_get(sw-
> >dpdk_cfg->dpdk_port_map[i].map_no[0], sw->dpdk_cfg-
> >dpdk_port_map[i].map_no[1]));
> +		}
> +	}
> +}
> +
> +
> +int
> +fm10k_switch_dpdk_port_start(struct fm10k_hw* hw,
> +		uint8_t is_pf, bool master, eth_fm10k_dev_init_half_func *func)
> +{
> +	int ret;
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	if (fm10k_switch_dpdk_port_reg(sw, hw, is_pf, master) != 0)	{
> +		FM10K_SW_ERR("Register ports failed!!!");
> +		return -1;
> +	}
> +
> +	/*
> +	 * After all pfs are started
> +	 * start switch here
> +	 */
> +	if (fm10k_sw.dpdk_cfg->pf_max != 0 &&
> +			fm10k_sw.dpdk_cfg->pf_bind == fm10k_sw.dpdk_cfg-
> >pf_num) {
> +		if (fm10k_switch_dpdk_cfg_check(&fm10k_sw) != 0)
> +			return -1;
> +
> +		ret = fm10k_switch_start(&fm10k_sw, fm10k_sw.dpdk_cfg-
> >master_hw, func);
> +		fm10k_switch_dpdk_cfg_describe(&fm10k_sw);
> +		return ret;
> +	}
> +	return 0;
> +}
> +
> +void fm10k_switch_dpdk_port_stop(struct fm10k_hw* hw)
> +{
> +	if (hw)
> +		return;
> +}
> +
> +
> +/*
> + * for multi-host, only dpdk port 0 and 1 are real rx/tx packets
> + * so we need init/setup/start dpdk port queue for them.
> + * for dpdk port 2/3, we need init/setup except start.
> + * we map the pf queue to 0/1 dpdk queue first, then map the other pf queue to
> 2/3 dpdk queue.
> + */
> +int
> +fm10k_switch_dpdk_hw_queue_map(struct fm10k_hw *hw,
> +		uint16_t queue, uint16_t max_queue, struct fm10k_hw
> **map_hw, uint16_t* map_queue)
> +{
> +	int idx, pf_no;
> +	int dpdk_port_no = fm10k_switch_dpdk_port_no_get(hw);
> +	struct fm10k_dpdk_port *port;
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	if (dpdk_port_no < 0) {
> +		FM10K_SW_ERR("Can not find the dpdk port!!!");
> +		return -1;
> +	}
> +
> +	port = &sw->dpdk_cfg->ports[dpdk_port_no];
> +
> +	if (port->type == FM10K_CONFIG_DPDK_VF) {
> +		FM10K_SW_ERR("Not support yet!!!");
> +		return -1;
> +	}
> +
> +	if (port->type != FM10K_CONFIG_DPDK_PF) {
> +		FM10K_SW_ERR("Can not be here!!!");
> +		return -1;
> +	}
> +
> +	if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type ==
> +			FM10K_CONFIG_PORT_MAP_PF) {
> +		pf_no = sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].map_no[0];
> +		*map_hw = sw->dpdk_cfg->pf_hw[pf_no];
> +		*map_queue = queue;
> +		return 1;
> +	} else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type ==
> +			FM10K_CONFIG_PORT_MAP_PFS) {
> +		idx = queue%2;
> +		pf_no = sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].map_no[idx];
> +		*map_hw = sw->dpdk_cfg->pf_hw[pf_no];
> +		*map_queue = queue/2;
> +		return 1;
> +	} else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type ==
> +			FM10K_CONFIG_PORT_MAP_PFSS) {
> +		idx = queue%2;
> +		pf_no = sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].map_no[idx];
> +		*map_hw = sw->dpdk_cfg->pf_hw[pf_no];
> +		*map_queue = (max_queue+1)/2 + queue/2;
> +		return 0;
> +	} else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type ==
> +			FM10K_CONFIG_PORT_MAP_NULL) {
> +		FM10K_SW_ERR("Unmapped dpdk port %d!!!", dpdk_port_no);
> +		return -1;
> +	}
> +	FM10K_SW_ERR("Unknown mapped type!!!");
> +	return -1;
> +}
> +
> +int
> +fm10k_switch_dpdk_mapped_hw_get(struct fm10k_hw *hw, struct fm10k_hw
> *hw_list[])
> +{
> +	int pf_no, pf_no_ext;
> +	int dpdk_port_no = fm10k_switch_dpdk_port_no_get(hw);
> +	struct fm10k_dpdk_port *port;
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	if (dpdk_port_no < 0) {
> +		FM10K_SW_ERR("Can not find the dpdk port!!!");
> +		return -1;
> +	}
> +
> +	port = &sw->dpdk_cfg->ports[dpdk_port_no];
> +
> +	if (port->type == FM10K_CONFIG_DPDK_VF) {
> +		hw_list[0] = hw;
> +		hw_list[1] = NULL;
> +		return 1;
> +	}
> +
> +	if (port->type != FM10K_CONFIG_DPDK_PF) {
> +		FM10K_SW_ERR("Can not be here!!!");
> +		return -1;
> +	} else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type ==
> +			FM10K_CONFIG_PORT_MAP_PF) {
> +		pf_no = sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].map_no[0];
> +		hw_list[0] = sw->dpdk_cfg->pf_hw[pf_no];
> +		hw_list[1] = NULL;
> +		return 1;
> +	} else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type ==
> +
> 	FM10K_CONFIG_PORT_MAP_PFS) {
> +		pf_no = sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].map_no[0];
> +		hw_list[0] = sw->dpdk_cfg->pf_hw[pf_no];
> +		pf_no_ext = sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].map_no[1];
> +		hw_list[1] = sw->dpdk_cfg->pf_hw[pf_no_ext];
> +		return 2;
> +	} else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type ==
> +
> 	FM10K_CONFIG_PORT_MAP_PFSS) {
> +			pf_no = sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].map_no[0];
> +			hw_list[0] = sw->dpdk_cfg->pf_hw[pf_no];
> +			pf_no_ext = sw->dpdk_cfg-
> >dpdk_port_map[dpdk_port_no].map_no[1];
> +			hw_list[1] = sw->dpdk_cfg->pf_hw[pf_no_ext];
> +			return 0;
> +	}
> +
> +	hw_list[0] = NULL;
> +	hw_list[1] = NULL;
> +	return 0;
> +}
> +
> +void
> +fm10k_switch_dpdk_tx_queue_num_set(struct fm10k_hw *hw, uint8_t num)
> +{
> +	int port_no = fm10k_switch_dpdk_port_no_get(hw);
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	if (port_no < 0) {
> +		FM10K_SW_ERR("Can not find the dpdk port!!!");
> +		return;
> +	}
> +
> +	sw->dpdk_cfg->ports[port_no].tx_queue_num = num;
> +}
> +
> +void
> +fm10k_switch_dpdk_rx_queue_num_set(struct fm10k_hw *hw, uint8_t num)
> +{
> +	int port_no = fm10k_switch_dpdk_port_no_get(hw);
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	if (port_no < 0) {
> +		FM10K_SW_ERR("Can not find the dpdk port!!!");
> +		return;
> +	}
> +
> +	sw->dpdk_cfg->ports[port_no].rx_queue_num = num;
> +}
> +
> +int
> +fm10k_switch_dpdk_pf_no_get(struct fm10k_hw *hw)
> +{
> +	int port_no = fm10k_switch_dpdk_port_no_get(hw);
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	if (port_no < 0) {
> +		FM10K_SW_ERR("Can not find the dpdk port!!!");
> +		return -1;
> +	}
> +
> +	return sw->dpdk_cfg->ports[port_no].pf_no;
> +}
> +
> +
> +void
> +fm10k_switch_flowset_switchto(const char *name)
> +{
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	fm10k_ffu_flowset_switch(sw, name);
> +}
> +
> +void
> +fm10k_switch_show_port(void)
> +{
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	fm10k_stats_epl_port_print(sw);
> +	fm10k_stats_dpdk_port_print(sw);
> +}
> +
> +void
> +fm10k_switch_show_ffu(void)
> +{
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	fm10k_stats_ffu_count_print(sw);
> +}
> +
> +void
> +fm10k_switch_show_bank(void)
> +{
> +	struct fm10k_switch *sw = fm10k_switch_get();
> +
> +	fm10k_stats_port_bank_print(sw);
> +}
> diff --git a/drivers/net/fm10k/switch/fm10k_switch.h
> b/drivers/net/fm10k/switch/fm10k_switch.h
> new file mode 100644
> index 0000000..de495e5
> --- /dev/null
> +++ b/drivers/net/fm10k/switch/fm10k_switch.h
> @@ -0,0 +1,341 @@
> +/***************************************************************
> ****************
> +
> +Copyright 2019   Silicom Ltd. Connectivity Solutions
> +
> +Licensed under the Apache License, Version 2.0 (the "License");
> +you may not use this file except in compliance with the License.
> +You may obtain a copy of the License at
> +
> +    http://www.apache.org/licenses/LICENSE-2.0
> +
> +Unless required by applicable law or agreed to in writing, software
> +distributed under the License is distributed on an "AS IS" BASIS,
> +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +See the License for the specific language governing permissions and
> +limitations under the License.
> +
> +****************************************************************
> ***********/
> +#ifndef _FM10K_SW_SWITCH_H_
> +#define _FM10K_SW_SWITCH_H_
> +
> +#include <rte_spinlock.h>
> +#include <pthread.h>
> +#include <sys/time.h>
> +#include <semaphore.h>
> +
> +#include "../fm10k.h"
> +#include "fm10k_debug.h"
> +#include "fm10k_regs.h"
> +
> +
> +/*
> + * EPL
> + */
> +#define FM10K_SW_EXT_PORTS_MAX	4
> +
> +#define FM10K_SW_EPLS_MAX		9
> +#define FM10K_SW_EPLS_SUPPORTED	2
> +#define FM10K_SW_EPL_LANES		4
> +#define FM10K_SW_EPLS_PEP_MAX	2
> +
> +/*
> + * PEP
> + */
> +#define FM10K_SW_PEP_GROUP_MAX	10
> +#define FM10K_SW_LOGICAL_PORTS_MAX	48
> +
> +#define FM10K_SW_PEPS_MAX		9
> +#define FM10K_SW_PEPS_SUPPORTED	4
> +#define FM10K_SW_PEP_PORTS_MAX	4
> +
> +/*
> + * GLORT
> + */
> +#define FM10K_SW_GROUP_MAX			10
> +#define FM10K_SW_VFS_MAX			64
> +#define FM10K_SW_PFS_GLORT_START	0x1000
> +#define FM10K_SW_VF_GLORT_START		0x2000
> +#define FM10K_SW_MULTI_GLORT_START	0x3000
> +#define FM10K_SW_DPORT_MASK(lport) (1ULL << (lport))
> +
> +
> +/*
> + * CONFIG
> + */
> +#define FM10K_SW_CONFIG_MAX			1000
> +#define FM10K_SW_FFU_RULE_MAX		256
> +#define FM10K_SW_FFU_RULE_ITEM_MAX	10
> +
> +/*
> + * FFU COUNT
> + */
> +#define FM10K_SW_FFU_CNT_BANK	3
> +#define FM10K_SW_POLICER_LAST	19
> +#define FM10K_SW_FFU_CNT_START 	(FM10K_SW_POLICER_LAST+1)
> +#define FM10K_SW_FFU_CNT_MAX	100
> +
> +#define FM10K_SW_PEP_QUEUES_MAX 256
> +#define FM10K_SW_VF_QUEUES_MAX	(FM10K_SW_PEP_QUEUES_MAX - 1) /*
> Need 1 queue for PF */
> +
> +#define FM10K_SW_FTAG_SIZE		8
> +#define FM10K_SW_PACKET_SIZE_MIN	17
> +#define FM10K_SW_PACKET_SIZE_MAX	(15*1024)
> +#define FM10K_SW_MTU_MAX
> 	(FM10K_SW_PACKET_SIZE_MAX - ETHER_HDR_LEN -
> ETHER_VLAN_ENCAP_LEN)
> +#define FM10K_SW_SEG_SIZE_MAX	(16*1024)
> +#define FM10K_SW_TSO_SIZE_MAX	(256*1024 - 1)
> +
> +#define FM10K_SW_MEM_POOL_SEG_SIZE	192
> +#define FM10K_SW_MEM_POOL_SEGS_MAX	24576
> +#define FM10K_SW_MEM_POOL_SEGS_RSVD	256
> +
> +
> +
> +#define FM10K_SW_CARD_ID(v_, d_)	(((v_) << 16) | (d_))
> +#define FM10K_SW_CARD(vname_, dname_) \
> +		FM10K_SW_CARD_ID(FM10K_SW_VENDOR_ID_##vname_,
> FM10K_SW_DEV_ID_##dname_)
> +
> +/*
> + * All IDs that may appear in the vendor ID or subsystem vendor ID.
> + */
> +#define FM10K_SW_VENDOR_ID_INTEL		0x8086
> +#define FM10K_SW_VENDOR_ID_SILICOM		0x1374
> +#define FM10K_SW_VENDOR_ID_SILICOM_RB	0x1B2E
> +
> +
> +/*
> + * All IDs that may appear in the device ID or subsystem device ID.
> + */
> +#define FM10K_SW_DEV_ID_FM10K			0x15a4
> +
> +/* Silicom cards */
> +#define FM10K_SW_DEV_ID_PE310G4DBIR_T			0x01B0
> +#define FM10K_SW_DEV_ID_PE310G4DBIR_SRD
> 	0x01B1
> +#define FM10K_SW_DEV_ID_PE310G4DBIR_LRD
> 	0x01B2
> +#define FM10K_SW_DEV_ID_PE310G4DBIR_ER			0x01B3
> +#define FM10K_SW_DEV_ID_PE310G4DBIR_DA			0x01B4
> +#define FM10K_SW_DEV_ID_PE340G2DBIR_QS41		0x01B8
> +#define FM10K_SW_DEV_ID_PE340G2DBIR_QS43		0x01B9
> +#define FM10K_SW_DEV_ID_PE340G2DBIR_QL4
> 	0x01BA
> +#define FM10K_SW_DEV_ID_PE3100G2DQIR_QXSL4		0x01C0
> +#define FM10K_SW_DEV_ID_PE3100G2DQIR_QXSL4_REV_2	0x01C4
> +#define FM10K_SW_DEV_ID_PE3100G2DQIRL_QXSL4		0x01C1
> +#define FM10K_SW_DEV_ID_PE3100G2DQIRM_QXSL4		0x01C2
> +#define FM10K_SW_DEV_ID_PE325G2DSIR
> 	0x01C8
> +
> +/*
> + * SWITCH
> + */
> +
> +struct fm10k_device_info {
> +	uint16_t subvendor;
> +	uint16_t subdevice;
> +	const char *desc;
> +	uint8_t num_ext_ports;
> +	uint8_t ext_port_speed;
> +	uint8_t num_epls;
> +	uint8_t num_peps;
> +};
> +
> +
> +struct fm10k_i2c;
> +struct fm10k_sbus;
> +struct fm10k_hw;
> +struct fm10k_ext_ports;
> +struct fm10k_dpdk_cfg;
> +
> +struct fm10k_sw_port_map {
> +	uint32_t glort;
> +	uint16_t logical_port; /* logical port number */
> +	uint16_t physical_port; /*  */
> +};
> +
> +struct fm10k_switch {
> +	uint32_t *hw_addr;
> +	uint32_t *sw_addr;
> +	struct fm10k_hw *master_hw;
> +	struct fm10k_device_info *info;
> +	pthread_mutex_t lock;
> +	struct fm10k_i2c *i2c;
> +	struct fm10k_sbus *epl_sbus;
> +	struct fm10k_ext_ports *ext_ports;
> +	sem_t intr_tq;
> +	pthread_t intr_task;
> +	pthread_t led_task;
> +	pthread_t stats_task;
> +	uint32_t detaching;
> +	uint32_t glort_cam_ram_idx;
> +	uint32_t glort_dest_table_idx;
> +	uint32_t mcast_dest_table_idx;
> +	uint32_t mcast_len_table_idx;
> +	uint32_t mcast_vlan_table_idx;
> +	uint32_t epl_serdes_code_version_build_id;
> +	uint16_t pep_mask; /* mask of non-master peps */
> +	uint8_t pepno;
> +	uint8_t serdes_loopback;
> +	uint8_t epla_no;
> +	uint8_t eplb_no;
> +	uint8_t mac_addr[6];
> +	struct fm10k_dpdk_cfg *dpdk_cfg;
> +	struct fm10k_sw_port_map *pep_map;
> +	struct fm10k_sw_port_map *epl_map;
> +	int inited;
> +};
> +
> +#define FM10K_SW_SWITCH_LOCK(sw_)		do { 	\
> +	pthread_mutex_lock(&((sw_)->lock)); 		\
> +} while(0)
> +
> +#define FM10K_SW_SWITCH_UNLOCK(sw_)		do { 	\
> +	pthread_mutex_unlock(&((sw_)->lock)); 		\
> +}while(0)
> +
> +#define FM10K_SW_NITEMS(x)		(sizeof(x)/sizeof(x[0]))
> +#define FM10K_SW_HOWMANY(x, y)	((x+y-1)/y)
> +
> +
> +static inline uint64_t
> +fm10k_uptime_us(void)
> +{
> +	struct timeval tv;
> +
> +	gettimeofday(&tv, NULL);
> +	return ((uint64_t)tv.tv_sec * 1000000 + tv.tv_usec);
> +}
> +
> +
> +static inline uint32_t
> +fm10k_read_switch_reg(struct fm10k_switch *sw, uint32_t reg)
> +{
> +	return ((volatile uint32_t *)sw->master_hw->sw_addr)[reg];
> +}
> +
> +static inline uint64_t
> +fm10k_read_switch_reg64(struct fm10k_switch *sw, uint32_t reg)
> +{
> +	uint64_t temp, result;
> +
> +	result = ((volatile uint32_t *)sw->master_hw->sw_addr)[reg];
> +	temp = ((volatile uint32_t *)sw->master_hw->sw_addr)[reg + 1];
> +	result |= temp << 32;
> +
> +	return (result);
> +}
> +
> +static inline void
> +fm10k_read_switch_array(struct fm10k_switch *sw, uint32_t reg,
> +    uint32_t *results, uint32_t count)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < count; i++)
> +		results[i] = ((volatile uint32_t *)sw->master_hw->sw_addr)[reg
> + i];
> +}
> +
> +
> +static inline void
> +fm10k_write_switch_reg(struct fm10k_switch *sw, uint32_t reg, uint32_t val)
> +{
> +	((volatile uint32_t *)sw->master_hw->sw_addr)[reg] = val;
> +}
> +
> +static inline void
> +fm10k_write_switch_reg64(struct fm10k_switch *sw, uint32_t reg, uint64_t val)
> +{
> +	((volatile uint32_t *)sw->master_hw->sw_addr)[reg] = val & 0xffffffff;
> +	((volatile uint32_t *)sw->master_hw->sw_addr)[reg + 1] = val >> 32;
> +}
> +
> +static inline void
> +fm10k_write_switch_reg128(struct fm10k_switch *sw, uint32_t reg,
> +    uint64_t val_hi, uint64_t val_lo)
> +{
> +
> +	((volatile uint32_t *)sw->master_hw->sw_addr)[reg] = val_lo & 0xffffffff;
> +	((volatile uint32_t *)sw->master_hw->sw_addr)[reg + 1] = val_lo >> 32;
> +
> +	((volatile uint32_t *)sw->master_hw->sw_addr)[reg + 2] = val_hi &
> 0xffffffff;
> +	((volatile uint32_t *)sw->master_hw->sw_addr)[reg + 3] = val_hi >> 32;
> +
> +}
> +
> +static inline void
> +fm10k_write_switch_array(struct fm10k_switch *sw, uint32_t reg,
> +    uint32_t *data, uint32_t count)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < count; i++)
> +		((volatile uint32_t *)sw->master_hw->sw_addr)[reg + i] =
> data[i];
> +}
> +
> +static inline uint32_t
> +fm10k_write_flush(struct fm10k_switch *sw)
> +{
> +	return ((volatile uint32_t *)sw->master_hw-
> >hw_addr)[FM10K_SW_CTRL];
> +}
> +
> +static inline void
> +fm10k_gpio_output_set(struct fm10k_switch *sw, int gpio_pin, int value)
> +{
> +	uint32_t data;
> +
> +	data = fm10k_read_switch_reg(sw, FM10K_SW_GPIO_CFG);
> +	data |= 1<<gpio_pin;
> +	data &= ~(1<<(gpio_pin + 16));
> +
> +	/* set gpio output */
> +	fm10k_write_switch_reg(sw, FM10K_SW_GPIO_CFG, data);
> +
> +	/*
> +	 * Wait 1 msec (PCA spec specifies reset pulse width = 4 ns and
> +	 *  and reset time = 100 ns)
> +	 */
> +	usec_delay(1000);
> +	/* set reset */
> +	data = fm10k_read_switch_reg(sw, FM10K_SW_GPIO_DATA);
> +	if (value == 0)
> +		data &= ~(1<<gpio_pin);
> +	else
> +		data |= 1<<gpio_pin;
> +
> +	fm10k_write_switch_reg(sw, FM10K_SW_GPIO_DATA, data);
> +}
> +
> +#define fm10k_udelay	usec_delay
> +typedef int eth_fm10k_dev_init_half_func(struct fm10k_hw *hw);
> +
> +unsigned int fm10k_switch_eplidx_to_eplno(struct fm10k_switch *sw,
> unsigned int eplidx);
> +void fm10k_switch_intr(struct fm10k_hw *hw);
> +
> +struct fm10k_switch *fm10k_switch_get(void);
> +struct fm10k_device_info* fm10k_get_device_info(struct fm10k_hw *hw);
> +int fm10k_switch_dpdk_port_start(struct fm10k_hw* hw,
> +		uint8_t is_pf, bool master, eth_fm10k_dev_init_half_func
> *func);
> +void fm10k_switch_dpdk_port_stop(struct fm10k_hw* hw);
> +int fm10k_switch_dpdk_hw_queue_map(struct fm10k_hw *hw,
> +		uint16_t queue, uint16_t max_queue, struct fm10k_hw
> **map_hw, uint16_t* map_queue);
> +int fm10k_switch_dpdk_mapped_hw_get(struct fm10k_hw *hw, struct
> fm10k_hw *hw_list[]);
> +int fm10k_switch_dpdk_pf_no_get(struct fm10k_hw *hw);
> +int fm10k_switch_dpdk_port_no_get(struct fm10k_hw *hw);
> +void fm10k_switch_dpdk_tx_queue_num_set(struct fm10k_hw *hw, uint8_t
> num);
> +void fm10k_switch_dpdk_rx_queue_num_set(struct fm10k_hw *hw, uint8_t
> num);
> +
> +uint32_t fm10k_switch_pf_logical_get(uint8_t pf_no);
> +uint32_t fm10k_switch_epl_logical_get(uint8_t epl_no);
> +uint32_t fm10k_switch_vf_glort_get(uint8_t vf_no);
> +uint32_t fm10k_switch_pf_glort_get(uint8_t pf_no);
> +uint32_t fm10k_switch_pfs_glort_get(uint8_t pf1, uint8_t pf2);
> +uint32_t fm10k_switch_epl_glort_get(uint8_t epl_no);
> +uint32_t fm10k_switch_multi_glort_get(uint8_t pf1, uint8_t pf2,
> +		uint16_t vlan1, uint16_t vlan2, bool *p_new);
> +
> +int fm10k_switch_mirror_set(struct fm10k_hw *hw, u16 dest_port, u16 vlan);
> +int fm10k_switch_mirror_reset(struct fm10k_hw *hw);
> +
> +void fm10k_switch_flowset_switchto(const char *name);
> +void fm10k_switch_show_port(void);
> +void fm10k_switch_show_ffu(void);
> +void fm10k_switch_show_bank(void);
> +
> +
> +#endif
> --
> 1.8.3.1


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-11-28 17:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1574664677-6357-1-git-send-email-xiaojun.liu@silicom.co.il>
2019-11-28  6:34 ` [dpdk-dev] [PATCH] net/fm10k: support switch function with local linux kernel driver Wang, Xiao W

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).