From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D2E4DA04DD; Thu, 28 Nov 2019 18:42:19 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8F0662B88; Thu, 28 Nov 2019 18:42:19 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 664932C52 for ; Thu, 28 Nov 2019 07:34:30 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Nov 2019 22:34:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,252,1571727600"; d="scan'208";a="211982629" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by orsmga006.jf.intel.com with ESMTP; 27 Nov 2019 22:34:27 -0800 Received: from fmsmsx154.amr.corp.intel.com (10.18.116.70) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 27 Nov 2019 22:34:26 -0800 Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by FMSMSX154.amr.corp.intel.com (10.18.116.70) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 27 Nov 2019 22:34:26 -0800 Received: from shsmsx106.ccr.corp.intel.com ([169.254.10.248]) by shsmsx102.ccr.corp.intel.com ([169.254.2.108]) with mapi id 14.03.0439.000; Thu, 28 Nov 2019 14:34:14 +0800 From: "Wang, Xiao W" To: Xiaojun Liu , "Zhang, Qi Z" , "Kwan, Ngai-mint" , "Fornal, Jakub" , "Keller, Jacob E" CC: "dev@dpdk.org" , "Zhang, Helin" , "Lee, Gary M" Thread-Topic: [PATCH] net/fm10k: support switch function with local linux kernel driver Thread-Index: AQHVo1zNBDEQA1zfhUCLn0wSl5qBJKegIr4w Date: Thu, 28 Nov 2019 06:34:14 +0000 Message-ID: References: <1574664677-6357-1-git-send-email-xiaojun.liu@silicom.co.il> In-Reply-To: <1574664677-6357-1-git-send-email-xiaojun.liu@silicom.co.il> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ctpclassification: CTP_NT x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiYjVjMDc4N2QtZTYxZS00YTA1LWEwZWEtYzliYjI3MGNkNjAxIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiaGpZNmUyeUtoOHZ4S0tcL3loMEVRUWNqSkxyOVJRTCtcL2drYVpTeWgxMVNtT1MrREdESWVmQzVxR1JqMWZtdm9JIn0= x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 28 Nov 2019 18:42:17 +0100 Subject: Re: [dpdk-dev] [PATCH] net/fm10k: support switch function with local linux kernel driver X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Hi, +Kwan, Jakub and Jacob to help on the review, especially on the switch mana= gement part. Thanks, Xiao > -----Original Message----- > From: Xiaojun Liu > Sent: Monday, November 25, 2019 2:52 PM > To: Zhang, Qi Z ; Wang, Xiao W > > Cc: dev@dpdk.org; Xiaojun Liu > Subject: [PATCH] net/fm10k: support switch function with local linux kern= el > driver >=20 > 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. >=20 > 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. >=20 > To enable the management, you need add > CONFIG_RTE_FM10K_MANAGEMENT=3Dy in > config/common_linux when building. >=20 > Signed-off-by: Xiaojun Liu > --- > 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 >=20 > 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 =3D librte_pmd_fm10k.a >=20 > +ifeq ($(CONFIG_RTE_FM10K_MANAGEMENT),y) > +LDLIBS +=3D -lpthread > +endif > + > CFLAGS +=3D -O3 > CFLAGS +=3D $(WERROR_FLAGS) > CFLAGS +=3D -DALLOW_EXPERIMENTAL_API > +ifeq ($(CONFIG_RTE_FM10K_MANAGEMENT),y) > +CFLAGS +=3D -DENABLE_FM10K_MANAGEMENT > +endif >=20 > EXPORT_MAP :=3D rte_pmd_fm10k_version.map >=20 > @@ -62,12 +69,19 @@ $(foreach obj, $(BASE_DRIVER_OBJS), $(eval > CFLAGS_$(obj)+=3D$(CFLAGS_BASE_DRIVER)) >=20 > VPATH +=3D $(SRCDIR)/base >=20 > +ifeq ($(CONFIG_RTE_FM10K_MANAGEMENT),y) > +VPATH +=3D $(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) +=3D fm10k_ethdev.c > SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_rxtx.c > +ifeq ($(CONFIG_RTE_FM10K_MANAGEMENT),y) > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_flow.c > +endif >=20 > SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_pf.c > SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_tlv.c > @@ -75,6 +89,20 @@ SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D > fm10k_common.c > SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_mbx.c > SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_vf.c > SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_api.c > + > +ifeq ($(CONFIG_RTE_FM10K_MANAGEMENT),y) > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_ext_port.c > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_i2c.c > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_sbus.c > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_serdes.c > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_sm.c > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_spico_code.c > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_stats.c > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_ffu.c > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_config.c > +SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) +=3D fm10k_switch.c > +endif > + > SRCS-$(CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR) +=3D fm10k_rxtx_vec.c >=20 > 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_ >=20 > +#ifdef ENABLE_FM10K_MANAGEMENT > +#include > +#include > +#include > +#include > +#include > +#include > +#endif > /* forward declaration */ > struct fm10k_hw; >=20 > @@ -701,10 +709,26 @@ struct fm10k_iov_info { > u16 num_pools; > }; >=20 > +#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) > }; >=20 > 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 @@ >=20 > #include "fm10k.h" > #include "base/fm10k_api.h" > +#ifdef ENABLE_FM10K_MANAGEMENT > +#include "switch/fm10k_regs.h" > +#include "switch/fm10k_switch.h" > +#endif >=20 > /* 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 =3D 0; > +#endif >=20 > int fm10k_logtype_init; > int fm10k_logtype_driver; > @@ -509,6 +519,15 @@ struct fm10k_xstats_name_off { > struct rte_eth_conf *dev_conf =3D &dev->data->dev_conf; > uint32_t mrqc, *key, i, reta, j; > uint64_t hf; > +#ifdef ENABLE_FM10K_MANAGEMENT > + uint16_t nb_rx_queues =3D dev->data->nb_rx_queues; > + int mapped_num; > + struct fm10k_hw *mapped_hws[2]; > + > + mapped_num =3D fm10k_switch_dpdk_mapped_hw_get(hw, > mapped_hws); > + if(mapped_num =3D=3D 2) > + nb_rx_queues /=3D 2; > +#endif >=20 > #define RSS_KEY_SIZE 40 > static uint8_t rss_intel_key[RSS_KEY_SIZE] =3D { > @@ -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 =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > +#else > + struct fm10k_hw *hw; > + struct fm10k_hw *unmap_hw =3D 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; >=20 > +#ifndef ENABLE_FM10K_MANAGEMENT > /* Disable TXINT to avoid possible interrupt */ > for (i =3D 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 >=20 > /* Setup TX queue */ > for (i =3D 0; i < dev->data->nb_tx_queues; ++i) { > + hw_queue_id =3D 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 =3D dev->data->tx_queues[i]; > base_addr =3D txq->hw_ring_phys_addr; > size =3D txq->nb_desc * sizeof(struct fm10k_tx_desc); >=20 > /* disable queue to avoid issues while updating state */ > - ret =3D tx_queue_disable(hw, i); > + ret =3D 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 =3D=3D fm10k_mac_pf) { > - FM10K_WRITE_REG(hw, FM10K_PFVTCTL(i), > + FM10K_WRITE_REG(hw, > FM10K_PFVTCTL(hw_queue_id), >=20 > FM10K_PFVTCTL_FTAG_DESC_ENABLE); > PMD_INIT_LOG(DEBUG, "FTAG mode is > enabled"); > } else { > @@ -676,15 +710,22 @@ struct fm10k_xstats_name_off { > } >=20 > /* 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); >=20 > /* assign default SGLORT for each TX queue by PF */ > +#ifndef ENABLE_FM10K_MANAGEMENT > if (hw->mac.type =3D=3D 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 =3D=3D fm10k_mac_pf) { > + data =3D > FM10K_SW_MAKE_REG_FIELD(TX_SGLORT_SGLORT, hw->mac.dglort_map); > + FM10K_WRITE_REG(hw, > FM10K_TX_SGLORT(hw_queue_id), data); > + } > +#endif > } >=20 > /* 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 =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > struct fm10k_macvlan_filter_info *macvlan; > struct rte_pci_device *pdev =3D RTE_ETH_DEV_TO_PCI(dev); > struct rte_intr_handle *intr_handle =3D &pdev->intr_handle; > + uint32_t logic_port =3D hw->mac.dglort_map; > + uint16_t queue_stride =3D 0; > +#else > + struct fm10k_hw *hw; > + struct fm10k_hw *unmap_hw =3D 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 =3D FM10K_RXDCTL_WRITE_BACK_MIN_DELAY; > - uint32_t logic_port =3D hw->mac.dglort_map; > uint16_t buf_size; > - uint16_t queue_stride =3D 0; >=20 > +#ifndef ENABLE_FM10K_MANAGEMENT > /* enable RXINT for interrupt mode */ > i =3D 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 >=20 > /* Setup RX queues */ > for (i =3D 0; i < dev->data->nb_rx_queues; ++i) { > + hw_queue_id =3D 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 =3D dev->data->rx_queues[i]; > base_addr =3D rxq->hw_ring_phys_addr; > size =3D rxq->nb_desc * sizeof(union fm10k_rx_desc); >=20 > /* disable queue to avoid issues while updating state */ > - ret =3D rx_queue_disable(hw, i); > + ret =3D 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; > } >=20 > /* 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); >=20 > /* Configure the Rx buffer size for one buff without split */ > buf_size =3D (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) - > @@ -761,7 +816,7 @@ struct fm10k_xstats_name_off { > */ > buf_size -=3D FM10K_RX_DATABUF_ALIGN; >=20 > - 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); >=20 > @@ -771,9 +826,9 @@ struct fm10k_xstats_name_off { > rxq->offloads & DEV_RX_OFFLOAD_SCATTER) { > uint32_t reg; > dev->data->scattered_rx =3D 1; > - reg =3D FM10K_READ_REG(hw, FM10K_SRRCTL(i)); > + reg =3D FM10K_READ_REG(hw, > FM10K_SRRCTL(hw_queue_id)); > reg |=3D FM10K_SRRCTL_BUFFER_CHAINING_EN; > - FM10K_WRITE_REG(hw, FM10K_SRRCTL(i), reg); > + FM10K_WRITE_REG(hw, FM10K_SRRCTL(hw_queue_id), > reg); > } >=20 > /* 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 !=3D fm10k_mac_pf) > return 0; > +#ifndef ENABLE_FM10K_MANAGEMENT > macvlan =3D FM10K_DEV_PRIVATE_TO_MACVLAN(dev->data- > >dev_private); > if (macvlan->nb_queue_pools) > queue_stride =3D 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 >=20 > 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 =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > +#else > + struct fm10k_hw *hw; > + struct fm10k_hw *unmap_hw =3D 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 =3D rx_queue_id; >=20 > PMD_INIT_FUNC_TRACE(); >=20 > +#ifdef ENABLE_FM10K_MANAGEMENT > + ret =3D 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 !=3D 1) /* reference port's queue don't need start */ > + return 0; > +#endif > + > rxq =3D dev->data->rx_queues[rx_queue_id]; > err =3D rx_queue_reset(rxq); > if (err =3D=3D -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); >=20 > /* Set PF ownership flag for PF devices */ > - reg =3D FM10K_READ_REG(hw, FM10K_RXQCTL(rx_queue_id)); > + reg =3D FM10K_READ_REG(hw, FM10K_RXQCTL(hw_queue_id)); > if (hw->mac.type =3D=3D fm10k_mac_pf) > reg |=3D FM10K_RXQCTL_PF; > reg |=3D 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); >=20 > /* 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] =3D > RTE_ETH_QUEUE_STATE_STARTED; >=20 > 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 =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > +#else > + struct fm10k_hw *hw; > + struct fm10k_hw *unmap_hw =3D 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 =3D FM10K_TXDCTL_WRITE_BACK_MIN_DELAY; > struct fm10k_tx_queue *q =3D dev->data->tx_queues[tx_queue_id]; > + uint16_t hw_queue_id =3D tx_queue_id; >=20 > PMD_INIT_FUNC_TRACE(); >=20 > +#ifdef ENABLE_FM10K_MANAGEMENT > + ret =3D 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 !=3D 1) > + return 0; > +#endif > + > q->ops->reset(q); >=20 > /* 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); >=20 > /* 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] =3D > RTE_ETH_QUEUE_STATE_STARTED; > @@ -1081,9 +1170,22 @@ static inline int fm10k_glort_valid(struct fm10k_h= w > *hw) > { > struct fm10k_hw *hw =3D 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 >=20 > PMD_INIT_FUNC_TRACE(); >=20 > +#ifdef ENABLE_FM10K_MANAGEMENT > + mapped_num =3D 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 =3D fm10k_stop_hw(hw); > if (diag !=3D FM10K_SUCCESS) { > @@ -1102,6 +1204,57 @@ static inline int fm10k_glort_valid(struct fm10k_h= w > *hw) > PMD_INIT_LOG(ERR, "Hardware start failed: %d", diag); > return -EIO; > } > +#else > + for (j =3D 0; j < mapped_num; j++) { > + struct rte_pci_device *pdev =3D RTE_ETH_DEV_TO_PCI((struct > rte_eth_dev *)(mapped_hws[j]->rte_dev)); > + struct rte_intr_handle *intr_handle =3D &pdev->intr_handle; > + > + /* stop, init, then start the hw */ > + diag =3D fm10k_stop_hw(mapped_hws[j]); > + if (diag !=3D FM10K_SUCCESS) { > + PMD_INIT_LOG(ERR, "Hardware stop failed: %d", diag); > + return -EIO; > + } > + > + diag =3D fm10k_init_hw(mapped_hws[j]); > + if (diag !=3D FM10K_SUCCESS) { > + PMD_INIT_LOG(ERR, "Hardware init failed: %d", diag); > + return -EIO; > + } > + > + diag =3D fm10k_start_hw(mapped_hws[j]); > + if (diag !=3D FM10K_SUCCESS) { > + PMD_INIT_LOG(ERR, "Hardware start failed: %d", diag); > + return -EIO; > + } > + > + /* Disable TXINT to avoid possible interrupt */ > + for (i =3D 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 =3D 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 =3D=3D > 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 >=20 > diag =3D fm10k_dev_tx_init(dev); > if (diag) { > @@ -1153,12 +1306,28 @@ static inline int fm10k_glort_valid(struct fm10k_= hw > *hw) > } > } >=20 > +#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 >=20 > fm10k_link_update(dev, 0); >=20 > +#ifdef ENABLE_FM10K_MANAGEMENT > + /* Admit all VLANs */ > + for (j =3D 0; j <=3D 64; j++) { > + for (i =3D 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 =3D FM10K_READ_REG(hw, FM10K_CTRL_EXT); > + data &=3D ~FM10K_SW_CTRL_EXT_SWITCH_LOOPBACK; > + FM10K_WRITE_REG(hw, FM10K_CTRL_EXT, data); > +#endif > + > return 0; > } >=20 > @@ -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 =3D > FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private); > +#else > + struct fm10k_hw *hw; > + struct fm10k_hw *unmap_hw =3D > + 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 =3D > FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private); > int i; >=20 > PMD_INIT_FUNC_TRACE(); >=20 > +#ifndef ENABLE_FM10K_MANAGEMENT > fm10k_update_hw_stats(hw, hw_stats); > +#else > + mapped_num =3D fm10k_switch_dpdk_mapped_hw_get(unmap_hw, > mapped_hws); > + if (mapped_num < 0 || mapped_num > 2) > + return -EIO; > + > + for (i =3D 0; i < mapped_num; i++) { > + struct rte_eth_dev *mydev =3D mapped_hws[i]->rte_dev; > + hw_stats =3D FM10K_DEV_PRIVATE_TO_STATS(mydev->data- > >dev_private); > + fm10k_update_hw_stats(mapped_hws[i], hw_stats); > + } > +#endif >=20 > ipackets =3D opackets =3D ibytes =3D obytes =3D imissed =3D 0; > + > +#ifndef ENABLE_FM10K_MANAGEMENT > for (i =3D 0; (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) && > (i < hw->mac.max_queues); ++i) { > stats->q_ipackets[i] =3D 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 +=3D stats->q_obytes[i]; > imissed +=3D stats->q_errors[i]; > } > +#else > + if (mapped_num) { > + for (i =3D 0; (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) && > + (i < unmap_hw->mac.max_queues); ++i) { > + hw_queue_id =3D 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 =3D hw->rte_dev; > + hw_stats =3D > FM10K_DEV_PRIVATE_TO_STATS(mydev->data->dev_private); > + } > + stats->q_ipackets[i] =3D hw_stats- > >q[hw_queue_id].rx_packets.count; > + stats->q_opackets[i] =3D hw_stats- > >q[hw_queue_id].tx_packets.count; > + stats->q_ibytes[i] =3D hw_stats- > >q[hw_queue_id].rx_bytes.count; > + stats->q_obytes[i] =3D hw_stats- > >q[hw_queue_id].tx_bytes.count; > + ipackets +=3D stats->q_ipackets[i]; > + opackets +=3D stats->q_opackets[i]; > + ibytes +=3D stats->q_ibytes[i]; > + obytes +=3D stats->q_obytes[i]; > + } > + } > +#endif > stats->ipackets =3D ipackets; > stats->opackets =3D opackets; > stats->ibytes =3D 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 =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > +#else > + struct fm10k_hw *hw; > + struct fm10k_hw *unmap_hw =3D FM10K_DEV_PRIVATE_TO_HW(dev- > >data->dev_private); > +#endif > struct fm10k_dev_info *dev_info =3D > 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 =3D queue_id; >=20 > PMD_INIT_FUNC_TRACE(); >=20 > +#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 =3D conf->offloads | dev->data->dev_conf.rxmode.offloads; >=20 > /* 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 =3D dev->data->port_id; > q->queue_id =3D queue_id; > q->tail_ptr =3D (volatile uint32_t *) > - &((uint32_t *)hw->hw_addr)[FM10K_RDT(queue_id)]; > + &((uint32_t *)hw->hw_addr)[FM10K_RDT(hw_queue_id)]; > q->offloads =3D 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 =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > +#else > + struct fm10k_hw *hw; > + struct fm10k_hw *unmap_hw =3D 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 =3D queue_id; >=20 > PMD_INIT_FUNC_TRACE(); >=20 > +#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 =3D conf->offloads | dev->data->dev_conf.txmode.offloads; >=20 > /* 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 =3D offloads; > q->ops =3D &def_txq_ops; > q->tail_ptr =3D (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; >=20 > @@ -2280,6 +2518,74 @@ static uint64_t > fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev) > return 0; > } >=20 > +#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 =3D 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 =3D 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 =3D 0; > + > + if (dev =3D=3D NULL) > + return -EINVAL; > + > + switch (filter_type) { > + case RTE_ETH_FILTER_GENERIC: > + if (filter_op !=3D RTE_ETH_FILTER_GET) > + return -EINVAL; > + *(const void **)arg =3D &fm10k_flow_ops; > + break; > + default: > + PMD_DRV_LOG(WARNING, "Filter type (%d) not supported", > + filter_type); > + ret =3D -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 =3D 0; > +#endif >=20 > if (hw->mac.type !=3D fm10k_mac_pf) > return; > @@ -2601,11 +2910,20 @@ static uint64_t > fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev) > } >=20 > /* 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 =3D 0; > + writeback |=3D FM10K_EICR_SWITCHNOTREADY; > +#endif > + } >=20 > if (cause & FM10K_EICR_SWITCHREADY) { > PMD_INIT_LOG(INFO, "INT: Switch is ready"); > +#ifdef ENABLE_FM10K_MANAGEMENT > + fm10k_switch_ready =3D 1; > + writeback |=3D FM10K_EICR_SWITCHREADY; > +#endif > if (dev_info->sm_down =3D=3D 1) { > fm10k_mbx_lock(hw); >=20 > @@ -2656,6 +2974,7 @@ static uint64_t > fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev) > } >=20 > /* Handle mailbox message */ > +#ifndef ENABLE_FM10K_MANAGEMENT > fm10k_mbx_lock(hw); > err =3D 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); > } >=20 > +#else > + if (cause & FM10K_EICR_MAILBOX) { > + fm10k_mbx_lock(hw); > + err =3D hw->mbx.ops.process(hw, &hw->mbx); > + fm10k_mbx_unlock(hw); > + writeback |=3D FM10K_EICR_MAILBOX; > + if (err =3D=3D FM10K_ERR_RESET_REQUESTED) { > + PMD_INIT_LOG(INFO, "INT: Switch is down"); > + dev_info->sm_down =3D 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 */ > } >=20 > +#ifndef ENABLE_FM10K_MANAGEMENT > /* Clear these 3 events if having any */ > cause &=3D 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 >=20 > /* 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 =3D fm10k_reta_query, > .rss_hash_update =3D fm10k_rss_hash_update, > .rss_hash_conf_get =3D fm10k_rss_hash_conf_get, > +#ifdef ENABLE_FM10K_MANAGEMENT > + .mirror_rule_set =3D fm10k_mirror_rule_set, > + .mirror_rule_reset =3D fm10k_mirror_rule_reset, > + .filter_ctrl =3D fm10k_dev_filter_ctrl, > +#endif > }; >=20 > static int ftag_check_handler(__rte_unused const char *key, > @@ -3071,13 +3425,87 @@ static void __attribute__((cold)) > info->sm_down =3D false; > } >=20 > +#ifdef ENABLE_FM10K_MANAGEMENT > +static int eth_fm10k_dev_init_hook(struct fm10k_hw *hw) > +{ > + int i, switch_ready; > + struct rte_eth_dev *dev =3D (struct rte_eth_dev*)hw->rte_dev; > + > + /* Make sure Switch Manager is ready before going forward. */ > + if (hw->mac.type =3D=3D fm10k_mac_pf) { > + switch_ready =3D 0; > + > + for (i =3D 0; i < MAX_QUERY_SWITCH_STATE_TIMES; i++) { > + fm10k_mbx_lock(hw); > + switch_ready =3D 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 =3D=3D 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 =3D=3D 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 =3D=3D fm10k_mac_pf) { > + for (i =3D 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 =3D=3D 0) { > + hw->mac.default_vid =3D 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 =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > struct rte_pci_device *pdev =3D RTE_ETH_DEV_TO_PCI(dev); > struct rte_intr_handle *intr_handle =3D &pdev->intr_handle; > - int diag, i; > + int diag; > +#ifndef ENABLE_FM10K_MANAGEMENT > + int i; > +#endif > struct fm10k_macvlan_filter_info *macvlan; >=20 > 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 =3D (void *)pdev->mem_resource[4].addr; >=20 > + TAILQ_INIT(&hw->flow_list); > +#endif > /* Store fm10k_adapter pointer */ > hw->back =3D dev->data->dev_private; >=20 > @@ -3125,6 +3557,26 @@ static void __attribute__((cold)) > return -EIO; > } >=20 > +#ifdef ENABLE_FM10K_MANAGEMENT > + if (hw->mac.type =3D=3D fm10k_mac_pf) { > + if (hw->hw_addr =3D=3D NULL || hw->sw_addr =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "Bad mem resource." > + " Try to blacklist unused devices."); > + return -EIO; > + } > + } else { > + if (hw->hw_addr =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "Bad mem resource." > + " Try to blacklist unused devices."= ); > + return -EIO; > + } > + } > + > + /* Store fm10k_adapter pointer */ > + hw->back =3D dev->data->dev_private; > + hw->rte_dev =3D dev; > +#endif > + > /* Initialize parameters */ > fm10k_params_init(dev); >=20 > @@ -3205,6 +3657,7 @@ static void __attribute__((cold)) > hw->mac.ops.update_int_moderator(hw); >=20 > /* Make sure Switch Manager is ready before going forward. */ > +#ifndef ENABLE_FM10K_MANAGEMENT > if (hw->mac.type =3D=3D fm10k_mac_pf) { > int switch_ready =3D 0; >=20 > @@ -3264,11 +3717,21 @@ static void __attribute__((cold)) > MAIN_VSI_POOL_NUMBER); >=20 > return 0; > +#else > + if (hw->mac.type =3D=3D fm10k_mac_pf) { > + bool master =3D 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 > } >=20 > static int > eth_fm10k_dev_uninit(struct rte_eth_dev *dev) > { > +#ifdef ENABLE_FM10K_MANAGEMENT > + struct fm10k_hw *hw =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > +#endif > PMD_INIT_FUNC_TRACE(); >=20 > /* only uninitialize in the primary process */ > @@ -3278,6 +3741,10 @@ static void __attribute__((cold)) > /* safe to close dev here */ > fm10k_dev_close(dev); >=20 > +#ifdef ENABLE_FM10K_MANAGEMENT > + fm10k_switch_dpdk_port_stop(hw); > +#endif > + > return 0; > } >=20 > diff --git a/drivers/net/fm10k/fm10k_flow.c b/drivers/net/fm10k/fm10k_flo= w.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 > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#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 =3D { > + .validate =3D fm10k_flow_validate, > + .create =3D fm10k_flow_create, > + .destroy =3D fm10k_flow_destroy, > + .flush =3D fm10k_flow_flush, > +}; > + > +union fm10k_filter_t cons_filter; > +enum rte_filter_type fm10k_cons_filter_type =3D 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[] =3D { > + RTE_FLOW_ITEM_TYPE_ETH, > + RTE_FLOW_ITEM_TYPE_MPLS, > + RTE_FLOW_ITEM_TYPE_END, > +}; > + > +static enum rte_flow_item_type pattern_vlan_1[] =3D { > + 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[] =3D { > + 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[] =3D { > + /* 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 =3D actions + index; > \ > + while (act->type =3D=3D RTE_FLOW_ACTION_TYPE_VOID) { > \ > + index++; > \ > + act =3D 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 !=3D RTE_FLOW_ITEM_TYPE_END) { > + if (is_void) > + is_find =3D item->type =3D=3D RTE_FLOW_ITEM_TYPE_VOID; > + else > + is_find =3D item->type !=3D 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 =3D 0; > + const struct rte_flow_item *pb =3D pattern, *pe =3D pattern; > + > + for (;;) { > + /* Find a non-void item first */ > + pb =3D fm10k_find_first_item(pb, false); > + if (pb->type =3D=3D RTE_FLOW_ITEM_TYPE_END) { > + pe =3D pb; > + break; > + } > + > + /* Find a void item */ > + pe =3D fm10k_find_first_item(pb + 1, true); > + > + cpy_count =3D pe - pb; > + rte_memcpy(items, pb, sizeof(struct rte_flow_item) * > cpy_count); > + > + items +=3D cpy_count; > + > + if (pe->type =3D=3D RTE_FLOW_ITEM_TYPE_END) { > + pb =3D pe; > + break; > + } > + > + pb =3D 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 =3D pattern; > + > + while ((*item_array =3D=3D item->type) && > + (*item_array !=3D RTE_FLOW_ITEM_TYPE_END)) { > + item_array++; > + item++; > + } > + > + return (*item_array =3D=3D RTE_FLOW_ITEM_TYPE_END && > + item->type =3D=3D 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 *id= x) > +{ > + parse_filter_t parse_filter =3D NULL; > + uint8_t i =3D *idx; > + > + for (; i < RTE_DIM(fm10k_supported_patterns); i++) { > + if (fm10k_match_pattern(fm10k_supported_patterns[i].items, > + pattern)) { > + parse_filter =3D fm10k_supported_patterns[i].parse_filter; > + break; > + } > + } > + > + *idx =3D ++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 =3D 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] =3D {0xFF, 0xFF, 0xF0}; > + uint32_t label_be =3D 0; > + uint32_t be_mask =3D 0; > + > + for (; item->type !=3D 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 =3D 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 =3D > + (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) =3D=3D 0x8847) > + filter->mpls_type =3D FM10K_MPLS_TYPE_UNI; > + else if (rte_be_to_cpu_16(eth_spec->type) =3D=3D 0x8848) > + filter->mpls_type =3D 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 =3D > + (const struct rte_flow_item_mpls *)item->spec; > + mpls_mask =3D > + (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 =3D rte_be_to_cpu_32(label_be) >> 4; > + filter->mpls_header_mask =3D > rte_be_to_cpu_32(be_mask) >> 4; > + > + fm10k_cons_filter_type =3D 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 =3D 0; > + > + /* Check if the first non-void action is QUEUE or DROP. */ > + NEXT_ITEM_OF_ACTION(act, actions, index); > + if (act->type !=3D RTE_FLOW_ACTION_TYPE_QUEUE && > + act->type !=3D 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 =3D=3D RTE_FLOW_ACTION_TYPE_QUEUE) { > + act_q =3D (const struct rte_flow_action_queue *)act->conf; > + filter->mpls_action =3D FM10K_MPLS_ACTION_QUEUE; > + filter->queue =3D act_q->index; > + } else { > + filter->mpls_action =3D FM10K_MPLS_ACTION_DROP; > + } > + > + /* Check if the next non-void item is END */ > + index++; > + NEXT_ITEM_OF_ACTION(act, actions, index); > + if (act->type !=3D 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 =3D > + &filter->mpls_filter; > + int ret; > + > + ret =3D fm10k_flow_parse_mpls_pattern(dev, pattern, > + error, mpls_filter); > + if (ret) > + return ret; > + > + ret =3D fm10k_flow_parse_mpls_action(actions, error, mpls_filter); > + if (ret) > + return ret; > + > + ret =3D 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 =3D 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 !=3D 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 =3D item->type; > + switch (item_type) { > + case RTE_FLOW_ITEM_TYPE_VLAN: > + vlan_spec =3D > + (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 =3D > + (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 =3D 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 !=3D 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 !=3D RTE_FLOW_ACTION_TYPE_MARK && act->type !=3D > 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 =3D=3D 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 !=3D 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 =3D > + &filter->vlan_filter; > + > + ret =3D fm10k_flow_parse_vlan_pattern(dev, pattern, > + error, vlan_filter); > + if (ret) > + return ret; > + > + ret =3D fm10k_flow_parse_vlan_action(dev, actions, error, vlan_filter); > + if (ret) > + return ret; > + > + if(attr->ingress) > + vlan_filter->is_ingress =3D 1; > + else if(attr->egress) > + vlan_filter->is_ingress =3D 0; > + vlan_filter->ffu_prio =3D attr->priority; > + > + ret =3D 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 =3D 0; /* non-void item number of pattern*/ > + uint32_t i =3D 0; > + bool flag =3D false; > + int ret =3D -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 !=3D RTE_FLOW_ITEM_TYPE_END) { > + if ((pattern + i)->type !=3D RTE_FLOW_ITEM_TYPE_VOID) > + item_num++; > + i++; > + } > + item_num++; > + > + items =3D 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 =3D 0; > + do { > + parse_filter =3D 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 =3D parse_filter(dev, attr, items, actions, > + error, &cons_filter); > + flag =3D 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 =3D 0, set_vlan_num =3D 0; > + u16 fw_port_id =3D 0, bp_port_id =3D 0; > + u16 filter_vlan_id =3D 0, fw_vlan_id =3D 0, bp_vlan_id =3D 0; > + struct fm10k_hw *hw =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > + struct fm10k_cfg_flow *cf; > + > + cf =3D 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 =3D fm10k_switch_dpdk_port_no_get(hw); > + for (i=3D0; i<4; i++) { > + if (pattern[i].type =3D=3D RTE_FLOW_ITEM_TYPE_VLAN) { > + filter_vlan_id =3D rte_be_to_cpu_16(((const struct > rte_flow_item_vlan*)pattern[i].spec)->tci); > + } > + else if (pattern[i].type =3D=3D RTE_FLOW_ITEM_TYPE_PHY_PORT) { > + if(set_port_num) > + bp_port_id =3D ((const struct > rte_flow_item_phy_port*)pattern[i].spec)->index; > + else > + fw_port_id =3D ((const struct > rte_flow_item_phy_port*)pattern[i].spec)->index; > + set_port_num++; > + } > + else if (pattern[i].type =3D=3D RTE_FLOW_ITEM_TYPE_END) > + break; > + } > + > + for (i=3D0; i<3; i++) { > + if (actions[i].type =3D=3D RTE_FLOW_ACTION_TYPE_MARK) { > + if (set_vlan_num) > + bp_vlan_id =3D ((const struct > rte_flow_action_mark*)actions[i].conf)->id; > + else > + fw_vlan_id =3D ((const struct > rte_flow_action_mark*)actions[i].conf)->id; > + set_vlan_num++; > + } > + else if (actions[i].type =3D=3D 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 =3D FM10K_CONFIG_FLOW_EXT_PORT; > + cf->src_port.port_no =3D fw_port_id; > + cf->src_port.vlan_id =3D filter_vlan_id; > + cf->fw_port[0].port_type =3D > FM10K_CONFIG_FLOW_DPDK_PORT; > + cf->fw_port[0].port_no =3D port_id; > + cf->fw_port[0].vlan_id =3D fw_vlan_id; > + } else if (!attr->ingress && attr->egress) { > + /* this port is DPDK port and it is source port */ > + cf->src_port.port_type =3D FM10K_CONFIG_FLOW_DPDK_PORT; > + cf->src_port.port_no =3D port_id; > + cf->src_port.vlan_id =3D filter_vlan_id; > + cf->fw_port[0].port_type =3D FM10K_CONFIG_FLOW_EXT_PORT; > + cf->fw_port[0].port_no =3D fw_port_id; > + cf->fw_port[0].vlan_id =3D fw_vlan_id; > + } > + else if (!attr->ingress && !attr->egress) { > + /* two ports are external port */ > + cf->src_port.port_type =3D FM10K_CONFIG_FLOW_EXT_PORT; > + cf->src_port.port_no =3D port_id; > + cf->src_port.vlan_id =3D filter_vlan_id; > + cf->fw_port[0].port_type =3D FM10K_CONFIG_FLOW_EXT_PORT; > + cf->fw_port[0].port_no =3D fw_port_id; > + cf->fw_port[0].vlan_id =3D fw_vlan_id; > + } else { > + /* two ports are DPDK port */ > + cf->src_port.port_type =3D FM10K_CONFIG_FLOW_DPDK_PORT; > + cf->src_port.port_no =3D port_id; > + cf->src_port.vlan_id =3D filter_vlan_id; > + cf->fw_port[0].port_type =3D > FM10K_CONFIG_FLOW_DPDK_PORT; > + cf->fw_port[0].port_no =3D fw_port_id; > + cf->fw_port[0].vlan_id =3D fw_vlan_id; > + } > + > + if (set_port_num =3D=3D 2 && set_vlan_num =3D=3D 2) { > + cf->fw_port[1].port_type =3D FM10K_CONFIG_FLOW_EXT_PORT; > + cf->fw_port[1].port_no =3D bp_port_id; > + cf->fw_port[1].vlan_id =3D 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 =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > + struct rte_flow *flow; > + struct fm10k_switch *sw =3D fm10k_switch_get(); > + struct fm10k_cfg_flow *cf; > + int ret; > + > + flow =3D 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 =3D fm10k_flow_validate(dev, attr, pattern, actions, error); > + if (ret < 0) > + return NULL; > + > + cf =3D fm10k_flow_cfg_transfer(dev, attr, pattern, actions, error); > + if (!cf) > + goto free_flow; > + > + flow->rule =3D 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 =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > + int ret =3D 0; > + struct fm10k_switch *sw =3D 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 =3D FM10K_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > + struct rte_flow *flow; > + void *temp; > + int ret =3D 0; > + struct fm10k_cfg_flow *cf; > + struct fm10k_switch *sw =3D fm10k_switch_get(); > + > + /* Delete flows in flow list. */ > + TAILQ_FOREACH_SAFE(flow, &hw->flow_list, node, temp) { > + cf =3D 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 > + > +#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 =3D "/etc/dpdk_fm10k.conf= "; > +static struct fm10k_dpdk_cfg fm10k_config_dpdk_cfg; > + > +static struct fm10k_cfg_key_item fm10k_config_key_items[] =3D { > + /* 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]=3D"default"; > + > +static struct fm10k_cfg_config_item fm10k_silc_nic_2ext_2pep[] =3D { > + {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=3D2}, > + > + {FM10K_CONFIG_EXT_PORT_SPEED, > FM10K_CONFIG_VALUE_INT, 0, > + "# Set external port speed, 40 means 40G, 100 > means 100G.", .val.int64=3D100}, > + > + {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=3D0}, > + {FM10K_CONFIG_DPDK_PORT_MAP_PF, > FM10K_CONFIG_VALUE_INT, 1, "", .val.int64=3D1}, > + > + {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=3D0}, > + {FM10K_CONFIG_EXT_PORT_MAP_PF, > FM10K_CONFIG_VALUE_INT, 2, "", .val.int64=3D1}, > + > + {FM10K_CONFIG_FLOWSET_START, > FM10K_CONFIG_VALUE_STR, 0, "# Define flow rule", .val.str=3Ddefault_flows= et}, > + {FM10K_CONFIG_FLOWSET_STOP, > FM10K_CONFIG_VALUE_STR, 0, "", .val.str=3Ddefault_flowset}, > + {FM10K_CONFIG_FLOWSET_ENABLE, > FM10K_CONFIG_VALUE_STR, 0, "", .val.str=3Ddefault_flowset}, > + > + {FM10K_CONFIG_TYPE_NULL, 0, 0, "", .val.int64=3D0}, > +}; > + > +static struct fm10k_cfg_config_item fm10k_silc_nic_2ext_4pep[] =3D { > + {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=3D4}, > + > + {FM10K_CONFIG_EXT_PORT_SPEED, > FM10K_CONFIG_VALUE_INT, 0, > + "# Set external port speed, 40 means 40G, 100 > means 100G.", .val.int64=3D100}, > + > + {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=3D0}, > + {FM10K_CONFIG_DPDK_PORT_MAP_PF, > FM10K_CONFIG_VALUE_INT, 0, "", .val.int64=3D2}, > + {FM10K_CONFIG_DPDK_PORT_MAP_PF, > FM10K_CONFIG_VALUE_INT, 1, "", .val.int64=3D1}, > + {FM10K_CONFIG_DPDK_PORT_MAP_PF, > FM10K_CONFIG_VALUE_INT, 1, "", .val.int64=3D3}, > + > + {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=3D0}, > + {FM10K_CONFIG_EXT_PORT_MAP_PF, > FM10K_CONFIG_VALUE_INT, 1, "", .val.int64=3D2}, > + {FM10K_CONFIG_EXT_PORT_MAP_PF, > FM10K_CONFIG_VALUE_INT, 2, "", .val.int64=3D1}, > + {FM10K_CONFIG_EXT_PORT_MAP_PF, > FM10K_CONFIG_VALUE_INT, 2, "", .val.int64=3D3}, > + > + {FM10K_CONFIG_FLOWSET_START, > FM10K_CONFIG_VALUE_STR, 0, "# Define flow rule", .val.str=3Ddefault_flows= et}, > + {FM10K_CONFIG_FLOWSET_STOP, > FM10K_CONFIG_VALUE_STR, 0, "", .val.str=3Ddefault_flowset}, > + {FM10K_CONFIG_FLOWSET_ENABLE, > FM10K_CONFIG_VALUE_STR, 0, "", .val.str=3Ddefault_flowset}, > + > + {FM10K_CONFIG_TYPE_NULL, 0, 0, "", .val.int64=3D0}, > +}; > + > + > +static int > +fm10k_config_conf_line_parser(char* buff, struct fm10k_cfg_config_item* > item) > +{ > + char *p; > + char *endptr; > + const char *cfg_delims =3D { " " }; > + const char *key_delims =3D { "." }; > + 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 =3D 0; > + uint16_t i, j; > + uint8_t val_type =3D FM10K_CONFIG_VALUE_NULL; > + > + for (i =3D 0; i < 3; i++) { > + if (i =3D=3D 0) > + p =3D strtok(buff, cfg_delims); > + else > + p =3D strtok(NULL, cfg_delims); > + if (p =3D=3D NULL) > + return -1; > + strncpy(cfgs[i], p, FM10K_CONFIG_STR_MAX); > + } > + > + p =3D strtok(NULL, cfg_delims); > + if (p) > + return -1; > + > + memset(cmp_keys, 0, sizeof(cmp_keys)); > + for (i =3D 0; i < FM10K_CONFIG_WORD_MAX; i++) { > + if (i =3D=3D 0) > + p =3D strtok(cfgs[0], key_delims); > + else > + p =3D strtok(NULL, key_delims); > + if (p =3D=3D NULL) > + break; > + strncpy(cmp_keys[i], p, FM10K_CONFIG_WORD_LEN); > + } > + > + if (strcmp(cfgs[1], "int") =3D=3D 0) > + val_type =3D FM10K_CONFIG_VALUE_INT; > + else if (strcmp(cfgs[1], "string") =3D=3D 0) > + val_type =3D FM10K_CONFIG_VALUE_STR; > + else > + return -1; > + > + for (i =3D 0; i < FM10K_SW_NITEMS(fm10k_config_key_items); i++) { > + key =3D &fm10k_config_key_items[i]; > + for (j =3D 0; j < FM10K_CONFIG_WORD_MAX; j++) { > + if (key->key_str[j] && > + strlen(cmp_keys[j]) > 0) { > + if (strcmp(key->key_str[j], "*") =3D=3D 0) { > + key_param =3D strtol(cmp_keys[j], > &endptr, 10); > + if ((key_param =3D=3D 0 && endptr =3D=3D > cmp_keys[j]) || > + (endptr !=3D cmp_keys[j] > && strlen(endptr) !=3D 0)) > + break; > + } > + else if (strcmp(key->key_str[j], cmp_keys[j]) !=3D > 0) > + break; > + } > + else if (key->key_str[j] =3D=3D 0 && > + strlen(cmp_keys[j]) =3D=3D 0) { > + if (val_type =3D=3D FM10K_CONFIG_VALUE_STR) { > + item->val.str =3D malloc(strlen(cfgs[2]) + > 1); > + if (item->val.str =3D=3D NULL) > + return -1; > + strcpy(item->val.str, cfgs[2]); > + } > + else > + item->val.int64 =3D strtol(cfgs[2], NULL, > 10); > + item->type =3D key->type; > + item->key_param =3D key_param; > + item->val_type =3D val_type; > + return 0; > + } > + } > + } > + return -1; > +} > + > +static bool > +fm10k_config_blank_line_check(char *line) > +{ > + uint16_t i; > + > + for (i =3D 0; i < strlen(line); i++) { > + if (line[i] =3D=3D ' ' || > + line[i] =3D=3D '\n' || > + line[i] =3D=3D '\t' || line[i] =3D=3D 0x0d) /* 0d: CR */ > + continue; > + else > + return false; > + } > + return true; > +} > + > +static int > +fm10k_config_conf_file_load(void) > +{ > + int i =3D 0; > + FILE *fp; > + char buff[255]; > + struct fm10k_cfg_config_item* item; > + > + fp =3D fopen(fm10k_config_dpdk_conf_file, "r"); > + if (fp =3D=3D NULL) > + return -1; > + > + fm10k_config_dpdk_cfg.config_list =3D > + malloc(sizeof(struct fm10k_cfg_config_item) * > FM10K_SW_CONFIG_MAX); > + if (fm10k_config_dpdk_cfg.config_list =3D=3D 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] =3D=3D '#' || buff[0] =3D=3D 0) > + continue; > + > + if (fm10k_config_blank_line_check(buff)) > + continue; > + > + item =3D &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 =3D > 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 =3D new; > +} > + > +bool > +fm10k_config_flow_list_end(struct fm10k_cfg_flow *list, struct > fm10k_cfg_flow *flow) > +{ > + return (list =3D=3D flow); > +} > + > +static void > +fm10k_config_flow_list_init(struct fm10k_cfg_flow *list) > +{ > + list->next =3D list; > + list->prev =3D list; > +} > + > +static void > +fm10k_config_flow_list_add(struct fm10k_cfg_flow *new, struct > fm10k_cfg_flow *list) > +{ > + struct fm10k_cfg_flow *next =3D list->next; > + next->prev =3D new; > + new->next =3D next; > + new->prev =3D list; > + list->next =3D 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 =3D flow->next; > + flow->next->prev =3D flow->prev; > + flow->prev =3D NULL; > + flow->next =3D NULL; > +} > + > +struct fm10k_cfg_flowset * > +fm10k_config_flowset_get(const char* name) > +{ > + struct fm10k_cfg_flowset *flowset; > + > + flowset =3D fm10k_config_dpdk_cfg.flowset_head.next; > + while (flowset) { > + if (strcmp(flowset->name, name) =3D=3D 0) > + break; > + flowset =3D flowset->next; > + } > + > + if (flowset =3D=3D NULL) { > + flowset =3D malloc(sizeof(struct fm10k_cfg_flowset)); > + if (flowset =3D=3D NULL) > + return NULL; > + strcpy(flowset->name, name); > + fm10k_config_flow_list_init(&flowset->flow_head); > + flowset->next =3D fm10k_config_dpdk_cfg.flowset_head.next; > + fm10k_config_dpdk_cfg.flowset_head.next =3D 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 =3D NULL; > + > + if (flowset =3D=3D NULL) > + return -1; > + > + tmp =3D flowset->flow_head.next; > + while (!fm10k_config_flow_list_end(&flowset->flow_head, tmp)) { > + if (tmp->flow_no =3D=3D flow_no) { > + flow =3D tmp; > + break; > + } > + tmp =3D tmp->next; > + } > + if (flow =3D=3D NULL) { > + flow =3D malloc(sizeof(struct fm10k_cfg_flow)); > + memset(flow, 0, sizeof(struct fm10k_cfg_flow)); > + flow->flow_no =3D flow_no; > + fm10k_config_flow_list_add_tail(flowset, flow); > + } > + if (flow =3D=3D NULL) > + return -1; > + > + switch (type) { > + case FM10K_CONFIG_FLOW_COND_SRC_EXT_PORT: > + flow->src_port.port_type =3D FM10K_CONFIG_FLOW_EXT_PORT; > + flow->src_port.port_no =3D val; > + break; > + case FM10K_CONFIG_FLOW_COND_SRC_DPDK_PORT: > + flow->src_port.port_type =3D > FM10K_CONFIG_FLOW_DPDK_PORT; > + flow->src_port.port_no =3D val; > + break; > + case FM10K_CONFIG_FLOW_COND_VLAN: > + flow->src_port.vlan_id =3D val; > + break; > + case FM10K_CONFIG_FLOW_ACT_FW_EXT_PORT: > + if (flow->fw_port[0].port_type =3D=3D > FM10K_CONFIG_FLOW_NONE_PORT) { > + flow->fw_port[0].port_type =3D > FM10K_CONFIG_FLOW_EXT_PORT; > + flow->fw_port[0].port_no =3D val; > + } else { > + flow->fw_port[1].port_type =3D > FM10K_CONFIG_FLOW_EXT_PORT; > + flow->fw_port[1].port_no =3D val; > + } > + break; > + case FM10K_CONFIG_FLOW_ACT_FW_DPDK_PORT: > + if (flow->fw_port[0].port_type =3D=3D > FM10K_CONFIG_FLOW_NONE_PORT) { > + flow->fw_port[0].port_type =3D > FM10K_CONFIG_FLOW_DPDK_PORT; > + flow->fw_port[0].port_no =3D val; > + } else { > + flow->fw_port[1].port_type =3D > FM10K_CONFIG_FLOW_DPDK_PORT; > + flow->fw_port[1].port_no =3D val; > + } > + break; > + case FM10K_CONFIG_FLOW_ACT_FW_VALN: > + if (flow->fw_port[0].vlan_id =3D=3D 0) > + flow->fw_port[0].vlan_id =3D val; > + else > + flow->fw_port[1].vlan_id =3D 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 =3D NULL; > + > + for (i =3D 0; i < FM10K_SW_CONFIG_MAX; i++) { > + item =3D &(fm10k_config_dpdk_cfg.config_list[i]); > + if (item->type =3D=3D FM10K_CONFIG_TYPE_NULL) > + break; > + > + switch (item->type) { > + case FM10K_CONFIG_BIND_PF_NUMBER: > + fm10k_config_dpdk_cfg.pf_num =3D item->val.int64; > + break; > + case FM10K_CONFIG_EXT_PORT_SPEED: > + fm10k_config_dpdk_cfg.ext_port_speed =3D item- > >val.int64; > + break; > + case FM10K_CONFIG_DPDK_PORT_MAP_PF: > + if (fm10k_config_dpdk_cfg.dpdk_port_map[item- > >key_param].type > + =3D=3D FM10K_CONFIG_PORT_MAP_PF) { > + fm10k_config_dpdk_cfg.dpdk_port_map[item- > >key_param].type =3D FM10K_CONFIG_PORT_MAP_PFS; > + fm10k_config_dpdk_cfg.dpdk_port_map[item- > >key_param].map_no[1] =3D item->val.int64; > + } else { > + fm10k_config_dpdk_cfg.dpdk_port_map[item- > >key_param].type =3D FM10K_CONFIG_PORT_MAP_PF; > + fm10k_config_dpdk_cfg.dpdk_port_map[item- > >key_param].map_no[0] =3D item->val.int64; > + } > + break; > + case FM10K_CONFIG_EXT_PORT_MAP_PF: > + if (fm10k_config_dpdk_cfg.ext_port_map[item- > >key_param-1].type > + =3D=3D FM10K_CONFIG_PORT_MAP_PF) { > + fm10k_config_dpdk_cfg.ext_port_map[item- > >key_param-1].type =3D FM10K_CONFIG_PORT_MAP_PFS; > + fm10k_config_dpdk_cfg.ext_port_map[item- > >key_param-1].map_no[1] =3D item->val.int64; > + } else { > + fm10k_config_dpdk_cfg.ext_port_map[item- > >key_param-1].type =3D FM10K_CONFIG_PORT_MAP_PF; > + fm10k_config_dpdk_cfg.ext_port_map[item- > >key_param-1].map_no[0] =3D 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 =3D item->type-FM10K_CONFIG_DEBUG_START; > + tmp =3D fm10k_config_dpdk_cfg.debug_cfg; > + data =3D 1; > + if (item->val.int64 !=3D 1) > + fm10k_config_dpdk_cfg.debug_cfg =3D tmp & > ~(data< + else > + fm10k_config_dpdk_cfg.debug_cfg |=3D > (data< + break; > + case FM10K_CONFIG_DEBUG_STATS_INTERVAL: > + fm10k_config_dpdk_cfg.stats_interval =3D item- > >val.int64; > + break; > + > + case FM10K_CONFIG_FLOWSET_START: > + item->val.str[strlen(item->val.str) - 2] =3D 0; /* skip /r/n */ > + flowset =3D fm10k_config_flowset_get(item->val.str); > + if (flowset =3D=3D NULL) > + return -1; > + break; > + case FM10K_CONFIG_FLOWSET_STOP: > + flowset =3D NULL; > + break; > + case FM10K_CONFIG_FLOWSET_ENABLE: > + item->val.str[strlen(item->val.str)-2] =3D 0; /* skip /r/n */ > + fm10k_config_dpdk_cfg.current =3D > 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 =3D=3D NULL || > + fm10k_cfg_flow_item_set(flowset, > item->key_param, item->type, item->val.int64) !=3D 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) =3D=3D 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] =3D ""; > + > + fp =3D fopen(fm10k_config_dpdk_conf_file, "w"); > + if (fp =3D=3D NULL) > + return -1; > + > + for (i =3D 0; i < FM10K_SW_CONFIG_MAX; i++) { > + item =3D &(fm10k_config_dpdk_cfg.config_list[i]); > + if (item->type =3D=3D FM10K_CONFIG_TYPE_NULL) > + break; > + buff[0] =3D 0; > + if (strlen(item->describe) > 0) > + sprintf(buff, "\n\n%s\n", item->describe); > + for (j =3D 0; j < FM10K_SW_NITEMS(fm10k_config_key_items); j++) > { > + key =3D &fm10k_config_key_items[j]; > + if (item->type =3D=3D key->type) { > + for (k =3D 0; k < FM10K_CONFIG_WORD_MAX; > k++) { > + if (key->key_str[k] =3D=3D 0) > + break; > + if (k =3D=3D 0) > + sprintf(buff+strlen(buff), "%s", > key->key_str[k]); > + else { > + if (strcmp(key->key_str[k], "*") > =3D=3D 0) > + > sprintf(buff+strlen(buff), ".%u", item->key_param); > + else > + > sprintf(buff+strlen(buff), ".%s", key->key_str[k]); > + } > + } > + if (item->val_type =3D=3D > FM10K_CONFIG_VALUE_INT) > + sprintf(buff+strlen(buff), " int %lld\n", > (long long int)item->val.int64); > + else if (item->val_type =3D=3D > 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 =3D fm10k_config_dpdk_cfg.flowset_head.next; > + while (flowset) { > + printf("\n FLOWSET : %s\n", flowset->name); > + struct fm10k_cfg_flow* flow =3D flowset->flow_head.next; > + while (!fm10k_config_flow_list_end(&flowset->flow_head, > flow)) { > + const char *port_type[3] =3D { "NON", "EXT", "DPDK" }; > + if (flow->fw_port[1].port_type !=3D > 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_i= d, > + port_type[flow- > >fw_port[1].port_type], flow->fw_port[1].port_no, flow->fw_port[1].vlan_i= d); > + } 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_i= d); > + } > + flow =3D flow->next; > + } > + flowset =3D 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 =3D 0; i < fm10k_config_dpdk_cfg.ext_port_num; i++) { > + if (fm10k_config_dpdk_cfg.ext_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_NULL) > + continue; > + if (fm10k_config_dpdk_cfg.ext_port_map[i].type =3D=3D > 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 =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + if (fm10k_config_dpdk_cfg.dpdk_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_NULL) > + continue; > + if (fm10k_config_dpdk_cfg.ext_port_map[i].type =3D=3D > 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 =3D fm10k_config_dpdk_cfg.flowset_head.next; > + while (flowset) { > + printf("\n FLOWSET : %s\n", flowset->name); > + struct fm10k_cfg_flow* flow =3D flowset->flow_head.next; > + while (!fm10k_config_flow_list_end(&flowset->flow_head, > flow)) { > + const char *port_type[3] =3D { "NON", "EXT", "DPDK" }; > + if (flow->fw_port[1].port_type !=3D > 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_i= d, > + port_type[flow- > >fw_port[1].port_type], flow->fw_port[1].port_no, flow->fw_port[1].vlan_i= d); > + } 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_i= d); > + } > + flow =3D flow->next; > + } > + flowset =3D flowset->next; > + } > + printf("\n"); > +} > + > +int > +fm10k_config_init(struct fm10k_switch *sw, struct fm10k_hw *hw) > +{ > + struct fm10k_device_info *info =3D fm10k_get_device_info(hw); > + > + fm10k_config_dpdk_cfg.stats_interval =3D 2; > + fm10k_config_dpdk_cfg.pf_max =3D info->num_peps; > + fm10k_config_dpdk_cfg.ext_port_num =3D info->num_ext_ports; > + > + if (!fm10k_config_conf_file_exist()) { > + if (info->num_epls =3D=3D 2 && info->num_peps =3D=3D 2) > + fm10k_config_dpdk_cfg.config_list =3D > fm10k_silc_nic_2ext_2pep; > + else if (info->num_epls =3D=3D 2 && info->num_peps =3D=3D 4) > + fm10k_config_dpdk_cfg.config_list =3D > 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 =3D &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 > +#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 > + > +#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_)) =3D=3D > 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, unsi= gned > int eplno); > +static void fm10k_ext_port_intr(struct fm10k_ext_port *port, uint32_t ep= l_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 =3D sw->pep; > + struct fm10k_ext_ports *ports; > + struct fm10k_ext_port *port; > + struct fm10k_ext_port_lane *lane; > + struct fm10k_device_info *cfg =3D sw->info; > + unsigned int is_quad, lane_speed; > + unsigned int i, j; > + unsigned int eplidx, laneno; > + > + FM10K_SW_TRACE("attaching external ports\n"); > + > + ports =3D (struct fm10k_ext_ports *)rte_zmalloc("fm10k_ext_ports", > sizeof(struct fm10k_ext_ports), 0); > + if (ports =3D=3D NULL) { > + FM10K_SW_ERR("failed to allocate external ports\n"); > + goto fail; > + } > + > + ports->ports =3D (struct fm10k_ext_port > *)rte_zmalloc("fm10k_ext_port_list", sizeof(struct fm10k_ext_port)*cfg- > >num_ext_ports, 0); > + if (ports->ports =3D=3D NULL) { > + FM10K_SW_ERR("failed to allocate external ports list\n"); > + goto fail; > + } > + ports->sw =3D sw; > + ports->num_ports =3D cfg->num_ext_ports; > + ports->ports_per_epl =3D cfg->num_ext_ports / cfg->num_epls; > + ports->epl_mask =3D 0; > + > + switch (cfg->ext_port_speed) { > + default: > + case 10: > + is_quad =3D 0; > + lane_speed =3D 10; > + break; > + case 25: > + is_quad =3D 0; > + lane_speed =3D 25; > + break; > + case 40: > + is_quad =3D 1; > + lane_speed =3D 10; > + break; > + case 100: > + is_quad =3D 1; > + lane_speed =3D 25; > + break; > + } > + > + for (i =3D 0; i < ports->num_ports; i++) { > + port =3D &ports->ports[i]; > + port->ports =3D ports; > + fm10k_ext_port_eplidx_lane(ports, i, &eplidx, &laneno); > + port->portno =3D i; > + port->eplno =3D fm10k_switch_eplidx_to_eplno(sw, eplidx); > + snprintf(port->name, sizeof(port->name), "EPL[%u][%u]", > + port->eplno, port->first_lane); > + port->first_lane =3D laneno; > + port->is_quad =3D is_quad; > + port->num_lanes =3D port->is_quad ? 4 : 1; > + port->lane_speed =3D lane_speed; > + port->sm =3D fm10k_sm_attach( > + FM10K_SW_EXT_PORT_NUM_EVENTS, 0, > + fm10k_ext_port_process_event, NULL, > + (void*)port); > + if (port->sm =3D=3D NULL) > + goto fail; > + port->sm->portno =3D port->portno; > + port->sm->laneno =3D 0; > + port->an_im =3D FM10K_SW_AN_IM_ALL; > + port->link_im =3D FM10K_SW_LINK_IM_ALL; > + > + for (j =3D port->first_lane; > + j < port->first_lane + port->num_lanes; j++) { > + lane =3D &port->lanes[j]; > + lane->port =3D port; > + lane->abs_laneno =3D port->eplno * > FM10K_SW_EPL_LANES + j; > + lane->rel_laneno =3D j; > + lane->im =3D FM10K_SW_SERDES_IM_ALL; > + lane->sm =3D 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 =3D=3D NULL) > + goto fail; > + lane->sm->portno =3D lane->port->portno; > + lane->sm->laneno =3D lane->rel_laneno; > + } > + > + ports->epl_mask |=3D (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 =3D 0; i < ports->num_ports; i++) { > + port =3D &ports->ports[i]; > + > + if (port->sm) > + fm10k_sm_detach(port->sm); > + for (j =3D port->first_lane; > + j < port->first_lane + port->num_lanes; j++) { > + lane =3D &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 =3D ports->epl_mask & > + FM10K_SW_REG_FIELD64(gid, GLOBAL_INTERRUPT_DETECT_EPL); > + for (i =3D 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 epl= no) > +{ > + struct fm10k_switch *sw =3D 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 =3D 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 =3D 0; i < ports->num_ports; i++) { > + port =3D &ports->ports[i]; > + if (port->eplno !=3D 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 =3D 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 =3D 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 =3D 0; i < ports->num_ports; i++) { > + port =3D &ports->ports[i]; > + if (port->eplno !=3D 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 =3D port->ports->sw; > + struct fm10k_ext_port_lane *lane; > + unsigned int i; > + uint32_t serdes_ip, data =3D 0; > + > + for (i =3D port->first_lane; > + i < port->first_lane + port->num_lanes; i++) { > + lane =3D &port->lanes[i]; > + if (epl_ip & FM10K_SW_EPL_IP_SERDES_INTERRUPT(i)) { > + FM10K_SW_SWITCH_LOCK(sw); > + serdes_ip =3D fm10k_read_switch_reg(sw, > + FM10K_SW_SERDES_IP(port->eplno, i)); > + serdes_ip &=3D ~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 =3D 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 i= nt > */ > + unsigned int port_state =3D port->sm->state; > + > + return (port_state =3D=3D 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 =3D 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 =3D=3D PORT_EVENT(BRING_UP)) { > + fm10k_ext_port_phy_enable(port); > + > + for (i =3D port->first_lane; > + i < port->first_lane + port->num_lanes; i++) { > + lane =3D &port->lanes[i]; > + fm10k_sm_send_event(lane->sm, > LANE_EVENT(BRING_UP)); > + } > + sm->state =3D PORT_STATE(WAITING_FOR_LANES); > + } > + break; > + > + case PORT_STATE(WAITING_FOR_LANES): > + if (event =3D=3D PORT_EVENT(LANE_UP)) { > + lanes_up =3D 0; > + for (i =3D port->first_lane; > + i < port->first_lane + port->num_lanes; i++) { > + lane =3D &port->lanes[i]; > + if (lane->sm->state !=3D LANE_STATE(UP)) > + break; > + lanes_up++; > + } > + if (lanes_up =3D=3D port->num_lanes) > + { > + sm->state =3D PORT_STATE(UP); > + FM10K_SW_INFO("Port %d is LINK UP", port- > >portno); > + } > + } else if (event =3D=3D PORT_EVENT(BRING_DOWN)) { > + fm10k_ext_port_bring_down(port); > + } > + break; > + > + case PORT_STATE(UP): > + if (event =3D=3D PORT_EVENT(LANE_DOWN)) { > + sm->state =3D PORT_STATE(WAITING_FOR_LANES); > + FM10K_SW_INFO("Port %d is LINK DOWN", port- > >portno); > + } else if (event =3D=3D 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 =3D port->sm; > + struct fm10k_ext_port_lane *lane; > + unsigned int i; > + > + sm->state =3D PORT_STATE(DOWN); > + > + fm10k_ext_port_phy_disable(port); > + > + for (i =3D port->first_lane; > + i < port->first_lane + port->num_lanes; i++) { > + lane =3D &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 =3D sm->ctx; > + struct fm10k_ext_port *port =3D lane->port; > + struct fm10k_switch *sw =3D 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 =3D=3D LANE_EVENT(BRING_UP)) { > + lane->flags &=3D ~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 =3D fm10k_epl_serdes_start_bringup(lane); > + if (error =3D=3D 0) { > + sm->state =3D LANE_STATE(WAIT_PLL_LOCK); > + > + /* > + * Enable PLL lock interrupts. > + */ > + lane->im &=3D > ~(FM10K_SW_SERDES_IM_RX_RDY | > + FM10K_SW_SERDES_IM_TX_RDY); > + } > + } > + break; > + > + case LANE_STATE(WAIT_PLL_LOCK): > + if ((event =3D=3D LANE_EVENT(RX_PLL_LOCK)) || > + (event =3D=3D LANE_EVENT(TX_PLL_LOCK))) { > + if (event =3D=3D LANE_EVENT(RX_PLL_LOCK)) > + lane->flags |=3D LANE_FLAG(RX_LOCKED); > + if (event =3D=3D LANE_EVENT(TX_PLL_LOCK)) > + lane->flags |=3D LANE_FLAG(TX_LOCKED); > + if (LANE_FLAGS_SET(lane, PLLS_LOCKED)) { > + error =3D > fm10k_epl_serdes_continue_bringup(lane); > + if (error =3D=3D 0) { > + sm->state =3D > LANE_STATE(WAIT_SIGNAL_OK); > + /* unmask RX signal OK interrupt */ > + lane->im |=3D > (FM10K_SW_SERDES_IM_RX_RDY | > + FM10K_SW_SERDES_IM_TX_RDY); > + lane->im &=3D > ~FM10K_SW_SERDES_IM_RX_SIGNAL_OK; > + } > + } > + } else if (event =3D=3D LANE_EVENT(BRING_DOWN)) { > + fm10k_ext_port_disable_lane(lane); > + } > + break; > + > + case LANE_STATE(WAIT_SIGNAL_OK): > + if (event =3D=3D LANE_EVENT(SIGNAL_OK)) { > + sm->state =3D 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 =3D 0; > + fm10k_sm_timer_start(sm, LANE_TIMER(DFE_TUNING), > + LANE_POLL(DFE_ICAL)); > + } else if (event =3D=3D LANE_EVENT(BRING_DOWN)) { > + fm10k_ext_port_disable_lane(lane); > + } > + break; > + > + case LANE_STATE(WAIT_DFE_ICAL): > + if (event =3D=3D LANE_EVENT(DFE_TUNING_COMPLETE)) { > + sm->state =3D LANE_STATE(WAIT_DFE_PCAL); > + > + fm10k_epl_serdes_start_dfe_pcal(lane); > + > + lane->dfe_poll_time_ms =3D 0; > + fm10k_sm_timer_start(sm, LANE_TIMER(DFE_TUNING), > + LANE_POLL(DFE_PCAL)); > + } else if ((event =3D=3D LANE_EVENT(DFE_TUNING_FAILED)) || > + (event =3D=3D LANE_EVENT(DFE_TUNING_TIMED_OUT))) { > + fm10k_ext_port_restart_lane(lane); > + } else if (event =3D=3D LANE_EVENT(BRING_DOWN)) { > + fm10k_ext_port_disable_lane(lane); > + } > + break; > + > + case LANE_STATE(WAIT_DFE_PCAL): > + if (event =3D=3D LANE_EVENT(DFE_TUNING_COMPLETE)) { > + fm10k_epl_serdes_set_signal_detect(lane, > + FM10K_SW_LANE_OVERRIDE_NORMAL); > + > + sm->state =3D LANE_STATE(UP); > + fm10k_sm_send_event(port->sm, > PORT_EVENT(LANE_UP)); > + } else if ((event =3D=3D LANE_EVENT(DFE_TUNING_FAILED)) || > + (event =3D=3D LANE_EVENT(DFE_TUNING_TIMED_OUT)) || > + (event =3D=3D LANE_EVENT(SIGNAL_NOK))) { > + fm10k_ext_port_restart_lane(lane); > + } else if (event =3D=3D LANE_EVENT(BRING_DOWN)) { > + fm10k_ext_port_disable_lane(lane); > + } > + break; > + > + case LANE_STATE(UP): > + if (event =3D=3D LANE_EVENT(SIGNAL_NOK)) { > + fm10k_ext_port_restart_lane(lane); > + } else if (event =3D=3D 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 =3D sm->ctx; > + uint32_t status; > + > + switch (sm->state) { > + case LANE_STATE(WAIT_DFE_ICAL): > + if (timer =3D=3D LANE_TIMER(DFE_TUNING)) { > + lane->dfe_poll_time_ms +=3D LANE_POLL(DFE_ICAL); > + fm10k_epl_serdes_dfe_ical_status(lane, &status); > + > + if (status =3D=3D > 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 =3D=3D > 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 =3D=3D LANE_TIMER(DFE_TUNING)) { > + lane->dfe_poll_time_ms +=3D LANE_POLL(DFE_PCAL); > + > + fm10k_epl_serdes_dfe_pcal_status(lane, &status); > + if (status =3D=3D > 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 =3D lane->sm; > + struct fm10k_ext_port *port =3D lane->port; > + int error; > + > + error =3D fm10k_epl_serdes_start_bringup(lane); > + if (error =3D=3D 0) { > + sm->state =3D LANE_STATE(WAIT_PLL_LOCK); > + > + /* > + * Enable PLL lock interrupts. > + */ > + lane->flags &=3D > ~FM10K_SW_EXT_PORT_LANE_FLAGS_PLLS_LOCKED; > + lane->im |=3D FM10K_SW_SERDES_IM_RX_SIGNAL_OK; > + lane->im =3D ~(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 =3D lane->sm; > + > + fm10k_sm_timer_cancel(sm, LANE_TIMER(DFE_TUNING)); > + fm10k_epl_serdes_disable(lane); > + > + /* > + * Disable all interrupts. > + */ > + lane->im =3D FM10K_SW_SERDES_IM_ALL; > + > + sm->state =3D 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 =3D ext_port_idx / ports->ports_per_epl; > + *lane =3D ext_port_idx % ports->ports_per_epl; > +} > + > + > +static void > +fm10k_ext_port_phy_enable(struct fm10k_ext_port *port) > +{ > + struct fm10k_switch *sw =3D port->ports->sw; > + struct fm10k_device_info *cfg =3D 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 =3D=3D 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 =3D=3D 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 =3D=3D 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=3D0x%04x subdevice=3D0x%04x)\n", > + cfg->subvendor, cfg->subdevice); > + break; > + } > +} > + > +static void > +fm10k_ext_port_phy_disable(struct fm10k_ext_port *port) > +{ > + struct fm10k_switch *sw =3D port->ports->sw; > + struct fm10k_device_info *cfg =3D 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 =3D=3D 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 =3D=3D 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 =3D=3D 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=3D0x%04x subdevice=3D0x%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] =3D { > + 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 =3D id/8; > + int offset =3D id%8; > + > + return (fm10k_ffu_bitmap[num]>>offset)&0x1; > +} > + > +static void > +fm10k_ffu_rule_set_bit(int id, uint8_t bit) > +{ > + int num =3D id/8; > + int offset =3D id%8; > + uint8_t tmp =3D fm10k_ffu_bitmap[num]; > + uint8_t data =3D 1; > + > + if (bit =3D=3D 0) > + fm10k_ffu_bitmap[num] =3D tmp & ~(data< + else > + fm10k_ffu_bitmap[num] |=3D (data< +} > + > +static int > +fm10k_ffu_rule_alloc(void) > +{ > + int i; > + > + for (i =3D FM10K_FFU_FLOW_START; i < FM10K_FFU_RULE_MAX; i++) > + { > + if (fm10k_ffu_rule_get_bit(i) !=3D 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 =3D > + 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 =3D FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY, > sglort); > + temp64_2 =3D 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 =3D 0x40; > + temp64 =3D temp64<<32 | > + > FM10K_SW_MAKE_REG_FIELD(FFU_SLICE_SRAM_ROUTE_GLORT_DGLORT, > dglort); > + temp64 |=3D 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 =3D FM10K_SW_FFU_CNT_BANK<<(35-23) | > (FM10K_SW_FFU_CNT_START+idx); > + temp64 |=3D 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 =3D (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 =3D 0; > + for (i =3D 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 =3D 16 / num_dports; > + hashed_entries =3D num_dports * amplification_factor; > + temp64 =3D FM10K_SW_MAKE_REG_FIELD64( > + GLORT_RAM_STRICT, > + FM10K_SW_GLORT_RAM_STRICT_HASHED); > + temp64 |=3D > FM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_DEST_INDEX, sw- > >glort_dest_table_idx); > + temp64 |=3D > FM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_DEST_COUNT, hashed_entries); > + fm10k_write_switch_reg64(sw, FM10K_SW_GLORT_RAM(idx), > temp64); > + > + for (i =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) > + if (dport_mask & (1ULL << i)) > + for (j =3D 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 =3D FM10K_SW_MAKE_REG_FIELD64( > + GLORT_RAM_STRICT, > + FM10K_SW_GLORT_RAM_STRICT_STRICT); > + temp64 |=3D > 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 =3D 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 lpo= rt1, > uint8_t lport2, uint16_t vlan1, uint16_t vlan2) > +{ > + uint32_t dglort; > + bool is_new; > + uint32_t idx; > + uint64_t temp64; > + > + dglort =3D 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 =3D 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 =3D FM10K_SW_MAKE_REG_FIELD64( > + GLORT_RAM_STRICT, > + FM10K_SW_GLORT_RAM_STRICT_STRICT); > + temp64 |=3D 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 =3D sw->mcast_dest_table_idx; > + temp64 =3D temp64<<48 | 1< + 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 =3D sw->mcast_len_table_idx; > + temp64 =3D 1< + 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 =3D 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 =3D 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 =3D 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 =3D data; > + > + if (start =3D=3D end) > + tmp64 =3D data>>start & 1; > + else { > + tmp64 =3D tmp64<<(64-end); > + tmp64 =3D tmp64>>(64-end+start); > + } > + return tmp64; > +} > + > +static uint32_t > +fm10k_data64_field32_get(uint64_t data, int start, int end) > +{ > + uint64_t tmp64 =3D data; > + uint32_t tmp32; > + > + if (start =3D=3D end) > + tmp32 =3D data>>start & 1; > + else { > + tmp64 =3D tmp64<<(64-end); > + tmp32 =3D tmp64>>(64-end+start); > + } > + return tmp32; > +} > + > +static uint32_t > +fm10k_data32_field_get(uint32_t data, int start, int end) > +{ > + uint32_t tmp32 =3D data; > + > + if (start =3D=3D end) > + tmp32 =3D data>>start & 1; > + else { > + tmp32 =3D tmp32<<(64-end); > + tmp32 =3D 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 =3D 0; i < sw->glort_cam_ram_idx; i++) { > + data32 =3D 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 =3D 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 =3D fm10k_data64_field32_get(data64, 2, 13); > + data64 =3D 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 =3D fm10k_data64_field32_get(data64, 48, 59); > + if (tmp32 =3D=3D 0) > + continue; > + data64 =3D 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 =3D fm10k_data64_field32_get(data64, 48, 61); > + data32 =3D 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 =3D fm10k_data32_field_get(data32, 0, 14); > + data32 =3D 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 =3D 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 =3D data[0]; > + > + for (i =3D 0; i < 32; i++) > + { > + if ((ffu_valid & 1< + continue; > + > + printf("------ SLICE%d ------\n", i); > + > + fm10k_read_switch_array(sw, FM10K_SW_FFU_SLICE_VALID(i), > data, 2); > + if (data[0] !=3D 0 || data[1] !=3D 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] !=3D 0 || data[1] !=3D 0) > + printf("FFU_SLICE_CASCADE_ACTION[%d]: %#x %#x\n", > i, data[0], data[1]); > + > + for (j =3D 0; j < 1; j++) > + { > + fm10k_read_switch_array(sw, > FM10K_SW_FFU_SLICE_CFG(i, j), data, 2); > + if (data[0] !=3D 0 || data[1] !=3D 0) > + printf("FFU_SLICE_CFG[%d][%d]: %#x %#x\n", i, > j, data[0], data[1]); > + } > + for (j =3D 0; j < 32; j++) { > + fm10k_read_switch_array(sw, > FM10K_SW_FFU_SLICE_TCAM(i, j), data, 4); > + if ((data[0] !=3D 0 || data[1] !=3D 0 || data[2] !=3D 0 || > data[3] !=3D 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] !=3D 0 || data[1] !=3D 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 =3D 0x60; /* higher than route, not necessary */ > + data64 =3D 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 =3D vlan; > + data64 =3D (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 =3D FM10K_FFU_SLICE_SGLORT_VID + 1; > + uint16_t mirror_profile =3D FM10K_FFU_MIRROR_PROFILE; > + > + table_idx =3D 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 =3D FM10K_FFU_SLICE_SGLORT_VID + 1; > + > + table_idx =3D 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 =3D fm10k_read_switch_reg64(sw, 0xE80000 + 0x2*vlan_id + > 0x20000); > + data |=3D 1< + 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 =3D 0; i < FM10K_SW_PEPS_SUPPORTED; i++) { > + if (sw->pep_map[i].glort =3D=3D glort) { > + fm10k_ffu_logical_port_vlan_set(sw, sw- > >pep_map[i].logical_port, vlan_id); > + break; > + } > + } > + for (i =3D 0; i < FM10K_SW_EPLS_SUPPORTED; i++) { > + if (sw->epl_map[i].glort =3D=3D 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 =3D 0; > + > + if (sw->dpdk_cfg->dpdk_port_map[port].type =3D=3D > FM10K_CONFIG_PORT_MAP_PFS || > + sw->dpdk_cfg->dpdk_port_map[port].type =3D=3D > FM10K_CONFIG_PORT_MAP_PFSS) { > + glort =3D 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 =3D=3D > FM10K_CONFIG_PORT_MAP_PF) { > + pf =3D sw->dpdk_cfg->dpdk_port_map[port].map_no[0]; > + glort =3D 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 =3D 0, sglort_vid_tcam_mask =3D 0; > + uint64_t sram[4] =3D { 0, 0, 0, 0 }; > + uint16_t sram_idx =3D 0, tcam_slice, sram_slice, i; > + > + sglort_vid_tcam |=3D sglort; > + sglort_vid_tcam_mask |=3D 0xffff; > + if (svlan) { > + temp64 =3D svlan; > + sglort_vid_tcam |=3D temp64<<16; > + sglort_vid_tcam_mask |=3D 0xfff0000; > + fm10k_ffu_glort_port_vlan_set(sw, sglort, svlan); > + } > + > + /* set counter */ > + sram[sram_idx] |=3D > 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] |=3D > 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 =3D 3; /* Force updating VLAN tag if present. Add if > absent. 11.5.3.4 */ > + sram[sram_idx] =3D 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 =3D FM10K_FFU_SLICE_SGLORT_VID; > + temp64 =3D > 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 =3D 0; i < sram_idx; i++) { > + sram_slice =3D 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 =3D 0, sglort_vid_tcam_mask =3D 0; > + uint64_t sram[4] =3D { 0, 0, 0, 0 }; > + uint16_t sram_idx =3D 0, tcam_slice, sram_slice, i; > + > + dglort =3D fm10k_ffu_set_dest_glort_multi_cast(sw, lport1, lport2, vlan= 1, > vlan2); > + > + sglort_vid_tcam |=3D sglort; > + sglort_vid_tcam_mask |=3D 0xffff; > + if (svlan) { > + temp64 =3D svlan; > + sglort_vid_tcam |=3D temp64<<16; > + sglort_vid_tcam_mask |=3D 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] |=3D > 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] |=3D > 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 =3D FM10K_FFU_SLICE_SGLORT_VID; > + temp64 =3D > 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 =3D 0; i < sram_idx; i++) > + { > + sram_slice =3D 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 =3D 0; > + uint16_t svlan =3D 0; > + uint16_t dglort =3D 0; > + uint16_t dvlan =3D 0; > + uint16_t lport1 =3D 0, lport2 =3D 0; > + uint16_t dvlan2 =3D 0; > + > + switch (flow->src_port.port_type) { > + case FM10K_CONFIG_FLOW_EXT_PORT: > + sglort =3D fm10k_switch_epl_glort_get(flow->src_port.port_no - > 1); > + break; > + case FM10K_CONFIG_FLOW_DPDK_PORT: > + sglort =3D 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 =3D fm10k_switch_epl_glort_get(flow->fw_port[0].port_no > - 1); > + lport1 =3D fm10k_switch_epl_logical_get(flow- > >fw_port[0].port_no - 1); > + break; > + case FM10K_CONFIG_FLOW_DPDK_PORT: > + dglort =3D fm10k_ffu_dpdk_port_glort_get(sw, flow- > >fw_port[0].port_no); > + lport1 =3D fm10k_switch_pf_logical_get(flow- > >fw_port[0].port_no); > + break; > + } > + svlan =3D flow->src_port.vlan_id; > + dvlan =3D flow->fw_port[0].vlan_id; > + > + flow->rule_id =3D fm10k_ffu_rule_alloc(); > + > + FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, "Set rule cond sglort:%#x, > vlan:%d =3D=3D> 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 =3D fm10k_switch_epl_glort_get(flow- > >fw_port[1].port_no - 1); > + lport2 =3D fm10k_switch_epl_logical_get(flow- > >fw_port[1].port_no - 1); > + break; > + case FM10K_CONFIG_FLOW_DPDK_PORT: > + dglort =3D fm10k_ffu_dpdk_port_glort_get(sw, flow- > >fw_port[1].port_no); > + lport2 =3D fm10k_switch_pf_logical_get(flow- > >fw_port[1].port_no); > + break; > + } > + dvlan2 =3D 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 =3D=3D 0) > + return; > + > + FM10K_FFU_RULE_PRINT(sw->dpdk_cfg, "Remove flow %d rule %d\n", > flow->flow_no, flow->rule_id); > + > + for (i =3D 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 =3D fm10k_config_flowset_current_get(); > + flow =3D flowset->flow_head.next; > + while (!fm10k_config_flow_list_end(&flowset->flow_head, flow)) { > + fm10k_ffu_flow_enable(sw, flow); > + flow =3D 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 =3D fm10k_config_flowset_current_get(); > + if (strcmp(cur_fs->name, new_name) =3D=3D 0) > + return; > + > + flowset =3D fm10k_config_flowset_get(new_name); > + if (flowset =3D=3D NULL) { > + FM10K_SW_ERR("Can not find flowset %s!!\n", new_name); > + return; > + } > + > + /* disable current flowset */ > + flow =3D cur_fs->flow_head.next; > + while (!fm10k_config_flow_list_end(&cur_fs->flow_head, flow)) { > + fm10k_ffu_flow_disable(sw, flow); > + flow =3D flow->next; > + } > + > + /* enable new flowset */ > + fm10k_config_flowset_current_set(flowset); > + flow =3D flowset->flow_head.next; > + while (!fm10k_config_flow_list_end(&flowset->flow_head, flow)) { > + fm10k_ffu_flow_enable(sw, flow); > + flow =3D flow->next; > + } > +} > + > + > +int > +fm10k_ffu_init(struct fm10k_switch *sw, struct fm10k_dpdk_cfg *cfg) > +{ > + int ret =3D 0; > + uint64_t data64; > + uint16_t i, j; > + uint32_t sglort =3D 0, dglort =3D 0; > + uint16_t table_idx =3D 0; > + uint16_t ffu_slice =3D FM10K_FFU_SLICE_START; > + > + sw->mcast_dest_table_idx =3D 1; > + sw->mcast_len_table_idx =3D 1; > + sw->mcast_vlan_table_idx =3D 1; > + > + for (i =3D 0; i < sizeof(fm10k_ffu_slice_cfgs)/sizeof(uint64_t); i++) { > + for (j =3D 0; j < FM10K_SW_FFU_NUM_SCENARIOS; j++) { > + data64 =3D 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 =3D %#llx\n", > + FM10K_FFU_SLICE_START+i, (unsigned long > long)data64); > + } > + > + for (table_idx=3D0; table_idx < FM10K_SW_FFU_SLICE_TCAM_ENTRIES/2; > table_idx++) > + for (i =3D 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 =3D 0; i < FM10K_SW_EXT_PORTS_MAX; i++) { > + if (cfg->ext_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_NULL) > + continue; > + > + if (cfg->ext_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PF) { > + sglort =3D fm10k_switch_epl_glort_get(i); > + dglort =3D fm10k_switch_pf_glort_get(cfg- > >ext_port_map[i].map_no[0]); > + } else if (cfg->ext_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PFS) { > + sglort =3D fm10k_switch_epl_glort_get(i); > + dglort =3D fm10k_switch_pfs_glort_get(cfg- > >ext_port_map[i].map_no[0], cfg->ext_port_map[i].map_no[1]); > + } > + > + table_idx =3D 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 =3D 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 =3D 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 =3D 0; > + for (i =3D ffu_slice; i < FM10K_SW_FFU_NUM_SLICES; i++) > + data64 |=3D 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 =3D 0; i < sw->info->num_peps; i++) { > + if (sw->pep_map[i].glort =3D=3D 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 =3D 0; i < FM10K_SW_EPLS_SUPPORTED; i++) { > + if (sw->epl_map[i].glort =3D=3D 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 =3D 0; i < FM10K_SW_EXT_PORTS_MAX; i++) { > + uint64_t dport_mask =3D 0; > + > + if (cfg->ext_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PFS) { > + dglort =3D fm10k_switch_pfs_glort_get(cfg- > >ext_port_map[i].map_no[0], cfg->ext_port_map[i].map_no[1]); > + dport_mask =3D 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=3Dsw->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 =3D 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 > + > +#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 > + > +#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 =3D (struct fm10k_i2c *)rte_zmalloc("fm10k_i2c", sizeof(struct > fm10k_i2c), 0); > + if (i2c =3D=3D NULL) { > + FM10K_SW_INFO("i2c: failed to allocate context"); > + goto fail; > + } > + > + i2c->sw =3D 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 =3D i2c->sw; > + struct fm10k_device_info *cfg =3D sw->info; > + uint32_t freq =3D FM10K_SW_I2C_CFG_DIVIDER_400_KHZ; > + uint32_t data; > + > + if (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice) =3D=3D > + FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4)) > + freq =3D 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 =3D fm10k_read_switch_reg(sw, FM10K_SW_I2C_CFG); > + data &=3D ~FM10K_SW_I2C_CFG_SLAVE_ENABLE; > + if (FM10K_SW_CARD_ID(cfg->subvendor, cfg->subdevice) =3D=3D > + FM10K_SW_CARD(SILICOM, PE3100G2DQIRM_QXSL4)) > + FM10K_SW_REPLACE_REG_FIELD(data, I2C_CFG_DIVIDER, freq); > + data &=3D ~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) =3D=3D > + 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 =3D i2c->sw; > + struct fm10k_i2c_req *req; > + int i; > + uint32_t data[3]; > + uint32_t ctrl; > + > + req =3D i2c->cur_req; > + > + FM10K_SW_SWITCH_LOCK(sw); > + ctrl =3D 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 =3D FM10K_SW_REG_FIELD(ctrl, > I2C_CTRL_COMMAND_COMPLETED); > + > + if ((req->cmd =3D=3D FM10K_SW_I2C_COMMAND_RD || > + req->cmd =3D=3D FM10K_SW_I2C_COMMAND_WR_RD) && > + req->status =3D=3D FM10K_SW_I2C_COMPLETION_NORMAL) { > + > + for (i =3D 0; i < FM10K_SW_HOWMANY(req->read_len, 4); i++) > + data[i] =3D fm10k_read_switch_reg(sw, > FM10K_SW_I2C_DATA(i)); > + > + switch (req->read_len) { > + case 12: req->msg[11] =3D data[2] & 0xff; /* FALLTHROUGH > */ > + case 11: req->msg[10] =3D (data[2] >> 8) & 0xff; /* > FALLTHROUGH */ > + case 10: req->msg[9] =3D (data[2] >> 16) & 0xff; /* > FALLTHROUGH */ > + case 9: req->msg[8] =3D (data[2] >> 24) & 0xff; /* FALLTHROUGH > */ > + > + case 8: req->msg[7] =3D data[1] & 0xff; /* FALLTHROUGH */ > + case 7: req->msg[6] =3D (data[1] >> 8) & 0xff; /* FALLTHROUGH > */ > + case 6: req->msg[5] =3D (data[1] >> 16) & 0xff; /* FALLTHROUGH > */ > + case 5: req->msg[4] =3D (data[1] >> 24) & 0xff; /* FALLTHROUGH > */ > + > + case 4: req->msg[3] =3D data[0] & 0xff; /* FALLTHROUGH */ > + case 3: req->msg[2] =3D (data[0] >> 8) & 0xff; /* FALLTHROUGH > */ > + case 2: req->msg[1] =3D (data[0] >> 16) & 0xff; /* FALLTHROUGH > */ > + case 1: req->msg[0] =3D (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 =3D i2c->sw; > + int i; > + uint32_t ctrl; > + uint32_t data[3]; > + > + if (((req->cmd =3D=3D FM10K_SW_I2C_COMMAND_WR || > + req->cmd =3D=3D FM10K_SW_I2C_COMMAND_WR_RD) && > + req->write_len > FM10K_SW_I2C_MSG_MAX) || > + ((req->cmd =3D=3D FM10K_SW_I2C_COMMAND_RD || > + req->cmd =3D=3D FM10K_SW_I2C_COMMAND_WR_RD) && > + ((req->read_len =3D=3D 0 || > + req->read_len > FM10K_SW_I2C_MSG_MAX)))) > + return (-1); > + > + FM10K_SW_TRACE("i2c: initiating command %u", req->cmd); > + > + ctrl =3D > + FM10K_SW_MAKE_REG_FIELD(I2C_CTRL_ADDR, req->addr << 1) | > + FM10K_SW_MAKE_REG_FIELD(I2C_CTRL_COMMAND, req->cmd); > + > + if (req->cmd =3D=3D FM10K_SW_I2C_COMMAND_WR || > + req->cmd =3D=3D FM10K_SW_I2C_COMMAND_WR_RD) { > + ctrl |=3D FM10K_SW_MAKE_REG_FIELD(I2C_CTRL_LENGTH_W, > req->write_len); > + > + data[0] =3D data[1] =3D data[2] =3D 0; > + switch (req->write_len) { > + case 12: data[2] |=3D req->msg[11]; /* FALLTHROUGH */ > + case 11: data[2] |=3D req->msg[10] << 8; /* FALLTHROUGH */ > + case 10: data[2] |=3D req->msg[9] << 16; /* FALLTHROUGH */ > + case 9: data[2] |=3D req->msg[8] << 24; /* FALLTHROUGH */ > + > + case 8: data[1] |=3D req->msg[7]; /* FALLTHROUGH */ > + case 7: data[1] |=3D req->msg[6] << 8; /* FALLTHROUGH */ > + case 6: data[1] |=3D req->msg[5] << 16; /* FALLTHROUGH */ > + case 5: data[1] |=3D req->msg[4] << 24; /* FALLTHROUGH */ > + > + case 4: data[0] |=3D req->msg[3]; /* FALLTHROUGH */ > + case 3: data[0] |=3D req->msg[2] << 8; /* FALLTHROUGH */ > + case 2: data[0] |=3D req->msg[1] << 16; /* FALLTHROUGH */ > + case 1: data[0] |=3D req->msg[0] << 24; /* FALLTHROUGH */ > + } > + > + for (i =3D 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 =3D=3D FM10K_SW_I2C_COMMAND_RD || > + req->cmd =3D=3D FM10K_SW_I2C_COMMAND_WR_RD) > + ctrl |=3D FM10K_SW_MAKE_REG_FIELD(I2C_CTRL_LENGTH_R, > req->read_len); > + > + req->status =3D FM10K_SW_I2C_COMPLETION_RUNNING; > + i2c->cur_req =3D 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 =3D=3D 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 =3D addr; > + req.cmd =3D FM10K_SW_I2C_COMMAND_RD; > + req.read_len =3D 1; > + req.msg[0] =3D 0; > + > + error =3D fm10k_i2c_exec(i2c, &req); > + if (error) > + goto done; > + > + if (req.status !=3D FM10K_SW_I2C_COMPLETION_NORMAL) { > + FM10K_SW_INFO("i2c read failed (%u)", req.status); > + error =3D -1; > + goto done; > + } > + > + *result =3D req.msg[0]; > + > +done: > + return (error); > +} > + > +int > +fm10k_i2c_read8_ext(struct fm10k_i2c *i2c, uint8_t addr, uint8_t reg, ui= nt8_t > *result) > +{ > + struct fm10k_i2c_req req; > + int error; > + > + req.addr =3D addr; > + req.cmd =3D FM10K_SW_I2C_COMMAND_WR_RD; > + req.write_len =3D 1; > + req.read_len =3D 1; > + req.msg[0] =3D reg; > + > + error =3D fm10k_i2c_exec(i2c, &req); > + if (error) > + goto done; > + > + if (req.status !=3D FM10K_SW_I2C_COMPLETION_NORMAL) { > + FM10K_SW_INFO("i2c read failed (%u)", req.status); > + error =3D -1; > + goto done; > + } > + > + *result =3D 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 =3D addr; > + req.cmd =3D FM10K_SW_I2C_COMMAND_WR; > + req.write_len =3D 1; > + req.msg[0] =3D data; > + > + error =3D fm10k_i2c_exec(i2c, &req); > + if (error) > + goto done; > + > + if (req.status !=3D FM10K_SW_I2C_COMPLETION_NORMAL) { > + error =3D -1; > + goto done; > + } > + > +done: > + return (error); > +} > + > +int > +fm10k_i2c_write16(struct fm10k_i2c *i2c, uint8_t addr, uint8_t data0, ui= nt8_t > data1) > +{ > + struct fm10k_i2c_req req; > + int error; > + > + req.addr =3D addr; > + req.cmd =3D FM10K_SW_I2C_COMMAND_WR; > + req.write_len =3D 2; > + req.msg[0] =3D data0; > + req.msg[1] =3D data1; > + > + error =3D fm10k_i2c_exec(i2c, &req); > + if (error) > + goto done; > + > + if (req.status !=3D FM10K_SW_I2C_COMPLETION_NORMAL) { > + error =3D -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 =3D addr; > + req.cmd =3D FM10K_SW_I2C_COMMAND_WR; > + req.write_len =3D 0; > + > + error =3D fm10k_i2c_exec(i2c, &req); > + if (error) > + goto done; > + > + if (req.status !=3D FM10K_SW_I2C_COMPLETION_NORMAL) { > + error =3D -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 > +#include > +#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 > + > +/* 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_) =3D (((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_) =3D (((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_) =3D (((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_) =3D (((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] =3D > \ > + ((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] =3D > \ > + (((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) > =3D=3D \ > + 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 th= e > + * direct values for programming the ITR interval field when using a Gen= 3 > + * 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 interfac= es. > + */ > +#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(), whi= ch > + * 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-bi= t 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-bi= t 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 > + > +#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 =3D (struct fm10k_sbus *)rte_zmalloc("fm10k_sbus", sizeof(struct > fm10k_sbus), 0); > + if (sb =3D=3D NULL) { > + FM10K_SW_INFO("sbus %s: failed to allocate context", name); > + goto fail; > + } > + > + sb->sw =3D sw; > + sb->name =3D name; > + pthread_mutex_init(&sb->lock, NULL); > + > + sb->cfg_reg =3D cfg_reg; > + sb->cmd_reg =3D cfg_reg + FM10K_SW_REG_OFF(1); > + sb->req_reg =3D cfg_reg + FM10K_SW_REG_OFF(2); > + sb->resp_reg =3D cfg_reg + FM10K_SW_REG_OFF(3); > + > + error =3D 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 =3D fm10k_sbus_sbm_reset(sb); > + if (error) > + goto done; > + > + error =3D fm10k_sbus_reset_all(sb); > + if (error) > + goto done; > + > + /* set clock to REFCLK/2 */ > + error =3D 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 =3D 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 !=3D 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 =3D -1; > + goto done; > + } > + > +done: > + return (error); > +} > + > +static int > +fm10k_sbus_exec(struct fm10k_sbus *sb, struct fm10k_sbus_req *req) > +{ > + struct fm10k_switch *sw =3D sb->sw; > + unsigned int total_usecs; > + unsigned int drop_lock; > + unsigned int delay_time; > + int error =3D 0; > + uint32_t data; > + uint8_t expected_result; > + > + FM10K_SW_SBUS_LOCK(sb); > + > + FM10K_SW_SWITCH_LOCK(sw); > + data =3D 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 =3D -1; > + goto done; > + } > + > + switch (req->op) { > + case FM10K_SW_SBUS_OP_RESET: > + FM10K_SW_TRACE("sbus %s: RESET dev=3D0x%02x reg=3D0x%02x > data=3D0x%08x", > + sb->name, req->dev, req->reg, req->data); > + expected_result =3D 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=3D0x%02x reg=3D0x%02x > data=3D0x%08x", > + sb->name, req->dev, req->reg, req->data); > + expected_result =3D 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=3D0x%02x reg=3D0x%02x", > + sb->name, req->dev, req->reg); > + expected_result =3D FM10K_SW_SBUS_RESULT_READ; > + req->data =3D 0; > + break; > + default: > + FM10K_SW_INFO("sbus %s: invalid opcode 0x%02x", > + sb->name, req->op); > + error =3D -1; > + goto done; > + } > + > + /* Clear the execute bit */ > + fm10k_write_switch_reg(sw, sb->cmd_reg, 0); > + > + data =3D > + 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 =3D 0; > + delay_time =3D 1; > + drop_lock =3D 0; > + do { > + if (drop_lock) > + FM10K_SW_SWITCH_UNLOCK(sw); > + fm10k_udelay(delay_time); > + if (drop_lock) > + FM10K_SW_SWITCH_LOCK(sw); > + total_usecs +=3D delay_time; > + if (total_usecs >=3D > FM10K_SW_SBUS_COMMAND_WAIT_LOCK_US_MAX) { > + drop_lock =3D 1; > + delay_time <<=3D 1; > + } > + > + data =3D 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) !=3D > + 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 =3D -1; > + goto done; > + } > + if (req->op =3D=3D FM10K_SW_SBUS_OP_READ) { > + req->data =3D > + fm10k_read_switch_reg(sw, sb->resp_reg); > + FM10K_SW_TRACE("sbus %s: READ > data=3D0x%02x", sb->name, > + req->data); > + } > + goto done; > + } > + > + } while (total_usecs < FM10K_SW_SBUS_COMMAND_TIMEOUT_US); > + > + error =3D -1; > + FM10K_SW_INFO("sbus %s: command timed out after %u us " > + "(op=3D0x%02x dev=3D0x%02x reg=3D0x%02x data=3D0x%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 =3D FM10K_SW_SBUS_OP_RESET; > + req.dev =3D FM10K_SW_SBUS_ADDR_BROADCAST; > + req.reg =3D 0; > + req.data =3D 0; > + > + error =3D 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 =3D FM10K_SW_SBUS_OP_RESET; > + req.dev =3D FM10K_SW_SBUS_ADDR_SPICO; > + req.reg =3D 0; > + req.data =3D 0; > + > + error =3D 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 =3D FM10K_SW_SBUS_OP_READ; > + req.dev =3D dev; > + req.reg =3D reg; > + > + error =3D fm10k_sbus_exec(sb, &req); > + *data =3D 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 =3D FM10K_SW_SBUS_OP_WRITE; > + req.dev =3D dev; > + req.reg =3D reg; > + req.data =3D data; > + > + error =3D 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 > + > + > +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, uin= t32_t > *data); > +int fm10k_sbus_write(struct fm10k_sbus *sb, uint8_t dev, uint8_t reg, ui= nt32_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, con= st > uint16_t *image, > + unsigned int num_words); > +static int fm10k_swap_image_check_crc(struct fm10k_sbus *sb, unsigned in= t > 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_swit= ch > *sw, > + uint32_t expected_version_build_id); > +static int fm10k_epl_serdes_spico_do_crc(struct fm10k_switch *sw, unsign= ed > int serdes); > +static int fm10k_epl_serdes_spico_reset(struct fm10k_switch *sw, unsigne= d 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, unsign= ed > 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, unsi= gned > 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_switc= h > *sw, > + unsigned int serdes, unsigned int addr, uint32_t data, uint32_t mas= k, > + uint32_t *result); > +static int fm10k_epl_serdes_dma_esb_read(struct fm10k_switch *sw, unsign= ed > 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, unsigne= d > 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, unsi= gned > int serdes, > + uint32_t *status); > +static int fm10k_epl_serdes_get_ical_result(struct fm10k_switch *sw, uns= igned > int serdes, > + uint32_t *converged); > + > + > +int > +fm10k_epl_serdes_reset_and_load_all(struct fm10k_switch *sw) > +{ > + struct fm10k_sbus *sb =3D sw->epl_sbus; > + int error; > + > + FM10K_SW_TRACE( > + "sbus %s: initializing EPL serdes", sb->name); > + > + error =3D fm10k_spico_ram_bist(sb); > + if (error) > + goto done; > + > + error =3D 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 =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x00, > 0x03); > + if (error) > + goto done; > + > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x00, > 0x05); > + if (error) > + goto done; > + > + start_time_us =3D fm10k_uptime_us(); > + elapsed_time_ms =3D 0; > + while (elapsed_time_ms < FM10K_SW_SERDES_BIST_TIMEOUT_MS) { > + elapsed_time_ms =3D (fm10k_uptime_us() - start_time_us) / 1000; > + error =3D fm10k_sbus_read(sb, FM10K_SW_SBUS_ADDR_SPICO, > 0x00, &data); > + if (error) > + goto done; > + > + if (data & 0x18) { > + error =3D fm10k_sbus_write(sb, > FM10K_SW_SBUS_ADDR_SPICO, 0x00, > + 0x00); > + if (error) > + goto done; > + if ((data & 0x18) !=3D 0x08) { > + FM10K_SW_INFO("sbus %s: SPICO RAM " > + "BIST failed with bad status (0x%08x)", > + sb->name, data); > + error =3D -1; > + goto done; > + } > + goto done; > + } > + } > + fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x00, 0x00); > + error =3D -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 =3D 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 =3D 0; > + > + FM10K_SW_TRACE( > + "sbus %s: loading SPICO code", sb->name); > + > + sbm_code_image =3D fm10000_sbus_master_code_prd; > + sbm_code_size =3D fm10000_sbus_master_code_size_prd; > + sbm_code_version_build_id =3D > + fm10000_sbus_master_code_versionBuildId_prd; > + > + FM10K_SW_TRACE( > + "sbus %s: sbm code version=3D%4.4x build=3D%4.4x", > + sb->name, sbm_code_version_build_id >> 16, > + sbm_code_version_build_id & 0xffff); > + > + serdes_code_image =3D fm10000_serdes_spico_code_prd2; > + serdes_code_size =3D fm10000_serdes_spico_code_size_prd2; > + serdes_code_version_build_id =3D > + fm10000_serdes_spico_code_versionBuildId_prd2; > + sw->epl_serdes_code_version_build_id =3D serdes_code_version_build_id; > + > + FM10K_SW_TRACE( > + "sbus %s: serdes code version=3D%4.4x build=3D%4.4x", > + sb->name, serdes_code_version_build_id >> 16, > + serdes_code_version_build_id & 0xffff); > + > + swap_code_image =3D fm10000_serdes_swap_code_prd2; > + swap_code_size =3D fm10000_serdes_swap_code_size_prd2; > + > + error =3D fm10k_sbm_spico_upload_image(sb, sbm_code_image, > + sbm_code_size); > + if (error) > + goto done; > + > + error =3D 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) =3D=3D 0) { > + error =3D fm10k_serdes_swap_upload_image(sb, > + swap_code_image, swap_code_size); > + swap_crc_code =3D 0x1a; > + } else { > + error =3D fm10k_serdes_swap_alt_upload_image(sb, > + swap_code_image, swap_code_size); > + swap_crc_code =3D 0x04; > + } > + if (error) > + goto done; > + > + error =3D fm10k_swap_image_check_crc(sb, swap_crc_code); > + if (error) > + goto done; > + } > + > + error =3D fm10k_serdes_spico_upload_image(sb, > FM10K_SW_SBUS_ADDR_BROADCAST, > + serdes_code_image, serdes_code_size); > + if (error) > + goto done; > + > + error =3D 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 =3D (1 << 6) | (1 << 7); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01, > data); > + if (error) > + goto done; > + > + data &=3D ~(1 << 7); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01, > data); > + if (error) > + goto done; > + > + data |=3D (1 << 9); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01, > data); > + if (error) > + goto done; > + > + start_time_us =3D fm10k_uptime_us(); > + for (i =3D 0; i < num_words; i++) { > + data =3D 0x80000000 | ((uint32_t)image[i] << 16) | i; > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, > 0x03, data); > + if (error) > + goto done; > + } > + elapsed_time_us =3D 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 =3D (1 << 6); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01, > data); > + if (error) > + goto done; > + > + data =3D (1 << 18) | (1 << 19); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x16, > data); > + if (error) > + goto done; > + > + data =3D (1 << 6) | (1 << 8); > + error =3D 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 =3D fm10k_sbm_spico_do_crc(sb); > + if (error) > + goto done; > + > + error =3D fm10k_sbm_get_version_build_id(sb, &version_build_id); > + if (error) > + goto done; > + > + if (version_build_id !=3D 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 =3D -1; > + goto done; > + } > + FM10K_SW_TRACE("sbus %s: SBM SPICO image " > + "version=3D0x%4.4x build_id=3D0x%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 =3D fm10k_sbm_spico_int(sb, 0x02, 0, &crc); > + if (error) > + goto done; > + > + crc =3D crc >> 16; > + if (crc =3D=3D 0xffff) { > + FM10K_SW_INFO("sbus %s: SBM SPICO CRC check failed " > + "(CRC interrupt returned 0xffff)", sb->name); > + error =3D -1; > + goto done; > + } else if (crc =3D=3D 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 =3D fm10k_sbm_spico_int(sb, 0x00, 0, &result); > + if (error) > + goto done; > + > + *version_build_id =3D result & 0xffff0000; > + error =3D fm10k_sbm_spico_int(sb, 0x01, 0, &result); > + if (error) > + goto done; > + > + *version_build_id |=3D (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 =3D fm10k_sbm_spico_int(sb, 0x1c, 0, &addr); > + if (error) > + goto done; > + > + addr >>=3D 16; > + if (addr =3D=3D 0xffff) { > + FM10K_SW_INFO("sbus %s: invalid build - cannot " > + "upload SBM swap image", sb->name); > + error =3D -1; > + goto done; > + } > + FM10K_SW_TRACE("sbus %s: SBM swap image initial load " > + "address 0x%04x (%u)", sb->name, addr, addr); > + > + reg05 =3D 1; > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x05, > reg05); > + if (error) > + goto done; > + > + error =3D fm10k_sbus_read(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01, > ®01); > + if (error) > + goto done; > + > + reg01 |=3D (1 << 9); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01, > reg01); > + if (error) > + goto done; > + > + start_time_us =3D fm10k_uptime_us(); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x03, > addr); > + if (error) > + goto done; > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x03, > 0x80000000 | addr); > + if (error) > + goto done; > + > + for (i =3D 0; i < num_words - 2; i +=3D 3) { > + error =3D 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 =3D=3D 2) { > + error =3D 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 =3D=3D 1) { > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, > 0x14, > + 0x40000000 | image[i]); > + if (error) > + goto done; > + } > + elapsed_time_us =3D 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 &=3D ~(1 << 9); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01, > reg01); > + if (error) > + goto done; > + > + reg05 &=3D ~(1 << 0); > + error =3D 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 =3D 1; > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x05, > reg05); > + if (error) > + goto done; > + > + error =3D fm10k_sbus_read(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01, > ®01); > + if (error) > + goto done; > + > + reg01 |=3D (1 << 10) | (1 << 11); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01, > reg01); > + if (error) > + goto done; > + > + addr =3D 0x0400; > + FM10K_SW_TRACE("sbus %s: SBM swap image initial load " > + "address 0x%04x (%u)", sb->name, addr, addr); > + > + start_time_us =3D fm10k_uptime_us(); > + for (i =3D 0; i < num_words; i++) { > + error =3D 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 =3D 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 &=3D ~((1 << 10) | (1 << 11)); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x01, > reg01); > + if (error) > + goto done; > + > + reg05 &=3D ~(1 << 0); > + error =3D 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 =3D > + fm10k_sbm_spico_int(sb, crc_code, 0, &crc); > + if (error) > + goto done; > + > + crc >>=3D 16; > + if (crc =3D=3D 0xffff) { > + FM10K_SW_INFO("sbus %s: SBM swap image CRC check " > + "failed (CRC interrupt 0x%02x returned 0xffff)", > + sb->name, crc_code); > + error =3D -1; > + goto done; > + } else if (crc =3D=3D 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 =3D (1 << 0) | (1 << 4); > + error =3D fm10k_sbus_write(sb, dev, 0x07, reg07); > + if (error) > + goto done; > + > + reg07 &=3D ~(1 << 0); > + error =3D fm10k_sbus_write(sb, dev, 0x07, reg07); > + if (error) > + goto done; > + > + data =3D (1 << 30); > + error =3D fm10k_sbus_write(sb, dev, 0x00, data); > + if (error) > + goto done; > + > + data =3D (1 << 4) | (1 << 5); > + error =3D fm10k_sbus_write(sb, dev, 0x08, data); > + if (error) > + goto done; > + > + start_time_us =3D fm10k_uptime_us(); > + for (i =3D 0; i < num_words; i+=3D 3) { > + data =3D 0xc0000000 | image[i]; > + if (i + 1 < num_words) { > + data |=3D (uint32_t)image[i + 1] << 10; > + > + if (i + 2 < num_words) > + data |=3D (uint32_t)image[i + 2] << 20; > + } > + error =3D fm10k_sbus_write(sb, dev, 0x0a, data); > + if (error) > + goto done; > + } > + elapsed_time_us =3D 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 =3D fm10k_sbus_write(sb, dev, 0x00, 0); > + if (error) > + goto done; > + > + error =3D fm10k_sbus_write(sb, dev, 0x01, 0x20000000); > + if (error) > + goto done; > + > + data =3D (1 << 18) | (1 << 19); > + error =3D fm10k_sbus_write(sb, dev, 0x0b, data); > + if (error) > + goto done; > + > + reg07 |=3D (1 << 0); > + error =3D fm10k_sbus_write(sb, dev, 0x07, reg07); > + if (error) > + goto done; > + > + reg07 &=3D ~(1 << 0); > + error =3D fm10k_sbus_write(sb, dev, 0x07, reg07); > + if (error) > + goto done; > + > + reg07 |=3D (1 << 1); > + error =3D fm10k_sbus_write(sb, dev, 0x07, reg07); > + if (error) > + goto done; > + > + error =3D 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 =3D sw->epl_sbus; > + unsigned int first =3D 0; > + unsigned int last =3D 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 =3D first; i <=3D last; i++) { > + error =3D fm10k_sbus_read(sb, > FM10K_SW_SBUS_ADDR_EPL_SERDES(i), 0xff, > + &data); > + if (error || (data !=3D 0x01)) { > + FM10K_SW_TRACE("sbus %s: skipping " > + "serdes %u (error=3D%d, data=3D0x%08x)", sb->name, i, > + error, data); > + continue; > + } > + > + error =3D fm10k_epl_serdes_spico_do_crc(sw, i); > + if (error) > + goto done; > + > + error =3D fm10k_epl_serdes_get_version_build_id(sw, i, > + &version_build_id); > + if (error) > + goto done; > + > + if (version_build_id !=3D 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 =3D -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 serd= es) > +{ > + struct fm10k_sbus *sb =3D sw->epl_sbus; > + int error; > + uint32_t crc; > + > + FM10K_SW_TRACE("sbus %s: serdes %u: performing SPICO " > + "CRC check", sb->name, serdes); > + > + error =3D fm10k_epl_serdes_spico_int(sw, serdes, 0x3c, 0, &crc); > + if (error) > + goto done; > + > + if (crc !=3D 0) { > + FM10K_SW_INFO("sbus %s: serdes %u: SPICO CRC check " > + "failed (CRC interrupt returned 0x%08x)", > + sb->name, serdes, crc); > + error =3D -1; > + goto done; > + } > + > +done: > + return (error); > +} > + > +static int > +fm10k_epl_serdes_spico_reset(struct fm10k_switch *sw, unsigned int serde= s) > +{ > + struct fm10k_sbus *sb =3D sw->epl_sbus; > + int error; > + uint32_t data; > + uint8_t addr =3D 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 =3D fm10k_sbus_write(sb, addr, 0, 0x00); > + if (error) > + goto done; > + fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US); > + > + data =3D (1 << 0) | (1 << 4); > + error =3D fm10k_sbus_write(sb, addr, 0x07, data); > + fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US); > + if (error) > + goto done; > + > + data =3D (1 << 18) | (1 << 19); > + error =3D fm10k_sbus_write(sb, addr, 0x0b, data); > + fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US); > + if (error) > + goto done; > + > + data =3D (1 << 4); > + error =3D fm10k_sbus_write(sb, addr, 0x07, data); > + fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US); > + if (error) > + goto done; > + > + data =3D (1 << 1); > + error =3D fm10k_sbus_write(sb, addr, 0x07, data); > + fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US); > + if (error) > + goto done; > + > + error =3D 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 =3D fm10k_epl_serdes_spico_int(sw, serdes, 0x00, 0, &data); > + if (error) > + goto done; > + > + *version_build_id =3D data << 16; > + error =3D fm10k_epl_serdes_spico_int(sw, serdes, 0x3f, 0, &data); > + if (error) > + goto done; > + > + *version_build_id |=3D data & 0xffff; > +done: > + return (error); > +} > + > +static int > +fm10k_sbm_spico_int(struct fm10k_sbus *sb, uint8_t int_num, uint32_t par= am, > + 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=3D0x%08x)", sb->name, int_num, param); > + > + /* int write */ > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x02, > + (param << 16) | int_num); > + if (error) > + goto done; > + > + error =3D fm10k_sbus_read(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x07, > &data); > + if (error) > + goto done; > + > + data |=3D (1 << 0); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x07, > data); > + if (error) > + goto done; > + > + data &=3D ~(1 << 0); > + error =3D fm10k_sbus_write(sb, FM10K_SW_SBUS_ADDR_SPICO, 0x07, > data); > + if (error) > + goto done; > + > + /* int read */ > + start_time_us =3D fm10k_uptime_us(); > + elapsed_time_ms =3D 0; > + while (elapsed_time_ms < FM10K_SW_SBM_INTERRUPT_TIMEOUT_MS) > { > + elapsed_time_ms =3D (fm10k_uptime_us() - start_time_us) / 1000; > + error =3D fm10k_sbus_read(sb, FM10K_SW_SBUS_ADDR_SPICO, > 0x08, &data); > + if (error) > + goto done; > + > + if ((data & 0x8000) || ((data & 0x3ff) =3D=3D 0)) { > + if (elapsed_time_ms > 5) > + fm10k_udelay(5); > + } else { > + FM10K_SW_TRACE("sbus %s: SBM " > + "interrupt 0x%02x (param=3D0x%08x, result=3D0x%08x)", > + sb->name, int_num, param, data); > + *result =3D data; > + goto done; > + } > + } > + error =3D -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 =3D 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 =3D FM10K_SW_SBUS_ADDR_EPL_SERDES(serdes); > + > + FM10K_SW_TRACE("sbus %s: serdes %u: (sbus addr 0x%02x) " > + "interrupt 0x%04x (param=3D0x%08x)", sb->name, serdes, sbus_addr, > + int_num, param); > + > + /* int write */ > + start_time_us =3D fm10k_uptime_us(); > + elapsed_time_ms =3D 0; > + while (elapsed_time_ms < > FM10K_SW_SERDES_INTERRUPT_TIMEOUT_MS) { > + elapsed_time_ms =3D (fm10k_uptime_us() - start_time_us) / 1000; > + error =3D 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 >=3D FM10K_SW_SERDES_INTERRUPT_TIMEOUT_MS) > { > + error =3D fm10k_sbus_read(sb, sbus_addr, 0x03, &intr); > + FM10K_SW_INFO("sbus %s: serdes %u: interrupt timed out " > + "after %u ms (intr=3D0x%04x param=3D0x%04x error=3D%u " > + "reg[4]=3D0x%08x)", sb->name, serdes, > + (uint32_t)elapsed_time_ms, intr >> 16, intr & 0xffff, error, > + data); > + error =3D -1; > + goto done; > + } else { > + error =3D fm10k_sbus_write(sb, sbus_addr, 0x03, > + ((uint32_t)int_num << 16) | param); > + if (error) > + goto done; > + } > + > + /* int read */ > + start_time_us =3D fm10k_uptime_us(); > + elapsed_time_ms =3D 0; > + while (elapsed_time_ms < > FM10K_SW_SERDES_INTERRUPT_TIMEOUT_MS) { > + elapsed_time_ms =3D (fm10k_uptime_us() - start_time_us) / 1000; > + error =3D 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 >=3D FM10K_SW_SERDES_INTERRUPT_TIMEOUT_MS) > { > + error =3D fm10k_sbus_read(sb, sbus_addr, 0x03, &intr); > + FM10K_SW_INFO("sbus %s: serdes %u: interrupt timed out " > + "(2) after %u ms (intr=3D0x%04x param=3D0x%04x error=3D%u " > + "reg[4]=3D0x%08x)", sb->name, serdes, > + (uint32_t)elapsed_time_ms, intr >> 16, intr & 0xffff, error, > + data); > + error =3D -1; > + goto done; > + } else { > + FM10K_SW_TRACE("sbus %s: serdes %u: interrupt " > + "0x%04x (param=3D0x%08x, result=3D0x%08x)", sb->name, serdes, > + int_num, param, data); > + if (result) > + *result =3D data; > + } > + > +done: > + return (error); > +} > + > + > +int > +fm10k_epl_serdes_start_bringup(struct fm10k_ext_port_lane *lane) > +{ > + struct fm10k_switch *sw =3D lane->port->ports->sw; > + unsigned int serdes =3D lane->abs_laneno; > + unsigned int speed =3D lane->port->lane_speed; > + unsigned int divider, width_mode; > + int error =3D 0; > + uint32_t data; > + > + /* > + * Bit rate and width > + */ > + if (speed =3D=3D 25) { > + /* 25G */ > + divider =3D FM10K_SW_SERDES_DIVIDER_ETHMODE_25G; > + width_mode =3D FM10K_SW_SERDES_WIDTH_40; > + } else { > + /* 10G */ > + divider =3D FM10K_SW_SERDES_DIVIDER_ETHMODE_10G; > + width_mode =3D FM10K_SW_SERDES_WIDTH_20; > + } > + > + /* > + * state =3D CONFIGURED > + */ > + > + FM10K_SW_TRACE( > + "sbus %s: serdes %u: configuring", sw->epl_sbus->name, > + serdes); > + > + error =3D fm10k_epl_serdes_spico_reset(sw, serdes); > + fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US); > + if (error) > + goto done; > + > + error =3D 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 =3D 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 =3D fm10k_epl_serdes_spico_int02_retry(sw, serdes, 0x1ff, > + FM10K_SW_SERDES_INT02_TIMEOUT_MS); > + if (error) > + goto done; > + > + error =3D 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 =3D fm10k_epl_serdes_set_tx_eq(sw, serdes, > + FM10K_SW_SERDES_EQ_SEL_ATTEN, 0); > + if (error) > + goto done; > + error =3D fm10k_epl_serdes_set_tx_eq(sw, serdes, > + FM10K_SW_SERDES_EQ_SEL_PRECUR, 0); > + if (error) > + goto done; > + error =3D 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 =3D (1 << 0) | (1 << 1); > + error =3D > + 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 =3D (1 << 0); > + error =3D > + 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 =3D 0x0300; > + error =3D 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 =3D > + 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 =3D 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 =3D lane->port->ports->sw; > + unsigned int serdes =3D lane->abs_laneno; > + unsigned int speed =3D lane->port->lane_speed; > + unsigned int width_mode; > + int error =3D 0; > + int near_loopback =3D sw->serdes_loopback; > + > + if (speed =3D=3D 25) { > + /* 25G */ > + width_mode =3D FM10K_SW_SERDES_WIDTH_40; > + } else { > + /* 10G */ > + width_mode =3D FM10K_SW_SERDES_WIDTH_20; > + } > + > + fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US); > + error =3D fm10k_epl_serdes_set_pcsl_bit_slip(sw, serdes); > + if (error) > + goto done; > + > + fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US); > + error =3D 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 =3D > + fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x01, 0x07); > + if (error) > + goto done; > + > + fm10k_udelay(FM10K_SW_SERDES_CONFIG_DELAY_US); > + error =3D fm10k_epl_serdes_init_signal_ok(sw, serdes, 0); > + if (error) > + goto done; > + > + if (near_loopback) { > + /* enable near loopback */ > + error =3D 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 =3D lane->port->ports->sw; > + unsigned int serdes =3D lane->abs_laneno; > + int error =3D 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 =3D 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 serd= es, > + unsigned int divider) > +{ > + int error; > + uint32_t data; > + > + FM10K_SW_TRACE( > + "sbus %s: serdes %u: setting bit rate", > + sw->epl_sbus->name, serdes); > + > + data =3D divider & 0x7ff; > + data |=3D (1 << 12); > + data |=3D (1 << 15); > + > + error =3D 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 =3D FM10K_SW_SERDES_WIDTH_20 | > (FM10K_SW_SERDES_WIDTH_20 << 4); > + fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US); > + error =3D fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x14, data); > + if (error) > + goto done; > + > + data =3D width_mode | (width_mode << 4); > + fm10k_udelay(FM10K_SW_SERDES_RESET_DELAY_US); > + error =3D 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 =3D (tx_eq & 0xff) | (which << 14); > + error =3D 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 =3D lane->port->ports->sw; > + unsigned int eplno =3D 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 =3D=3D 0) ? "NORMAL" : > + (override =3D=3D 1) ? "FORCE_GOOD" : > + (override =3D=3D 2) ? "FORCE_BAD" : ""); > + > + FM10K_SW_SWITCH_LOCK(sw); > + data =3D 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 =3D fm10k_read_switch_reg(sw, FM10K_SW_PCSL_CFG(eplno, > lane)); > + if (width_mode =3D=3D FM10K_SW_SERDES_WIDTH_40) { > + pcsl_cfg &=3D ~FM10K_SW_PCSL_CFG_RX_GB_NARROW; > + pcsl_cfg &=3D ~FM10K_SW_PCSL_CFG_TX_GB_NARROW; > + } else { > + pcsl_cfg |=3D FM10K_SW_PCSL_CFG_RX_GB_NARROW; > + pcsl_cfg |=3D FM10K_SW_PCSL_CFG_TX_GB_NARROW; > + } > + pcsl_cfg &=3D ~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 =3D > + fm10k_epl_serdes_spico_int(sw, serdes, 0x0c, (1 << 7), &int_return)= ; > + if (error) > + goto done; > + > + FM10K_SW_SWITCH_LOCK(sw); > + pcsl_cfg =3D fm10k_read_switch_reg(sw, FM10K_SW_PCSL_CFG(eplno, > lane)); > + pcsl_cfg |=3D FM10K_SW_PCSL_CFG_RX_BIT_SLIP_ENABLE; > + if (int_return & 0x1) > + pcsl_cfg |=3D 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 =3D 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 se= rdes, > + 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 =3D > + fm10k_epl_serdes_spico_int(sw, serdes, 0x20, 0x20, NULL); > + if (error) > + goto done; > + > + error =3D 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 =3D fm10k_uptime_us(); > + elapsed_time_ms =3D 0; > + while (elapsed_time_ms < timeout_ms) { > + elapsed_time_ms =3D (fm10k_uptime_us() - start_time_us) / 1000; > + error =3D > + fm10k_epl_serdes_spico_int(sw, serdes, 0x02, data, &result); > + if (result =3D=3D 0x02) { > + error =3D 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 =3D fm10k_epl_serdes_spico_int(sw, serdes, 0x18, > + 0x8000 | (addr & 0xff), NULL); > + if (error) > + goto done; > + > + error =3D 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 =3D fm10k_epl_serdes_spico_int(sw, serdes, 0x18, > + 0x4000 | (addr & 0x3fff), result); > + if (error) > + goto done; > + > + error =3D 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 =3D fm10k_epl_serdes_spico_int(sw, serdes, 0x18, > + 0x4000 | (addr & 0x3fff), NULL); > + if (error) > + goto done; > + > + error =3D 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 =3D fm10k_epl_serdes_dma_esb_read(sw, serdes, addr, &read_data); > + if (error) > + goto done; > + > + error =3D fm10k_epl_serdes_dma_esb_write(sw, serdes, addr, > + (data & mask) | (read_data & ~mask)); > + if (error) > + goto done; > + if(result) > + *result =3D (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 =3D fm10k_epl_serdes_spico_int(sw, serdes, int_num, param, > &result); > + if (error) > + goto done; > + if (result !=3D int_num) { > + error =3D -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 =3D serdes / FM10K_SW_EPL_LANES; > + *lane =3D serdes % FM10K_SW_EPL_LANES; > + } > +} > + > +static int > +fm10k_epl_serdes_configure_near_loopback(struct fm10k_ext_port_lane > *lane) > +{ > + struct fm10k_switch *sw =3D lane->port->ports->sw; > + unsigned int serdes =3D 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 =3D (1 << 8) | (1 << 0); > + error =3D 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 =3D > + 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 =3D lane->port->ports->sw; > + unsigned int serdes =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D lane->port->ports->sw; > + unsigned int serdes =3D lane->abs_laneno; > + unsigned int speed =3D 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 =3D=3D 25) > + param =3D FM10K_SW_LINK_OPT_PARAM_A25G; > + else > + param =3D FM10K_SW_LINK_OPT_PARAM_A10G; > + > + if ((sw->epl_serdes_code_version_build_id >> 16) > 0x1055) > + error =3D fm10k_epl_serdes_config_dfe_param(sw, serdes, > param); > + > + error =3D 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 =3D lane->port->ports->sw; > + unsigned int serdes =3D lane->abs_laneno; > + int error; > + uint32_t dfe_status, converged; > + > + error =3D fm10k_epl_serdes_get_dfe_status(sw, serdes, &dfe_status); > + if (error) > + goto done; > + > + if ((dfe_status & 0x11) =3D=3D 0x11) { > + *status =3D FM10K_SW_SERDES_DFE_ICAL_IN_PROGRESS; > + } else { > + error =3D fm10k_epl_serdes_get_ical_result(sw, serdes, > &converged); > + if (error) > + goto done; > + if (converged) > + *status =3D FM10K_SW_SERDES_DFE_ICAL_CONVERGED; > + else > + *status =3D 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 =3D lane->port->ports->sw; > + unsigned int serdes =3D lane->abs_laneno; > + unsigned int speed =3D 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 =3D=3D 25) > + param =3D FM10K_SW_LINK_OPT_PARAM_B25G; > + else > + param =3D FM10K_SW_LINK_OPT_PARAM_B10G; > + > + if ((sw->epl_serdes_code_version_build_id >> 16) > 0x1055) > + error =3D fm10k_epl_serdes_config_dfe_param(sw, serdes, > param); > + > + error =3D 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 =3D lane->port->ports->sw; > + unsigned int serdes =3D lane->abs_laneno; > + int error; > + uint32_t dfe_status; > + > + error =3D fm10k_epl_serdes_get_dfe_status(sw, serdes, &dfe_status); > + if (error) > + goto done; > + if (dfe_status & 0x02) > + *status =3D FM10K_SW_SERDES_DFE_PCAL_COMPLETE; > + else > + *status =3D 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 =3D lane->port->ports->sw; > + unsigned int serdes =3D lane->abs_laneno; > + int error; > + unsigned int ical_stopped, pcal_stopped; > + unsigned int i; > + uint32_t dfe_status, status; > + > + error =3D fm10k_epl_serdes_get_dfe_status(sw, serdes, &dfe_status); > + if (error) > + goto done; > + > + ical_stopped =3D 0; > + pcal_stopped =3D 0; > + > + if (!force_reset) { > + if (dfe_status & 0x3) { > + /* stop all DFE tuning */ > + error =3D fm10k_epl_serdes_spico_wr_only_int(sw, > serdes, > + 0x0a, 0); > + if (error) > + goto done; > + > + for (i =3D 0; > + i < FM10K_SW_SERDES_ICAL_STOP_MAX_CYCLES; > + i++) { > + error =3D fm10k_epl_serdes_dfe_ical_status(lane, > + &status); > + if (error) > + goto done; > + if (status !=3D > + > FM10K_SW_SERDES_DFE_ICAL_IN_PROGRESS) { > + ical_stopped =3D 1; > + break; > + } > + fm10k_udelay( > + > FM10K_SW_SERDES_DFE_STOP_CYCLE_DELAY_US); > + } > + > + if (ical_stopped) > + for (i =3D 0; > + i < > FM10K_SW_SERDES_PCAL_STOP_MAX_CYCLES; > + i++) { > + error =3D > + fm10k_epl_serdes_dfe_pcal_status( > + lane, > + &status); > + if (error) > + goto done; > + if (status !=3D > + > FM10K_SW_SERDES_DFE_PCAL_IN_PROGRESS) { > + pcal_stopped =3D 0; > + break; > + } > + fm10k_udelay( > + > FM10K_SW_SERDES_DFE_STOP_CYCLE_DELAY_US); > + } > + } > + > + if (ical_stopped && pcal_stopped && (dfe_status & 0x40)) { > + error =3D fm10k_epl_serdes_start_dfe_pcal(lane); > + if (error) > + goto done; > + pcal_stopped =3D 0; > + for (i =3D 0; i < > FM10K_SW_SERDES_PCAL_STOP_MAX_CYCLES; i++) { > + error =3D fm10k_epl_serdes_dfe_pcal_status(lane, > + &status); > + if (error) > + goto done; > + if (status !=3D > + > FM10K_SW_SERDES_DFE_PCAL_IN_PROGRESS) { > + pcal_stopped =3D 1; > + break; > + } > + > fm10k_udelay(FM10K_SW_SERDES_DFE_STOP_CYCLE_DELAY_US); > + } > + } > + } > + > + if (!ical_stopped || !pcal_stopped) { > + error =3D -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 =3D fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x18, 0x07); > + if (error) > + goto done; > + > + error =3D fm10k_epl_serdes_spico_wr_only_int(sw, serdes, 0x19, > + param & 0xffff); > + if (error) > + goto done; > + > + error =3D 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 =3D 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=3D%u fine_active=3D%u adaptive=3D%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 =3D 0; > + > + error =3D fm10k_epl_serdes_spico_int(sw, serdes, 0x126, > + (4 << 12), &val1); > + if (error) > + goto done; > + > + error =3D fm10k_epl_serdes_spico_int(sw, serdes, 0x126, > + (4 << 12) | (1 << 8), &val2); > + if (error) > + goto done; > + > + /* sign extension */ > + if (val1 & 0x8000) > + val1 |=3D 0xffff0000; > + if (val2 & 0x8000) > + val2 |=3D 0xffff0000; > + diff =3D abs(val2 - val1); > + > + if (diff >=3D FM10K_SW_SERDES_DFE_DATA_LEVEL0_THRESHOLD) > + *converged =3D 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 > +#include > +#include > + > +#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 =3D (struct fm10k_sm *)rte_zmalloc("fm10k_sm", sizeof(struct > fm10k_sm), 0); > + if (sm =3D=3D NULL) > + goto fail; > + > + sm->num_events =3D num_events; > + fm10k_sm_event_heap_init(&sm->events); > + pthread_create(&sm->event_task, NULL, fm10k_sm_handle_event, sm); > + sm->num_timers =3D num_timers; > + if (sm->num_timers > 0) { > + sm->timers =3D (struct fm10k_sm_timer > *)rte_zmalloc("fm10k_sm_timers", > + sizeof(struct fm10k_sm_timer) * sm->num_timers, 0); > + if (sm->timers =3D=3D NULL) > + goto fail; > + } > + > + sm->event_handler =3D event_handler; > + sm->timer_handler =3D timer_handler; > + sm->ctx =3D ctx; > + > + for (i =3D 0; i < sm->num_timers; i++) { > + timer =3D &sm->timers[i]; > + sem_init(&timer->tq, 0, 0); > + timer->sm =3D sm; > + pthread_create(&timer->t, NULL, fm10k_sm_handle_timer, > timer); > + timer->timer_id =3D 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 =3D &sm->timers[timer_id]; > + > + gettimeofday(&timer->start, 0); > + timer->timeout_ms =3D timeout_ms; > + timer->running =3D 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 =3D &sm->timers[timer_id]; > + timer->running =3D 0; > +} > + > +static void * > +fm10k_sm_handle_event(void *ctx) > +{ > + struct fm10k_sm *sm =3D ctx; > + uint16_t event_id; > + > + while (1) { > + event_id =3D 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 =3D ctx; > + struct fm10k_sm *sm =3D 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 =3D (now.tv_sec - timer->start.tv_sec)*1000000; > + cost +=3D (now.tv_usec - timer->start.tv_usec); > + if (cost < timer->timeout_ms*1000) { > + timeout =3D timer->timeout_ms*1000; > + timeout -=3D cost; > + sleep.tv_sec =3D timeout/1000000; > + sleep.tv_usec =3D 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 =3D 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 =3D heap->heap[0]; > + for (i=3D1; icount; i++) { > + heap->heap[i-1] =3D 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 >=3D FM10K_SM_ID_HEAP_MAX) { > + pthread_mutex_unlock(&heap->lock); > + return; > + } > + heap->heap[heap->count] =3D 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 > + > +#include > +#include > +#include > +#include > + > +/* > + * 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 interr= upts > + * 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 spec= ific > + * event, as it is often the case that a timer is used to poll for statu= s, > + * and different events might be generated upong timer expiration depend= ing > + * 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 sta= te > + * 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>=3D0 timers ident= ified > + * 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, t= hen > + * 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, unsign= ed > 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 =3D 0x1013000= 1; > +const uint32_t fm10000_sbus_master_code_size_prd =3D 3338; > + > +const uint16_t fm10000_sbus_master_code_prd[] =3D { > + 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 =3D > 0x20550045; > +const uint32_t fm10000_serdes_spico_code_size_prd2 =3D 12167; > + > +const uint16_t fm10000_serdes_spico_code_prd2[] =3D { > + 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 =3D > 0x20550045; > +const uint32_t fm10000_serdes_swap_code_size_prd2 =3D 7842; > + > +const uint16_t fm10000_serdes_swap_code_prd2[] =3D { > + 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 > + > +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 =3D reg(epl, lane); \ > + sgList[sgListCnt].data =3D (uint32_t*)&counters->var; \ > + sgList[sgListCnt].count =3D 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 =3D reg(epl, lane); \ > + sgList[sgListCnt].data =3D (uint32_t*)varPtr; \ > + sgList[sgListCnt].count =3D 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 =3D FM10K_MOD_STATS_BANK_FRAME(bank, (physPor= t > << 4 | bin), 0); \ > + sgList[sgListCnt].data =3D (uint32_t*)(((uint8_t*)counters)+frameOff= set); > \ > + sgList[sgListCnt].count =3D 2; > \ > + sgListCnt++; >=20 > \ > + sgList[sgListCnt].addr =3D FM10K_MOD_STATS_BANK_BYTE(bank, (physPort= << > 4 | bin), 0); \ > + sgList[sgListCnt].data =3D (uint32_t*)(((uint8_t*)counters)+byteOffs= et); > \ > + sgList[sgListCnt].count =3D 2; > \ > + sgListCnt++; >=20 > \ > +} 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 =3D FM10K_RX_STATS_BANK(bank, (physPort << 4 = | bin), > 0); \ > + sgList[sgListCnt].data =3D cntRxPortStatsBank[bank][bin]; > \ > + sgList[sgListCnt].count =3D 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) ) =3D (uint64_t) ( > \ > + ((uint64_t)(cntRxPortStatsBank[bank][bin][1]) << 32) | > \ > + ((uint64_t)(cntRxPortStatsBank[bank][bin][0]) ) ); > \ > + *( (uint64_t*) (((uint8_t*)counters)+byteOffset) ) =3D (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[] =3D { > + /* 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[] =3D { > + /* 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 =3D 0; > + int i; > + > + for (i =3D 0 ; err =3D=3D 0 && i < nEntries ; i++) > + { > + uint32_t addr =3D sgList[i].addr; > + uint32_t count =3D sgList[i].count; > + uint32_t *data =3D 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 =3D true; > + uint32_t i; > + struct fm10k_scatter_gather_entry sgList[MAX_STATS_SGLIST]; > + int sgListCnt =3D 0; > + /* Temporary bin array to retrieve 128bit port counters (frame + byt= es). */ > + 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 expli= citly > + * set below, which will be the fields not supported by the FM10000, > + * will be 0 on return. > + */ > + memset(counters, 0, sizeof(*counters)); > + > + physPort =3D ext_port->portno; > + epl =3D ext_port->eplno; > + lane =3D ext_port->first_lane; > + > + counters->cntVersion =3D 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 =3D 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 =3D 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 =3D FM10K_CM_APPLY_DROP_COUNT(physPort, 0); > + sgList[sgListCnt].data =3D (uint32_t*) &counters->cntTxCMDropPkts; > + sgList[sgListCnt].count =3D 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 >=3D 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 =3D 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 =3D 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 =3D counters->cntRxUcstPktsNonIP + > + counters->cntRxUcstPktsIPv4 + > + counters->cntRxUcstPktsIPv6; > + > + counters->cntRxMcstPkts =3D counters->cntRxMcstPktsNonIP + > + counters->cntRxMcstPktsIPv4 + > + counters->cntRxMcstPktsIPv6; > + > + counters->cntRxBcstPkts =3D counters->cntRxBcstPktsNonIP + > + counters->cntRxBcstPktsIPv4 + > + counters->cntRxBcstPktsIPv6; > + > + /* > + * Misc. counters. > + */ > + counters->cntRxOctetsNonIp =3D counters->cntRxUcstOctetsNonIP + > + counters->cntRxMcstOctetsNonIP + > + counters->cntRxBcstOctetsNonIP; > + > + counters->cntRxOctetsIPv4 =3D counters->cntRxUcstOctetsIPv4 + > + counters->cntRxMcstOctetsIPv4 + > + counters->cntRxBcstOctetsIPv4; > + > + counters->cntRxOctetsIPv6 =3D counters->cntRxUcstOctetsIPv6 + > + counters->cntRxMcstOctetsIPv6 + > + counters->cntRxBcstOctetsIPv6; > + > + counters->cntRxGoodOctets =3D counters->cntRxOctetsNonIp + > + counters->cntRxOctetsIPv4 + > + counters->cntRxOctetsIPv6; > + } else { > + /* > + * RX counters. > + */ > + counters->cntRxUcstPkts =3D counters->cntRxUcstPktsNonIP; > + counters->cntRxMcstPkts =3D counters->cntRxMcstPktsNonIP; > + counters->cntRxBcstPkts =3D counters->cntRxBcstPktsNonIP; > + > + /* > + * Misc. counters. > + */ > + counters->cntRxOctetsNonIp =3D counters->cntRxUcstOctetsNonIP + > + counters->cntRxMcstOctetsNonIP + > + counters->cntRxBcstOctetsNonIP; > + > + counters->cntRxGoodOctets =3D counters->cntRxOctetsNonIp; > + } > + > + counters->cntTriggerDropRedirPkts =3D counters->cntTriggerRedirPkts = + > + counters->cntTriggerDropPkts; > + > + /* Emulate Tx Octets counter using the sum of all size bins. */ > + counters->cntTxOctets +=3D counters->cntTxMinTo63octets; > + counters->cntTxOctets +=3D counters->cntTx64octets; > + counters->cntTxOctets +=3D counters->cntTx65to127octets; > + counters->cntTxOctets +=3D counters->cntTx128to255octets; > + counters->cntTxOctets +=3D counters->cntTx256to511octets; > + counters->cntTxOctets +=3D counters->cntTx512to1023octets; > + counters->cntTxOctets +=3D counters->cntTx1024to1522octets; > + counters->cntTxOctets +=3D counters->cntTx1523to2047octets; > + counters->cntTxOctets +=3D counters->cntTx2048to4095octets; > + counters->cntTxOctets +=3D counters->cntTx4096to8191octets; > + counters->cntTxOctets +=3D counters->cntTx8192to10239octets; > + counters->cntTxOctets +=3D 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 =3D fm10k_read_switch_reg64(sw, > + 0xE40000 + > 0x4000*FM10K_SW_FFU_CNT_BANK + > 0x4*(table_id+FM10K_SW_FFU_CNT_START) + 0x8000); > + } else { > + data =3D 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 =3D FM10K_FFU_EXT_PORT_RULE_INGRESS(epl); > + data =3D fm10k_stats_ffu_count_get(sw, table_id); > + printf(" FFU[%d] ingress %-12llu\n", > + table_id, (long long unsigned int)(data)); > + > + table_id =3D FM10K_FFU_EXT_PORT_RULE_EGRESS(epl); > + data =3D 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 =3D 0; i < FM10K_STATS_RULE_NUM_MAX; i++) { > + if (fm10k_stats_rule_list[i] =3D=3D 0) { > + fm10k_stats_rule_list[i] =3D 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 =3D 0; i < FM10K_STATS_RULE_NUM_MAX; i++) { > + if (fm10k_stats_rule_list[i] =3D=3D 0) > + continue; > + > + rule_id =3D fm10k_stats_rule_list[i]; > + data =3D 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] =3D 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 =3D 0; i < FM10K_SW_EPLS_SUPPORTED; i++) { > + lport =3D sw->epl_map[i].logical_port; > + ext_port.portno =3D lport; > + fm10k_get_port_counters(sw, &ext_port, &counters); > + > + data.rx_pkts =3D counters.cntRxBcstPkts + > counters.cntRxUcstPkts; > + data.tx_pkts =3D counters.cntTxBcstPkts + counters.cntTxUcstPkts; > + data.rx_drop =3D 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] =3D 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 =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + if (sw->dpdk_cfg->ports[i].hw =3D=3D NULL) > + continue; > + if (sw->dpdk_cfg->ports[i].type !=3D FM10K_CONFIG_DPDK_PF) > + continue; > + if (sw->dpdk_cfg->dpdk_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_NULL) > + continue; > + > + memset(&mydata, 0, sizeof(mydata)); > + if (sw->dpdk_cfg->dpdk_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PFS) { > + for (j =3D 0; j < 2; j++) { > + pf_no =3D sw->dpdk_cfg- > >dpdk_port_map[i].map_no[j]; > + lport =3D sw->pep_map[pf_no].logical_port; > + memset(&ext_port, 0, sizeof(ext_port)); > + ext_port.portno =3D lport; > + fm10k_get_port_counters(sw, &ext_port, > &counters); > + data.rx_pkts =3D counters.cntRxBcstPkts + > counters.cntRxUcstPkts; > + data.tx_pkts =3D counters.cntTxBcstPkts + > counters.cntTxUcstPkts; > + data.rx_drop =3D counters.cntCmPrivDropPkts; > + mydata.rx_pkts +=3D data.rx_pkts- > last_data[pf_no].rx_pkts; > + mydata.tx_pkts +=3D data.tx_pkts- > last_data[pf_no].tx_pkts; > + mydata.rx_drop +=3D data.rx_drop- > last_data[pf_no].rx_drop; > + last_data[pf_no] =3D data; > + } > + } else if (sw->dpdk_cfg->dpdk_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PF) { > + pf_no =3D sw->dpdk_cfg->dpdk_port_map[i].map_no[0]; > + lport =3D sw->pep_map[pf_no].logical_port; > + memset(&ext_port, 0, sizeof(ext_port)); > + ext_port.portno =3D lport; > + fm10k_get_port_counters(sw, &ext_port, &counters); > + data.rx_pkts =3D counters.cntRxBcstPkts + > counters.cntRxUcstPkts; > + data.tx_pkts =3D counters.cntTxBcstPkts + > counters.cntTxUcstPkts; > + data.rx_drop =3D counters.cntCmPrivDropPkts; > + mydata.rx_pkts +=3D data.rx_pkts- > last_data[pf_no].rx_pkts; > + mydata.tx_pkts +=3D data.tx_pkts- > last_data[pf_no].tx_pkts; > + mydata.rx_drop +=3D data.rx_drop- > last_data[pf_no].rx_drop; > + last_data[pf_no] =3D data; > + } else > + continue; > + > + if (sw->dpdk_cfg->dpdk_port_map[i].type =3D=3D > 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 =3D 0; j < sw->dpdk_cfg->ports[i].tx_queue_num; j++) > + { > + struct fm10k_hw *hw =3D sw->dpdk_cfg->ports[i].hw; > + uint16_t queue_id =3D 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 =3D fm10k_switch_dpdk_pf_no_get(hw); > + data.tx_pkts =3D FM10K_READ_REG(hw, > FM10K_QPTC(queue_id)); > + data.rx_pkts =3D FM10K_READ_REG(hw, > FM10K_QPRC(queue_id)); > + data.rx_drop =3D FM10K_READ_REG(hw, > FM10K_QPRDC(queue_id)); > + mydata.tx_pkts +=3D data.tx_pkts - > last_queue_data[pf_no][queue_id].tx_pkts; > + mydata.rx_pkts +=3D data.rx_pkts - > last_queue_data[pf_no][queue_id].rx_pkts; > + mydata.rx_drop +=3D 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] =3D 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 =3D lport; > + fm10k_get_port_counters(sw, &ext_port, &counters); > + > + for (i =3D 0; i < FM10K_SW_NITEMS(rxPortCntMapTable); i++) { > + pdata =3D > (uint64_t*)((uint8_t*)(&counters)+rxPortCntMapTable[i].frameOffset); > + if (*pdata !=3D 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 =3D 0; i < FM10K_SW_NITEMS(txPortCntMapTable); i++) { > + pdata =3D > (uint64_t*)((uint8_t*)(&counters)+txPortCntMapTable[i].frameOffset); > + if (*pdata !=3D 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 =3D 0; i < FM10K_SW_EPLS_SUPPORTED; i++) { > + fm10k_stats_port_counter_print(sw, sw- > >epl_map[i].logical_port); > + } > + for (i =3D 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 =3D 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 > + > + > +#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 > +#include > + > +#include > + > +#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[] =3D { > + { 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] =3D { > + {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] =3D { > + {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 =3D (pf2 & 0xf) | (pf1<<4 & 0xf0); > + else > + idx =3D (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 =3D 0; i < FM10K_SW_FFU_RULE_MAX; i++) { > + if (lport1 =3D=3D fm10k_multi_glorts[i].lport1 && > + lport2 =3D=3D fm10k_multi_glorts[i].lport2 && > + vlan1 =3D=3D fm10k_multi_glorts[i].vlan1 && > + vlan2 =3D=3D fm10k_multi_glorts[i].vlan2) { > + if(p_new !=3D NULL) > + *p_new =3D false; > + return FM10K_SW_MULTI_GLORT_START + i; > + } > + } > + > + for (i =3D 0; i < FM10K_SW_FFU_RULE_MAX; i++) { > + if (fm10k_multi_glorts[i].lport1 =3D=3D 0 && > + fm10k_multi_glorts[i].lport2 =3D=3D 0 && > + fm10k_multi_glorts[i].vlan1 =3D=3D 0 && > + fm10k_multi_glorts[i].vlan2 =3D=3D 0) { > + fm10k_multi_glorts[i].lport1 =3D lport1; > + fm10k_multi_glorts[i].lport2 =3D lport2; > + fm10k_multi_glorts[i].vlan1 =3D vlan1; > + fm10k_multi_glorts[i].vlan2 =3D vlan2; > + if(p_new !=3D NULL) > + *p_new =3D 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 =3D 0; > + > + for (i =3D 0; i < FM10K_SW_EPLS_SUPPORTED; i++) { > + fm10k_sched_prog[i].idle =3D 0; > + fm10k_sched_prog[i].phys =3D > fm10k_epl_port_map[i].physical_port; > + fm10k_sched_prog[i].log =3D fm10k_epl_port_map[i].logical_port; > + fm10k_sched_prog[i].quad =3D FM10K_SW_QUAD_ON; > + } > + start +=3D FM10K_SW_EPLS_SUPPORTED; > + for (i =3D 0; i < FM10K_SW_PEPS_SUPPORTED; i++) { > + fm10k_sched_prog[start+i].idle =3D 0; > + fm10k_sched_prog[start+i].phys =3D > fm10k_pep_port_map[i].physical_port; > + fm10k_sched_prog[start+i].log =3D > fm10k_pep_port_map[i].logical_port; > + fm10k_sched_prog[start+i].quad =3D FM10K_SW_QUAD_40_100; > + } > + start +=3D FM10K_SW_PEPS_SUPPORTED; > + fm10k_sched_prog[start].idle =3D 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 =3D hw->vendor_id; > + uint16_t pci_device =3D hw->device_id; > + uint16_t pci_subvendor =3D hw->subsystem_vendor_id; > + uint16_t pci_subdevice =3D hw->subsystem_device_id; > + > + if ((pci_vendor !=3D FM10K_SW_VENDOR_ID_INTEL) || > + (pci_device !=3D FM10K_SW_DEV_ID_FM10K)) > + return (NULL); > + > + for (i =3D 0; i < FM10K_SW_NITEMS(fm10k_device_table); i++) { > + info =3D &fm10k_device_table[i]; > + if ((pci_subvendor =3D=3D info->subvendor) && > + (pci_subdevice =3D=3D info->subdevice)) { > + return (info); > + } > + } > + > + return (NULL); > +} > + > + > +static void > +fm10k_switch_determine_epls(struct fm10k_switch *sw) > +{ > + struct fm10k_device_info *cfg =3D sw->info; > + unsigned int i; > + uint8_t phys; > + > + sw->epla_no =3D 0; > + sw->eplb_no =3D 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 =3D 1; > + sw->eplb_no =3D 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 =3D 1; > + sw->eplb_no =3D 7; > + break; > + } > + > + for (i =3D 0; i < FM10K_SW_NITEMS(fm10k_sched_prog); i++) { > + if (fm10k_sched_prog[i].idle) > + continue; > + > + phys =3D fm10k_sched_prog[i].phys; > + if (phys <=3D 3) { > + /* Substitute actual epla phys port number */ > + fm10k_sched_prog[i].phys =3D sw->epla_no * 4 + phys; > + } else if (phys >=3D 4 && phys <=3D 7) { > + /* Substitute actual eplb phys port number */ > + fm10k_sched_prog[i].phys =3D sw->eplb_no * 4 + (phys - > 4); > + } > + } > +} > + > +static void > +fm10k_hw_eicr_disable_source(struct fm10k_switch *sw, unsigned int sourc= e) > +{ > + unsigned int shift; > + > + switch (source) { > + case FM10K_SW_EICR_PCA_FAULT: > + shift =3D FM10K_SW_EICR_PCA_FAULT_SHIFT; > + break; > + case FM10K_SW_EICR_THI_FAULT: > + shift =3D FM10K_SW_EICR_THI_FAULT_SHIFT; > + break; > + case FM10K_SW_EICR_FUM_FAULT: > + shift =3D FM10K_SW_EICR_FUM_FAULT_SHIFT; > + break; > + case FM10K_SW_EICR_MAILBOX: > + shift =3D FM10K_SW_EICR_MAILBOX_SHIFT; > + break; > + case FM10K_SW_EICR_SWITCH_READY: > + shift =3D FM10K_SW_EICR_SWITCH_READY_SHIFT; > + break; > + case FM10K_SW_EICR_SWITCH_NREADY: > + shift =3D FM10K_SW_EICR_SWITCH_NREADY_SHIFT; > + break; > + case FM10K_SW_EICR_SWITCH_INT: > + shift =3D FM10K_SW_EICR_SWITCH_INT_SHIFT; > + break; > + case FM10K_SW_EICR_SRAM_ERROR: > + shift =3D FM10K_SW_EICR_SRAM_ERROR_SHIFT; > + break; > + case FM10K_SW_EICR_VFLR: > + shift =3D FM10K_SW_EICR_VFLR_SHIFT; > + break; > + case FM10K_SW_EICR_MAX_HOLD_TIME: > + shift =3D 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 eplid= x) > +{ > + 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 =3D=3D 0 || pcs =3D=3D FM10K_SW_EPL_PCS_SEL_DISABLE) { > + if (pcs =3D=3D FM10K_SW_EPL_PCS_SEL_40GBASER || > + pcs =3D=3D FM10K_SW_EPL_PCS_SEL_100GBASER) > + return (FM10K_AM_TIMEOUT / 2); > + else > + return (0); > + } > + > + if (pcs =3D=3D FM10K_SW_EPL_PCS_SEL_40GBASER || > + pcs =3D=3D FM10K_SW_EPL_PCS_SEL_100GBASER) { > + am_ppm =3D 1000000 / FM10K_AM_TIMEOUT; > + scale =3D FM10K_COMP_PPM_SCALE / 2; > + } else { > + am_ppm =3D 0; > + scale =3D FM10K_COMP_PPM_SCALE; > + } > + > + ppm =3D num_ppm + am_ppm; > + timeout =3D scale / ppm; > + > + if(timeout >=3D 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 =3D sw->ext_ports; > + struct fm10k_ext_port *port; > + struct fm10k_device_info *cfg =3D 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 =3D fm10k_get_device_info(hw); > + if (cfg =3D=3D 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 =3D FM10K_SW_EPL_PCS_SEL_10GBASER; > + qpl =3D FM10K_SW_EPL_QPL_MODE_L1_L1_L1_L1; > + dic_enable =3D 1; > + anti_bubble_wm =3D 5; > + rate_fifo_wm =3D 3; > + rate_fifo_slow_inc =3D 12; > + rate_fifo_fast_inc =3D 13; > + break; > + /* XXX what is the physical config for 25G? */ > + case 25: > + pcs =3D FM10K_SW_EPL_PCS_SEL_100GBASER; > + qpl =3D FM10K_SW_EPL_QPL_MODE_L1_L1_L1_L1; > + dic_enable =3D 0; > + anti_bubble_wm =3D 6; > + rate_fifo_wm =3D 3; > + rate_fifo_slow_inc =3D 32; > + rate_fifo_fast_inc =3D 33; > + break; > + case 40: > + pcs =3D FM10K_SW_EPL_PCS_SEL_40GBASER; > + qpl =3D FM10K_SW_EPL_QPL_MODE_L4_XX_XX_XX; > + dic_enable =3D 1; > + anti_bubble_wm =3D 4; > + rate_fifo_wm =3D 5; > + rate_fifo_slow_inc =3D 51; > + rate_fifo_fast_inc =3D 52; > + break; > + case 100: > + pcs =3D FM10K_SW_EPL_PCS_SEL_100GBASER; > + qpl =3D FM10K_SW_EPL_QPL_MODE_L4_XX_XX_XX; > + dic_enable =3D 1; > + anti_bubble_wm =3D 4; > + rate_fifo_wm =3D 3; > + rate_fifo_slow_inc =3D 129; > + rate_fifo_fast_inc =3D 130; > + break; > + default: > + error =3D -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 =3D 0; i < FM10K_SW_EPLS_MAX; i++) { > + data =3D fm10k_read_switch_reg(sw, FM10K_SW_EPL_CFG_A(i)); > + data &=3D ~FM10K_SW_EPL_CFG_A_ACTIVE_QUAD; > + if (FM10K_SW_EXT_PORTS_EPL_USED(ext_ports, i)) { > + for (j =3D 0; j < ext_ports->num_ports; j++) { > + port =3D &ext_ports->ports[j]; > + if (port->eplno =3D=3D i) > + data |=3D 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 =3D 0; > + for (i =3D 0; i < FM10K_SW_EPLS_MAX; i++) { > + if (FM10K_SW_EXT_PORTS_EPL_USED(ext_ports, i)) { > + for (j =3D 0; j < FM10K_SW_EPL_LANES; j++) { > + if (j < ext_ports->ports_per_epl) > + pcstmp =3D pcs; > + else > + pcstmp =3D > FM10K_SW_EPL_PCS_SEL_DISABLE; > + data |=3D > + FM10K_SW_MAKE_REG_FIELD_IDX( > + EPL_CFG_B_PCS_SEL, > + j, > + pcstmp); > + } > + data |=3D > + FM10K_SW_MAKE_REG_FIELD( > + EPL_CFG_B_QPL_MODE, > + qpl); > + } else { > + for (j =3D 0; j < FM10K_SW_EPL_LANES; j++) > + data |=3D > + FM10K_SW_MAKE_REG_FIELD_IDX( > + EPL_CFG_B_PCS_SEL, > + j, > + FM10K_SW_EPL_PCS_SEL_DISABLE); > + data |=3D > + 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 =3D 0; i < FM10K_SW_EPLS_MAX; i++) { > + if (!FM10K_SW_EXT_PORTS_EPL_USED(ext_ports, i)) > + continue; > + for (j =3D 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 =3D > + > 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 =3D 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 =3D=3D 10 ? 4 : 0); > + fm10k_write_switch_reg(sw, FM10K_SW_LINK_RULES(i, > j), data); > + > + /* XXX add 10GBASER config */ > + } > + > + if (cfg->ext_port_speed !=3D 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 =3D 0; i < FM10K_SW_EPLS_MAX; i++) { > + if (!FM10K_SW_EXT_PORTS_EPL_USED(ext_ports, i)) > + continue; > + for (j =3D 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 =3D fm10k_read_switch_reg(sw, > + FM10K_SW_LANE_ENERGY_DETECT_CFG(i, j)); > + data |=3D > + > 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 &=3D > + > ~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 =3D fm10k_read_switch_reg(sw, > + FM10K_SW_LANE_SIGNAL_DETECT_CFG(i, j)); > + data &=3D > + > ~(FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_MASK_RX_SIGNAL_OK | > + > FM10K_SW_LANE_SIGNAL_DETECT_CFG_SD_MASK_RX_RDY); > + data |=3D > + > 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 =3D 0; > + data |=3D ((1 << j) << 4) | (1 << j); > + fm10k_write_switch_reg(sw, > + FM10K_SW_EPL_FIFO_ERROR_STATUS(i), data); > + } > + } > + > + error =3D fm10k_epl_serdes_reset_and_load_all(sw); > + if (error) > + goto done; > + > + /* > + * EPL_FIFO_ERROR_STATUS LINK_IP > + */ > + for (i =3D 0; i < FM10K_SW_EPLS_MAX; i++) { > + if (!FM10K_SW_EXT_PORTS_EPL_USED(ext_ports, i)) > + continue; > + for (j =3D 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 =3D 0; > + data |=3D ((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 =3D &fm10k_sw; > + int src_port =3D fm10k_switch_dpdk_port_no_get(hw); > + > + /* source port is external port number */ > + if (src_port < 0 || src_port =3D=3D 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 =3D &fm10k_sw; > + int src_port =3D 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 =3D sw->info->num_peps + > FM10K_SW_EPLS_SUPPORTED; > + fm10k_sw_lport all_lports[num_lports]; > + struct fm10k_device_info *cfg =3D 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 =3D 0; > + for (i =3D 0; i < sw->info->num_peps; i++, table_idx++) { > + all_lports[table_idx].lport =3D sw->pep_map[i].logical_port; > + all_lports[table_idx].has_ftag =3D 1; > + } > + for (i =3D 0; i < FM10K_SW_EPLS_SUPPORTED; i++, table_idx++) { > + all_lports[table_idx].lport =3D sw->epl_map[i].logical_port; > + all_lports[table_idx].has_ftag =3D 0; > + } > + > + if (table_idx !=3D num_lports) { > + FM10K_SW_ERR("fm10k switch lport table construction error"); > + return -1; > + } > + > + /* > + * Reset the switch to get to the default state > + */ > + data =3D fm10k_read_switch_reg(sw, FM10K_SW_SOFT_RESET); > + data &=3D ~FM10K_SW_SOFT_RESET_SWITCH_READY; > + fm10k_write_switch_reg(sw, FM10K_SW_SOFT_RESET, data); > + fm10k_write_flush(sw); > + > + usec_delay(100); > + data =3D fm10k_read_switch_reg(sw, FM10K_SW_SOFT_RESET); > + data |=3D 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 =3D fm10k_read_switch_reg(sw, FM10K_SW_SOFT_RESET); > + data &=3D ~(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 =3D fm10k_sbus_attach(sw, "EPL", > FM10K_SW_SBUS_EPL_CFG); > + if (sw->epl_sbus =3D=3D NULL) { > + error =3D -1; > + goto done; > + } > + > + /* Clear non-BIST accessible pause state memories */ > + for (i =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D fm10k_read_switch_reg(sw, FM10K_SW_SYS_CFG_1); > + data &=3D ~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 =3D 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 =3D 0; > + for (i =3D 0; i < num_lports; i++) > + data64 |=3D > FM10K_SW_INGRESS_VID_TABLE_MEMBERSHIP(all_lports[i].lport); > + for (i =3D 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 =3D 0; > + for (i =3D 0; i < num_lports; i++) > + data64 |=3D > FM10K_SW_EGRESS_VID_TABLE_MEMBERSHIP(all_lports[i].lport); > + for (i =3D 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 =3D 0; i < FM10K_SW_INGRESS_VID_TABLE_ENTRIES; i++) { > + data64 =3D i; > + data64 =3D data64<<48; > + fm10k_write_switch_reg64(sw, 0xE80000+0x2*i+0x20000, > data64); > + } > + > + /* Configure MST instance 0 to forward for all ports */ > + data64 =3D 0; > + for (i =3D 0; i < num_lports; i++) > + data64 |=3D > FM10K_SW_EGRESS_MST_TABLE_FORWARDING(all_lports[i].lport); > + fm10k_write_switch_reg64(sw, FM10K_SW_EGRESS_MST_TABLE(0), > data64); > + > + data64 =3D 0; > + data64_2 =3D 0; > + for (i =3D 0; i < num_lports; i++) { > + if (all_lports[i].lport < > + FM10K_SW_INGRESS_MST_TABLE_PORTS_PER_TABLE) { > + data64 |=3D > + 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 |=3D > + 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 =3D 0; i < num_lports; i++) { > + data64 =3D fm10k_read_switch_reg64(sw, > + FM10K_SW_PARSER_PORT_CFG_1(all_lports[i].lport)); > + data64 |=3D 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 =3D fm10k_read_switch_reg64(sw, > + FM10K_SW_PARSER_PORT_CFG_1(all_lports[i].lport)); > + data64 |=3D FM10K_SW_PARSER_PORT_CFG_1_FTAG; > + fm10k_write_switch_reg64(sw, > + FM10K_SW_PARSER_PORT_CFG_1(all_lports[i].lport), > + data64); > + > + data64 =3D fm10k_read_switch_reg64(sw, > + > FM10K_SW_MOD_PER_PORT_CFG_2(all_lports[i].lport)); > + data64 |=3D 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 =3D fm10k_read_switch_reg64(sw, > + FM10K_SW_PARSER_PORT_CFG_2(all_lports[i].lport)); > + data64 |=3D FM10K_SW_PARSER_PORT_CFG_2_PARSE_L3; > + data64 |=3D 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 =3D 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 =3D 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 =3D=3D 40 || cfg->ext_port_speed =3D=3D 100) > + is_quad =3D 1; > + else > + is_quad =3D 0; > + for (i =3D 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 =3D FM10K_SW_SCHED_SCHEDULE_IDLE; > + else { > + data =3D FM10K_SW_SCHED_SCHEDULE_ENTRY( > + fm10k_sched_prog[i].phys, > + fm10k_sched_prog[i].log, > + (fm10k_sched_prog[i].quad =3D=3D > 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 =3D 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 =3D FM10K_SW_RX_STATS_CFG_ENABLE_ALL_BANKS; > + data64 =3D > + FM10K_SW_MOD_STATS_CFG_ENABLE_GROUP_7 | > + FM10K_SW_MOD_STATS_CFG_ENABLE_GROUP_8; > + for (i =3D 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 =3D fm10k_read_switch_reg(sw, FM10K_SW_SOFT_RESET); > + data |=3D 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 =3D 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 =3D 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 =3D 24/FM10K_LED_BLINKS_PER_SECOND; > + else > + max =3D 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 =3D 0x6a; > + for (i =3D 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 =3D 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 =3D 24/FM10K_LED_BLINKS_PER_SECOND; > + else > + max =3D 1; > + fm10k_i2c_write16(sw->i2c, addr, 0x13, max - 1); > + > + addr =3D 0x69; > + } > + FM10K_SW_I2C_REQ_UNLOCK(sw->i2c); > + break; > + > + case FM10K_SW_CARD(SILICOM, PE3100G2DQIRL_QXSL4): > + FM10K_SW_I2C_REQ_LOCK(sw->i2c); > + addr =3D 0x62; > + fm10k_i2c_write16(sw->i2c, addr, 0x03, 0x88); > + fm10k_i2c_write16(sw->i2c, addr, 0x01, 0x0); > + > + data =3D fm10k_read_switch_reg(sw, 0xc2b); > + data |=3D 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 =3D 0x62; > + fm10k_i2c_write16(sw->i2c, addr, 0x03, 0x0); > + fm10k_i2c_write16(sw->i2c, addr, 0x01, 0x0); > + > + addr =3D 0x65; > + fm10k_i2c_write16(sw->i2c, addr, 0x03, 0xf0); > + fm10k_i2c_write16(sw->i2c, addr, 0x01, 0x0); > + > + addr =3D 0x66; > + fm10k_i2c_write16(sw->i2c, addr, 0x03, 0x0); > + fm10k_i2c_write16(sw->i2c, addr, 0x01, 0x0); > + > + /* set LEC_CFG */ > + data =3D fm10k_read_switch_reg(sw, 0xc2b); > + data |=3D 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=3D0x%04x subdevice=3D0x%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 =3D 0x3; /* group blink */ > + else > + bits =3D 0x1; /* full on */ > + } else > + bits =3D 0; /* off */ > + > + return (bits); > +} > + > +static void > +fm10k_switch_process_leds(void *ctx) > +{ > + struct fm10k_switch *sw =3D ctx; > + struct fm10k_device_info *cfg =3D sw->info; > + struct fm10k_ext_ports *ports =3D sw->ext_ports; > + struct fm10k_ext_port *port; > + unsigned int i; > + unsigned int num_ports =3D ports->num_ports; > + uint32_t data; > + uint8_t update_port[num_ports]; > + uint8_t led_flags =3D 0, read; > + uint8_t addr; > + > + FM10K_SW_SWITCH_LOCK(sw); > + > + if (sw->master_hw->sw_addr =3D=3D NULL) { > + FM10K_SW_SWITCH_UNLOCK(sw); > + return; > + } > + > + for (i =3D 0; i < num_ports; i++) { > + port =3D &ports->ports[i]; > + data =3D fm10k_read_switch_reg(sw, > + FM10K_SW_EPL_LED_STATUS(port->eplno)); > + led_flags =3D > + ((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] =3D (led_flags !=3D port->last_led_flags); > + port->last_led_flags =3D 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 =3D > + 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 =3D 0; i < 2; i++) { > + if (update_port[i] =3D=3D 0) > + continue; > + > + addr =3D (i =3D=3D 0) ? 0x6a : 0x69; > + > + port =3D &ports->ports[i]; > + led_flags =3D 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 =3D 0; > + addr =3D 0x62; > + for (i =3D 0; i < 2; i++) { > + if (!update_port[i]) > + continue; > + port =3D &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 |=3D 0x6<<(4*i); /* 100G */ > + break; > + case 40: > + case 10: > + led_flags |=3D 0x4<<(4*i); /* 40G */ > + break; > + default: > + led_flags =3D 0; > + } > + } else > + led_flags =3D 0; /* off */ > + } > + > + if (update_port[0] || update_port[1]) { > + fm10k_i2c_read8_ext(sw->i2c, addr, 0x1, &read); > + if(update_port[0]) > + led_flags |=3D read&0xf0; > + else > + led_flags |=3D 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 =3D 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 =3D (i =3D=3D 0) ? 0x62 : 0x66; > + port =3D &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 =3D 0x08; /* 100G */ > + break; > + case 40: > + led_flags =3D 0x02; /* 40G */ > + break; > + } > + } else > + led_flags =3D 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 =3D ctx; > + > + while (sw->detaching =3D=3D 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 =3D 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 =3D > + 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 =3D 0x6a; > + led_flags =3D fm10k_switch_pca9635_led_bits(0); > + for (i =3D 0; i < 2; i++) { > + port =3D &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 =3D 0x69; > + } > + FM10K_SW_I2C_REQ_UNLOCK(sw->i2c); > + break; > + } > +} > + > + > +static void * > +fm10k_switch_process_intr(void *ctx) > +{ > + struct fm10k_switch *sw =3D 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 =3D 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 =3D fm10k_read_switch_reg64(sw, > FM10K_SW_GLOBAL_INTERRUPT_DETECT); > + FM10K_SW_SWITCH_UNLOCK(sw); > + > + reenable_mask =3D 0; > + if (ports) { > + epl_mask =3D fm10k_ext_ports_epl_intrs(ports, gid); > + reenable_mask |=3D > + > 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 |=3D 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 =3D > + 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 &=3D ~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 =3D 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 =3D &fm10k_sw; > + > + if (hw =3D=3D NULL || sw =3D=3D NULL) > + return; > + > + FM10K_SW_SWITCH_LOCK(sw); > + sw->detaching =3D 1; > + FM10K_SW_SWITCH_UNLOCK(sw); > + > + if (sw->ext_ports) { > + ports =3D 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 =3D 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 =3D 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 =3D fm10k_read_switch_reg(sw, > FM10K_SW_PLL_FABRIC_CTRL); > + refdiv =3D FM10K_SW_REG_FIELD(ctrl, PLL_FABRIC_REFDIV); > + fbdiv4 =3D FM10K_SW_REG_FIELD(ctrl, PLL_FABRIC_FBDIV4); > + fbdiv255 =3D FM10K_SW_REG_FIELD(ctrl, PLL_FABRIC_FBDIV255); > + > + freq =3D (15625 * 4 * fbdiv255 * (1 + fbdiv4)) / (refdiv * 100); > + break; > + } > + case FM10K_SW_PLL_FABRIC_FREQSEL_F600: freq =3D 600; break; > + case FM10K_SW_PLL_FABRIC_FREQSEL_F500: freq =3D 500; break; > + case FM10K_SW_PLL_FABRIC_FREQSEL_F400: freq =3D 400; break; > + case FM10K_SW_PLL_FABRIC_FREQSEL_F300: freq =3D 300; break; > + default: > + freq =3D 0; > + break; > + } > + > + return (freq); > +} > + > +static unsigned int > +fm10k_switch_get_sku(struct fm10k_switch *sw) > +{ > + uint32_t fuse_data; > + > + fuse_data =3D 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 =3D "FM10840"; break; > + case FM10K_SW_FUSE_SKU_FM10420: name =3D "FM10420"; break; > + case FM10K_SW_FUSE_SKU_FM10064: name =3D "FM10064"; break; > + default: name =3D "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 =3D 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 =3D fm10k_read_switch_reg(sw, FM10K_SW_SOFT_RESET); > + for (i =3D 0; i < FM10K_SW_PEPS_MAX; i++) { > + if (!(device_cfg & FM10K_SW_DEVICE_CFG_PCIE_EN(i))) > + continue; > + > + pair =3D i / 2; > + reset_state =3D !!(resets & > FM10K_SW_SOFT_RESET_PCIE_RESET(i)); > + active_state =3D !!(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 =3D=3D 0) > + FM10K_SW_INFO("switch: PEP[%u,%u] is > enabled in 1x8 " > + "mode (Reset=3D%u, Active=3D%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=3D%u, " > + "Active=3D%u)", i, i - 1, i, reset_state, > + active_state); > + } else { > + FM10K_SW_INFO("switch: PEP[%u] is enabled in 1x4 " > + "mode (Reset=3D%u, Active=3D%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 =3D 0; > + > + /* > + * XXX apparently no way to determine one's own PEP number. > + */ > + switch (sw->info->num_peps) { > + case 1: > + sw->pepno =3D 0; > + break; > + > + case 2: > + /* > + * XXX assumption is using even numbered PEPs starting with 0, > and > + * the highest numbered PEP is the master > + */ > + sw->pepno =3D 2; > + for (i =3D 0; i < sw->info->num_peps - 1; i++) { > + sw->pep_mask |=3D (1 << (i * 2)); > + } > + break; > + > + case 4: > + sw->pepno =3D 6; > + sw->pep_mask =3D 0x7f; > + break; > + > + default: > + sw->pepno =3D 0; > + } > + > + /* When not zero, initialize serdes in 'near loopback' mode */ > + sw->serdes_loopback =3D 0; > + > + pthread_mutex_init(&sw->lock, NULL); > + > + fm10k_switch_determine_epls(sw); > + > + sw->ext_ports =3D fm10k_ext_ports_attach(sw); > + if (sw->ext_ports =3D=3D NULL) > + goto fail; > + > + /* label all external ports with their logical port numbers */ > + for (i =3D 0; i < sw->ext_ports->num_ports; i++) > + sw->ext_ports->ports[i].lport =3D 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 =3D fm10k_i2c_attach(sw); > + if (sw->i2c =3D=3D NULL) > + goto fail; > + > + error =3D fm10k_switch_init(hw, sw); > + if (error) > + goto fail; > + > + for (i =3D 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 =3D 1; > + return (sw); > +fail: > + if (sw !=3D 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 =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + if (sw->dpdk_cfg->ports[i].pf_no =3D=3D 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 =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + if (sw->dpdk_cfg->dpdk_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PF) { > + if (sw->dpdk_cfg->dpdk_port_map[i].map_no[0] =3D=3D > pf_no) > + return i; > + } else if (sw->dpdk_cfg->dpdk_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PFS || > + sw->dpdk_cfg->dpdk_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PFSS) { > + if (sw->dpdk_cfg->dpdk_port_map[i].map_no[0] =3D=3D > pf_no || > + sw->dpdk_cfg- > >dpdk_port_map[i].map_no[1] =3D=3D 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 =3D 0; i < FM10K_SW_EXT_PORTS_MAX; i++) { > + if (sw->dpdk_cfg->ext_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PF) { > + if (sw->dpdk_cfg->ext_port_map[i].map_no[0] =3D=3D > pf_no) > + return i; > + } else if (sw->dpdk_cfg->ext_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PFS) { > + if (sw->dpdk_cfg->ext_port_map[i].map_no[0] =3D=3D > pf_no || > + sw->dpdk_cfg- > >ext_port_map[i].map_no[1] =3D=3D 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 =3D 0; > + int pf_no; > + > + sw->info =3D fm10k_get_device_info(master_hw); > + sw->master_hw =3D master_hw; > + sw->pep_map =3D fm10k_pep_port_map; > + sw->epl_map =3D fm10k_epl_port_map; > + > + sw->info->ext_port_speed =3D sw->dpdk_cfg->ext_port_speed; > + fm10k_switch_set_sched_prog(); > + fm10k_switch_attach(master_hw, &fm10k_sw); > + > + for (i =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + port =3D &sw->dpdk_cfg->ports[i]; > + if (port->type =3D=3D FM10K_CONFIG_DPDK_PF && > + sw->dpdk_cfg->dpdk_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_PFS) { > + for (j =3D 0; j< 2; j++) { > + pf_no =3D sw->dpdk_cfg- > >dpdk_port_map[i].map_no[j]; > + dpdk_port_no =3D > fm10k_switch_dpdk_port_get(sw, pf_no); > + if (sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].type =3D=3D FM10K_CONFIG_PORT_MAP_PF) { > + sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].type =3D FM10K_CONFIG_PORT_MAP_PFSS; > + sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].map_no[0] =3D sw->dpdk_cfg- > >dpdk_port_map[i].map_no[0]; > + sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].map_no[1] =3D sw->dpdk_cfg- > >dpdk_port_map[i].map_no[1]; > + } > + } > + } > + } > + > + /* do initialze all ports, after switch is ready */ > + for (i =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + uint32_t sglort; > + struct fm10k_dpdk_port *port =3D &sw->dpdk_cfg->ports[i]; > + struct fm10k_hw *hw =3D port->hw; > + > + if (hw =3D=3D NULL) > + break; > + > + if (port->type =3D=3D FM10K_CONFIG_DPDK_PF) { > + pf_no =3D fm10k_switch_dpdk_pf_no_get(hw); > + if (sw->dpdk_cfg->ext_port_map[ext_port_no].type =3D=3D > FM10K_CONFIG_PORT_MAP_PF) { > + sglort =3D fm10k_switch_pf_glort_get(pf_no); > + } else if (sw->dpdk_cfg- > >ext_port_map[ext_port_no].type =3D=3D FM10K_CONFIG_PORT_MAP_PFS) { > + ext_port_no =3D > fm10k_switch_mapped_ext_port_get(sw, pf_no); > + sglort =3D 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 =3D 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 =3D=3D NULL && is_pf) { > + if (fm10k_config_init(sw, hw) < 0) > + return -1; > + } > + > + for (i =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + port =3D &sw->dpdk_cfg->ports[i]; > + if (master && port->hw && > + port->type =3D=3D FM10K_CONFIG_DPDK_PF) { > + port->pf_no =3D sw->dpdk_cfg->pf_max - 1 - > + (hw->mac.addr[5] - port->hw- > >mac.addr[5]); > + sw->dpdk_cfg->pf_hw[port->pf_no] =3D port->hw; > + } > + > + if (port->hw =3D=3D NULL) { > + port->hw =3D hw; > + if (is_pf) { > + sw->dpdk_cfg->pf_bind ++; > + port->type =3D FM10K_CONFIG_DPDK_PF; > + if (sw->dpdk_cfg->dpdk_port_map[i].type > + =3D=3D > FM10K_CONFIG_PORT_MAP_NULL) { > + sw->dpdk_cfg->dpdk_port_map[i].type > =3D FM10K_CONFIG_PORT_MAP_PF; > + sw->dpdk_cfg- > >dpdk_port_map[i].map_no[0] =3D i; > + } > + } else > + port->type =3D FM10K_CONFIG_DPDK_VF; > + if (master) > + sw->dpdk_cfg->master_hw =3D hw; > + if (sw->dpdk_cfg->master_hw) { > + port->pf_no =3D 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] =3D port- > >hw; > + } > + > + return 0; > + } > + } > + return -1; > +} > + > +int > +fm10k_switch_dpdk_port_no_get(struct fm10k_hw *hw) > +{ > + int i; > + > + for (i =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + if (fm10k_sw.dpdk_cfg->ports[i].hw =3D=3D NULL) > + break; > + > + if (fm10k_sw.dpdk_cfg->ports[i].hw =3D=3D hw) > + return i; > + } > + return -1; > +} > + > + > +static int > +fm10k_switch_dpdk_cfg_check(struct fm10k_switch *sw) > +{ > + int i; > + bool need_default =3D true; > + struct fm10k_dpdk_port* port; > + > + if (sw->dpdk_cfg->master_hw =3D=3D NULL) { > + FM10K_SW_ERR("Master PF is not bound!!!"); > + return -1; > + } > + > + for (i =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + port =3D &sw->dpdk_cfg->ports[i]; > + if (port->type =3D=3D FM10K_CONFIG_DPDK_PF && > + sw->dpdk_cfg->dpdk_port_map[i].type !=3D > FM10K_CONFIG_PORT_MAP_NULL) { > + need_default =3D false; > + break; > + } > + } > + > + if (need_default) { > + for (i =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + if (port->type =3D=3D FM10K_CONFIG_DPDK_PF) { > + sw->dpdk_cfg->dpdk_port_map[i].type =3D > FM10K_CONFIG_PORT_MAP_PF; > + sw->dpdk_cfg->dpdk_port_map[i].map_no[0] =3D > 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 =3D 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] =3D=3D NULL) > + continue; > + > + dev =3D (struct rte_eth_dev*)(sw->dpdk_cfg->pf_hw[i]->rte_dev); > + pdev =3D RTE_ETH_DEV_TO_PCI(dev); > + mac =3D 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 =3D 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) { > + if (sw->dpdk_cfg->ports[i].type =3D=3D FM10K_CONFIG_DPDK_NULL) > + break; > + if (sw->dpdk_cfg->dpdk_port_map[i].type =3D=3D > FM10K_CONFIG_PORT_MAP_NULL) > + break; > + if (sw->dpdk_cfg->dpdk_port_map[i].type =3D=3D > 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 =3D 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 =3D=3D > FM10K_CONFIG_PORT_MAP_NULL) > + printf("\n"); > + else if (sw->dpdk_cfg->ext_port_map[i].type =3D=3D > 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 =3D fm10k_switch_get(); > + > + if (fm10k_switch_dpdk_port_reg(sw, hw, is_pf, master) !=3D 0) { > + FM10K_SW_ERR("Register ports failed!!!"); > + return -1; > + } > + > + /* > + * After all pfs are started > + * start switch here > + */ > + if (fm10k_sw.dpdk_cfg->pf_max !=3D 0 && > + fm10k_sw.dpdk_cfg->pf_bind =3D=3D fm10k_sw.dpdk_cfg- > >pf_num) { > + if (fm10k_switch_dpdk_cfg_check(&fm10k_sw) !=3D 0) > + return -1; > + > + ret =3D 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 qu= eue 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 =3D fm10k_switch_dpdk_port_no_get(hw); > + struct fm10k_dpdk_port *port; > + struct fm10k_switch *sw =3D fm10k_switch_get(); > + > + if (dpdk_port_no < 0) { > + FM10K_SW_ERR("Can not find the dpdk port!!!"); > + return -1; > + } > + > + port =3D &sw->dpdk_cfg->ports[dpdk_port_no]; > + > + if (port->type =3D=3D FM10K_CONFIG_DPDK_VF) { > + FM10K_SW_ERR("Not support yet!!!"); > + return -1; > + } > + > + if (port->type !=3D FM10K_CONFIG_DPDK_PF) { > + FM10K_SW_ERR("Can not be here!!!"); > + return -1; > + } > + > + if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type =3D=3D > + FM10K_CONFIG_PORT_MAP_PF) { > + pf_no =3D sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].map_no[0]; > + *map_hw =3D sw->dpdk_cfg->pf_hw[pf_no]; > + *map_queue =3D queue; > + return 1; > + } else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type =3D=3D > + FM10K_CONFIG_PORT_MAP_PFS) { > + idx =3D queue%2; > + pf_no =3D sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].map_no[idx]; > + *map_hw =3D sw->dpdk_cfg->pf_hw[pf_no]; > + *map_queue =3D queue/2; > + return 1; > + } else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type =3D=3D > + FM10K_CONFIG_PORT_MAP_PFSS) { > + idx =3D queue%2; > + pf_no =3D sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].map_no[idx]; > + *map_hw =3D sw->dpdk_cfg->pf_hw[pf_no]; > + *map_queue =3D (max_queue+1)/2 + queue/2; > + return 0; > + } else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type =3D=3D > + 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 =3D fm10k_switch_dpdk_port_no_get(hw); > + struct fm10k_dpdk_port *port; > + struct fm10k_switch *sw =3D fm10k_switch_get(); > + > + if (dpdk_port_no < 0) { > + FM10K_SW_ERR("Can not find the dpdk port!!!"); > + return -1; > + } > + > + port =3D &sw->dpdk_cfg->ports[dpdk_port_no]; > + > + if (port->type =3D=3D FM10K_CONFIG_DPDK_VF) { > + hw_list[0] =3D hw; > + hw_list[1] =3D NULL; > + return 1; > + } > + > + if (port->type !=3D 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 =3D=3D > + FM10K_CONFIG_PORT_MAP_PF) { > + pf_no =3D sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].map_no[0]; > + hw_list[0] =3D sw->dpdk_cfg->pf_hw[pf_no]; > + hw_list[1] =3D NULL; > + return 1; > + } else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type =3D=3D > + > FM10K_CONFIG_PORT_MAP_PFS) { > + pf_no =3D sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].map_no[0]; > + hw_list[0] =3D sw->dpdk_cfg->pf_hw[pf_no]; > + pf_no_ext =3D sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].map_no[1]; > + hw_list[1] =3D sw->dpdk_cfg->pf_hw[pf_no_ext]; > + return 2; > + } else if (sw->dpdk_cfg->dpdk_port_map[dpdk_port_no].type =3D=3D > + > FM10K_CONFIG_PORT_MAP_PFSS) { > + pf_no =3D sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].map_no[0]; > + hw_list[0] =3D sw->dpdk_cfg->pf_hw[pf_no]; > + pf_no_ext =3D sw->dpdk_cfg- > >dpdk_port_map[dpdk_port_no].map_no[1]; > + hw_list[1] =3D sw->dpdk_cfg->pf_hw[pf_no_ext]; > + return 0; > + } > + > + hw_list[0] =3D NULL; > + hw_list[1] =3D NULL; > + return 0; > +} > + > +void > +fm10k_switch_dpdk_tx_queue_num_set(struct fm10k_hw *hw, uint8_t num) > +{ > + int port_no =3D fm10k_switch_dpdk_port_no_get(hw); > + struct fm10k_switch *sw =3D 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 =3D num; > +} > + > +void > +fm10k_switch_dpdk_rx_queue_num_set(struct fm10k_hw *hw, uint8_t num) > +{ > + int port_no =3D fm10k_switch_dpdk_port_no_get(hw); > + struct fm10k_switch *sw =3D 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 =3D num; > +} > + > +int > +fm10k_switch_dpdk_pf_no_get(struct fm10k_hw *hw) > +{ > + int port_no =3D fm10k_switch_dpdk_port_no_get(hw); > + struct fm10k_switch *sw =3D 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 =3D fm10k_switch_get(); > + > + fm10k_ffu_flowset_switch(sw, name); > +} > + > +void > +fm10k_switch_show_port(void) > +{ > + struct fm10k_switch *sw =3D 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 =3D fm10k_switch_get(); > + > + fm10k_stats_ffu_count_print(sw); > +} > + > +void > +fm10k_switch_show_bank(void) > +{ > + struct fm10k_switch *sw =3D 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 > +#include > +#include > +#include > + > +#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 =3D ((volatile uint32_t *)sw->master_hw->sw_addr)[reg]; > + temp =3D ((volatile uint32_t *)sw->master_hw->sw_addr)[reg + 1]; > + result |=3D 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 =3D 0; i < count; i++) > + results[i] =3D ((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 v= al) > +{ > + ((volatile uint32_t *)sw->master_hw->sw_addr)[reg] =3D 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] =3D val & 0xffffffff= ; > + ((volatile uint32_t *)sw->master_hw->sw_addr)[reg + 1] =3D 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] =3D val_lo & 0xfffff= fff; > + ((volatile uint32_t *)sw->master_hw->sw_addr)[reg + 1] =3D val_lo >> 32= ; > + > + ((volatile uint32_t *)sw->master_hw->sw_addr)[reg + 2] =3D val_hi & > 0xffffffff; > + ((volatile uint32_t *)sw->master_hw->sw_addr)[reg + 3] =3D 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 =3D 0; i < count; i++) > + ((volatile uint32_t *)sw->master_hw->sw_addr)[reg + i] =3D > 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 =3D fm10k_read_switch_reg(sw, FM10K_SW_GPIO_CFG); > + data |=3D 1< + data &=3D ~(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 =3D 4 ns and > + * and reset time =3D 100 ns) > + */ > + usec_delay(1000); > + /* set reset */ > + data =3D fm10k_read_switch_reg(sw, FM10K_SW_GPIO_DATA); > + if (value =3D=3D 0) > + data &=3D ~(1< + else > + data |=3D 1< + > + 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