get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/17138/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 17138,
    "url": "https://patches.dpdk.org/api/patches/17138/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1479740470-6723-10-git-send-email-arybchenko@solarflare.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1479740470-6723-10-git-send-email-arybchenko@solarflare.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1479740470-6723-10-git-send-email-arybchenko@solarflare.com",
    "date": "2016-11-21T15:00:23",
    "name": "[dpdk-dev,09/56] net/sfc: import libefx 5xxx/6xxx family support",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "7b6de61204d4d6b8293f3a04257a1fd740dc4c88",
    "submitter": {
        "id": 607,
        "url": "https://patches.dpdk.org/api/people/607/?format=api",
        "name": "Andrew Rybchenko",
        "email": "arybchenko@solarflare.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1479740470-6723-10-git-send-email-arybchenko@solarflare.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/17138/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/17138/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id A73C2D5A4;\n\tMon, 21 Nov 2016 16:03:26 +0100 (CET)",
            "from nbfkord-smmo02.seg.att.com (nbfkord-smmo02.seg.att.com\n\t[209.65.160.78]) by dpdk.org (Postfix) with ESMTP id 36F913977\n\tfor <dev@dpdk.org>; Mon, 21 Nov 2016 16:01:38 +0100 (CET)",
            "from unknown [12.187.104.26]\n\tby nbfkord-smmo02.seg.att.com(mxl_mta-7.2.4-7) with SMTP id\n\t15c03385.0.1541296.00-2367.3424230.nbfkord-smmo02.seg.att.com\n\t(envelope-from <arybchenko@solarflare.com>); \n\tMon, 21 Nov 2016 15:01:39 +0000 (UTC)",
            "from ocex03.SolarFlarecom.com (10.20.40.36) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id 15.0.1044.25; Mon, 21 Nov 2016 07:01:21 -0800",
            "from opal.uk.solarflarecom.com (10.17.10.1) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id\n\t15.0.1044.25 via Frontend Transport; Mon, 21 Nov 2016 07:01:21 -0800",
            "from uklogin.uk.solarflarecom.com (uklogin.uk.solarflarecom.com\n\t[10.17.10.10])\n\tby opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tuALF1Jti007125 for <dev@dpdk.org>; Mon, 21 Nov 2016 15:01:19 GMT",
            "from uklogin.uk.solarflarecom.com (localhost.localdomain\n\t[127.0.0.1])\n\tby uklogin.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tuALF1J30006765 for <dev@dpdk.org>; Mon, 21 Nov 2016 15:01:19 GMT"
        ],
        "X-MXL-Hash": "58330c537a22c9de-9044730e1737d324150cffc84d5ddffafa344330",
        "From": "Andrew Rybchenko <arybchenko@solarflare.com>",
        "To": "<dev@dpdk.org>",
        "Date": "Mon, 21 Nov 2016 15:00:23 +0000",
        "Message-ID": "<1479740470-6723-10-git-send-email-arybchenko@solarflare.com>",
        "X-Mailer": "git-send-email 1.8.2.3",
        "In-Reply-To": "<1479740470-6723-1-git-send-email-arybchenko@solarflare.com>",
        "References": "<1479740470-6723-1-git-send-email-arybchenko@solarflare.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-AnalysisOut": [
            "[v=2.1 cv=UI/baXry c=1 sm=1 tr=0 a=8BlWFWvVlq5taO8ncb8nKg==]",
            "[:17 a=L24OOQBejmoA:10 a=zRKbQ67AAAAA:8 a=0q0Olq3wAAAA:8 a=]",
            "[EBjG9A0JTL5qvJkvltYA:9 a=HBDMb62-Q6ZVLU9J:21 a=pMBGhp1AkdK]",
            "[9hLsB:21 a=udddAaYaByK6o6IJ:21 a=PA03WX8tBzeizutn5_OT:22 a]",
            "[=V4nVvlXdoJ47tVQdIAqM:22]"
        ],
        "X-Spam": "[F=0.2000000000; CM=0.500; S=0.200(2015072901)]",
        "X-MAIL-FROM": "<arybchenko@solarflare.com>",
        "X-SOURCE-IP": "[12.187.104.26]",
        "Subject": "[dpdk-dev] [PATCH 09/56] net/sfc: import libefx 5xxx/6xxx family\n\tsupport",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "EFSYS_OPT_SIENA should be enabled to use it.\n\nFrom Solarflare Communications Inc.\n\nSigned-off-by: Andrew Rybchenko <arybchenko@solarflare.com>\n---\n drivers/net/sfc/efx/base/efx_check.h   |   14 +\n drivers/net/sfc/efx/base/efx_ev.c      |  783 ++++++++++++++++++++++++\n drivers/net/sfc/efx/base/efx_filter.c  | 1042 ++++++++++++++++++++++++++++++++\n drivers/net/sfc/efx/base/efx_impl.h    |   70 +++\n drivers/net/sfc/efx/base/efx_intr.c    |  345 +++++++++++\n drivers/net/sfc/efx/base/efx_mac.c     |   97 +++\n drivers/net/sfc/efx/base/efx_mcdi.c    |   22 +\n drivers/net/sfc/efx/base/efx_nic.c     |   44 ++\n drivers/net/sfc/efx/base/efx_phy.c     |   15 +\n drivers/net/sfc/efx/base/efx_rx.c      |  417 +++++++++++++\n drivers/net/sfc/efx/base/efx_tx.c      |  488 +++++++++++++++\n drivers/net/sfc/efx/base/siena_flash.h |  215 +++++++\n drivers/net/sfc/efx/base/siena_impl.h  |  179 ++++++\n drivers/net/sfc/efx/base/siena_mac.c   |  205 +++++++\n drivers/net/sfc/efx/base/siena_mcdi.c  |  263 ++++++++\n drivers/net/sfc/efx/base/siena_nic.c   |  357 +++++++++++\n drivers/net/sfc/efx/base/siena_phy.c   |  375 ++++++++++++\n drivers/net/sfc/efx/base/siena_sram.c  |   74 +++\n 18 files changed, 5005 insertions(+)\n create mode 100644 drivers/net/sfc/efx/base/siena_flash.h\n create mode 100644 drivers/net/sfc/efx/base/siena_impl.h\n create mode 100644 drivers/net/sfc/efx/base/siena_mac.c\n create mode 100644 drivers/net/sfc/efx/base/siena_mcdi.c\n create mode 100644 drivers/net/sfc/efx/base/siena_nic.c\n create mode 100644 drivers/net/sfc/efx/base/siena_phy.c\n create mode 100644 drivers/net/sfc/efx/base/siena_sram.c",
    "diff": "diff --git a/drivers/net/sfc/efx/base/efx_check.h b/drivers/net/sfc/efx/base/efx_check.h\nindex 470f73c..190ac46 100644\n--- a/drivers/net/sfc/efx/base/efx_check.h\n+++ b/drivers/net/sfc/efx/base/efx_check.h\n@@ -47,12 +47,16 @@\n \n #if EFSYS_OPT_CHECK_REG\n /* Verify chip implements accessed registers */\n+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)\n #  error \"CHECK_REG requires SIENA or HUNTINGTON or MEDFORD\"\n+# endif\n #endif /* EFSYS_OPT_CHECK_REG */\n \n #if EFSYS_OPT_DECODE_INTR_FATAL\n /* Decode fatal errors */\n+# if !EFSYS_OPT_SIENA\n #  error \"INTR_FATAL requires SIENA\"\n+# endif\n #endif /* EFSYS_OPT_DECODE_INTR_FATAL */\n \n #ifdef EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE\n@@ -61,7 +65,9 @@\n \n #if EFSYS_OPT_FILTER\n /* Support hardware packet filters */\n+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)\n #  error \"FILTER requires SIENA or HUNTINGTON or MEDFORD\"\n+# endif\n #endif /* EFSYS_OPT_FILTER */\n \n #ifdef EFSYS_OPT_MAC_FALCON_GMAC\n@@ -74,9 +80,17 @@\n \n #if EFSYS_OPT_MCDI\n /* Support management controller messages */\n+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)\n #  error \"MCDI requires SIENA or HUNTINGTON or MEDFORD\"\n+# endif\n #endif /* EFSYS_OPT_MCDI */\n \n+#if (EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)\n+# if !EFSYS_OPT_MCDI\n+#  error \"SIENA or HUNTINGTON or MEDFORD requires MCDI\"\n+# endif\n+#endif\n+\n #if EFSYS_OPT_MCDI_LOGGING\n /* Support MCDI logging */\n # if !EFSYS_OPT_MCDI\ndiff --git a/drivers/net/sfc/efx/base/efx_ev.c b/drivers/net/sfc/efx/base/efx_ev.c\nindex 942dac6..59f4d02 100644\n--- a/drivers/net/sfc/efx/base/efx_ev.c\n+++ b/drivers/net/sfc/efx/base/efx_ev.c\n@@ -39,6 +39,61 @@\n \n \n \n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_ev_init(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t\t\tvoid\n+siena_ev_fini(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_ev_qcreate(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tunsigned int index,\n+\t__in\t\tefsys_mem_t *esmp,\n+\t__in\t\tsize_t n,\n+\t__in\t\tuint32_t id,\n+\t__in\t\tuint32_t us,\n+\t__in\t\tuint32_t flags,\n+\t__in\t\tefx_evq_t *eep);\n+\n+static\t\t\tvoid\n+siena_ev_qdestroy(\n+\t__in\t\tefx_evq_t *eep);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_ev_qprime(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tunsigned int count);\n+\n+static\t\t\tvoid\n+siena_ev_qpost(\n+\t__in\tefx_evq_t *eep,\n+\t__in\tuint16_t data);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_ev_qmoderate(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tunsigned int us);\n+\n+#endif /* EFSYS_OPT_SIENA */\n+\n+#if EFSYS_OPT_SIENA\n+static const efx_ev_ops_t\t__efx_ev_siena_ops = {\n+\tsiena_ev_init,\t\t\t\t/* eevo_init */\n+\tsiena_ev_fini,\t\t\t\t/* eevo_fini */\n+\tsiena_ev_qcreate,\t\t\t/* eevo_qcreate */\n+\tsiena_ev_qdestroy,\t\t\t/* eevo_qdestroy */\n+\tsiena_ev_qprime,\t\t\t/* eevo_qprime */\n+\tsiena_ev_qpost,\t\t\t\t/* eevo_qpost */\n+\tsiena_ev_qmoderate,\t\t\t/* eevo_qmoderate */\n+};\n+#endif /* EFSYS_OPT_SIENA */\n+\n+\n \t__checkReturn\tefx_rc_t\n efx_ev_init(\n \t__in\t\tefx_nic_t *enp)\n@@ -55,6 +110,11 @@ efx_ev_init(\n \t}\n \n \tswitch (enp->en_family) {\n+#if EFSYS_OPT_SIENA\n+\tcase EFX_FAMILY_SIENA:\n+\t\teevop = &__efx_ev_siena_ops;\n+\t\tbreak;\n+#endif /* EFSYS_OPT_SIENA */\n \n \tdefault:\n \t\tEFSYS_ASSERT(0);\n@@ -440,3 +500,726 @@ efx_ev_qmoderate(\n \treturn (rc);\n }\n \n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_ev_init(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_oword_t oword;\n+\n+\t/*\n+\t * Program the event queue for receive and transmit queue\n+\t * flush events.\n+\t */\n+\tEFX_BAR_READO(enp, FR_AZ_DP_CTRL_REG, &oword);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_FLS_EVQ_ID, 0);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_DP_CTRL_REG, &oword);\n+\n+\treturn (0);\n+\n+}\n+\n+static  __checkReturn   boolean_t\n+siena_ev_rx_not_ok(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_qword_t *eqp,\n+\t__in\t\tuint32_t label,\n+\t__in\t\tuint32_t id,\n+\t__inout\t\tuint16_t *flagsp)\n+{\n+\tboolean_t ignore = B_FALSE;\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_TOBE_DISC) != 0) {\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_TOBE_DISC);\n+\t\tEFSYS_PROBE(tobe_disc);\n+\t\t/*\n+\t\t * Assume this is a unicast address mismatch, unless below\n+\t\t * we find either FSF_AZ_RX_EV_ETH_CRC_ERR or\n+\t\t * EV_RX_PAUSE_FRM_ERR is set.\n+\t\t */\n+\t\t(*flagsp) |= EFX_ADDR_MISMATCH;\n+\t}\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_FRM_TRUNC) != 0) {\n+\t\tEFSYS_PROBE2(frm_trunc, uint32_t, label, uint32_t, id);\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);\n+\t\t(*flagsp) |= EFX_DISCARD;\n+\n+\t}\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_ETH_CRC_ERR) != 0) {\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR);\n+\t\tEFSYS_PROBE(crc_err);\n+\t\t(*flagsp) &= ~EFX_ADDR_MISMATCH;\n+\t\t(*flagsp) |= EFX_DISCARD;\n+\t}\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PAUSE_FRM_ERR) != 0) {\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_PAUSE_FRM_ERR);\n+\t\tEFSYS_PROBE(pause_frm_err);\n+\t\t(*flagsp) &= ~EFX_ADDR_MISMATCH;\n+\t\t(*flagsp) |= EFX_DISCARD;\n+\t}\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BUF_OWNER_ID_ERR) != 0) {\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_BUF_OWNER_ID_ERR);\n+\t\tEFSYS_PROBE(owner_id_err);\n+\t\t(*flagsp) |= EFX_DISCARD;\n+\t}\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR) != 0) {\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR);\n+\t\tEFSYS_PROBE(ipv4_err);\n+\t\t(*flagsp) &= ~EFX_CKSUM_IPV4;\n+\t}\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR) != 0) {\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR);\n+\t\tEFSYS_PROBE(udp_chk_err);\n+\t\t(*flagsp) &= ~EFX_CKSUM_TCPUDP;\n+\t}\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_IP_FRAG_ERR) != 0) {\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_IP_FRAG_ERR);\n+\n+\t\t/*\n+\t\t * If IP is fragmented FSF_AZ_RX_EV_IP_FRAG_ERR is set. This\n+\t\t * causes FSF_AZ_RX_EV_PKT_OK to be clear. This is not an error\n+\t\t * condition.\n+\t\t */\n+\t\t(*flagsp) &= ~(EFX_PKT_TCP | EFX_PKT_UDP | EFX_CKSUM_TCPUDP);\n+\t}\n+\n+\treturn (ignore);\n+}\n+\n+static\t__checkReturn\tboolean_t\n+siena_ev_rx(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_qword_t *eqp,\n+\t__in\t\tconst efx_ev_callbacks_t *eecp,\n+\t__in_opt\tvoid *arg)\n+{\n+\tuint32_t id;\n+\tuint32_t size;\n+\tuint32_t label;\n+\tboolean_t ok;\n+\tuint32_t hdr_type;\n+\tboolean_t is_v6;\n+\tuint16_t flags;\n+\tboolean_t ignore;\n+\tboolean_t should_abort;\n+\n+\tEFX_EV_QSTAT_INCR(eep, EV_RX);\n+\n+\t/* Basic packet information */\n+\tid = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_DESC_PTR);\n+\tsize = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BYTE_CNT);\n+\tlabel = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_Q_LABEL);\n+\tok = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PKT_OK) != 0);\n+\n+\thdr_type = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_HDR_TYPE);\n+\n+\tis_v6 = (EFX_QWORD_FIELD(*eqp, FSF_CZ_RX_EV_IPV6_PKT) != 0);\n+\n+\t/*\n+\t * If packet is marked as OK and packet type is TCP/IP or\n+\t * UDP/IP or other IP, then we can rely on the hardware checksums.\n+\t */\n+\tswitch (hdr_type) {\n+\tcase FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_TCP:\n+\t\tflags = EFX_PKT_TCP | EFX_CKSUM_TCPUDP;\n+\t\tif (is_v6) {\n+\t\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV6);\n+\t\t\tflags |= EFX_PKT_IPV6;\n+\t\t} else {\n+\t\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV4);\n+\t\t\tflags |= EFX_PKT_IPV4 | EFX_CKSUM_IPV4;\n+\t\t}\n+\t\tbreak;\n+\n+\tcase FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_UDP:\n+\t\tflags = EFX_PKT_UDP | EFX_CKSUM_TCPUDP;\n+\t\tif (is_v6) {\n+\t\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV6);\n+\t\t\tflags |= EFX_PKT_IPV6;\n+\t\t} else {\n+\t\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV4);\n+\t\t\tflags |= EFX_PKT_IPV4 | EFX_CKSUM_IPV4;\n+\t\t}\n+\t\tbreak;\n+\n+\tcase FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_OTHER:\n+\t\tif (is_v6) {\n+\t\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV6);\n+\t\t\tflags = EFX_PKT_IPV6;\n+\t\t} else {\n+\t\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV4);\n+\t\t\tflags = EFX_PKT_IPV4 | EFX_CKSUM_IPV4;\n+\t\t}\n+\t\tbreak;\n+\n+\tcase FSE_AZ_RX_EV_HDR_TYPE_OTHER:\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_NON_IP);\n+\t\tflags = 0;\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tEFSYS_ASSERT(B_FALSE);\n+\t\tflags = 0;\n+\t\tbreak;\n+\t}\n+\n+\t/* Detect errors included in the FSF_AZ_RX_EV_PKT_OK indication */\n+\tif (!ok) {\n+\t\tignore = siena_ev_rx_not_ok(eep, eqp, label, id, &flags);\n+\t\tif (ignore) {\n+\t\t\tEFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id,\n+\t\t\t    uint32_t, size, uint16_t, flags);\n+\n+\t\t\treturn (B_FALSE);\n+\t\t}\n+\t}\n+\n+\t/* If we're not discarding the packet then it is ok */\n+\tif (~flags & EFX_DISCARD)\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_OK);\n+\n+\t/* Detect multicast packets that didn't match the filter */\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_MCAST_PKT) != 0) {\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_MCAST_PKT);\n+\n+\t\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_MCAST_HASH_MATCH) != 0) {\n+\t\t\tEFX_EV_QSTAT_INCR(eep, EV_RX_MCAST_HASH_MATCH);\n+\t\t} else {\n+\t\t\tEFSYS_PROBE(mcast_mismatch);\n+\t\t\tflags |= EFX_ADDR_MISMATCH;\n+\t\t}\n+\t} else {\n+\t\tflags |= EFX_PKT_UNICAST;\n+\t}\n+\n+\t/*\n+\t * The packet parser in Siena can abort parsing packets under\n+\t * certain error conditions, setting the PKT_NOT_PARSED bit\n+\t * (which clears PKT_OK). If this is set, then don't trust\n+\t * the PKT_TYPE field.\n+\t */\n+\tif (!ok) {\n+\t\tuint32_t parse_err;\n+\n+\t\tparse_err = EFX_QWORD_FIELD(*eqp, FSF_CZ_RX_EV_PKT_NOT_PARSED);\n+\t\tif (parse_err != 0)\n+\t\t\tflags |= EFX_CHECK_VLAN;\n+\t}\n+\n+\tif (~flags & EFX_CHECK_VLAN) {\n+\t\tuint32_t pkt_type;\n+\n+\t\tpkt_type = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PKT_TYPE);\n+\t\tif (pkt_type >= FSE_AZ_RX_EV_PKT_TYPE_VLAN)\n+\t\t\tflags |= EFX_PKT_VLAN_TAGGED;\n+\t}\n+\n+\tEFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id,\n+\t    uint32_t, size, uint16_t, flags);\n+\n+\tEFSYS_ASSERT(eecp->eec_rx != NULL);\n+\tshould_abort = eecp->eec_rx(arg, label, id, size, flags);\n+\n+\treturn (should_abort);\n+}\n+\n+static\t__checkReturn\tboolean_t\n+siena_ev_tx(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_qword_t *eqp,\n+\t__in\t\tconst efx_ev_callbacks_t *eecp,\n+\t__in_opt\tvoid *arg)\n+{\n+\tuint32_t id;\n+\tuint32_t label;\n+\tboolean_t should_abort;\n+\n+\tEFX_EV_QSTAT_INCR(eep, EV_TX);\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_COMP) != 0 &&\n+\t    EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_ERR) == 0 &&\n+\t    EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_TOO_BIG) == 0 &&\n+\t    EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_WQ_FF_FULL) == 0) {\n+\n+\t\tid = EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_DESC_PTR);\n+\t\tlabel = EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_Q_LABEL);\n+\n+\t\tEFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id);\n+\n+\t\tEFSYS_ASSERT(eecp->eec_tx != NULL);\n+\t\tshould_abort = eecp->eec_tx(arg, label, id);\n+\n+\t\treturn (should_abort);\n+\t}\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_COMP) != 0)\n+\t\tEFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,\n+\t\t\t    uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),\n+\t\t\t    uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_ERR) != 0)\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_TX_PKT_ERR);\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_TOO_BIG) != 0)\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_TX_PKT_TOO_BIG);\n+\n+\tif (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_WQ_FF_FULL) != 0)\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_TX_WQ_FF_FULL);\n+\n+\tEFX_EV_QSTAT_INCR(eep, EV_TX_UNEXPECTED);\n+\treturn (B_FALSE);\n+}\n+\n+static\t__checkReturn\tboolean_t\n+siena_ev_global(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_qword_t *eqp,\n+\t__in\t\tconst efx_ev_callbacks_t *eecp,\n+\t__in_opt\tvoid *arg)\n+{\n+\t_NOTE(ARGUNUSED(eqp, eecp, arg))\n+\n+\tEFX_EV_QSTAT_INCR(eep, EV_GLOBAL);\n+\n+\treturn (B_FALSE);\n+}\n+\n+static\t__checkReturn\tboolean_t\n+siena_ev_driver(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_qword_t *eqp,\n+\t__in\t\tconst efx_ev_callbacks_t *eecp,\n+\t__in_opt\tvoid *arg)\n+{\n+\tboolean_t should_abort;\n+\n+\tEFX_EV_QSTAT_INCR(eep, EV_DRIVER);\n+\tshould_abort = B_FALSE;\n+\n+\tswitch (EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBCODE)) {\n+\tcase FSE_AZ_TX_DESCQ_FLS_DONE_EV: {\n+\t\tuint32_t txq_index;\n+\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);\n+\n+\t\ttxq_index = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);\n+\n+\t\tEFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);\n+\n+\t\tEFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);\n+\t\tshould_abort = eecp->eec_txq_flush_done(arg, txq_index);\n+\n+\t\tbreak;\n+\t}\n+\tcase FSE_AZ_RX_DESCQ_FLS_DONE_EV: {\n+\t\tuint32_t rxq_index;\n+\t\tuint32_t failed;\n+\n+\t\trxq_index = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_DESCQ_ID);\n+\t\tfailed = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);\n+\n+\t\tEFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);\n+\t\tEFSYS_ASSERT(eecp->eec_rxq_flush_failed != NULL);\n+\n+\t\tif (failed) {\n+\t\t\tEFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_FAILED);\n+\n+\t\t\tEFSYS_PROBE1(rx_descq_fls_failed, uint32_t, rxq_index);\n+\n+\t\t\tshould_abort = eecp->eec_rxq_flush_failed(arg,\n+\t\t\t\t\t\t\t\t    rxq_index);\n+\t\t} else {\n+\t\t\tEFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);\n+\n+\t\t\tEFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);\n+\n+\t\t\tshould_abort = eecp->eec_rxq_flush_done(arg, rxq_index);\n+\t\t}\n+\n+\t\tbreak;\n+\t}\n+\tcase FSE_AZ_EVQ_INIT_DONE_EV:\n+\t\tEFSYS_ASSERT(eecp->eec_initialized != NULL);\n+\t\tshould_abort = eecp->eec_initialized(arg);\n+\n+\t\tbreak;\n+\n+\tcase FSE_AZ_EVQ_NOT_EN_EV:\n+\t\tEFSYS_PROBE(evq_not_en);\n+\t\tbreak;\n+\n+\tcase FSE_AZ_SRM_UPD_DONE_EV: {\n+\t\tuint32_t code;\n+\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_DRIVER_SRM_UPD_DONE);\n+\n+\t\tcode = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);\n+\n+\t\tEFSYS_ASSERT(eecp->eec_sram != NULL);\n+\t\tshould_abort = eecp->eec_sram(arg, code);\n+\n+\t\tbreak;\n+\t}\n+\tcase FSE_AZ_WAKE_UP_EV: {\n+\t\tuint32_t id;\n+\n+\t\tid = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);\n+\n+\t\tEFSYS_ASSERT(eecp->eec_wake_up != NULL);\n+\t\tshould_abort = eecp->eec_wake_up(arg, id);\n+\n+\t\tbreak;\n+\t}\n+\tcase FSE_AZ_TX_PKT_NON_TCP_UDP:\n+\t\tEFSYS_PROBE(tx_pkt_non_tcp_udp);\n+\t\tbreak;\n+\n+\tcase FSE_AZ_TIMER_EV: {\n+\t\tuint32_t id;\n+\n+\t\tid = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);\n+\n+\t\tEFSYS_ASSERT(eecp->eec_timer != NULL);\n+\t\tshould_abort = eecp->eec_timer(arg, id);\n+\n+\t\tbreak;\n+\t}\n+\tcase FSE_AZ_RX_DSC_ERROR_EV:\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DSC_ERROR);\n+\n+\t\tEFSYS_PROBE(rx_dsc_error);\n+\n+\t\tEFSYS_ASSERT(eecp->eec_exception != NULL);\n+\t\tshould_abort = eecp->eec_exception(arg,\n+\t\t\tEFX_EXCEPTION_RX_DSC_ERROR, 0);\n+\n+\t\tbreak;\n+\n+\tcase FSE_AZ_TX_DSC_ERROR_EV:\n+\t\tEFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DSC_ERROR);\n+\n+\t\tEFSYS_PROBE(tx_dsc_error);\n+\n+\t\tEFSYS_ASSERT(eecp->eec_exception != NULL);\n+\t\tshould_abort = eecp->eec_exception(arg,\n+\t\t\tEFX_EXCEPTION_TX_DSC_ERROR, 0);\n+\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn (should_abort);\n+}\n+\n+static\t__checkReturn\tboolean_t\n+siena_ev_drv_gen(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_qword_t *eqp,\n+\t__in\t\tconst efx_ev_callbacks_t *eecp,\n+\t__in_opt\tvoid *arg)\n+{\n+\tuint32_t data;\n+\tboolean_t should_abort;\n+\n+\tEFX_EV_QSTAT_INCR(eep, EV_DRV_GEN);\n+\n+\tdata = EFX_QWORD_FIELD(*eqp, FSF_AZ_EV_DATA_DW0);\n+\tif (data >= ((uint32_t)1 << 16)) {\n+\t\tEFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,\n+\t\t\t    uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),\n+\t\t\t    uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));\n+\t\treturn (B_TRUE);\n+\t}\n+\n+\tEFSYS_ASSERT(eecp->eec_software != NULL);\n+\tshould_abort = eecp->eec_software(arg, (uint16_t)data);\n+\n+\treturn (should_abort);\n+}\n+\n+#if EFSYS_OPT_MCDI\n+\n+static\t__checkReturn\tboolean_t\n+siena_ev_mcdi(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_qword_t *eqp,\n+\t__in\t\tconst efx_ev_callbacks_t *eecp,\n+\t__in_opt\tvoid *arg)\n+{\n+\tefx_nic_t *enp = eep->ee_enp;\n+\tunsigned int code;\n+\tboolean_t should_abort = B_FALSE;\n+\n+\tEFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);\n+\n+\tif (enp->en_family != EFX_FAMILY_SIENA)\n+\t\tgoto out;\n+\n+\tEFSYS_ASSERT(eecp->eec_link_change != NULL);\n+\tEFSYS_ASSERT(eecp->eec_exception != NULL);\n+\n+\tEFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);\n+\n+\tcode = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE);\n+\tswitch (code) {\n+\tcase MCDI_EVENT_CODE_BADSSERT:\n+\t\tefx_mcdi_ev_death(enp, EINTR);\n+\t\tbreak;\n+\n+\tcase MCDI_EVENT_CODE_CMDDONE:\n+\t\tefx_mcdi_ev_cpl(enp,\n+\t\t    MCDI_EV_FIELD(eqp, CMDDONE_SEQ),\n+\t\t    MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),\n+\t\t    MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));\n+\t\tbreak;\n+\n+\tcase MCDI_EVENT_CODE_LINKCHANGE: {\n+\t\tefx_link_mode_t link_mode;\n+\n+\t\tsiena_phy_link_ev(enp, eqp, &link_mode);\n+\t\tshould_abort = eecp->eec_link_change(arg, link_mode);\n+\t\tbreak;\n+\t}\n+\tcase MCDI_EVENT_CODE_SENSOREVT: {\n+\t\tshould_abort = B_FALSE;\n+\t\tbreak;\n+\t}\n+\tcase MCDI_EVENT_CODE_SCHEDERR:\n+\t\t/* Informational only */\n+\t\tbreak;\n+\n+\tcase MCDI_EVENT_CODE_REBOOT:\n+\t\tefx_mcdi_ev_death(enp, EIO);\n+\t\tbreak;\n+\n+\tcase MCDI_EVENT_CODE_MAC_STATS_DMA:\n+\t\tbreak;\n+\n+\tcase MCDI_EVENT_CODE_FWALERT: {\n+\t\tuint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON);\n+\n+\t\tif (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS)\n+\t\t\tshould_abort = eecp->eec_exception(arg,\n+\t\t\t\tEFX_EXCEPTION_FWALERT_SRAM,\n+\t\t\t\tMCDI_EV_FIELD(eqp, FWALERT_DATA));\n+\t\telse\n+\t\t\tshould_abort = eecp->eec_exception(arg,\n+\t\t\t\tEFX_EXCEPTION_UNKNOWN_FWALERT,\n+\t\t\t\tMCDI_EV_FIELD(eqp, DATA));\n+\t\tbreak;\n+\t}\n+\n+\tdefault:\n+\t\tEFSYS_PROBE1(mc_pcol_error, int, code);\n+\t\tbreak;\n+\t}\n+\n+out:\n+\treturn (should_abort);\n+}\n+\n+#endif\t/* EFSYS_OPT_MCDI */\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_ev_qprime(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tunsigned int count)\n+{\n+\tefx_nic_t *enp = eep->ee_enp;\n+\tuint32_t rptr;\n+\tefx_dword_t dword;\n+\n+\trptr = count & eep->ee_mask;\n+\n+\tEFX_POPULATE_DWORD_1(dword, FRF_AZ_EVQ_RPTR, rptr);\n+\n+\tEFX_BAR_TBL_WRITED(enp, FR_AZ_EVQ_RPTR_REG, eep->ee_index,\n+\t\t\t    &dword, B_FALSE);\n+\n+\treturn (0);\n+}\n+\n+static\t\tvoid\n+siena_ev_qpost(\n+\t__in\tefx_evq_t *eep,\n+\t__in\tuint16_t data)\n+{\n+\tefx_nic_t *enp = eep->ee_enp;\n+\tefx_qword_t ev;\n+\tefx_oword_t oword;\n+\n+\tEFX_POPULATE_QWORD_2(ev, FSF_AZ_EV_CODE, FSE_AZ_EV_CODE_DRV_GEN_EV,\n+\t    FSF_AZ_EV_DATA_DW0, (uint32_t)data);\n+\n+\tEFX_POPULATE_OWORD_3(oword, FRF_AZ_DRV_EV_QID, eep->ee_index,\n+\t    EFX_DWORD_0, EFX_QWORD_FIELD(ev, EFX_DWORD_0),\n+\t    EFX_DWORD_1, EFX_QWORD_FIELD(ev, EFX_DWORD_1));\n+\n+\tEFX_BAR_WRITEO(enp, FR_AZ_DRV_EV_REG, &oword);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_ev_qmoderate(\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tunsigned int us)\n+{\n+\tefx_nic_t *enp = eep->ee_enp;\n+\tefx_nic_cfg_t *encp = &(enp->en_nic_cfg);\n+\tunsigned int locked;\n+\tefx_dword_t dword;\n+\tefx_rc_t rc;\n+\n+\tif (us > encp->enc_evq_timer_max_us) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\t/* If the value is zero then disable the timer */\n+\tif (us == 0) {\n+\t\tEFX_POPULATE_DWORD_2(dword,\n+\t\t    FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS,\n+\t\t    FRF_CZ_TC_TIMER_VAL, 0);\n+\t} else {\n+\t\tunsigned int ticks;\n+\n+\t\tif ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)\n+\t\t\tgoto fail2;\n+\n+\t\tEFSYS_ASSERT(ticks > 0);\n+\t\tEFX_POPULATE_DWORD_2(dword,\n+\t\t    FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_INT_HLDOFF,\n+\t\t    FRF_CZ_TC_TIMER_VAL, ticks - 1);\n+\t}\n+\n+\tlocked = (eep->ee_index == 0) ? 1 : 0;\n+\n+\tEFX_BAR_TBL_WRITED(enp, FR_BZ_TIMER_COMMAND_REGP0,\n+\t    eep->ee_index, &dword, locked);\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_ev_qcreate(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tunsigned int index,\n+\t__in\t\tefsys_mem_t *esmp,\n+\t__in\t\tsize_t n,\n+\t__in\t\tuint32_t id,\n+\t__in\t\tuint32_t us,\n+\t__in\t\tuint32_t flags,\n+\t__in\t\tefx_evq_t *eep)\n+{\n+\tefx_nic_cfg_t *encp = &(enp->en_nic_cfg);\n+\tuint32_t size;\n+\tefx_oword_t oword;\n+\tefx_rc_t rc;\n+\tboolean_t notify_mode;\n+\n+\t_NOTE(ARGUNUSED(esmp))\n+\n+\tEFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS));\n+\tEFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS));\n+\n+\tif (!ISP2(n) || (n < EFX_EVQ_MINNEVS) || (n > EFX_EVQ_MAXNEVS)) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\tif (index >= encp->enc_evq_limit) {\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\tfor (size = 0; (1 << size) <= (EFX_EVQ_MAXNEVS / EFX_EVQ_MINNEVS);\n+\t    size++)\n+\t\tif ((1 << size) == (int)(n / EFX_EVQ_MINNEVS))\n+\t\t\tbreak;\n+\tif (id + (1 << size) >= encp->enc_buftbl_limit) {\n+\t\trc = EINVAL;\n+\t\tgoto fail4;\n+\t}\n+\n+\t/* Set up the handler table */\n+\teep->ee_rx\t= siena_ev_rx;\n+\teep->ee_tx\t= siena_ev_tx;\n+\teep->ee_driver\t= siena_ev_driver;\n+\teep->ee_global\t= siena_ev_global;\n+\teep->ee_drv_gen\t= siena_ev_drv_gen;\n+#if EFSYS_OPT_MCDI\n+\teep->ee_mcdi\t= siena_ev_mcdi;\n+#endif\t/* EFSYS_OPT_MCDI */\n+\n+\tnotify_mode = ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) !=\n+\t    EFX_EVQ_FLAGS_NOTIFY_INTERRUPT);\n+\n+\t/* Set up the new event queue */\n+\tEFX_POPULATE_OWORD_3(oword, FRF_CZ_TIMER_Q_EN, 1,\n+\t    FRF_CZ_HOST_NOTIFY_MODE, notify_mode,\n+\t    FRF_CZ_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS);\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, index, &oword, B_TRUE);\n+\n+\tEFX_POPULATE_OWORD_3(oword, FRF_AZ_EVQ_EN, 1, FRF_AZ_EVQ_SIZE, size,\n+\t    FRF_AZ_EVQ_BUF_BASE_ID, id);\n+\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, index, &oword, B_TRUE);\n+\n+\t/* Set initial interrupt moderation */\n+\tsiena_ev_qmoderate(eep, us);\n+\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+#endif /* EFSYS_OPT_SIENA */\n+\n+#if EFSYS_OPT_SIENA\n+\n+static\t\tvoid\n+siena_ev_qdestroy(\n+\t__in\tefx_evq_t *eep)\n+{\n+\tefx_nic_t *enp = eep->ee_enp;\n+\tefx_oword_t oword;\n+\n+\t/* Purge event queue */\n+\tEFX_ZERO_OWORD(oword);\n+\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL,\n+\t    eep->ee_index, &oword, B_TRUE);\n+\n+\tEFX_ZERO_OWORD(oword);\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, eep->ee_index, &oword, B_TRUE);\n+}\n+\n+static\t\tvoid\n+siena_ev_fini(\n+\t__in\tefx_nic_t *enp)\n+{\n+\t_NOTE(ARGUNUSED(enp))\n+}\n+\n+#endif /* EFSYS_OPT_SIENA */\ndiff --git a/drivers/net/sfc/efx/base/efx_filter.c b/drivers/net/sfc/efx/base/efx_filter.c\nindex 8ae865f..c612731 100644\n--- a/drivers/net/sfc/efx/base/efx_filter.c\n+++ b/drivers/net/sfc/efx/base/efx_filter.c\n@@ -34,6 +34,51 @@\n \n #if EFSYS_OPT_FILTER\n \n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_filter_init(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t\t\tvoid\n+siena_filter_fini(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_filter_restore(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_filter_add(\n+\t__in\t\tefx_nic_t *enp,\n+\t__inout\t\tefx_filter_spec_t *spec,\n+\t__in\t\tboolean_t may_replace);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_filter_delete(\n+\t__in\t\tefx_nic_t *enp,\n+\t__inout\t\tefx_filter_spec_t *spec);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_filter_supported_filters(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tuint32_t *list,\n+\t__out\t\tsize_t *length);\n+\n+#endif /* EFSYS_OPT_SIENA */\n+\n+#if EFSYS_OPT_SIENA\n+static const efx_filter_ops_t\t__efx_filter_siena_ops = {\n+\tsiena_filter_init,\t\t/* efo_init */\n+\tsiena_filter_fini,\t\t/* efo_fini */\n+\tsiena_filter_restore,\t\t/* efo_restore */\n+\tsiena_filter_add,\t\t/* efo_add */\n+\tsiena_filter_delete,\t\t/* efo_delete */\n+\tsiena_filter_supported_filters,\t/* efo_supported_filters */\n+\tNULL,\t\t\t\t/* efo_reconfigure */\n+};\n+#endif /* EFSYS_OPT_SIENA */\n+\n \t__checkReturn\tefx_rc_t\n efx_filter_insert(\n \t__in\t\tefx_nic_t *enp,\n@@ -96,6 +141,11 @@ efx_filter_init(\n \tEFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_FILTER));\n \n \tswitch (enp->en_family) {\n+#if EFSYS_OPT_SIENA\n+\tcase EFX_FAMILY_SIENA:\n+\t\tefop = &__efx_filter_siena_ops;\n+\t\tbreak;\n+#endif /* EFSYS_OPT_SIENA */\n \n \tdefault:\n \t\tEFSYS_ASSERT(0);\n@@ -329,4 +379,996 @@ efx_filter_spec_set_mc_def(\n \n \n \n+#if EFSYS_OPT_SIENA\n+\n+/*\n+ * \"Fudge factors\" - difference between programmed value and actual depth.\n+ * Due to pipelined implementation we need to program H/W with a value that\n+ * is larger than the hop limit we want.\n+ */\n+#define\tFILTER_CTL_SRCH_FUDGE_WILD 3\n+#define\tFILTER_CTL_SRCH_FUDGE_FULL 1\n+\n+/*\n+ * Hard maximum hop limit.  Hardware will time-out beyond 200-something.\n+ * We also need to avoid infinite loops in efx_filter_search() when the\n+ * table is full.\n+ */\n+#define\tFILTER_CTL_SRCH_MAX 200\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_filter_spec_from_gen_spec(\n+\t__out\t\tsiena_filter_spec_t *sf_spec,\n+\t__in\t\tefx_filter_spec_t *gen_spec)\n+{\n+\tefx_rc_t rc;\n+\tboolean_t is_full = B_FALSE;\n+\n+\tif (gen_spec->efs_flags & EFX_FILTER_FLAG_TX)\n+\t\tEFSYS_ASSERT3U(gen_spec->efs_flags, ==, EFX_FILTER_FLAG_TX);\n+\telse\n+\t\tEFSYS_ASSERT3U(gen_spec->efs_flags, &, EFX_FILTER_FLAG_RX);\n+\n+\t/* Falconsiena only has one RSS context */\n+\tif ((gen_spec->efs_flags & EFX_FILTER_FLAG_RX_RSS) &&\n+\t    gen_spec->efs_rss_context != 0) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tsf_spec->sfs_flags = gen_spec->efs_flags;\n+\tsf_spec->sfs_dmaq_id = gen_spec->efs_dmaq_id;\n+\n+\tswitch (gen_spec->efs_match_flags) {\n+\tcase EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |\n+\t    EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |\n+\t    EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT:\n+\t\tis_full = B_TRUE;\n+\t\t/* Fall through */\n+\tcase EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |\n+\t    EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT: {\n+\t\tuint32_t rhost, host1, host2;\n+\t\tuint16_t rport, port1, port2;\n+\n+\t\tif (gen_spec->efs_ether_type != EFX_ETHER_TYPE_IPV4) {\n+\t\t\trc = ENOTSUP;\n+\t\t\tgoto fail2;\n+\t\t}\n+\t\tif (gen_spec->efs_loc_port == 0 ||\n+\t\t    (is_full && gen_spec->efs_rem_port == 0)) {\n+\t\t\trc = EINVAL;\n+\t\t\tgoto fail3;\n+\t\t}\n+\t\tswitch (gen_spec->efs_ip_proto) {\n+\t\tcase EFX_IPPROTO_TCP:\n+\t\t\tif (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {\n+\t\t\t\tsf_spec->sfs_type = (is_full ?\n+\t\t\t\t    EFX_SIENA_FILTER_TX_TCP_FULL :\n+\t\t\t\t    EFX_SIENA_FILTER_TX_TCP_WILD);\n+\t\t\t} else {\n+\t\t\t\tsf_spec->sfs_type = (is_full ?\n+\t\t\t\t    EFX_SIENA_FILTER_RX_TCP_FULL :\n+\t\t\t\t    EFX_SIENA_FILTER_RX_TCP_WILD);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase EFX_IPPROTO_UDP:\n+\t\t\tif (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {\n+\t\t\t\tsf_spec->sfs_type = (is_full ?\n+\t\t\t\t    EFX_SIENA_FILTER_TX_UDP_FULL :\n+\t\t\t\t    EFX_SIENA_FILTER_TX_UDP_WILD);\n+\t\t\t} else {\n+\t\t\t\tsf_spec->sfs_type = (is_full ?\n+\t\t\t\t    EFX_SIENA_FILTER_RX_UDP_FULL :\n+\t\t\t\t    EFX_SIENA_FILTER_RX_UDP_WILD);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\trc = ENOTSUP;\n+\t\t\tgoto fail4;\n+\t\t}\n+\t\t/*\n+\t\t * The filter is constructed in terms of source and destination,\n+\t\t * with the odd wrinkle that the ports are swapped in a UDP\n+\t\t * wildcard filter. We need to convert from local and remote\n+\t\t * addresses (zero for a wildcard).\n+\t\t */\n+\t\trhost = is_full ? gen_spec->efs_rem_host.eo_u32[0] : 0;\n+\t\trport = is_full ? gen_spec->efs_rem_port : 0;\n+\t\tif (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {\n+\t\t\thost1 = gen_spec->efs_loc_host.eo_u32[0];\n+\t\t\thost2 = rhost;\n+\t\t} else {\n+\t\t\thost1 = rhost;\n+\t\t\thost2 = gen_spec->efs_loc_host.eo_u32[0];\n+\t\t}\n+\t\tif (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {\n+\t\t\tif (sf_spec->sfs_type ==\n+\t\t\t    EFX_SIENA_FILTER_TX_UDP_WILD) {\n+\t\t\t\tport1 = rport;\n+\t\t\t\tport2 = gen_spec->efs_loc_port;\n+\t\t\t} else {\n+\t\t\t\tport1 = gen_spec->efs_loc_port;\n+\t\t\t\tport2 = rport;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tif (sf_spec->sfs_type ==\n+\t\t\t    EFX_SIENA_FILTER_RX_UDP_WILD) {\n+\t\t\t\tport1 = gen_spec->efs_loc_port;\n+\t\t\t\tport2 = rport;\n+\t\t\t} else {\n+\t\t\t\tport1 = rport;\n+\t\t\t\tport2 = gen_spec->efs_loc_port;\n+\t\t\t}\n+\t\t}\n+\t\tsf_spec->sfs_dword[0] = (host1 << 16) | port1;\n+\t\tsf_spec->sfs_dword[1] = (port2 << 16) | (host1 >> 16);\n+\t\tsf_spec->sfs_dword[2] = host2;\n+\t\tbreak;\n+\t}\n+\n+\tcase EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_OUTER_VID:\n+\t\tis_full = B_TRUE;\n+\t\t/* Fall through */\n+\tcase EFX_FILTER_MATCH_LOC_MAC:\n+\t\tif (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {\n+\t\t\tsf_spec->sfs_type = (is_full ?\n+\t\t\t    EFX_SIENA_FILTER_TX_MAC_FULL :\n+\t\t\t    EFX_SIENA_FILTER_TX_MAC_WILD);\n+\t\t} else {\n+\t\t\tsf_spec->sfs_type = (is_full ?\n+\t\t\t    EFX_SIENA_FILTER_RX_MAC_FULL :\n+\t\t\t    EFX_SIENA_FILTER_RX_MAC_WILD);\n+\t\t}\n+\t\tsf_spec->sfs_dword[0] = is_full ? gen_spec->efs_outer_vid : 0;\n+\t\tsf_spec->sfs_dword[1] =\n+\t\t    gen_spec->efs_loc_mac[2] << 24 |\n+\t\t    gen_spec->efs_loc_mac[3] << 16 |\n+\t\t    gen_spec->efs_loc_mac[4] <<  8 |\n+\t\t    gen_spec->efs_loc_mac[5];\n+\t\tsf_spec->sfs_dword[2] =\n+\t\t    gen_spec->efs_loc_mac[0] << 8 |\n+\t\t    gen_spec->efs_loc_mac[1];\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tEFSYS_ASSERT(B_FALSE);\n+\t\trc = ENOTSUP;\n+\t\tgoto fail5;\n+\t}\n+\n+\treturn (0);\n+\n+fail5:\n+\tEFSYS_PROBE(fail5);\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+/*\n+ * The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit\n+ * key derived from the n-tuple.\n+ */\n+static\t\t\tuint16_t\n+siena_filter_tbl_hash(\n+\t__in\t\tuint32_t key)\n+{\n+\tuint16_t tmp;\n+\n+\t/* First 16 rounds */\n+\ttmp = 0x1fff ^ (uint16_t)(key >> 16);\n+\ttmp = tmp ^ tmp >> 3 ^ tmp >> 6;\n+\ttmp = tmp ^ tmp >> 9;\n+\n+\t/* Last 16 rounds */\n+\ttmp = tmp ^ tmp << 13 ^ (uint16_t)(key & 0xffff);\n+\ttmp = tmp ^ tmp >> 3 ^ tmp >> 6;\n+\ttmp = tmp ^ tmp >> 9;\n+\n+\treturn (tmp);\n+}\n+\n+/*\n+ * To allow for hash collisions, filter search continues at these\n+ * increments from the first possible entry selected by the hash.\n+ */\n+static\t\t\tuint16_t\n+siena_filter_tbl_increment(\n+\t__in\t\tuint32_t key)\n+{\n+\treturn ((uint16_t)(key * 2 - 1));\n+}\n+\n+static\t__checkReturn\tboolean_t\n+siena_filter_test_used(\n+\t__in\t\tsiena_filter_tbl_t *sftp,\n+\t__in\t\tunsigned int index)\n+{\n+\tEFSYS_ASSERT3P(sftp->sft_bitmap, !=, NULL);\n+\treturn ((sftp->sft_bitmap[index / 32] & (1 << (index % 32))) != 0);\n+}\n+\n+static\t\t\tvoid\n+siena_filter_set_used(\n+\t__in\t\tsiena_filter_tbl_t *sftp,\n+\t__in\t\tunsigned int index)\n+{\n+\tEFSYS_ASSERT3P(sftp->sft_bitmap, !=, NULL);\n+\tsftp->sft_bitmap[index / 32] |= (1 << (index % 32));\n+\t++sftp->sft_used;\n+}\n+\n+static\t\t\tvoid\n+siena_filter_clear_used(\n+\t__in\t\tsiena_filter_tbl_t *sftp,\n+\t__in\t\tunsigned int index)\n+{\n+\tEFSYS_ASSERT3P(sftp->sft_bitmap, !=, NULL);\n+\tsftp->sft_bitmap[index / 32] &= ~(1 << (index % 32));\n+\n+\t--sftp->sft_used;\n+\tEFSYS_ASSERT3U(sftp->sft_used, >=, 0);\n+}\n+\n+\n+static\t\t\tsiena_filter_tbl_id_t\n+siena_filter_tbl_id(\n+\t__in\t\tsiena_filter_type_t type)\n+{\n+\tsiena_filter_tbl_id_t tbl_id;\n+\n+\tswitch (type) {\n+\tcase EFX_SIENA_FILTER_RX_TCP_FULL:\n+\tcase EFX_SIENA_FILTER_RX_TCP_WILD:\n+\tcase EFX_SIENA_FILTER_RX_UDP_FULL:\n+\tcase EFX_SIENA_FILTER_RX_UDP_WILD:\n+\t\ttbl_id = EFX_SIENA_FILTER_TBL_RX_IP;\n+\t\tbreak;\n+\n+\tcase EFX_SIENA_FILTER_RX_MAC_FULL:\n+\tcase EFX_SIENA_FILTER_RX_MAC_WILD:\n+\t\ttbl_id = EFX_SIENA_FILTER_TBL_RX_MAC;\n+\t\tbreak;\n+\n+\tcase EFX_SIENA_FILTER_TX_TCP_FULL:\n+\tcase EFX_SIENA_FILTER_TX_TCP_WILD:\n+\tcase EFX_SIENA_FILTER_TX_UDP_FULL:\n+\tcase EFX_SIENA_FILTER_TX_UDP_WILD:\n+\t\ttbl_id = EFX_SIENA_FILTER_TBL_TX_IP;\n+\t\tbreak;\n+\n+\tcase EFX_SIENA_FILTER_TX_MAC_FULL:\n+\tcase EFX_SIENA_FILTER_TX_MAC_WILD:\n+\t\ttbl_id = EFX_SIENA_FILTER_TBL_TX_MAC;\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tEFSYS_ASSERT(B_FALSE);\n+\t\ttbl_id = EFX_SIENA_FILTER_NTBLS;\n+\t\tbreak;\n+\t}\n+\treturn (tbl_id);\n+}\n+\n+static\t\t\tvoid\n+siena_filter_reset_search_depth(\n+\t__inout\t\tsiena_filter_t *sfp,\n+\t__in\t\tsiena_filter_tbl_id_t tbl_id)\n+{\n+\tswitch (tbl_id) {\n+\tcase EFX_SIENA_FILTER_TBL_RX_IP:\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_RX_TCP_FULL] = 0;\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_RX_TCP_WILD] = 0;\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_RX_UDP_FULL] = 0;\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_RX_UDP_WILD] = 0;\n+\t\tbreak;\n+\n+\tcase EFX_SIENA_FILTER_TBL_RX_MAC:\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_RX_MAC_FULL] = 0;\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_RX_MAC_WILD] = 0;\n+\t\tbreak;\n+\n+\tcase EFX_SIENA_FILTER_TBL_TX_IP:\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_TX_TCP_FULL] = 0;\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_TX_TCP_WILD] = 0;\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_TX_UDP_FULL] = 0;\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_TX_UDP_WILD] = 0;\n+\t\tbreak;\n+\n+\tcase EFX_SIENA_FILTER_TBL_TX_MAC:\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_TX_MAC_FULL] = 0;\n+\t\tsfp->sf_depth[EFX_SIENA_FILTER_TX_MAC_WILD] = 0;\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tEFSYS_ASSERT(B_FALSE);\n+\t\tbreak;\n+\t}\n+}\n+\n+static\t\t\tvoid\n+siena_filter_push_rx_limits(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tsiena_filter_t *sfp = enp->en_filter.ef_siena_filter;\n+\tefx_oword_t oword;\n+\n+\tEFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);\n+\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TCP_FULL_SRCH_LIMIT,\n+\t    sfp->sf_depth[EFX_SIENA_FILTER_RX_TCP_FULL] +\n+\t    FILTER_CTL_SRCH_FUDGE_FULL);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TCP_WILD_SRCH_LIMIT,\n+\t    sfp->sf_depth[EFX_SIENA_FILTER_RX_TCP_WILD] +\n+\t    FILTER_CTL_SRCH_FUDGE_WILD);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_UDP_FULL_SRCH_LIMIT,\n+\t    sfp->sf_depth[EFX_SIENA_FILTER_RX_UDP_FULL] +\n+\t    FILTER_CTL_SRCH_FUDGE_FULL);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_UDP_WILD_SRCH_LIMIT,\n+\t    sfp->sf_depth[EFX_SIENA_FILTER_RX_UDP_WILD] +\n+\t    FILTER_CTL_SRCH_FUDGE_WILD);\n+\n+\tif (sfp->sf_tbl[EFX_SIENA_FILTER_TBL_RX_MAC].sft_size) {\n+\t\tEFX_SET_OWORD_FIELD(oword,\n+\t\t    FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,\n+\t\t    sfp->sf_depth[EFX_SIENA_FILTER_RX_MAC_FULL] +\n+\t\t    FILTER_CTL_SRCH_FUDGE_FULL);\n+\t\tEFX_SET_OWORD_FIELD(oword,\n+\t\t    FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,\n+\t\t    sfp->sf_depth[EFX_SIENA_FILTER_RX_MAC_WILD] +\n+\t\t    FILTER_CTL_SRCH_FUDGE_WILD);\n+\t}\n+\n+\tEFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);\n+}\n+\n+static\t\t\tvoid\n+siena_filter_push_tx_limits(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tsiena_filter_t *sfp = enp->en_filter.ef_siena_filter;\n+\tefx_oword_t oword;\n+\n+\tEFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword);\n+\n+\tif (sfp->sf_tbl[EFX_SIENA_FILTER_TBL_TX_IP].sft_size != 0) {\n+\t\tEFX_SET_OWORD_FIELD(oword,\n+\t\t    FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE,\n+\t\t    sfp->sf_depth[EFX_SIENA_FILTER_TX_TCP_FULL] +\n+\t\t    FILTER_CTL_SRCH_FUDGE_FULL);\n+\t\tEFX_SET_OWORD_FIELD(oword,\n+\t\t    FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE,\n+\t\t    sfp->sf_depth[EFX_SIENA_FILTER_TX_TCP_WILD] +\n+\t\t    FILTER_CTL_SRCH_FUDGE_WILD);\n+\t\tEFX_SET_OWORD_FIELD(oword,\n+\t\t    FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE,\n+\t\t    sfp->sf_depth[EFX_SIENA_FILTER_TX_UDP_FULL] +\n+\t\t    FILTER_CTL_SRCH_FUDGE_FULL);\n+\t\tEFX_SET_OWORD_FIELD(oword,\n+\t\t    FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE,\n+\t\t    sfp->sf_depth[EFX_SIENA_FILTER_TX_UDP_WILD] +\n+\t\t    FILTER_CTL_SRCH_FUDGE_WILD);\n+\t}\n+\n+\tif (sfp->sf_tbl[EFX_SIENA_FILTER_TBL_TX_MAC].sft_size != 0) {\n+\t\tEFX_SET_OWORD_FIELD(\n+\t\t\toword, FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE,\n+\t\t\tsfp->sf_depth[EFX_SIENA_FILTER_TX_MAC_FULL] +\n+\t\t\tFILTER_CTL_SRCH_FUDGE_FULL);\n+\t\tEFX_SET_OWORD_FIELD(\n+\t\t\toword, FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE,\n+\t\t\tsfp->sf_depth[EFX_SIENA_FILTER_TX_MAC_WILD] +\n+\t\t\tFILTER_CTL_SRCH_FUDGE_WILD);\n+\t}\n+\n+\tEFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);\n+}\n+\n+/* Build a filter entry and return its n-tuple key. */\n+static\t__checkReturn\tuint32_t\n+siena_filter_build(\n+\t__out\t\tefx_oword_t *filter,\n+\t__in\t\tsiena_filter_spec_t *spec)\n+{\n+\tuint32_t dword3;\n+\tuint32_t key;\n+\tuint8_t  type  = spec->sfs_type;\n+\tuint32_t flags = spec->sfs_flags;\n+\n+\tswitch (siena_filter_tbl_id(type)) {\n+\tcase EFX_SIENA_FILTER_TBL_RX_IP: {\n+\t\tboolean_t is_udp = (type == EFX_SIENA_FILTER_RX_UDP_FULL ||\n+\t\t    type == EFX_SIENA_FILTER_RX_UDP_WILD);\n+\t\tEFX_POPULATE_OWORD_7(*filter,\n+\t\t    FRF_BZ_RSS_EN,\n+\t\t    (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0,\n+\t\t    FRF_BZ_SCATTER_EN,\n+\t\t    (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0,\n+\t\t    FRF_AZ_TCP_UDP, is_udp,\n+\t\t    FRF_AZ_RXQ_ID, spec->sfs_dmaq_id,\n+\t\t    EFX_DWORD_2, spec->sfs_dword[2],\n+\t\t    EFX_DWORD_1, spec->sfs_dword[1],\n+\t\t    EFX_DWORD_0, spec->sfs_dword[0]);\n+\t\tdword3 = is_udp;\n+\t\tbreak;\n+\t}\n+\n+\tcase EFX_SIENA_FILTER_TBL_RX_MAC: {\n+\t\tboolean_t is_wild = (type == EFX_SIENA_FILTER_RX_MAC_WILD);\n+\t\tEFX_POPULATE_OWORD_7(*filter,\n+\t\t    FRF_CZ_RMFT_RSS_EN,\n+\t\t    (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0,\n+\t\t    FRF_CZ_RMFT_SCATTER_EN,\n+\t\t    (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0,\n+\t\t    FRF_CZ_RMFT_RXQ_ID, spec->sfs_dmaq_id,\n+\t\t    FRF_CZ_RMFT_WILDCARD_MATCH, is_wild,\n+\t\t    FRF_CZ_RMFT_DEST_MAC_DW1, spec->sfs_dword[2],\n+\t\t    FRF_CZ_RMFT_DEST_MAC_DW0, spec->sfs_dword[1],\n+\t\t    FRF_CZ_RMFT_VLAN_ID, spec->sfs_dword[0]);\n+\t\tdword3 = is_wild;\n+\t\tbreak;\n+\t}\n+\n+\tcase EFX_SIENA_FILTER_TBL_TX_IP: {\n+\t\tboolean_t is_udp = (type == EFX_SIENA_FILTER_TX_UDP_FULL ||\n+\t\t    type == EFX_SIENA_FILTER_TX_UDP_WILD);\n+\t\tEFX_POPULATE_OWORD_5(*filter,\n+\t\t    FRF_CZ_TIFT_TCP_UDP, is_udp,\n+\t\t    FRF_CZ_TIFT_TXQ_ID, spec->sfs_dmaq_id,\n+\t\t    EFX_DWORD_2, spec->sfs_dword[2],\n+\t\t    EFX_DWORD_1, spec->sfs_dword[1],\n+\t\t    EFX_DWORD_0, spec->sfs_dword[0]);\n+\t\tdword3 = is_udp | spec->sfs_dmaq_id << 1;\n+\t\tbreak;\n+\t}\n+\n+\tcase EFX_SIENA_FILTER_TBL_TX_MAC: {\n+\t\tboolean_t is_wild = (type == EFX_SIENA_FILTER_TX_MAC_WILD);\n+\t\tEFX_POPULATE_OWORD_5(*filter,\n+\t\t    FRF_CZ_TMFT_TXQ_ID, spec->sfs_dmaq_id,\n+\t\t    FRF_CZ_TMFT_WILDCARD_MATCH, is_wild,\n+\t\t    FRF_CZ_TMFT_SRC_MAC_DW1, spec->sfs_dword[2],\n+\t\t    FRF_CZ_TMFT_SRC_MAC_DW0, spec->sfs_dword[1],\n+\t\t    FRF_CZ_TMFT_VLAN_ID, spec->sfs_dword[0]);\n+\t\tdword3 = is_wild | spec->sfs_dmaq_id << 1;\n+\t\tbreak;\n+\t}\n+\n+\tdefault:\n+\t\tEFSYS_ASSERT(B_FALSE);\n+\t\treturn (0);\n+\t}\n+\n+\tkey =\n+\t    spec->sfs_dword[0] ^\n+\t    spec->sfs_dword[1] ^\n+\t    spec->sfs_dword[2] ^\n+\t    dword3;\n+\n+\treturn (key);\n+}\n+\n+static\t__checkReturn\t\tefx_rc_t\n+siena_filter_push_entry(\n+\t__inout\t\t\tefx_nic_t *enp,\n+\t__in\t\t\tsiena_filter_type_t type,\n+\t__in\t\t\tint index,\n+\t__in\t\t\tefx_oword_t *eop)\n+{\n+\tefx_rc_t rc;\n+\n+\tswitch (type) {\n+\tcase EFX_SIENA_FILTER_RX_TCP_FULL:\n+\tcase EFX_SIENA_FILTER_RX_TCP_WILD:\n+\tcase EFX_SIENA_FILTER_RX_UDP_FULL:\n+\tcase EFX_SIENA_FILTER_RX_UDP_WILD:\n+\t\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_FILTER_TBL0, index,\n+\t\t    eop, B_TRUE);\n+\t\tbreak;\n+\n+\tcase EFX_SIENA_FILTER_RX_MAC_FULL:\n+\tcase EFX_SIENA_FILTER_RX_MAC_WILD:\n+\t\tEFX_BAR_TBL_WRITEO(enp, FR_CZ_RX_MAC_FILTER_TBL0, index,\n+\t\t    eop, B_TRUE);\n+\t\tbreak;\n+\n+\tcase EFX_SIENA_FILTER_TX_TCP_FULL:\n+\tcase EFX_SIENA_FILTER_TX_TCP_WILD:\n+\tcase EFX_SIENA_FILTER_TX_UDP_FULL:\n+\tcase EFX_SIENA_FILTER_TX_UDP_WILD:\n+\t\tEFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_FILTER_TBL0, index,\n+\t\t    eop, B_TRUE);\n+\t\tbreak;\n+\n+\tcase EFX_SIENA_FILTER_TX_MAC_FULL:\n+\tcase EFX_SIENA_FILTER_TX_MAC_WILD:\n+\t\tEFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_MAC_FILTER_TBL0, index,\n+\t\t    eop, B_TRUE);\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tEFSYS_ASSERT(B_FALSE);\n+\t\trc = ENOTSUP;\n+\t\tgoto fail1;\n+\t}\n+\treturn (0);\n+\n+fail1:\n+\treturn (rc);\n+}\n+\n+\n+static\t__checkReturn\tboolean_t\n+siena_filter_equal(\n+\t__in\t\tconst siena_filter_spec_t *left,\n+\t__in\t\tconst siena_filter_spec_t *right)\n+{\n+\tsiena_filter_tbl_id_t tbl_id;\n+\n+\ttbl_id = siena_filter_tbl_id(left->sfs_type);\n+\n+\n+\tif (left->sfs_type != right->sfs_type)\n+\t\treturn (B_FALSE);\n+\n+\tif (memcmp(left->sfs_dword, right->sfs_dword,\n+\t\tsizeof (left->sfs_dword)))\n+\t\treturn (B_FALSE);\n+\n+\tif ((tbl_id == EFX_SIENA_FILTER_TBL_TX_IP ||\n+\t\ttbl_id == EFX_SIENA_FILTER_TBL_TX_MAC) &&\n+\t    left->sfs_dmaq_id != right->sfs_dmaq_id)\n+\t\treturn (B_FALSE);\n+\n+\treturn (B_TRUE);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_filter_search(\n+\t__in\t\tsiena_filter_tbl_t *sftp,\n+\t__in\t\tsiena_filter_spec_t *spec,\n+\t__in\t\tuint32_t key,\n+\t__in\t\tboolean_t for_insert,\n+\t__out\t\tint *filter_index,\n+\t__out\t\tunsigned int *depth_required)\n+{\n+\tunsigned int hash, incr, filter_idx, depth;\n+\n+\thash = siena_filter_tbl_hash(key);\n+\tincr = siena_filter_tbl_increment(key);\n+\n+\tfilter_idx = hash & (sftp->sft_size - 1);\n+\tdepth = 1;\n+\n+\tfor (;;) {\n+\t\t/*\n+\t\t * Return success if entry is used and matches this spec\n+\t\t * or entry is unused and we are trying to insert.\n+\t\t */\n+\t\tif (siena_filter_test_used(sftp, filter_idx) ?\n+\t\t    siena_filter_equal(spec,\n+\t\t    &sftp->sft_spec[filter_idx]) :\n+\t\t    for_insert) {\n+\t\t\t*filter_index = filter_idx;\n+\t\t\t*depth_required = depth;\n+\t\t\treturn (0);\n+\t\t}\n+\n+\t\t/* Return failure if we reached the maximum search depth */\n+\t\tif (depth == FILTER_CTL_SRCH_MAX)\n+\t\t\treturn (for_insert ? EBUSY : ENOENT);\n+\n+\t\tfilter_idx = (filter_idx + incr) & (sftp->sft_size - 1);\n+\t\t++depth;\n+\t}\n+}\n+\n+static\t\t\tvoid\n+siena_filter_clear_entry(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tsiena_filter_tbl_t *sftp,\n+\t__in\t\tint index)\n+{\n+\tefx_oword_t filter;\n+\n+\tif (siena_filter_test_used(sftp, index)) {\n+\t\tsiena_filter_clear_used(sftp, index);\n+\n+\t\tEFX_ZERO_OWORD(filter);\n+\t\tsiena_filter_push_entry(enp,\n+\t\t    sftp->sft_spec[index].sfs_type,\n+\t\t    index, &filter);\n+\n+\t\tmemset(&sftp->sft_spec[index],\n+\t\t    0, sizeof (sftp->sft_spec[0]));\n+\t}\n+}\n+\n+\t\t\tvoid\n+siena_filter_tbl_clear(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tsiena_filter_tbl_id_t tbl_id)\n+{\n+\tsiena_filter_t *sfp = enp->en_filter.ef_siena_filter;\n+\tsiena_filter_tbl_t *sftp = &sfp->sf_tbl[tbl_id];\n+\tint index;\n+\tefsys_lock_state_t state;\n+\n+\tEFSYS_LOCK(enp->en_eslp, state);\n+\n+\tfor (index = 0; index < sftp->sft_size; ++index) {\n+\t\tsiena_filter_clear_entry(enp, sftp, index);\n+\t}\n+\n+\tif (sftp->sft_used == 0)\n+\t\tsiena_filter_reset_search_depth(sfp, tbl_id);\n+\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_filter_init(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tsiena_filter_t *sfp;\n+\tsiena_filter_tbl_t *sftp;\n+\tint tbl_id;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_KMEM_ALLOC(enp->en_esip, sizeof (siena_filter_t), sfp);\n+\n+\tif (!sfp) {\n+\t\trc = ENOMEM;\n+\t\tgoto fail1;\n+\t}\n+\n+\tenp->en_filter.ef_siena_filter = sfp;\n+\n+\tswitch (enp->en_family) {\n+\tcase EFX_FAMILY_SIENA:\n+\t\tsftp = &sfp->sf_tbl[EFX_SIENA_FILTER_TBL_RX_IP];\n+\t\tsftp->sft_size = FR_AZ_RX_FILTER_TBL0_ROWS;\n+\n+\t\tsftp = &sfp->sf_tbl[EFX_SIENA_FILTER_TBL_RX_MAC];\n+\t\tsftp->sft_size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;\n+\n+\t\tsftp = &sfp->sf_tbl[EFX_SIENA_FILTER_TBL_TX_IP];\n+\t\tsftp->sft_size = FR_CZ_TX_FILTER_TBL0_ROWS;\n+\n+\t\tsftp = &sfp->sf_tbl[EFX_SIENA_FILTER_TBL_TX_MAC];\n+\t\tsftp->sft_size = FR_CZ_TX_MAC_FILTER_TBL0_ROWS;\n+\t\tbreak;\n+\n+\tdefault:\n+\t\trc = ENOTSUP;\n+\t\tgoto fail2;\n+\t}\n+\n+\tfor (tbl_id = 0; tbl_id < EFX_SIENA_FILTER_NTBLS; tbl_id++) {\n+\t\tunsigned int bitmap_size;\n+\n+\t\tsftp = &sfp->sf_tbl[tbl_id];\n+\t\tif (sftp->sft_size == 0)\n+\t\t\tcontinue;\n+\n+\t\tEFX_STATIC_ASSERT(sizeof (sftp->sft_bitmap[0]) ==\n+\t\t    sizeof (uint32_t));\n+\t\tbitmap_size =\n+\t\t    (sftp->sft_size + (sizeof (uint32_t) * 8) - 1) / 8;\n+\n+\t\tEFSYS_KMEM_ALLOC(enp->en_esip, bitmap_size, sftp->sft_bitmap);\n+\t\tif (!sftp->sft_bitmap) {\n+\t\t\trc = ENOMEM;\n+\t\t\tgoto fail3;\n+\t\t}\n+\n+\t\tEFSYS_KMEM_ALLOC(enp->en_esip,\n+\t\t    sftp->sft_size * sizeof (*sftp->sft_spec),\n+\t\t    sftp->sft_spec);\n+\t\tif (!sftp->sft_spec) {\n+\t\t\trc = ENOMEM;\n+\t\t\tgoto fail4;\n+\t\t}\n+\t\tmemset(sftp->sft_spec, 0,\n+\t\t    sftp->sft_size * sizeof (*sftp->sft_spec));\n+\t}\n+\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+\tsiena_filter_fini(enp);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\treturn (rc);\n+}\n+\n+static\t\t\tvoid\n+siena_filter_fini(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tsiena_filter_t *sfp = enp->en_filter.ef_siena_filter;\n+\tsiena_filter_tbl_id_t tbl_id;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);\n+\n+\tif (sfp == NULL)\n+\t\treturn;\n+\n+\tfor (tbl_id = 0; tbl_id < EFX_SIENA_FILTER_NTBLS; tbl_id++) {\n+\t\tsiena_filter_tbl_t *sftp = &sfp->sf_tbl[tbl_id];\n+\t\tunsigned int bitmap_size;\n+\n+\t\tEFX_STATIC_ASSERT(sizeof (sftp->sft_bitmap[0]) ==\n+\t\t    sizeof (uint32_t));\n+\t\tbitmap_size =\n+\t\t    (sftp->sft_size + (sizeof (uint32_t) * 8) - 1) / 8;\n+\n+\t\tif (sftp->sft_bitmap != NULL) {\n+\t\t\tEFSYS_KMEM_FREE(enp->en_esip, bitmap_size,\n+\t\t\t    sftp->sft_bitmap);\n+\t\t\tsftp->sft_bitmap = NULL;\n+\t\t}\n+\n+\t\tif (sftp->sft_spec != NULL) {\n+\t\t\tEFSYS_KMEM_FREE(enp->en_esip, sftp->sft_size *\n+\t\t\t    sizeof (*sftp->sft_spec), sftp->sft_spec);\n+\t\t\tsftp->sft_spec = NULL;\n+\t\t}\n+\t}\n+\n+\tEFSYS_KMEM_FREE(enp->en_esip, sizeof (siena_filter_t),\n+\t    enp->en_filter.ef_siena_filter);\n+}\n+\n+/* Restore filter state after a reset */\n+static\t__checkReturn\tefx_rc_t\n+siena_filter_restore(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tsiena_filter_t *sfp = enp->en_filter.ef_siena_filter;\n+\tsiena_filter_tbl_id_t tbl_id;\n+\tsiena_filter_tbl_t *sftp;\n+\tsiena_filter_spec_t *spec;\n+\tefx_oword_t filter;\n+\tint filter_idx;\n+\tefsys_lock_state_t state;\n+\tuint32_t key;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_LOCK(enp->en_eslp, state);\n+\n+\tfor (tbl_id = 0; tbl_id < EFX_SIENA_FILTER_NTBLS; tbl_id++) {\n+\t\tsftp = &sfp->sf_tbl[tbl_id];\n+\t\tfor (filter_idx = 0;\n+\t\t\tfilter_idx < sftp->sft_size;\n+\t\t\tfilter_idx++) {\n+\t\t\tif (!siena_filter_test_used(sftp, filter_idx))\n+\t\t\t\tcontinue;\n+\n+\t\t\tspec = &sftp->sft_spec[filter_idx];\n+\t\t\tif ((key = siena_filter_build(&filter, spec)) == 0) {\n+\t\t\t\trc = EINVAL;\n+\t\t\t\tgoto fail1;\n+\t\t\t}\n+\t\t\tif ((rc = siena_filter_push_entry(enp,\n+\t\t\t\t    spec->sfs_type, filter_idx, &filter)) != 0)\n+\t\t\t\tgoto fail2;\n+\t\t}\n+\t}\n+\n+\tsiena_filter_push_rx_limits(enp);\n+\tsiena_filter_push_tx_limits(enp);\n+\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n+\n+\treturn (rc);\n+}\n+\n+static\t __checkReturn\tefx_rc_t\n+siena_filter_add(\n+\t__in\t\tefx_nic_t *enp,\n+\t__inout\t\tefx_filter_spec_t *spec,\n+\t__in\t\tboolean_t may_replace)\n+{\n+\tefx_rc_t rc;\n+\tsiena_filter_spec_t sf_spec;\n+\tsiena_filter_t *sfp = enp->en_filter.ef_siena_filter;\n+\tsiena_filter_tbl_id_t tbl_id;\n+\tsiena_filter_tbl_t *sftp;\n+\tsiena_filter_spec_t *saved_sf_spec;\n+\tefx_oword_t filter;\n+\tint filter_idx;\n+\tunsigned int depth;\n+\tefsys_lock_state_t state;\n+\tuint32_t key;\n+\n+\n+\tEFSYS_ASSERT3P(spec, !=, NULL);\n+\n+\tif ((rc = siena_filter_spec_from_gen_spec(&sf_spec, spec)) != 0)\n+\t\tgoto fail1;\n+\n+\ttbl_id = siena_filter_tbl_id(sf_spec.sfs_type);\n+\tsftp = &sfp->sf_tbl[tbl_id];\n+\n+\tif (sftp->sft_size == 0) {\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\n+\tkey = siena_filter_build(&filter, &sf_spec);\n+\n+\tEFSYS_LOCK(enp->en_eslp, state);\n+\n+\trc = siena_filter_search(sftp, &sf_spec, key, B_TRUE,\n+\t    &filter_idx, &depth);\n+\tif (rc != 0)\n+\t\tgoto fail3;\n+\n+\tEFSYS_ASSERT3U(filter_idx, <, sftp->sft_size);\n+\tsaved_sf_spec = &sftp->sft_spec[filter_idx];\n+\n+\tif (siena_filter_test_used(sftp, filter_idx)) {\n+\t\tif (may_replace == B_FALSE) {\n+\t\t\trc = EEXIST;\n+\t\t\tgoto fail4;\n+\t\t}\n+\t}\n+\tsiena_filter_set_used(sftp, filter_idx);\n+\t*saved_sf_spec = sf_spec;\n+\n+\tif (sfp->sf_depth[sf_spec.sfs_type] < depth) {\n+\t\tsfp->sf_depth[sf_spec.sfs_type] = depth;\n+\t\tif (tbl_id == EFX_SIENA_FILTER_TBL_TX_IP ||\n+\t\t    tbl_id == EFX_SIENA_FILTER_TBL_TX_MAC)\n+\t\t\tsiena_filter_push_tx_limits(enp);\n+\t\telse\n+\t\t\tsiena_filter_push_rx_limits(enp);\n+\t}\n+\n+\tsiena_filter_push_entry(enp, sf_spec.sfs_type,\n+\t    filter_idx, &filter);\n+\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+\n+fail3:\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n+\tEFSYS_PROBE(fail3);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\treturn (rc);\n+}\n+\n+static\t __checkReturn\tefx_rc_t\n+siena_filter_delete(\n+\t__in\t\tefx_nic_t *enp,\n+\t__inout\t\tefx_filter_spec_t *spec)\n+{\n+\tefx_rc_t rc;\n+\tsiena_filter_spec_t sf_spec;\n+\tsiena_filter_t *sfp = enp->en_filter.ef_siena_filter;\n+\tsiena_filter_tbl_id_t tbl_id;\n+\tsiena_filter_tbl_t *sftp;\n+\tefx_oword_t filter;\n+\tint filter_idx;\n+\tunsigned int depth;\n+\tefsys_lock_state_t state;\n+\tuint32_t key;\n+\n+\tEFSYS_ASSERT3P(spec, !=, NULL);\n+\n+\tif ((rc = siena_filter_spec_from_gen_spec(&sf_spec, spec)) != 0)\n+\t\tgoto fail1;\n+\n+\ttbl_id = siena_filter_tbl_id(sf_spec.sfs_type);\n+\tsftp = &sfp->sf_tbl[tbl_id];\n+\n+\tkey = siena_filter_build(&filter, &sf_spec);\n+\n+\tEFSYS_LOCK(enp->en_eslp, state);\n+\n+\trc = siena_filter_search(sftp, &sf_spec, key, B_FALSE,\n+\t    &filter_idx, &depth);\n+\tif (rc != 0)\n+\t\tgoto fail2;\n+\n+\tsiena_filter_clear_entry(enp, sftp, filter_idx);\n+\tif (sftp->sft_used == 0)\n+\t\tsiena_filter_reset_search_depth(sfp, tbl_id);\n+\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_UNLOCK(enp->en_eslp, state);\n+\tEFSYS_PROBE(fail2);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\treturn (rc);\n+}\n+\n+#define\tMAX_SUPPORTED 4\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_filter_supported_filters(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tuint32_t *list,\n+\t__out\t\tsize_t *length)\n+{\n+\tint index = 0;\n+\tuint32_t rx_matches[MAX_SUPPORTED];\n+\tefx_rc_t rc;\n+\n+\tif (list == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\trx_matches[index++] =\n+\t    EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |\n+\t    EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |\n+\t    EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;\n+\n+\trx_matches[index++] =\n+\t    EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |\n+\t    EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT;\n+\n+\tif (enp->en_features & EFX_FEATURE_MAC_HEADER_FILTERS) {\n+\t\trx_matches[index++] =\n+\t\t    EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC;\n+\n+\t\trx_matches[index++] = EFX_FILTER_MATCH_LOC_MAC;\n+\t}\n+\n+\tEFSYS_ASSERT3U(index, <=, MAX_SUPPORTED);\n+\n+\t*length = index;\n+\tmemcpy(list, rx_matches, *length);\n+\n+\treturn (0);\n+\n+fail1:\n+\n+\treturn (rc);\n+}\n+\n+#undef MAX_SUPPORTED\n+\n+#endif /* EFSYS_OPT_SIENA */\n+\n #endif /* EFSYS_OPT_FILTER */\ndiff --git a/drivers/net/sfc/efx/base/efx_impl.h b/drivers/net/sfc/efx/base/efx_impl.h\nindex c6ec808..8d85f3f 100644\n--- a/drivers/net/sfc/efx/base/efx_impl.h\n+++ b/drivers/net/sfc/efx/base/efx_impl.h\n@@ -41,6 +41,10 @@\n #endif\n \n \n+#if EFSYS_OPT_SIENA\n+#include \"siena_impl.h\"\n+#endif\t/* EFSYS_OPT_SIENA */\n+\n #ifdef\t__cplusplus\n extern \"C\" {\n #endif\n@@ -274,9 +278,70 @@ typedef struct efx_nic_ops_s {\n \n #if EFSYS_OPT_FILTER\n \n+#if EFSYS_OPT_SIENA\n+\n+typedef struct siena_filter_spec_s {\n+\tuint8_t\t\tsfs_type;\n+\tuint32_t\tsfs_flags;\n+\tuint32_t\tsfs_dmaq_id;\n+\tuint32_t\tsfs_dword[3];\n+} siena_filter_spec_t;\n+\n+typedef enum siena_filter_type_e {\n+\tEFX_SIENA_FILTER_RX_TCP_FULL,\t/* TCP/IPv4 {dIP,dTCP,sIP,sTCP} */\n+\tEFX_SIENA_FILTER_RX_TCP_WILD,\t/* TCP/IPv4 {dIP,dTCP,  -,   -} */\n+\tEFX_SIENA_FILTER_RX_UDP_FULL,\t/* UDP/IPv4 {dIP,dUDP,sIP,sUDP} */\n+\tEFX_SIENA_FILTER_RX_UDP_WILD,\t/* UDP/IPv4 {dIP,dUDP,  -,   -} */\n+\tEFX_SIENA_FILTER_RX_MAC_FULL,\t/* Ethernet {dMAC,VLAN} */\n+\tEFX_SIENA_FILTER_RX_MAC_WILD,\t/* Ethernet {dMAC,   -} */\n+\n+\tEFX_SIENA_FILTER_TX_TCP_FULL,\t/* TCP/IPv4 {dIP,dTCP,sIP,sTCP} */\n+\tEFX_SIENA_FILTER_TX_TCP_WILD,\t/* TCP/IPv4 {  -,   -,sIP,sTCP} */\n+\tEFX_SIENA_FILTER_TX_UDP_FULL,\t/* UDP/IPv4 {dIP,dTCP,sIP,sTCP} */\n+\tEFX_SIENA_FILTER_TX_UDP_WILD,\t/* UDP/IPv4 {  -,   -,sIP,sUDP} */\n+\tEFX_SIENA_FILTER_TX_MAC_FULL,\t/* Ethernet {sMAC,VLAN} */\n+\tEFX_SIENA_FILTER_TX_MAC_WILD,\t/* Ethernet {sMAC,   -} */\n+\n+\tEFX_SIENA_FILTER_NTYPES\n+} siena_filter_type_t;\n+\n+typedef enum siena_filter_tbl_id_e {\n+\tEFX_SIENA_FILTER_TBL_RX_IP = 0,\n+\tEFX_SIENA_FILTER_TBL_RX_MAC,\n+\tEFX_SIENA_FILTER_TBL_TX_IP,\n+\tEFX_SIENA_FILTER_TBL_TX_MAC,\n+\tEFX_SIENA_FILTER_NTBLS\n+} siena_filter_tbl_id_t;\n+\n+typedef struct siena_filter_tbl_s {\n+\tint\t\t\tsft_size;\t/* number of entries */\n+\tint\t\t\tsft_used;\t/* active count */\n+\tuint32_t\t\t*sft_bitmap;\t/* active bitmap */\n+\tsiena_filter_spec_t\t*sft_spec;\t/* array of saved specs */\n+} siena_filter_tbl_t;\n+\n+typedef struct siena_filter_s {\n+\tsiena_filter_tbl_t\tsf_tbl[EFX_SIENA_FILTER_NTBLS];\n+\tunsigned int\t\tsf_depth[EFX_SIENA_FILTER_NTYPES];\n+} siena_filter_t;\n+\n+#endif\t/* EFSYS_OPT_SIENA */\n+\n typedef struct efx_filter_s {\n+#if EFSYS_OPT_SIENA\n+\tsiena_filter_t\t\t*ef_siena_filter;\n+#endif /* EFSYS_OPT_SIENA */\n } efx_filter_t;\n \n+#if EFSYS_OPT_SIENA\n+\n+extern\t\t\tvoid\n+siena_filter_tbl_clear(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tsiena_filter_tbl_id_t tbl);\n+\n+#endif\t/* EFSYS_OPT_SIENA */\n+\n #endif\t/* EFSYS_OPT_FILTER */\n \n #if EFSYS_OPT_MCDI\n@@ -341,6 +406,11 @@ struct efx_nic_s {\n #endif\t/* EFSYS_OPT_MCDI */\n \tuint32_t\t\ten_vport_id;\n \tunion {\n+#if EFSYS_OPT_SIENA\n+\t\tstruct {\n+\t\t\tint\t\t\tenu_unused;\n+\t\t} siena;\n+#endif\t/* EFSYS_OPT_SIENA */\n \t\tint\tenu_unused;\n \t} en_u;\n };\ndiff --git a/drivers/net/sfc/efx/base/efx_intr.c b/drivers/net/sfc/efx/base/efx_intr.c\nindex fb1812b..ecc09d3 100644\n--- a/drivers/net/sfc/efx/base/efx_intr.c\n+++ b/drivers/net/sfc/efx/base/efx_intr.c\n@@ -32,6 +32,73 @@\n #include \"efx_impl.h\"\n \n \n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_intr_init(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_intr_type_t type,\n+\t__in\t\tefsys_mem_t *esmp);\n+\n+static\t\t\tvoid\n+siena_intr_enable(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t\t\tvoid\n+siena_intr_disable(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t\t\tvoid\n+siena_intr_disable_unlocked(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_intr_trigger(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tunsigned int level);\n+\n+static\t\t\tvoid\n+siena_intr_fini(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t\t\tvoid\n+siena_intr_status_line(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tboolean_t *fatalp,\n+\t__out\t\tuint32_t *qmaskp);\n+\n+static\t\t\tvoid\n+siena_intr_status_message(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tunsigned int message,\n+\t__out\t\tboolean_t *fatalp);\n+\n+static\t\t\tvoid\n+siena_intr_fatal(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t__checkReturn\tboolean_t\n+siena_intr_check_fatal(\n+\t__in\t\tefx_nic_t *enp);\n+\n+\n+#endif /* EFSYS_OPT_SIENA */\n+\n+\n+#if EFSYS_OPT_SIENA\n+static const efx_intr_ops_t\t__efx_intr_siena_ops = {\n+\tsiena_intr_init,\t\t/* eio_init */\n+\tsiena_intr_enable,\t\t/* eio_enable */\n+\tsiena_intr_disable,\t\t/* eio_disable */\n+\tsiena_intr_disable_unlocked,\t/* eio_disable_unlocked */\n+\tsiena_intr_trigger,\t\t/* eio_trigger */\n+\tsiena_intr_status_line,\t\t/* eio_status_line */\n+\tsiena_intr_status_message,\t/* eio_status_message */\n+\tsiena_intr_fatal,\t\t/* eio_fatal */\n+\tsiena_intr_fini,\t\t/* eio_fini */\n+};\n+#endif\t/* EFSYS_OPT_SIENA */\n+\n \t__checkReturn\tefx_rc_t\n efx_intr_init(\n \t__in\t\tefx_nic_t *enp,\n@@ -57,6 +124,11 @@ efx_intr_init(\n \tenp->en_mod_flags |= EFX_MOD_INTR;\n \n \tswitch (enp->en_family) {\n+#if EFSYS_OPT_SIENA\n+\tcase EFX_FAMILY_SIENA:\n+\t\teiop = &__efx_intr_siena_ops;\n+\t\tbreak;\n+#endif\t/* EFSYS_OPT_SIENA */\n \n \tdefault:\n \t\tEFSYS_ASSERT(B_FALSE);\n@@ -199,3 +271,276 @@ efx_intr_fatal(\n /* ************************************************************************* */\n /* ************************************************************************* */\n \n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_intr_init(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_intr_type_t type,\n+\t__in\t\tefsys_mem_t *esmp)\n+{\n+\tefx_intr_t *eip = &(enp->en_intr);\n+\tefx_oword_t oword;\n+\n+\t/*\n+\t * bug17213 workaround.\n+\t *\n+\t * Under legacy interrupts, don't share a level between fatal\n+\t * interrupts and event queue interrupts. Under MSI-X, they\n+\t * must share, or we won't get an interrupt.\n+\t */\n+\tif (enp->en_family == EFX_FAMILY_SIENA &&\n+\t    eip->ei_type == EFX_INTR_LINE)\n+\t\teip->ei_level = 0x1f;\n+\telse\n+\t\teip->ei_level = 0;\n+\n+\t/* Enable all the genuinely fatal interrupts */\n+\tEFX_SET_OWORD(oword);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);\n+\tif (enp->en_family >= EFX_FAMILY_SIENA)\n+\t\tEFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);\n+\n+\t/* Set up the interrupt address register */\n+\tEFX_POPULATE_OWORD_3(oword,\n+\t    FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,\n+\t    FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,\n+\t    FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);\n+\n+\treturn (0);\n+}\n+\n+static\t\t\tvoid\n+siena_intr_enable(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_intr_t *eip = &(enp->en_intr);\n+\tefx_oword_t oword;\n+\n+\tEFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);\n+\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);\n+}\n+\n+static\t\t\tvoid\n+siena_intr_disable(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_oword_t oword;\n+\n+\tEFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);\n+\n+\tEFSYS_SPIN(10);\n+}\n+\n+static\t\t\tvoid\n+siena_intr_disable_unlocked(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_oword_t oword;\n+\n+\tEFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,\n+\t\t\t&oword, B_FALSE);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);\n+\tEFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,\n+\t    &oword, B_FALSE);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_intr_trigger(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tunsigned int level)\n+{\n+\tefx_intr_t *eip = &(enp->en_intr);\n+\tefx_oword_t oword;\n+\tunsigned int count;\n+\tuint32_t sel;\n+\tefx_rc_t rc;\n+\n+\t/* bug16757: No event queues can be initialized */\n+\tEFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));\n+\n+\tif (level >= EFX_NINTR_SIENA) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))\n+\t\treturn (ENOTSUP); /* avoid EFSYS_PROBE() */\n+\n+\tsel = level;\n+\n+\t/* Trigger a test interrupt */\n+\tEFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);\n+\n+\t/*\n+\t * Wait up to 100ms for the interrupt to be raised before restoring\n+\t * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will\n+\t * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL\n+\t */\n+\tcount = 0;\n+\tdo {\n+\t\tEFSYS_SPIN(100);\t/* 100us */\n+\n+\t\tEFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);\n+\t} while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);\n+\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+static\t__checkReturn\tboolean_t\n+siena_intr_check_fatal(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_intr_t *eip = &(enp->en_intr);\n+\tefsys_mem_t *esmp = eip->ei_esmp;\n+\tefx_oword_t oword;\n+\n+\t/* Read the syndrome */\n+\tEFSYS_MEM_READO(esmp, 0, &oword);\n+\n+\tif (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {\n+\t\tEFSYS_PROBE(fatal);\n+\n+\t\t/* Clear the fatal interrupt condition */\n+\t\tEFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);\n+\t\tEFSYS_MEM_WRITEO(esmp, 0, &oword);\n+\n+\t\treturn (B_TRUE);\n+\t}\n+\n+\treturn (B_FALSE);\n+}\n+\n+static\t\t\tvoid\n+siena_intr_status_line(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tboolean_t *fatalp,\n+\t__out\t\tuint32_t *qmaskp)\n+{\n+\tefx_intr_t *eip = &(enp->en_intr);\n+\tefx_dword_t dword;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);\n+\n+\t/*\n+\t * Read the queue mask and implicitly acknowledge the\n+\t * interrupt.\n+\t */\n+\tEFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);\n+\t*qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);\n+\n+\tEFSYS_PROBE1(qmask, uint32_t, *qmaskp);\n+\n+\tif (*qmaskp & (1U << eip->ei_level))\n+\t\t*fatalp = siena_intr_check_fatal(enp);\n+\telse\n+\t\t*fatalp = B_FALSE;\n+}\n+\n+static\t\t\tvoid\n+siena_intr_status_message(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tunsigned int message,\n+\t__out\t\tboolean_t *fatalp)\n+{\n+\tefx_intr_t *eip = &(enp->en_intr);\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);\n+\n+\tif (message == eip->ei_level)\n+\t\t*fatalp = siena_intr_check_fatal(enp);\n+\telse\n+\t\t*fatalp = B_FALSE;\n+}\n+\n+\n+static\t\tvoid\n+siena_intr_fatal(\n+\t__in\tefx_nic_t *enp)\n+{\n+#if EFSYS_OPT_DECODE_INTR_FATAL\n+\tefx_oword_t fatal;\n+\tefx_oword_t mem_per;\n+\n+\tEFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);\n+\tEFX_ZERO_OWORD(mem_per);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||\n+\t    EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)\n+\t\tEFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,\n+\t\t    EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),\n+\t\t    EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);\n+\n+\tif (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)\n+\t\tEFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,\n+\t\t    EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),\n+\t\t    EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));\n+#else\n+\tEFSYS_ASSERT(0);\n+#endif\n+}\n+\n+static\t\tvoid\n+siena_intr_fini(\n+\t__in\tefx_nic_t *enp)\n+{\n+\tefx_oword_t oword;\n+\n+\t/* Clear the interrupt address register */\n+\tEFX_ZERO_OWORD(oword);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);\n+}\n+\n+#endif /* EFSYS_OPT_SIENA */\ndiff --git a/drivers/net/sfc/efx/base/efx_mac.c b/drivers/net/sfc/efx/base/efx_mac.c\nindex 169dcf1..ce27376 100644\n--- a/drivers/net/sfc/efx/base/efx_mac.c\n+++ b/drivers/net/sfc/efx/base/efx_mac.c\n@@ -31,6 +31,28 @@\n #include \"efx.h\"\n #include \"efx_impl.h\"\n \n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_mac_multicast_list_set(\n+\t__in\t\tefx_nic_t *enp);\n+\n+#endif /* EFSYS_OPT_SIENA */\n+\n+#if EFSYS_OPT_SIENA\n+static const efx_mac_ops_t\t__efx_siena_mac_ops = {\n+\tsiena_mac_poll,\t\t\t\t/* emo_poll */\n+\tsiena_mac_up,\t\t\t\t/* emo_up */\n+\tsiena_mac_reconfigure,\t\t\t/* emo_addr_set */\n+\tsiena_mac_reconfigure,\t\t\t/* emo_pdu_set */\n+\tsiena_mac_pdu_get,\t\t\t/* emo_pdu_get */\n+\tsiena_mac_reconfigure,\t\t\t/* emo_reconfigure */\n+\tsiena_mac_multicast_list_set,\t\t/* emo_multicast_list_set */\n+\tNULL,\t\t\t\t\t/* emo_filter_set_default_rxq */\n+\tNULL,\t\t\t\t/* emo_filter_default_rxq_clear */\n+};\n+#endif\t/* EFSYS_OPT_SIENA */\n+\n \t__checkReturn\t\t\tefx_rc_t\n efx_mac_pdu_set(\n \t__in\t\t\t\tefx_nic_t *enp,\n@@ -465,6 +487,12 @@ efx_mac_select(\n \tint rc = EINVAL;\n \n \tswitch (enp->en_family) {\n+#if EFSYS_OPT_SIENA\n+\tcase EFX_FAMILY_SIENA:\n+\t\temop = &__efx_siena_mac_ops;\n+\t\ttype = EFX_MAC_SIENA;\n+\t\tbreak;\n+#endif /* EFSYS_OPT_SIENA */\n \n \tdefault:\n \t\trc = EINVAL;\n@@ -487,3 +515,72 @@ efx_mac_select(\n }\n \n \n+#if EFSYS_OPT_SIENA\n+\n+#define\tEFX_MAC_HASH_BITS\t(1 << 8)\n+\n+/* Compute the multicast hash as used on Falcon and Siena. */\n+static\tvoid\n+siena_mac_multicast_hash_compute(\n+\t__in_ecount(6*count)\t\tuint8_t const *addrs,\n+\t__in\t\t\t\tint count,\n+\t__out\t\t\t\tefx_oword_t *hash_low,\n+\t__out\t\t\t\tefx_oword_t *hash_high)\n+{\n+\tuint32_t crc, index;\n+\tint i;\n+\n+\tEFSYS_ASSERT(hash_low != NULL);\n+\tEFSYS_ASSERT(hash_high != NULL);\n+\n+\tEFX_ZERO_OWORD(*hash_low);\n+\tEFX_ZERO_OWORD(*hash_high);\n+\n+\tfor (i = 0; i < count; i++) {\n+\t\t/* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */\n+\t\tcrc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);\n+\t\tindex = crc % EFX_MAC_HASH_BITS;\n+\t\tif (index < 128) {\n+\t\t\tEFX_SET_OWORD_BIT(*hash_low, index);\n+\t\t} else {\n+\t\t\tEFX_SET_OWORD_BIT(*hash_high, index - 128);\n+\t\t}\n+\n+\t\taddrs += EFX_MAC_ADDR_LEN;\n+\t}\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_mac_multicast_list_set(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_port_t *epp = &(enp->en_port);\n+\tconst efx_mac_ops_t *emop = epp->ep_emop;\n+\tefx_oword_t old_hash[2];\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);\n+\n+\tmemcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));\n+\n+\tsiena_mac_multicast_hash_compute(\n+\t    epp->ep_mulcst_addr_list,\n+\t    epp->ep_mulcst_addr_count,\n+\t    &epp->ep_multicst_hash[0],\n+\t    &epp->ep_multicst_hash[1]);\n+\n+\tif ((rc = emop->emo_reconfigure(enp)) != 0)\n+\t\tgoto fail1;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\tmemcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));\n+\n+\treturn (rc);\n+}\n+\n+#endif /* EFSYS_OPT_SIENA */\ndiff --git a/drivers/net/sfc/efx/base/efx_mcdi.c b/drivers/net/sfc/efx/base/efx_mcdi.c\nindex 7b82096..7993ebf 100644\n--- a/drivers/net/sfc/efx/base/efx_mcdi.c\n+++ b/drivers/net/sfc/efx/base/efx_mcdi.c\n@@ -54,6 +54,23 @@\n \n \n \n+#if EFSYS_OPT_SIENA\n+\n+static const efx_mcdi_ops_t\t__efx_mcdi_siena_ops = {\n+\tsiena_mcdi_init,\t\t/* emco_init */\n+\tsiena_mcdi_send_request,\t/* emco_send_request */\n+\tsiena_mcdi_poll_reboot,\t\t/* emco_poll_reboot */\n+\tsiena_mcdi_poll_response,\t/* emco_poll_response */\n+\tsiena_mcdi_read_response,\t/* emco_read_response */\n+\tsiena_mcdi_fini,\t\t/* emco_fini */\n+\tsiena_mcdi_feature_supported,\t/* emco_feature_supported */\n+\tsiena_mcdi_get_timeout,\t\t/* emco_get_timeout */\n+};\n+\n+#endif\t/* EFSYS_OPT_SIENA */\n+\n+\n+\n \t__checkReturn\tefx_rc_t\n efx_mcdi_init(\n \t__in\t\tefx_nic_t *enp,\n@@ -66,6 +83,11 @@ efx_mcdi_init(\n \tEFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);\n \n \tswitch (enp->en_family) {\n+#if EFSYS_OPT_SIENA\n+\tcase EFX_FAMILY_SIENA:\n+\t\temcop = &__efx_mcdi_siena_ops;\n+\t\tbreak;\n+#endif\t/* EFSYS_OPT_SIENA */\n \n \tdefault:\n \t\tEFSYS_ASSERT(0);\ndiff --git a/drivers/net/sfc/efx/base/efx_nic.c b/drivers/net/sfc/efx/base/efx_nic.c\nindex 16c146b..f94ff49 100644\n--- a/drivers/net/sfc/efx/base/efx_nic.c\n+++ b/drivers/net/sfc/efx/base/efx_nic.c\n@@ -39,6 +39,20 @@ efx_family(\n {\n \tif (venid == EFX_PCI_VENID_SFC) {\n \t\tswitch (devid) {\n+#if EFSYS_OPT_SIENA\n+\t\tcase EFX_PCI_DEVID_SIENA_F1_UNINIT:\n+\t\t\t/*\n+\t\t\t * Hardware default for PF0 of uninitialised Siena.\n+\t\t\t * manftest must be able to cope with this device id.\n+\t\t\t */\n+\t\t\t*efp = EFX_FAMILY_SIENA;\n+\t\t\treturn (0);\n+\n+\t\tcase EFX_PCI_DEVID_BETHPAGE:\n+\t\tcase EFX_PCI_DEVID_SIENA:\n+\t\t\t*efp = EFX_FAMILY_SIENA;\n+\t\t\treturn (0);\n+#endif /* EFSYS_OPT_SIENA */\n \n \t\tcase EFX_PCI_DEVID_FALCON:\t/* Obsolete, not supported */\n \t\tdefault:\n@@ -122,6 +136,22 @@ efx_nic_biu_test(\n \treturn (rc);\n }\n \n+#if EFSYS_OPT_SIENA\n+\n+static const efx_nic_ops_t\t__efx_nic_siena_ops = {\n+\tsiena_nic_probe,\t\t/* eno_probe */\n+\tNULL,\t\t\t\t/* eno_board_cfg */\n+\tNULL,\t\t\t\t/* eno_set_drv_limits */\n+\tsiena_nic_reset,\t\t/* eno_reset */\n+\tsiena_nic_init,\t\t\t/* eno_init */\n+\tNULL,\t\t\t\t/* eno_get_vi_pool */\n+\tNULL,\t\t\t\t/* eno_get_bar_region */\n+\tsiena_nic_fini,\t\t\t/* eno_fini */\n+\tsiena_nic_unprobe,\t\t/* eno_unprobe */\n+};\n+\n+#endif\t/* EFSYS_OPT_SIENA */\n+\n \n \t__checkReturn\tefx_rc_t\n efx_nic_create(\n@@ -148,6 +178,20 @@ efx_nic_create(\n \tenp->en_magic = EFX_NIC_MAGIC;\n \n \tswitch (family) {\n+#if EFSYS_OPT_SIENA\n+\tcase EFX_FAMILY_SIENA:\n+\t\tenp->en_enop = &__efx_nic_siena_ops;\n+\t\tenp->en_features =\n+\t\t    EFX_FEATURE_IPV6 |\n+\t\t    EFX_FEATURE_LFSR_HASH_INSERT |\n+\t\t    EFX_FEATURE_LINK_EVENTS |\n+\t\t    EFX_FEATURE_PERIODIC_MAC_STATS |\n+\t\t    EFX_FEATURE_MCDI |\n+\t\t    EFX_FEATURE_LOOKAHEAD_SPLIT |\n+\t\t    EFX_FEATURE_MAC_HEADER_FILTERS |\n+\t\t    EFX_FEATURE_TX_SRC_FILTERS;\n+\t\tbreak;\n+#endif\t/* EFSYS_OPT_SIENA */\n \n \tdefault:\n \t\trc = ENOTSUP;\ndiff --git a/drivers/net/sfc/efx/base/efx_phy.c b/drivers/net/sfc/efx/base/efx_phy.c\nindex 7b9a330..a6a2af4 100644\n--- a/drivers/net/sfc/efx/base/efx_phy.c\n+++ b/drivers/net/sfc/efx/base/efx_phy.c\n@@ -32,6 +32,16 @@\n #include \"efx_impl.h\"\n \n \n+#if EFSYS_OPT_SIENA\n+static const efx_phy_ops_t\t__efx_phy_siena_ops = {\n+\tsiena_phy_power,\t\t/* epo_power */\n+\tNULL,\t\t\t\t/* epo_reset */\n+\tsiena_phy_reconfigure,\t\t/* epo_reconfigure */\n+\tsiena_phy_verify,\t\t/* epo_verify */\n+\tsiena_phy_oui_get,\t\t/* epo_oui_get */\n+};\n+#endif\t/* EFSYS_OPT_SIENA */\n+\n \t__checkReturn\tefx_rc_t\n efx_phy_probe(\n \t__in\t\tefx_nic_t *enp)\n@@ -48,6 +58,11 @@ efx_phy_probe(\n \n \t/* Hook in operations structure */\n \tswitch (enp->en_family) {\n+#if EFSYS_OPT_SIENA\n+\tcase EFX_FAMILY_SIENA:\n+\t\tepop = &__efx_phy_siena_ops;\n+\t\tbreak;\n+#endif\t/* EFSYS_OPT_SIENA */\n \tdefault:\n \t\trc = ENOTSUP;\n \t\tgoto fail1;\ndiff --git a/drivers/net/sfc/efx/base/efx_rx.c b/drivers/net/sfc/efx/base/efx_rx.c\nindex 4129e09..97da63d 100644\n--- a/drivers/net/sfc/efx/base/efx_rx.c\n+++ b/drivers/net/sfc/efx/base/efx_rx.c\n@@ -32,6 +32,79 @@\n #include \"efx_impl.h\"\n \n \n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_init(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t\t\tvoid\n+siena_rx_fini(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_prefix_pktlen(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tuint8_t *buffer,\n+\t__out\t\tuint16_t *lengthp);\n+\n+static\t\t\tvoid\n+siena_rx_qpost(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in_ecount(n)\tefsys_dma_addr_t *addrp,\n+\t__in\t\tsize_t size,\n+\t__in\t\tunsigned int n,\n+\t__in\t\tunsigned int completed,\n+\t__in\t\tunsigned int added);\n+\n+static\t\t\tvoid\n+siena_rx_qpush(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in\t\tunsigned int added,\n+\t__inout\t\tunsigned int *pushedp);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_qflush(\n+\t__in\t\tefx_rxq_t *erp);\n+\n+static\t\t\tvoid\n+siena_rx_qenable(\n+\t__in\t\tefx_rxq_t *erp);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_qcreate(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tunsigned int index,\n+\t__in\t\tunsigned int label,\n+\t__in\t\tefx_rxq_type_t type,\n+\t__in\t\tefsys_mem_t *esmp,\n+\t__in\t\tsize_t n,\n+\t__in\t\tuint32_t id,\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_rxq_t *erp);\n+\n+static\t\t\tvoid\n+siena_rx_qdestroy(\n+\t__in\t\tefx_rxq_t *erp);\n+\n+#endif /* EFSYS_OPT_SIENA */\n+\n+\n+#if EFSYS_OPT_SIENA\n+static const efx_rx_ops_t __efx_rx_siena_ops = {\n+\tsiena_rx_init,\t\t\t\t/* erxo_init */\n+\tsiena_rx_fini,\t\t\t\t/* erxo_fini */\n+\tsiena_rx_prefix_pktlen,\t\t\t/* erxo_prefix_pktlen */\n+\tsiena_rx_qpost,\t\t\t\t/* erxo_qpost */\n+\tsiena_rx_qpush,\t\t\t\t/* erxo_qpush */\n+\tsiena_rx_qflush,\t\t\t/* erxo_qflush */\n+\tsiena_rx_qenable,\t\t\t/* erxo_qenable */\n+\tsiena_rx_qcreate,\t\t\t/* erxo_qcreate */\n+\tsiena_rx_qdestroy,\t\t\t/* erxo_qdestroy */\n+};\n+#endif\t/* EFSYS_OPT_SIENA */\n+\n+\n \t__checkReturn\tefx_rc_t\n efx_rx_init(\n \t__inout\t\tefx_nic_t *enp)\n@@ -53,6 +126,11 @@ efx_rx_init(\n \t}\n \n \tswitch (enp->en_family) {\n+#if EFSYS_OPT_SIENA\n+\tcase EFX_FAMILY_SIENA:\n+\t\terxop = &__efx_rx_siena_ops;\n+\t\tbreak;\n+#endif /* EFSYS_OPT_SIENA */\n \n \tdefault:\n \t\tEFSYS_ASSERT(0);\n@@ -240,3 +318,342 @@ efx_psuedo_hdr_pkt_length_get(\n \treturn (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));\n }\n \n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_init(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_oword_t oword;\n+\tunsigned int index;\n+\n+\tEFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);\n+\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_DESC_PUSH_EN, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, 0x3000 / 32);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);\n+\n+\t/* Zero the RSS table */\n+\tfor (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS;\n+\t    index++) {\n+\t\tEFX_ZERO_OWORD(oword);\n+\t\tEFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,\n+\t\t\t\t    index, &oword, B_TRUE);\n+\t}\n+\n+\treturn (0);\n+}\n+\n+\n+#define\tEFX_RX_LFSR_HASH(_enp, _insert)\t\t\t\t\t\\\n+\tdo {\t\t\t\t\t\t\t\t\\\n+\t\tefx_oword_t oword;\t\t\t\t\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\tEFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword);\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR,\t\\\n+\t\t    (_insert) ? 1 : 0);\t\t\t\t\t\\\n+\t\tEFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword);\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\tif ((_enp)->en_family == EFX_FAMILY_SIENA) {\t\t\\\n+\t\t\tEFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3,\t\\\n+\t\t\t    &oword);\t\t\t\t\t\\\n+\t\t\tEFX_SET_OWORD_FIELD(oword,\t\t\t\\\n+\t\t\t    FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 0);\t\\\n+\t\t\tEFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3,\t\\\n+\t\t\t    &oword);\t\t\t\t\t\\\n+\t\t}\t\t\t\t\t\t\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\t_NOTE(CONSTANTCONDITION)\t\t\t\t\\\n+\t} while (B_FALSE)\n+\n+#define\tEFX_RX_TOEPLITZ_IPV4_HASH(_enp, _insert, _ip, _tcp)\t\t\\\n+\tdo {\t\t\t\t\t\t\t\t\\\n+\t\tefx_oword_t oword;\t\t\t\t\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\tEFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG,\t&oword);\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 1);\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH,\t\t\\\n+\t\t    (_ip) ? 1 : 0);\t\t\t\t\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP,\t\t\\\n+\t\t    (_tcp) ? 0 : 1);\t\t\t\t\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR,\t\\\n+\t\t    (_insert) ? 1 : 0);\t\t\t\t\t\\\n+\t\tEFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword);\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\t_NOTE(CONSTANTCONDITION)\t\t\t\t\\\n+\t} while (B_FALSE)\n+\n+#define\tEFX_RX_TOEPLITZ_IPV6_HASH(_enp, _ip, _tcp, _rc)\t\t\t\\\n+\tdo {\t\t\t\t\t\t\t\t\\\n+\t\tefx_oword_t oword;\t\t\t\t\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\tEFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword);\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword,\t\t\t\t\\\n+\t\t    FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1);\t\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword,\t\t\t\t\\\n+\t\t    FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, (_ip) ? 1 : 0);\t\\\n+\t\tEFX_SET_OWORD_FIELD(oword,\t\t\t\t\\\n+\t\t    FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS, (_tcp) ? 0 : 1);\t\\\n+\t\tEFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword);\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\t(_rc) = 0;\t\t\t\t\t\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\t_NOTE(CONSTANTCONDITION)\t\t\t\t\\\n+\t} while (B_FALSE)\n+\n+\n+/*\n+ * Falcon/Siena psuedo-header\n+ * --------------------------\n+ *\n+ * Receive packets are prefixed by an optional 16 byte pseudo-header.\n+ * The psuedo-header is a byte array of one of the forms:\n+ *\n+ *  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15\n+ * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.TT.TT.TT.TT\n+ * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.LL.LL\n+ *\n+ * where:\n+ *   TT.TT.TT.TT   Toeplitz hash (32-bit big-endian)\n+ *   LL.LL         LFSR hash     (16-bit big-endian)\n+ */\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_prefix_pktlen(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tuint8_t *buffer,\n+\t__out\t\tuint16_t *lengthp)\n+{\n+\t_NOTE(ARGUNUSED(enp, buffer, lengthp))\n+\n+\t/* Not supported by Falcon/Siena hardware */\n+\tEFSYS_ASSERT(0);\n+\treturn (ENOTSUP);\n+}\n+\n+\n+static\t\t\tvoid\n+siena_rx_qpost(\n+\t__in\t\tefx_rxq_t *erp,\n+\t__in_ecount(n)\tefsys_dma_addr_t *addrp,\n+\t__in\t\tsize_t size,\n+\t__in\t\tunsigned int n,\n+\t__in\t\tunsigned int completed,\n+\t__in\t\tunsigned int added)\n+{\n+\tefx_qword_t qword;\n+\tunsigned int i;\n+\tunsigned int offset;\n+\tunsigned int id;\n+\n+\t/* The client driver must not overfill the queue */\n+\tEFSYS_ASSERT3U(added - completed + n, <=,\n+\t    EFX_RXQ_LIMIT(erp->er_mask + 1));\n+\n+\tid = added & (erp->er_mask);\n+\tfor (i = 0; i < n; i++) {\n+\t\tEFSYS_PROBE4(rx_post, unsigned int, erp->er_index,\n+\t\t    unsigned int, id, efsys_dma_addr_t, addrp[i],\n+\t\t    size_t, size);\n+\n+\t\tEFX_POPULATE_QWORD_3(qword,\n+\t\t    FSF_AZ_RX_KER_BUF_SIZE, (uint32_t)(size),\n+\t\t    FSF_AZ_RX_KER_BUF_ADDR_DW0,\n+\t\t    (uint32_t)(addrp[i] & 0xffffffff),\n+\t\t    FSF_AZ_RX_KER_BUF_ADDR_DW1,\n+\t\t    (uint32_t)(addrp[i] >> 32));\n+\n+\t\toffset = id * sizeof (efx_qword_t);\n+\t\tEFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword);\n+\n+\t\tid = (id + 1) & (erp->er_mask);\n+\t}\n+}\n+\n+static\t\t\tvoid\n+siena_rx_qpush(\n+\t__in\tefx_rxq_t *erp,\n+\t__in\tunsigned int added,\n+\t__inout\tunsigned int *pushedp)\n+{\n+\tefx_nic_t *enp = erp->er_enp;\n+\tunsigned int pushed = *pushedp;\n+\tuint32_t wptr;\n+\tefx_oword_t oword;\n+\tefx_dword_t dword;\n+\n+\t/* All descriptors are pushed */\n+\t*pushedp = added;\n+\n+\t/* Push the populated descriptors out */\n+\twptr = added & erp->er_mask;\n+\n+\tEFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DESC_WPTR, wptr);\n+\n+\t/* Only write the third DWORD */\n+\tEFX_POPULATE_DWORD_1(dword,\n+\t    EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));\n+\n+\t/* Guarantee ordering of memory (descriptors) and PIO (doorbell) */\n+\tEFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,\n+\t    wptr, pushed & erp->er_mask);\n+\tEFSYS_PIO_WRITE_BARRIER();\n+\tEFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0,\n+\t\t\t    erp->er_index, &dword, B_FALSE);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_qflush(\n+\t__in\tefx_rxq_t *erp)\n+{\n+\tefx_nic_t *enp = erp->er_enp;\n+\tefx_oword_t oword;\n+\tuint32_t label;\n+\n+\tlabel = erp->er_index;\n+\n+\t/* Flush the queue */\n+\tEFX_POPULATE_OWORD_2(oword, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,\n+\t    FRF_AZ_RX_FLUSH_DESCQ, label);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_RX_FLUSH_DESCQ_REG, &oword);\n+\n+\treturn (0);\n+}\n+\n+static\t\tvoid\n+siena_rx_qenable(\n+\t__in\tefx_rxq_t *erp)\n+{\n+\tefx_nic_t *enp = erp->er_enp;\n+\tefx_oword_t oword;\n+\n+\tEFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);\n+\n+\tEFX_BAR_TBL_READO(enp, FR_AZ_RX_DESC_PTR_TBL,\n+\t\t\t    erp->er_index, &oword, B_TRUE);\n+\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DC_HW_RPTR, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_HW_RPTR, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_EN, 1);\n+\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,\n+\t\t\t    erp->er_index, &oword, B_TRUE);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_rx_qcreate(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tunsigned int index,\n+\t__in\t\tunsigned int label,\n+\t__in\t\tefx_rxq_type_t type,\n+\t__in\t\tefsys_mem_t *esmp,\n+\t__in\t\tsize_t n,\n+\t__in\t\tuint32_t id,\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_rxq_t *erp)\n+{\n+\tefx_nic_cfg_t *encp = &(enp->en_nic_cfg);\n+\tefx_oword_t oword;\n+\tuint32_t size;\n+\tboolean_t jumbo;\n+\tefx_rc_t rc;\n+\n+\t_NOTE(ARGUNUSED(esmp))\n+\n+\tEFX_STATIC_ASSERT(EFX_EV_RX_NLABELS ==\n+\t    (1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH));\n+\tEFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);\n+\tEFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);\n+\n+\tEFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));\n+\tEFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));\n+\n+\tif (!ISP2(n) || (n < EFX_RXQ_MINNDESCS) || (n > EFX_RXQ_MAXNDESCS)) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\tif (index >= encp->enc_rxq_limit) {\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\tfor (size = 0; (1 << size) <= (EFX_RXQ_MAXNDESCS / EFX_RXQ_MINNDESCS);\n+\t    size++)\n+\t\tif ((1 << size) == (int)(n / EFX_RXQ_MINNDESCS))\n+\t\t\tbreak;\n+\tif (id + (1 << size) >= encp->enc_buftbl_limit) {\n+\t\trc = EINVAL;\n+\t\tgoto fail3;\n+\t}\n+\n+\tswitch (type) {\n+\tcase EFX_RXQ_TYPE_DEFAULT:\n+\t\tjumbo = B_FALSE;\n+\t\tbreak;\n+\n+\tdefault:\n+\t\trc = EINVAL;\n+\t\tgoto fail4;\n+\t}\n+\n+\t/* Set up the new descriptor queue */\n+\tEFX_POPULATE_OWORD_7(oword,\n+\t    FRF_AZ_RX_DESCQ_BUF_BASE_ID, id,\n+\t    FRF_AZ_RX_DESCQ_EVQ_ID, eep->ee_index,\n+\t    FRF_AZ_RX_DESCQ_OWNER_ID, 0,\n+\t    FRF_AZ_RX_DESCQ_LABEL, label,\n+\t    FRF_AZ_RX_DESCQ_SIZE, size,\n+\t    FRF_AZ_RX_DESCQ_TYPE, 0,\n+\t    FRF_AZ_RX_DESCQ_JUMBO, jumbo);\n+\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,\n+\t\t\t    erp->er_index, &oword, B_TRUE);\n+\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+static\t\tvoid\n+siena_rx_qdestroy(\n+\t__in\tefx_rxq_t *erp)\n+{\n+\tefx_nic_t *enp = erp->er_enp;\n+\tefx_oword_t oword;\n+\n+\tEFSYS_ASSERT(enp->en_rx_qcount != 0);\n+\t--enp->en_rx_qcount;\n+\n+\t/* Purge descriptor queue */\n+\tEFX_ZERO_OWORD(oword);\n+\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,\n+\t\t\t    erp->er_index, &oword, B_TRUE);\n+\n+\t/* Free the RXQ object */\n+\tEFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);\n+}\n+\n+static\t\tvoid\n+siena_rx_fini(\n+\t__in\tefx_nic_t *enp)\n+{\n+\t_NOTE(ARGUNUSED(enp))\n+}\n+\n+#endif /* EFSYS_OPT_SIENA */\ndiff --git a/drivers/net/sfc/efx/base/efx_tx.c b/drivers/net/sfc/efx/base/efx_tx.c\nindex 4f0099f..7333f0a 100644\n--- a/drivers/net/sfc/efx/base/efx_tx.c\n+++ b/drivers/net/sfc/efx/base/efx_tx.c\n@@ -33,6 +33,101 @@\n \n #define\tEFX_TX_QSTAT_INCR(_etp, _stat)\n \n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_tx_init(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t\t\tvoid\n+siena_tx_fini(\n+\t__in\t\tefx_nic_t *enp);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_tx_qcreate(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tunsigned int index,\n+\t__in\t\tunsigned int label,\n+\t__in\t\tefsys_mem_t *esmp,\n+\t__in\t\tsize_t n,\n+\t__in\t\tuint32_t id,\n+\t__in\t\tuint16_t flags,\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_txq_t *etp,\n+\t__out\t\tunsigned int *addedp);\n+\n+static\t\tvoid\n+siena_tx_qdestroy(\n+\t__in\tefx_txq_t *etp);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_tx_qpost(\n+\t__in\t\tefx_txq_t *etp,\n+\t__in_ecount(n)\tefx_buffer_t *eb,\n+\t__in\t\tunsigned int n,\n+\t__in\t\tunsigned int completed,\n+\t__inout\t\tunsigned int *addedp);\n+\n+static\t\t\tvoid\n+siena_tx_qpush(\n+\t__in\tefx_txq_t *etp,\n+\t__in\tunsigned int added,\n+\t__in\tunsigned int pushed);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_tx_qpace(\n+\t__in\t\tefx_txq_t *etp,\n+\t__in\t\tunsigned int ns);\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_tx_qflush(\n+\t__in\t\tefx_txq_t *etp);\n+\n+static\t\t\tvoid\n+siena_tx_qenable(\n+\t__in\tefx_txq_t *etp);\n+\n+\t__checkReturn\tefx_rc_t\n+siena_tx_qdesc_post(\n+\t__in\t\tefx_txq_t *etp,\n+\t__in_ecount(n)\tefx_desc_t *ed,\n+\t__in\t\tunsigned int n,\n+\t__in\t\tunsigned int completed,\n+\t__inout\t\tunsigned int *addedp);\n+\n+\tvoid\n+siena_tx_qdesc_dma_create(\n+\t__in\tefx_txq_t *etp,\n+\t__in\tefsys_dma_addr_t addr,\n+\t__in\tsize_t size,\n+\t__in\tboolean_t eop,\n+\t__out\tefx_desc_t *edp);\n+\n+#endif /* EFSYS_OPT_SIENA */\n+\n+\n+#if EFSYS_OPT_SIENA\n+static const efx_tx_ops_t\t__efx_tx_siena_ops = {\n+\tsiena_tx_init,\t\t\t\t/* etxo_init */\n+\tsiena_tx_fini,\t\t\t\t/* etxo_fini */\n+\tsiena_tx_qcreate,\t\t\t/* etxo_qcreate */\n+\tsiena_tx_qdestroy,\t\t\t/* etxo_qdestroy */\n+\tsiena_tx_qpost,\t\t\t\t/* etxo_qpost */\n+\tsiena_tx_qpush,\t\t\t\t/* etxo_qpush */\n+\tsiena_tx_qpace,\t\t\t\t/* etxo_qpace */\n+\tsiena_tx_qflush,\t\t\t/* etxo_qflush */\n+\tsiena_tx_qenable,\t\t\t/* etxo_qenable */\n+\tNULL,\t\t\t\t\t/* etxo_qpio_enable */\n+\tNULL,\t\t\t\t\t/* etxo_qpio_disable */\n+\tNULL,\t\t\t\t\t/* etxo_qpio_write */\n+\tNULL,\t\t\t\t\t/* etxo_qpio_post */\n+\tsiena_tx_qdesc_post,\t\t\t/* etxo_qdesc_post */\n+\tsiena_tx_qdesc_dma_create,\t\t/* etxo_qdesc_dma_create */\n+\tNULL,\t\t\t\t\t/* etxo_qdesc_tso_create */\n+\tNULL,\t\t\t\t\t/* etxo_qdesc_tso2_create */\n+\tNULL,\t\t\t\t\t/* etxo_qdesc_vlantci_create */\n+};\n+#endif /* EFSYS_OPT_SIENA */\n \n \t__checkReturn\tefx_rc_t\n efx_tx_init(\n@@ -55,6 +150,11 @@ efx_tx_init(\n \t}\n \n \tswitch (enp->en_family) {\n+#if EFSYS_OPT_SIENA\n+\tcase EFX_FAMILY_SIENA:\n+\t\tetxop = &__efx_tx_siena_ops;\n+\t\tbreak;\n+#endif /* EFSYS_OPT_SIENA */\n \n \tdefault:\n \t\tEFSYS_ASSERT(0);\n@@ -461,3 +561,391 @@ efx_tx_qdesc_vlantci_create(\n }\n \n \n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_tx_init(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_oword_t oword;\n+\n+\t/*\n+\t * Disable the timer-based TX DMA backoff and allow TX DMA to be\n+\t * controlled by the RX FIFO fill level (although always allow a\n+\t * minimal trickle).\n+\t */\n+\tEFX_BAR_READO(enp, FR_AZ_TX_RESERVED_REG, &oword);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER, 0xfe);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER_EN, 1);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_ONE_PKT_PER_Q, 1);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PUSH_EN, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DIS_NON_IP_EV, 1);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_THRESHOLD, 2);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff);\n+\n+\t/*\n+\t * Filter all packets less than 14 bytes to avoid parsing\n+\t * errors.\n+\t */\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_TX_RESERVED_REG, &oword);\n+\n+\t/*\n+\t * Do not set TX_NO_EOP_DISC_EN, since it limits packets to 16\n+\t * descriptors (which is bad).\n+\t */\n+\tEFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);\n+\n+\treturn (0);\n+}\n+\n+#define\tEFX_TX_DESC(_etp, _addr, _size, _eop, _added)\t\t\t\\\n+\tdo {\t\t\t\t\t\t\t\t\\\n+\t\tunsigned int id;\t\t\t\t\t\\\n+\t\tsize_t offset;\t\t\t\t\t\t\\\n+\t\tefx_qword_t qword;\t\t\t\t\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\tid = (_added)++ & (_etp)->et_mask;\t\t\t\\\n+\t\toffset = id * sizeof (efx_qword_t);\t\t\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\tEFSYS_PROBE5(tx_post, unsigned int, (_etp)->et_index,\t\\\n+\t\t    unsigned int, id, efsys_dma_addr_t, (_addr),\t\\\n+\t\t    size_t, (_size), boolean_t, (_eop));\t\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\tEFX_POPULATE_QWORD_4(qword,\t\t\t\t\\\n+\t\t    FSF_AZ_TX_KER_CONT, (_eop) ? 0 : 1,\t\t\t\\\n+\t\t    FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)(_size),\t\\\n+\t\t    FSF_AZ_TX_KER_BUF_ADDR_DW0,\t\t\t\t\\\n+\t\t    (uint32_t)((_addr) & 0xffffffff),\t\t\t\\\n+\t\t    FSF_AZ_TX_KER_BUF_ADDR_DW1,\t\t\t\t\\\n+\t\t    (uint32_t)((_addr) >> 32));\t\t\t\t\\\n+\t\tEFSYS_MEM_WRITEQ((_etp)->et_esmp, offset, &qword);\t\\\n+\t\t\t\t\t\t\t\t\t\\\n+\t\t_NOTE(CONSTANTCONDITION)\t\t\t\t\\\n+\t} while (B_FALSE)\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_tx_qpost(\n+\t__in\t\tefx_txq_t *etp,\n+\t__in_ecount(n)\tefx_buffer_t *eb,\n+\t__in\t\tunsigned int n,\n+\t__in\t\tunsigned int completed,\n+\t__inout\t\tunsigned int *addedp)\n+{\n+\tunsigned int added = *addedp;\n+\tunsigned int i;\n+\tint rc = ENOSPC;\n+\n+\tif (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1))\n+\t\tgoto fail1;\n+\n+\tfor (i = 0; i < n; i++) {\n+\t\tefx_buffer_t *ebp = &eb[i];\n+\t\tefsys_dma_addr_t start = ebp->eb_addr;\n+\t\tsize_t size = ebp->eb_size;\n+\t\tefsys_dma_addr_t end = start + size;\n+\n+\t\t/* Fragments must not span 4k boundaries. */\n+\t\tEFSYS_ASSERT(P2ROUNDUP(start + 1, 4096) >= end);\n+\n+\t\tEFX_TX_DESC(etp, start, size, ebp->eb_eop, added);\n+\t}\n+\n+\tEFX_TX_QSTAT_INCR(etp, TX_POST);\n+\n+\t*addedp = added;\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+static\t\tvoid\n+siena_tx_qpush(\n+\t__in\tefx_txq_t *etp,\n+\t__in\tunsigned int added,\n+\t__in\tunsigned int pushed)\n+{\n+\tefx_nic_t *enp = etp->et_enp;\n+\tuint32_t wptr;\n+\tefx_dword_t dword;\n+\tefx_oword_t oword;\n+\n+\t/* Push the populated descriptors out */\n+\twptr = added & etp->et_mask;\n+\n+\tEFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DESC_WPTR, wptr);\n+\n+\t/* Only write the third DWORD */\n+\tEFX_POPULATE_DWORD_1(dword,\n+\t    EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));\n+\n+\t/* Guarantee ordering of memory (descriptors) and PIO (doorbell) */\n+\tEFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,\n+\t    wptr, pushed & etp->et_mask);\n+\tEFSYS_PIO_WRITE_BARRIER();\n+\tEFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0,\n+\t\t\t    etp->et_index, &dword, B_FALSE);\n+}\n+\n+#define\tEFX_MAX_PACE_VALUE 20\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_tx_qpace(\n+\t__in\t\tefx_txq_t *etp,\n+\t__in\t\tunsigned int ns)\n+{\n+\tefx_nic_t *enp = etp->et_enp;\n+\tefx_nic_cfg_t *encp = &(enp->en_nic_cfg);\n+\tefx_oword_t oword;\n+\tunsigned int pace_val;\n+\tunsigned int timer_period;\n+\tefx_rc_t rc;\n+\n+\tif (ns == 0) {\n+\t\tpace_val = 0;\n+\t} else {\n+\t\t/*\n+\t\t * The pace_val to write into the table is s.t\n+\t\t * ns <= timer_period * (2 ^ pace_val)\n+\t\t */\n+\t\ttimer_period = 104 / encp->enc_clk_mult;\n+\t\tfor (pace_val = 1; pace_val <= EFX_MAX_PACE_VALUE; pace_val++) {\n+\t\t\tif ((timer_period << pace_val) >= ns)\n+\t\t\t\tbreak;\n+\t\t}\n+\t}\n+\tif (pace_val > EFX_MAX_PACE_VALUE) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\t/* Update the pacing table */\n+\tEFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index,\n+\t    &oword, B_TRUE);\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_tx_qflush(\n+\t__in\t\tefx_txq_t *etp)\n+{\n+\tefx_nic_t *enp = etp->et_enp;\n+\tefx_oword_t oword;\n+\tuint32_t label;\n+\n+\tefx_tx_qpace(etp, 0);\n+\n+\tlabel = etp->et_index;\n+\n+\t/* Flush the queue */\n+\tEFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,\n+\t    FRF_AZ_TX_FLUSH_DESCQ, label);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword);\n+\n+\treturn (0);\n+}\n+\n+static\t\tvoid\n+siena_tx_qenable(\n+\t__in\tefx_txq_t *etp)\n+{\n+\tefx_nic_t *enp = etp->et_enp;\n+\tefx_oword_t oword;\n+\n+\tEFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL,\n+\t\t\t    etp->et_index, &oword, B_TRUE);\n+\n+\tEFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index,\n+\t    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3),\n+\t    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_2),\n+\t    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_1),\n+\t    uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_0));\n+\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DC_HW_RPTR, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_HW_RPTR, 0);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1);\n+\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,\n+\t\t\t    etp->et_index, &oword, B_TRUE);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_tx_qcreate(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tunsigned int index,\n+\t__in\t\tunsigned int label,\n+\t__in\t\tefsys_mem_t *esmp,\n+\t__in\t\tsize_t n,\n+\t__in\t\tuint32_t id,\n+\t__in\t\tuint16_t flags,\n+\t__in\t\tefx_evq_t *eep,\n+\t__in\t\tefx_txq_t *etp,\n+\t__out\t\tunsigned int *addedp)\n+{\n+\tefx_nic_cfg_t *encp = &(enp->en_nic_cfg);\n+\tefx_oword_t oword;\n+\tuint32_t size;\n+\tefx_rc_t rc;\n+\n+\t_NOTE(ARGUNUSED(esmp))\n+\n+\tEFX_STATIC_ASSERT(EFX_EV_TX_NLABELS ==\n+\t    (1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH));\n+\tEFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);\n+\n+\tEFSYS_ASSERT(ISP2(encp->enc_txq_max_ndescs));\n+\tEFX_STATIC_ASSERT(ISP2(EFX_TXQ_MINNDESCS));\n+\n+\tif (!ISP2(n) || (n < EFX_TXQ_MINNDESCS) || (n > EFX_EVQ_MAXNEVS)) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\tif (index >= encp->enc_txq_limit) {\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\tfor (size = 0;\n+\t    (1 << size) <= (int)(encp->enc_txq_max_ndescs / EFX_TXQ_MINNDESCS);\n+\t    size++)\n+\t\tif ((1 << size) == (int)(n / EFX_TXQ_MINNDESCS))\n+\t\t\tbreak;\n+\tif (id + (1 << size) >= encp->enc_buftbl_limit) {\n+\t\trc = EINVAL;\n+\t\tgoto fail3;\n+\t}\n+\n+\t/* Set up the new descriptor queue */\n+\t*addedp = 0;\n+\n+\tEFX_POPULATE_OWORD_6(oword,\n+\t    FRF_AZ_TX_DESCQ_BUF_BASE_ID, id,\n+\t    FRF_AZ_TX_DESCQ_EVQ_ID, eep->ee_index,\n+\t    FRF_AZ_TX_DESCQ_OWNER_ID, 0,\n+\t    FRF_AZ_TX_DESCQ_LABEL, label,\n+\t    FRF_AZ_TX_DESCQ_SIZE, size,\n+\t    FRF_AZ_TX_DESCQ_TYPE, 0);\n+\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_NON_IP_DROP_DIS, 1);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_IP_CHKSM_DIS,\n+\t    (flags & EFX_TXQ_CKSUM_IPV4) ? 0 : 1);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_TCP_CHKSM_DIS,\n+\t    (flags & EFX_TXQ_CKSUM_TCPUDP) ? 0 : 1);\n+\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,\n+\t    etp->et_index, &oword, B_TRUE);\n+\n+\treturn (0);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_tx_qdesc_post(\n+\t__in\t\tefx_txq_t *etp,\n+\t__in_ecount(n)\tefx_desc_t *ed,\n+\t__in\t\tunsigned int n,\n+\t__in\t\tunsigned int completed,\n+\t__inout\t\tunsigned int *addedp)\n+{\n+\tunsigned int added = *addedp;\n+\tunsigned int i;\n+\tefx_rc_t rc;\n+\n+\tif (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail1;\n+\t}\n+\n+\tfor (i = 0; i < n; i++) {\n+\t\tefx_desc_t *edp = &ed[i];\n+\t\tunsigned int id;\n+\t\tsize_t offset;\n+\n+\t\tid = added++ & etp->et_mask;\n+\t\toffset = id * sizeof (efx_desc_t);\n+\n+\t\tEFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);\n+\t}\n+\n+\tEFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,\n+\t\t    unsigned int, added, unsigned int, n);\n+\n+\tEFX_TX_QSTAT_INCR(etp, TX_POST);\n+\n+\t*addedp = added;\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\treturn (rc);\n+}\n+\n+\tvoid\n+siena_tx_qdesc_dma_create(\n+\t__in\tefx_txq_t *etp,\n+\t__in\tefsys_dma_addr_t addr,\n+\t__in\tsize_t size,\n+\t__in\tboolean_t eop,\n+\t__out\tefx_desc_t *edp)\n+{\n+\t/* Fragments must not span 4k boundaries. */\n+\tEFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size);\n+\n+\tEFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,\n+\t\t    efsys_dma_addr_t, addr,\n+\t\t    size_t, size, boolean_t, eop);\n+\n+\tEFX_POPULATE_QWORD_4(edp->ed_eq,\n+\t\t\t    FSF_AZ_TX_KER_CONT, eop ? 0 : 1,\n+\t\t\t    FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)size,\n+\t\t\t    FSF_AZ_TX_KER_BUF_ADDR_DW0,\n+\t\t\t    (uint32_t)(addr & 0xffffffff),\n+\t\t\t    FSF_AZ_TX_KER_BUF_ADDR_DW1,\n+\t\t\t    (uint32_t)(addr >> 32));\n+}\n+\n+#endif /* EFSYS_OPT_SIENA */\n+\n+#if EFSYS_OPT_SIENA\n+\n+static\t\tvoid\n+siena_tx_qdestroy(\n+\t__in\tefx_txq_t *etp)\n+{\n+\tefx_nic_t *enp = etp->et_enp;\n+\tefx_oword_t oword;\n+\n+\t/* Purge descriptor queue */\n+\tEFX_ZERO_OWORD(oword);\n+\n+\tEFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,\n+\t\t\t    etp->et_index, &oword, B_TRUE);\n+}\n+\n+static\t\tvoid\n+siena_tx_fini(\n+\t__in\tefx_nic_t *enp)\n+{\n+\t_NOTE(ARGUNUSED(enp))\n+}\n+\n+#endif /* EFSYS_OPT_SIENA */\ndiff --git a/drivers/net/sfc/efx/base/siena_flash.h b/drivers/net/sfc/efx/base/siena_flash.h\nnew file mode 100644\nindex 0000000..e270055\n--- /dev/null\n+++ b/drivers/net/sfc/efx/base/siena_flash.h\n@@ -0,0 +1,215 @@\n+/*\n+ * Copyright (c) 2007-2016 Solarflare Communications Inc.\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ * 1. Redistributions of source code must retain the above copyright notice,\n+ *    this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright notice,\n+ *    this list of conditions and the following disclaimer in the documentation\n+ *    and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ *\n+ * The views and conclusions contained in the software and documentation are\n+ * those of the authors and should not be interpreted as representing official\n+ * policies, either expressed or implied, of the FreeBSD Project.\n+ */\n+\n+#ifndef\t_SYS_SIENA_FLASH_H\n+#define\t_SYS_SIENA_FLASH_H\n+\n+#pragma pack(1)\n+\n+/* Fixed locations near the start of flash (which may be in the internal PHY\n+ * firmware header) point to the boot header.\n+ *\n+ * - parsed by MC boot ROM and firmware\n+ * - reserved (but not parsed) by PHY firmware\n+ * - opaque to driver\n+ */\n+\n+#define\tSIENA_MC_BOOT_PHY_FW_HDR_LEN (0x20)\n+\n+#define\tSIENA_MC_BOOT_PTR_LOCATION (0x18)      /* First thing we try to boot */\n+#define\tSIENA_MC_BOOT_ALT_PTR_LOCATION (0x1c)  /* Alternative if that fails */\n+\n+#define\tSIENA_MC_BOOT_HDR_LEN (0x200)\n+\n+#define\tSIENA_MC_BOOT_MAGIC (0x51E4A001)\n+#define\tSIENA_MC_BOOT_VERSION (1)\n+\n+\n+/*Structures supporting an arbitrary number of binary blobs in the flash image\n+  intended to house code and tables for the satellite cpus*/\n+/*thanks to random.org for:*/\n+#define\tBLOBS_HEADER_MAGIC (0xBDA3BBD4)\n+#define\tBLOB_HEADER_MAGIC  (0xA1478A91)\n+\n+typedef struct blobs_hdr_s {\t\t\t/* GENERATED BY scripts/genfwdef */\n+\tefx_dword_t\tmagic;\n+\tefx_dword_t\tno_of_blobs;\n+} blobs_hdr_t;\n+\n+typedef struct blob_hdr_s {\t\t\t/* GENERATED BY scripts/genfwdef */\n+\tefx_dword_t\tmagic;\n+\tefx_dword_t\tcpu_type;\n+\tefx_dword_t\tbuild_variant;\n+\tefx_dword_t\toffset;\n+\tefx_dword_t\tlength;\n+\tefx_dword_t\tchecksum;\n+} blob_hdr_t;\n+\n+#define\tBLOB_CPU_TYPE_TXDI_TEXT (0)\n+#define\tBLOB_CPU_TYPE_RXDI_TEXT (1)\n+#define\tBLOB_CPU_TYPE_TXDP_TEXT (2)\n+#define\tBLOB_CPU_TYPE_RXDP_TEXT (3)\n+#define\tBLOB_CPU_TYPE_RXHRSL_HR_LUT (4)\n+#define\tBLOB_CPU_TYPE_RXHRSL_HR_LUT_CFG (5)\n+#define\tBLOB_CPU_TYPE_TXHRSL_HR_LUT (6)\n+#define\tBLOB_CPU_TYPE_TXHRSL_HR_LUT_CFG (7)\n+#define\tBLOB_CPU_TYPE_RXHRSL_HR_PGM  (8)\n+#define\tBLOB_CPU_TYPE_RXHRSL_SL_PGM  (9)\n+#define\tBLOB_CPU_TYPE_TXHRSL_HR_PGM  (10)\n+#define\tBLOB_CPU_TYPE_TXHRSL_SL_PGM  (11)\n+#define\tBLOB_CPU_TYPE_RXDI_VTBL0 (12)\n+#define\tBLOB_CPU_TYPE_TXDI_VTBL0 (13)\n+#define\tBLOB_CPU_TYPE_RXDI_VTBL1 (14)\n+#define\tBLOB_CPU_TYPE_TXDI_VTBL1 (15)\n+#define\tBLOB_CPU_TYPE_DUMPSPEC (32)\n+#define\tBLOB_CPU_TYPE_MC_XIP   (33)\n+\n+#define\tBLOB_CPU_TYPE_INVALID (31)\n+\n+/*\n+ * The upper four bits of the CPU type field specify the compression\n+ * algorithm used for this blob.\n+ */\n+#define\tBLOB_COMPRESSION_MASK (0xf0000000)\n+#define\tBLOB_CPU_TYPE_MASK    (0x0fffffff)\n+\n+#define\tBLOB_COMPRESSION_NONE (0x00000000) /* Stored as is */\n+#define\tBLOB_COMPRESSION_LZ   (0x10000000) /* see lib/lzdecoder.c */\n+\n+typedef struct siena_mc_boot_hdr_s {\t\t/* GENERATED BY scripts/genfwdef */\n+\tefx_dword_t\tmagic;\t\t\t/* = SIENA_MC_BOOT_MAGIC */\n+\tefx_word_t\thdr_version;\t\t/* this structure definition is version 1 */\n+\tefx_byte_t\tboard_type;\n+\tefx_byte_t\tfirmware_version_a;\n+\tefx_byte_t\tfirmware_version_b;\n+\tefx_byte_t\tfirmware_version_c;\n+\tefx_word_t\tchecksum;\t\t/* of whole header area + firmware image */\n+\tefx_word_t\tfirmware_version_d;\n+\tefx_byte_t\tmcfw_subtype;\n+\tefx_byte_t\tgeneration;\t\t/* Valid for medford, SBZ for earlier chips */\n+\tefx_dword_t\tfirmware_text_offset;\t/* offset to firmware .text */\n+\tefx_dword_t\tfirmware_text_size;\t/* length of firmware .text, in bytes */\n+\tefx_dword_t\tfirmware_data_offset;\t/* offset to firmware .data */\n+\tefx_dword_t\tfirmware_data_size;\t/* length of firmware .data, in bytes */\n+\tefx_byte_t\tspi_rate;\t\t/* SPI rate for reading image, 0 is BootROM default */\n+\tefx_byte_t\tspi_phase_adj;\t\t/* SPI SDO/SCL phase adjustment, 0 is default (no adj) */\n+\tefx_word_t\txpm_sector;\t\t/* The sector that contains the key, or 0xffff if unsigned (medford) SBZ (earlier) */\n+\tefx_dword_t\treserved_c[7];\t\t/* (set to 0) */\n+} siena_mc_boot_hdr_t;\n+\n+#define\tSIENA_MC_BOOT_HDR_PADDING \\\n+\t(SIENA_MC_BOOT_HDR_LEN - sizeof(siena_mc_boot_hdr_t))\n+\n+#define\tSIENA_MC_STATIC_CONFIG_MAGIC (0xBDCF5555)\n+#define\tSIENA_MC_STATIC_CONFIG_VERSION (0)\n+\n+typedef struct siena_mc_static_config_hdr_s {\t/* GENERATED BY scripts/genfwdef */\n+\tefx_dword_t\tmagic;\t\t\t/* = SIENA_MC_STATIC_CONFIG_MAGIC */\n+\tefx_word_t\tlength;\t\t\t/* of header area (i.e. not including VPD) */\n+\tefx_byte_t\tversion;\n+\tefx_byte_t\tcsum;\t\t\t/* over header area (i.e. not including VPD) */\n+\tefx_dword_t\tstatic_vpd_offset;\n+\tefx_dword_t\tstatic_vpd_length;\n+\tefx_dword_t\tcapabilities;\n+\tefx_byte_t\tmac_addr_base[6];\n+\tefx_byte_t\tgreen_mode_cal;\t\t/* Green mode calibration result */\n+\tefx_byte_t\tgreen_mode_valid;\t/* Whether cal holds a valid value */\n+\tefx_word_t\tmac_addr_count;\n+\tefx_word_t\tmac_addr_stride;\n+\tefx_word_t\tcalibrated_vref;\t/* Vref as measured during production */\n+\tefx_word_t\tadc_vref;\t\t/* Vref as read by ADC */\n+\tefx_dword_t\treserved2[1];\t\t/* (write as zero) */\n+\tefx_dword_t\tnum_dbi_items;\n+\tstruct {\n+\t\tefx_word_t\taddr;\n+\t\tefx_word_t\tbyte_enables;\n+\t\tefx_dword_t\tvalue;\n+\t} dbi[];\n+} siena_mc_static_config_hdr_t;\n+\n+/* This prefixes a valid XIP partition */\n+#define XIP_PARTITION_MAGIC (0x51DEC0DE)\n+\n+#define\tSIENA_MC_DYNAMIC_CONFIG_MAGIC (0xBDCFDDDD)\n+#define\tSIENA_MC_DYNAMIC_CONFIG_VERSION (0)\n+\n+typedef struct siena_mc_fw_version_s {\t\t/* GENERATED BY scripts/genfwdef */\n+\tefx_dword_t\tfw_subtype;\n+\tefx_word_t\tversion_w;\n+\tefx_word_t\tversion_x;\n+\tefx_word_t\tversion_y;\n+\tefx_word_t\tversion_z;\n+} siena_mc_fw_version_t;\n+\n+typedef struct siena_mc_dynamic_config_hdr_s {\t/* GENERATED BY scripts/genfwdef */\n+\tefx_dword_t\tmagic;\t\t\t/* = SIENA_MC_DYNAMIC_CONFIG_MAGIC */\n+\tefx_word_t\tlength;\t\t\t/* of header area (i.e. not including VPD) */\n+\tefx_byte_t\tversion;\n+\tefx_byte_t\tcsum;\t\t\t/* over header area (i.e. not including VPD) */\n+\tefx_dword_t\tdynamic_vpd_offset;\n+\tefx_dword_t\tdynamic_vpd_length;\n+\tefx_dword_t\tnum_fw_version_items;\n+\tsiena_mc_fw_version_t\tfw_version[];\n+} siena_mc_dynamic_config_hdr_t;\n+\n+#define\tSIENA_MC_EXPROM_SINGLE_MAGIC (0xAA55)  /* little-endian uint16_t */\n+\n+#define\tSIENA_MC_EXPROM_COMBO_MAGIC (0xB0070102)  /* little-endian uint32_t */\n+#define\tSIENA_MC_EXPROM_COMBO_V2_MAGIC (0xB0070103)  /* little-endian uint32_t */\n+\n+typedef struct siena_mc_combo_rom_hdr_s {\t/* GENERATED BY scripts/genfwdef */\n+\tefx_dword_t\tmagic;\t\t\t/* = SIENA_MC_EXPROM_COMBO_MAGIC or SIENA_MC_EXPROM_COMBO_V2_MAGIC */\n+\tunion\t\t{\n+\t\tstruct {\n+\t\t\tefx_dword_t\tlen1;\t/* length of first image */\n+\t\t\tefx_dword_t\tlen2;\t/* length of second image */\n+\t\t\tefx_dword_t\toff1;\t/* offset of first byte to edit to combine images */\n+\t\t\tefx_dword_t\toff2;\t/* offset of second byte to edit to combine images */\n+\t\t\tefx_word_t\tinfoblk0_off;/* infoblk offset */\n+\t\t\tefx_word_t\tinfoblk1_off;/* infoblk offset */\n+\t\t\tefx_byte_t\tinfoblk_len;/* length of space reserved for one infoblk structure */\n+\t\t\tefx_byte_t\treserved[7];/* (set to 0) */\n+\t\t} v1;\n+\t\tstruct {\n+\t\t\tefx_dword_t\tlen1;\t/* length of first image */\n+\t\t\tefx_dword_t\tlen2;\t/* length of second image */\n+\t\t\tefx_dword_t\toff1;\t/* offset of first byte to edit to combine images */\n+\t\t\tefx_dword_t\toff2;\t/* offset of second byte to edit to combine images */\n+\t\t\tefx_word_t\tinfoblk_off;/* infoblk start offset */\n+\t\t\tefx_word_t\tinfoblk_count;/* infoblk count  */\n+\t\t\tefx_byte_t\tinfoblk_len;/* length of space reserved for one infoblk structure */\n+\t\t\tefx_byte_t\treserved[7];/* (set to 0) */\n+\t\t} v2;\n+\t} data;\n+} siena_mc_combo_rom_hdr_t;\n+\n+#pragma pack()\n+\n+#endif\t/* _SYS_SIENA_FLASH_H */\ndiff --git a/drivers/net/sfc/efx/base/siena_impl.h b/drivers/net/sfc/efx/base/siena_impl.h\nnew file mode 100644\nindex 0000000..2c2a098\n--- /dev/null\n+++ b/drivers/net/sfc/efx/base/siena_impl.h\n@@ -0,0 +1,179 @@\n+/*\n+ * Copyright (c) 2009-2016 Solarflare Communications Inc.\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ * 1. Redistributions of source code must retain the above copyright notice,\n+ *    this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright notice,\n+ *    this list of conditions and the following disclaimer in the documentation\n+ *    and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ *\n+ * The views and conclusions contained in the software and documentation are\n+ * those of the authors and should not be interpreted as representing official\n+ * policies, either expressed or implied, of the FreeBSD Project.\n+ */\n+\n+#ifndef _SYS_SIENA_IMPL_H\n+#define\t_SYS_SIENA_IMPL_H\n+\n+#include \"efx.h\"\n+#include \"efx_regs.h\"\n+#include \"efx_mcdi.h\"\n+#include \"siena_flash.h\"\n+\n+#ifdef\t__cplusplus\n+extern \"C\" {\n+#endif\n+\n+#define\tSIENA_NVRAM_CHUNK 0x80\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_nic_probe(\n+\t__in\t\tefx_nic_t *enp);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_nic_reset(\n+\t__in\t\tefx_nic_t *enp);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_nic_init(\n+\t__in\t\tefx_nic_t *enp);\n+\n+extern\t\t\tvoid\n+siena_nic_fini(\n+\t__in\t\tefx_nic_t *enp);\n+\n+extern\t\t\tvoid\n+siena_nic_unprobe(\n+\t__in\t\tefx_nic_t *enp);\n+\n+#define\tSIENA_SRAM_ROWS\t0x12000\n+\n+extern\t\t\tvoid\n+siena_sram_init(\n+\t__in\t\tefx_nic_t *enp);\n+\n+#if EFSYS_OPT_MCDI\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_mcdi_init(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tconst efx_mcdi_transport_t *mtp);\n+\n+extern\t\t\tvoid\n+siena_mcdi_send_request(\n+\t__in\t\t\tefx_nic_t *enp,\n+\t__in_bcount(hdr_len)\tvoid *hdrp,\n+\t__in\t\t\tsize_t hdr_len,\n+\t__in_bcount(sdu_len)\tvoid *sdup,\n+\t__in\t\t\tsize_t sdu_len);\n+\n+extern\t__checkReturn\tboolean_t\n+siena_mcdi_poll_response(\n+\t__in\t\tefx_nic_t *enp);\n+\n+extern\t\t\tvoid\n+siena_mcdi_read_response(\n+\t__in\t\t\tefx_nic_t *enp,\n+\t__out_bcount(length)\tvoid *bufferp,\n+\t__in\t\t\tsize_t offset,\n+\t__in\t\t\tsize_t length);\n+\n+extern\t\t\tefx_rc_t\n+siena_mcdi_poll_reboot(\n+\t__in\t\tefx_nic_t *enp);\n+\n+extern\t\t\tvoid\n+siena_mcdi_fini(\n+\t__in\t\tefx_nic_t *enp);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_mcdi_feature_supported(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_mcdi_feature_id_t id,\n+\t__out\t\tboolean_t *supportedp);\n+\n+extern\t\t\tvoid\n+siena_mcdi_get_timeout(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_mcdi_req_t *emrp,\n+\t__out\t\tuint32_t *timeoutp);\n+\n+#endif /* EFSYS_OPT_MCDI */\n+\n+typedef struct siena_link_state_s {\n+\tuint32_t\t\tsls_adv_cap_mask;\n+\tuint32_t\t\tsls_lp_cap_mask;\n+\tunsigned int\t\tsls_fcntl;\n+\tefx_link_mode_t\t\tsls_link_mode;\n+\tboolean_t\t\tsls_mac_up;\n+} siena_link_state_t;\n+\n+extern\t\t\tvoid\n+siena_phy_link_ev(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_qword_t *eqp,\n+\t__out\t\tefx_link_mode_t *link_modep);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_phy_get_link(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tsiena_link_state_t *slsp);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_phy_power(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tboolean_t on);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_phy_reconfigure(\n+\t__in\t\tefx_nic_t *enp);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_phy_verify(\n+\t__in\t\tefx_nic_t *enp);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_phy_oui_get(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tuint32_t *ouip);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_mac_poll(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tefx_link_mode_t *link_modep);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_mac_up(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tboolean_t *mac_upp);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_mac_reconfigure(\n+\t__in\tefx_nic_t *enp);\n+\n+extern\t__checkReturn\tefx_rc_t\n+siena_mac_pdu_get(\n+\t__in\tefx_nic_t *enp,\n+\t__out\tsize_t *pdu);\n+\n+#ifdef\t__cplusplus\n+}\n+#endif\n+\n+#endif\t/* _SYS_SIENA_IMPL_H */\ndiff --git a/drivers/net/sfc/efx/base/siena_mac.c b/drivers/net/sfc/efx/base/siena_mac.c\nnew file mode 100644\nindex 0000000..71b0a9a\n--- /dev/null\n+++ b/drivers/net/sfc/efx/base/siena_mac.c\n@@ -0,0 +1,205 @@\n+/*\n+ * Copyright (c) 2009-2016 Solarflare Communications Inc.\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ * 1. Redistributions of source code must retain the above copyright notice,\n+ *    this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright notice,\n+ *    this list of conditions and the following disclaimer in the documentation\n+ *    and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ *\n+ * The views and conclusions contained in the software and documentation are\n+ * those of the authors and should not be interpreted as representing official\n+ * policies, either expressed or implied, of the FreeBSD Project.\n+ */\n+\n+#include \"efx.h\"\n+#include \"efx_impl.h\"\n+\n+#if EFSYS_OPT_SIENA\n+\n+\t__checkReturn\tefx_rc_t\n+siena_mac_poll(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tefx_link_mode_t *link_modep)\n+{\n+\tefx_port_t *epp = &(enp->en_port);\n+\tsiena_link_state_t sls;\n+\tefx_rc_t rc;\n+\n+\tif ((rc = siena_phy_get_link(enp, &sls)) != 0)\n+\t\tgoto fail1;\n+\n+\tepp->ep_adv_cap_mask = sls.sls_adv_cap_mask;\n+\tepp->ep_fcntl = sls.sls_fcntl;\n+\n+\t*link_modep = sls.sls_link_mode;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\t*link_modep = EFX_LINK_UNKNOWN;\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_mac_up(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tboolean_t *mac_upp)\n+{\n+\tsiena_link_state_t sls;\n+\tefx_rc_t rc;\n+\n+\t/*\n+\t * Because Siena doesn't *require* polling, we can't rely on\n+\t * siena_mac_poll() being executed to populate epp->ep_mac_up.\n+\t */\n+\tif ((rc = siena_phy_get_link(enp, &sls)) != 0)\n+\t\tgoto fail1;\n+\n+\t*mac_upp = sls.sls_mac_up;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_mac_reconfigure(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_port_t *epp = &(enp->en_port);\n+\tefx_oword_t multicast_hash[2];\n+\tefx_mcdi_req_t req;\n+\tuint8_t payload[MAX(MAX(MC_CMD_SET_MAC_IN_LEN,\n+\t\t\t\tMC_CMD_SET_MAC_OUT_LEN),\n+\t\t\t    MAX(MC_CMD_SET_MCAST_HASH_IN_LEN,\n+\t\t\t\tMC_CMD_SET_MCAST_HASH_OUT_LEN))];\n+\tunsigned int fcntl;\n+\tefx_rc_t rc;\n+\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_SET_MAC;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_SET_MAC_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;\n+\n+\tMCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);\n+\tMCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);\n+\tEFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),\n+\t\t\t    epp->ep_mac_addr);\n+\tMCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,\n+\t\t\t    SET_MAC_IN_REJECT_UNCST, !epp->ep_all_unicst,\n+\t\t\t    SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst);\n+\n+\tif (epp->ep_fcntl_autoneg)\n+\t\t/* efx_fcntl_set() has already set the phy capabilities */\n+\t\tfcntl = MC_CMD_FCNTL_AUTO;\n+\telse if (epp->ep_fcntl & EFX_FCNTL_RESPOND)\n+\t\tfcntl = (epp->ep_fcntl & EFX_FCNTL_GENERATE)\n+\t\t\t? MC_CMD_FCNTL_BIDIR\n+\t\t\t: MC_CMD_FCNTL_RESPOND;\n+\telse\n+\t\tfcntl = MC_CMD_FCNTL_OFF;\n+\n+\tMCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, fcntl);\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail1;\n+\t}\n+\n+\t/* Push multicast hash */\n+\n+\tif (epp->ep_all_mulcst) {\n+\t\t/* A hash matching all multicast is all 1s */\n+\t\tEFX_SET_OWORD(multicast_hash[0]);\n+\t\tEFX_SET_OWORD(multicast_hash[1]);\n+\t} else if (epp->ep_mulcst) {\n+\t\t/* Use the hash set by the multicast list */\n+\t\tmulticast_hash[0] = epp->ep_multicst_hash[0];\n+\t\tmulticast_hash[1] = epp->ep_multicst_hash[1];\n+\t} else {\n+\t\t/* A hash matching no traffic is simply 0 */\n+\t\tEFX_ZERO_OWORD(multicast_hash[0]);\n+\t\tEFX_ZERO_OWORD(multicast_hash[1]);\n+\t}\n+\n+\t/*\n+\t * Broadcast packets go through the multicast hash filter.\n+\t * The IEEE 802.3 CRC32 of the broadcast address is 0xbe2612ff\n+\t * so we always add bit 0xff to the mask (bit 0x7f in the\n+\t * second octword).\n+\t */\n+\tif (epp->ep_brdcst) {\n+\t\t/*\n+\t\t * NOTE: due to constant folding, some of this evaluates\n+\t\t * to null expressions, giving E_EXPR_NULL_EFFECT during\n+\t\t * lint on Illumos.  No good way to fix this without\n+\t\t * explicit coding the individual word/bit setting.\n+\t\t * So just suppress lint for this one line.\n+\t\t */\n+\t\t/* LINTED */\n+\t\tEFX_SET_OWORD_BIT(multicast_hash[1], 0x7f);\n+\t}\n+\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_SET_MCAST_HASH;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_SET_MCAST_HASH_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_SET_MCAST_HASH_OUT_LEN;\n+\n+\tmemcpy(MCDI_IN2(req, uint8_t, SET_MCAST_HASH_IN_HASH0),\n+\t    multicast_hash, sizeof (multicast_hash));\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail2;\n+\t}\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\t\tefx_rc_t\n+siena_mac_pdu_get(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tsize_t *pdu)\n+{\n+\treturn (ENOTSUP);\n+}\n+\n+#endif\t/* EFSYS_OPT_SIENA */\ndiff --git a/drivers/net/sfc/efx/base/siena_mcdi.c b/drivers/net/sfc/efx/base/siena_mcdi.c\nnew file mode 100644\nindex 0000000..63c29fc\n--- /dev/null\n+++ b/drivers/net/sfc/efx/base/siena_mcdi.c\n@@ -0,0 +1,263 @@\n+/*\n+ * Copyright (c) 2012-2016 Solarflare Communications Inc.\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ * 1. Redistributions of source code must retain the above copyright notice,\n+ *    this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright notice,\n+ *    this list of conditions and the following disclaimer in the documentation\n+ *    and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ *\n+ * The views and conclusions contained in the software and documentation are\n+ * those of the authors and should not be interpreted as representing official\n+ * policies, either expressed or implied, of the FreeBSD Project.\n+ */\n+\n+#include \"efx.h\"\n+#include \"efx_impl.h\"\n+\n+#if EFSYS_OPT_SIENA && EFSYS_OPT_MCDI\n+\n+#define\tSIENA_MCDI_PDU(_emip)\t\t\t\\\n+\t(((emip)->emi_port == 1)\t\t\\\n+\t? MC_SMEM_P0_PDU_OFST >> 2\t\t\\\n+\t: MC_SMEM_P1_PDU_OFST >> 2)\n+\n+#define\tSIENA_MCDI_DOORBELL(_emip)\t\t\\\n+\t(((emip)->emi_port == 1)\t\t\\\n+\t? MC_SMEM_P0_DOORBELL_OFST >> 2\t\t\\\n+\t: MC_SMEM_P1_DOORBELL_OFST >> 2)\n+\n+#define\tSIENA_MCDI_STATUS(_emip)\t\t\\\n+\t(((emip)->emi_port == 1)\t\t\\\n+\t? MC_SMEM_P0_STATUS_OFST >> 2\t\t\\\n+\t: MC_SMEM_P1_STATUS_OFST >> 2)\n+\n+\n+\t\t\tvoid\n+siena_mcdi_send_request(\n+\t__in\t\t\tefx_nic_t *enp,\n+\t__in_bcount(hdr_len)\tvoid *hdrp,\n+\t__in\t\t\tsize_t hdr_len,\n+\t__in_bcount(sdu_len)\tvoid *sdup,\n+\t__in\t\t\tsize_t sdu_len)\n+{\n+\tefx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);\n+\tefx_dword_t dword;\n+\tunsigned int pdur;\n+\tunsigned int dbr;\n+\tunsigned int pos;\n+\n+\tEFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);\n+\n+\tEFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);\n+\tpdur = SIENA_MCDI_PDU(emip);\n+\tdbr = SIENA_MCDI_DOORBELL(emip);\n+\n+\t/* Write the header */\n+\tEFSYS_ASSERT3U(hdr_len, ==, sizeof (efx_dword_t));\n+\tdword = *(efx_dword_t *)hdrp;\n+\tEFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_TRUE);\n+\n+\t/* Write the payload */\n+\tfor (pos = 0; pos < sdu_len; pos += sizeof (efx_dword_t)) {\n+\t\tdword = *(efx_dword_t *)((uint8_t *)sdup + pos);\n+\t\tEFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM,\n+\t\t    pdur + 1 + (pos >> 2), &dword, B_FALSE);\n+\t}\n+\n+\t/* Ring the doorbell */\n+\tEFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11);\n+\tEFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE);\n+}\n+\n+\t\t\tefx_rc_t\n+siena_mcdi_poll_reboot(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+#if 1\n+\t/*\n+\t * XXX Bug 25922, bug 26099: This function is not being used\n+\t * properly.  Until its callers are fixed, it should always\n+\t * return 0.\n+\t */\n+\t_NOTE(ARGUNUSED(enp))\n+\treturn (0);\n+#else\n+\tefx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);\n+\tunsigned int rebootr;\n+\tefx_dword_t dword;\n+\tuint32_t value;\n+\n+\tEFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);\n+\tEFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);\n+\trebootr = SIENA_MCDI_STATUS(emip);\n+\n+\tEFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE);\n+\tvalue = EFX_DWORD_FIELD(dword, EFX_DWORD_0);\n+\n+\tif (value == 0)\n+\t\treturn (0);\n+\n+\tEFX_ZERO_DWORD(dword);\n+\tEFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE);\n+\n+\tif (value == MC_STATUS_DWORD_ASSERT)\n+\t\treturn (EINTR);\n+\telse\n+\t\treturn (EIO);\n+#endif\n+}\n+\n+extern\t__checkReturn\tboolean_t\n+siena_mcdi_poll_response(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);\n+\tefx_dword_t hdr;\n+\tunsigned int pdur;\n+\n+\tEFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);\n+\tpdur = SIENA_MCDI_PDU(emip);\n+\n+\tEFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_FALSE);\n+\treturn (EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE) ? B_TRUE : B_FALSE);\n+}\n+\n+\t\t\tvoid\n+siena_mcdi_read_response(\n+\t__in\t\t\tefx_nic_t *enp,\n+\t__out_bcount(length)\tvoid *bufferp,\n+\t__in\t\t\tsize_t offset,\n+\t__in\t\t\tsize_t length)\n+{\n+\tefx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);\n+\tunsigned int pdur;\n+\tunsigned int pos;\n+\tefx_dword_t data;\n+\n+\tEFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);\n+\tpdur = SIENA_MCDI_PDU(emip);\n+\n+\tfor (pos = 0; pos < length; pos += sizeof (efx_dword_t)) {\n+\t\tEFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,\n+\t\t    pdur + ((offset + pos) >> 2), &data, B_FALSE);\n+\t\tmemcpy((uint8_t *)bufferp + pos, &data,\n+\t\t    MIN(sizeof (data), length - pos));\n+\t}\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_mcdi_init(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tconst efx_mcdi_transport_t *mtp)\n+{\n+\tefx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);\n+\tefx_oword_t oword;\n+\tunsigned int portnum;\n+\tefx_rc_t rc;\n+\n+\t_NOTE(ARGUNUSED(mtp))\n+\n+\tEFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);\n+\n+\t/* Determine the port number to use for MCDI */\n+\tEFX_BAR_READO(enp, FR_AZ_CS_DEBUG_REG, &oword);\n+\tportnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM);\n+\n+\tif (portnum == 0) {\n+\t\t/* Presumably booted from ROM; only MCDI port 1 will work */\n+\t\temip->emi_port = 1;\n+\t} else if (portnum <= 2) {\n+\t\temip->emi_port = portnum;\n+\t} else {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\t/* Siena BootROM and firmware only support MCDIv1 */\n+\temip->emi_max_version = 1;\n+\n+\t/*\n+\t * Wipe the atomic reboot status so subsequent MCDI requests succeed.\n+\t * BOOT_STATUS is preserved so eno_nic_probe() can boot out of the\n+\t * assertion handler.\n+\t */\n+\t(void) siena_mcdi_poll_reboot(enp);\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t\t\tvoid\n+siena_mcdi_fini(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\t_NOTE(ARGUNUSED(enp))\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_mcdi_feature_supported(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_mcdi_feature_id_t id,\n+\t__out\t\tboolean_t *supportedp)\n+{\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);\n+\n+\tswitch (id) {\n+\tcase EFX_MCDI_FEATURE_FW_UPDATE:\n+\tcase EFX_MCDI_FEATURE_LINK_CONTROL:\n+\tcase EFX_MCDI_FEATURE_MACADDR_CHANGE:\n+\tcase EFX_MCDI_FEATURE_MAC_SPOOFING:\n+\t\t*supportedp = B_TRUE;\n+\t\tbreak;\n+\tdefault:\n+\t\trc = ENOTSUP;\n+\t\tgoto fail1;\n+\t}\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+/* Default timeout for MCDI command processing. */\n+#define\tSIENA_MCDI_CMD_TIMEOUT_US\t(10 * 1000 * 1000)\n+\n+\t\t\tvoid\n+siena_mcdi_get_timeout(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_mcdi_req_t *emrp,\n+\t__out\t\tuint32_t *timeoutp)\n+{\n+\t_NOTE(ARGUNUSED(enp, emrp))\n+\n+\t*timeoutp = SIENA_MCDI_CMD_TIMEOUT_US;\n+}\n+\n+\n+#endif\t/* EFSYS_OPT_SIENA && EFSYS_OPT_MCDI */\ndiff --git a/drivers/net/sfc/efx/base/siena_nic.c b/drivers/net/sfc/efx/base/siena_nic.c\nnew file mode 100644\nindex 0000000..7be16dc\n--- /dev/null\n+++ b/drivers/net/sfc/efx/base/siena_nic.c\n@@ -0,0 +1,357 @@\n+/*\n+ * Copyright (c) 2009-2016 Solarflare Communications Inc.\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ * 1. Redistributions of source code must retain the above copyright notice,\n+ *    this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright notice,\n+ *    this list of conditions and the following disclaimer in the documentation\n+ *    and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ *\n+ * The views and conclusions contained in the software and documentation are\n+ * those of the authors and should not be interpreted as representing official\n+ * policies, either expressed or implied, of the FreeBSD Project.\n+ */\n+\n+#include \"efx.h\"\n+#include \"efx_impl.h\"\n+#include \"mcdi_mon.h\"\n+\n+#if EFSYS_OPT_SIENA\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_board_cfg(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_nic_cfg_t *encp = &(enp->en_nic_cfg);\n+\tuint8_t mac_addr[6];\n+\tefx_dword_t capabilities;\n+\tuint32_t board_type;\n+\tuint32_t nevq, nrxq, ntxq;\n+\tefx_rc_t rc;\n+\n+\t/* External port identifier using one-based port numbering */\n+\tencp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;\n+\n+\t/* Board configuration */\n+\tif ((rc = efx_mcdi_get_board_cfg(enp, &board_type,\n+\t\t    &capabilities, mac_addr)) != 0)\n+\t\tgoto fail1;\n+\n+\tEFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);\n+\n+\tencp->enc_board_type = board_type;\n+\n+\t/*\n+\t * There is no possibility to determine the number of PFs on Siena\n+\t * by issuing MCDI request, and it is not an easy task to find the\n+\t * value based on the board type, so 'enc_hw_pf_count' is set to 1\n+\t */\n+\tencp->enc_hw_pf_count = 1;\n+\n+\t/* Additional capabilities */\n+\tencp->enc_clk_mult = 1;\n+\tif (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {\n+\t\tenp->en_features |= EFX_FEATURE_TURBO;\n+\n+\t\tif (EFX_DWORD_FIELD(capabilities,\n+\t\t\tMC_CMD_CAPABILITIES_TURBO_ACTIVE)) {\n+\t\t\tencp->enc_clk_mult = 2;\n+\t\t}\n+\t}\n+\n+\tencp->enc_evq_timer_quantum_ns =\n+\t\tEFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;\n+\tencp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<\n+\t\tFRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;\n+\n+\t/* When hash header insertion is enabled, Siena inserts 16 bytes */\n+\tencp->enc_rx_prefix_size = 16;\n+\n+\t/* Alignment for receive packet DMA buffers */\n+\tencp->enc_rx_buf_align_start = 1;\n+\tencp->enc_rx_buf_align_end = 1;\n+\n+\t/* Alignment for WPTR updates */\n+\tencp->enc_rx_push_align = 1;\n+\n+\t/* Resource limits */\n+\trc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);\n+\tif (rc != 0) {\n+\t\tif (rc != ENOTSUP)\n+\t\t\tgoto fail2;\n+\n+\t\tnevq = 1024;\n+\t\tnrxq = EFX_RXQ_LIMIT_TARGET;\n+\t\tntxq = EFX_TXQ_LIMIT_TARGET;\n+\t}\n+\tencp->enc_evq_limit = nevq;\n+\tencp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);\n+\tencp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);\n+\n+\tencp->enc_txq_max_ndescs = 4096;\n+\n+\tencp->enc_buftbl_limit = SIENA_SRAM_ROWS -\n+\t    (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -\n+\t    (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));\n+\n+\tencp->enc_hw_tx_insert_vlan_enabled = B_FALSE;\n+\tencp->enc_fw_assisted_tso_enabled = B_FALSE;\n+\tencp->enc_fw_assisted_tso_v2_enabled = B_FALSE;\n+\tencp->enc_fw_assisted_tso_v2_n_contexts = 0;\n+\tencp->enc_allow_set_mac_with_installed_filters = B_TRUE;\n+\tencp->enc_rx_packed_stream_supported = B_FALSE;\n+\tencp->enc_rx_var_packed_stream_supported = B_FALSE;\n+\n+\t/* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */\n+\tencp->enc_required_pcie_bandwidth_mbps = 2 * 10000;\n+\tencp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;\n+\n+\tencp->enc_fw_verified_nvram_update_required = B_FALSE;\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+siena_phy_cfg(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_nic_cfg_t *encp = &(enp->en_nic_cfg);\n+\tefx_rc_t rc;\n+\n+\t/* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */\n+\tif ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)\n+\t\tgoto fail1;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_nic_probe(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_port_t *epp = &(enp->en_port);\n+\tefx_nic_cfg_t *encp = &(enp->en_nic_cfg);\n+\tsiena_link_state_t sls;\n+\tunsigned int mask;\n+\tefx_oword_t oword;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);\n+\n+\t/* Test BIU */\n+\tif ((rc = efx_nic_biu_test(enp)) != 0)\n+\t\tgoto fail1;\n+\n+\t/* Clear the region register */\n+\tEFX_POPULATE_OWORD_4(oword,\n+\t    FRF_AZ_ADR_REGION0, 0,\n+\t    FRF_AZ_ADR_REGION1, (1 << 16),\n+\t    FRF_AZ_ADR_REGION2, (2 << 16),\n+\t    FRF_AZ_ADR_REGION3, (3 << 16));\n+\tEFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);\n+\n+\t/* Read clear any assertion state */\n+\tif ((rc = efx_mcdi_read_assertion(enp)) != 0)\n+\t\tgoto fail2;\n+\n+\t/* Exit the assertion handler */\n+\tif ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)\n+\t\tgoto fail3;\n+\n+\t/* Wrestle control from the BMC */\n+\tif ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)\n+\t\tgoto fail4;\n+\n+\tif ((rc = siena_board_cfg(enp)) != 0)\n+\t\tgoto fail5;\n+\n+\tif ((rc = siena_phy_cfg(enp)) != 0)\n+\t\tgoto fail6;\n+\n+\t/* Obtain the default PHY advertised capabilities */\n+\tif ((rc = siena_nic_reset(enp)) != 0)\n+\t\tgoto fail7;\n+\tif ((rc = siena_phy_get_link(enp, &sls)) != 0)\n+\t\tgoto fail8;\n+\tepp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;\n+\tepp->ep_adv_cap_mask = sls.sls_adv_cap_mask;\n+\n+\tencp->enc_features = enp->en_features;\n+\n+\treturn (0);\n+\n+fail8:\n+\tEFSYS_PROBE(fail8);\n+fail7:\n+\tEFSYS_PROBE(fail7);\n+fail6:\n+\tEFSYS_PROBE(fail6);\n+fail5:\n+\tEFSYS_PROBE(fail5);\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_nic_reset(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_mcdi_req_t req;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);\n+\n+\t/* siena_nic_reset() is called to recover from BADASSERT failures. */\n+\tif ((rc = efx_mcdi_read_assertion(enp)) != 0)\n+\t\tgoto fail1;\n+\tif ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)\n+\t\tgoto fail2;\n+\n+\t/*\n+\t * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied\n+\t * for backwards compatibility with PORT_RESET_IN_LEN.\n+\t */\n+\tEFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);\n+\n+\treq.emr_cmd = MC_CMD_ENTITY_RESET;\n+\treq.emr_in_buf = NULL;\n+\treq.emr_in_length = 0;\n+\treq.emr_out_buf = NULL;\n+\treq.emr_out_length = 0;\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail3;\n+\t}\n+\n+\treturn (0);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (0);\n+}\n+\n+static\t\t\tvoid\n+siena_nic_rx_cfg(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_oword_t oword;\n+\n+\t/*\n+\t * RX_INGR_EN is always enabled on Siena, because we rely on\n+\t * the RX parser to be resiliant to missing SOP/EOP.\n+\t */\n+\tEFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);\n+\n+\t/* Disable parsing of additional 802.1Q in Q packets */\n+\tEFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);\n+\tEFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);\n+}\n+\n+static\t\t\tvoid\n+siena_nic_usrev_dis(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_oword_t\toword;\n+\n+\tEFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);\n+\tEFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_nic_init(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);\n+\n+\t/* Enable reporting of some events (e.g. link change) */\n+\tif ((rc = efx_mcdi_log_ctrl(enp)) != 0)\n+\t\tgoto fail1;\n+\n+\tsiena_sram_init(enp);\n+\n+\t/* Configure Siena's RX block */\n+\tsiena_nic_rx_cfg(enp);\n+\n+\t/* Disable USR_EVents for now */\n+\tsiena_nic_usrev_dis(enp);\n+\n+\t/* bug17057: Ensure set_link is called */\n+\tif ((rc = siena_phy_reconfigure(enp)) != 0)\n+\t\tgoto fail2;\n+\n+\tenp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t\t\tvoid\n+siena_nic_fini(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\t_NOTE(ARGUNUSED(enp))\n+}\n+\n+\t\t\tvoid\n+siena_nic_unprobe(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\t(void) efx_mcdi_drv_attach(enp, B_FALSE);\n+}\n+\n+#endif\t/* EFSYS_OPT_SIENA */\ndiff --git a/drivers/net/sfc/efx/base/siena_phy.c b/drivers/net/sfc/efx/base/siena_phy.c\nnew file mode 100644\nindex 0000000..0e3fc34\n--- /dev/null\n+++ b/drivers/net/sfc/efx/base/siena_phy.c\n@@ -0,0 +1,375 @@\n+/*\n+ * Copyright (c) 2009-2016 Solarflare Communications Inc.\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ * 1. Redistributions of source code must retain the above copyright notice,\n+ *    this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright notice,\n+ *    this list of conditions and the following disclaimer in the documentation\n+ *    and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ *\n+ * The views and conclusions contained in the software and documentation are\n+ * those of the authors and should not be interpreted as representing official\n+ * policies, either expressed or implied, of the FreeBSD Project.\n+ */\n+\n+#include \"efx.h\"\n+#include \"efx_impl.h\"\n+\n+#if EFSYS_OPT_SIENA\n+\n+static\t\t\tvoid\n+siena_phy_decode_cap(\n+\t__in\t\tuint32_t mcdi_cap,\n+\t__out\t\tuint32_t *maskp)\n+{\n+\tuint32_t mask;\n+\n+\tmask = 0;\n+\tif (mcdi_cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))\n+\t\tmask |= (1 << EFX_PHY_CAP_10HDX);\n+\tif (mcdi_cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))\n+\t\tmask |= (1 << EFX_PHY_CAP_10FDX);\n+\tif (mcdi_cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))\n+\t\tmask |= (1 << EFX_PHY_CAP_100HDX);\n+\tif (mcdi_cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))\n+\t\tmask |= (1 << EFX_PHY_CAP_100FDX);\n+\tif (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))\n+\t\tmask |= (1 << EFX_PHY_CAP_1000HDX);\n+\tif (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))\n+\t\tmask |= (1 << EFX_PHY_CAP_1000FDX);\n+\tif (mcdi_cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))\n+\t\tmask |= (1 << EFX_PHY_CAP_10000FDX);\n+\tif (mcdi_cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))\n+\t\tmask |= (1 << EFX_PHY_CAP_PAUSE);\n+\tif (mcdi_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))\n+\t\tmask |= (1 << EFX_PHY_CAP_ASYM);\n+\tif (mcdi_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))\n+\t\tmask |= (1 << EFX_PHY_CAP_AN);\n+\n+\t*maskp = mask;\n+}\n+\n+static\t\t\tvoid\n+siena_phy_decode_link_mode(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tuint32_t link_flags,\n+\t__in\t\tunsigned int speed,\n+\t__in\t\tunsigned int fcntl,\n+\t__out\t\tefx_link_mode_t *link_modep,\n+\t__out\t\tunsigned int *fcntlp)\n+{\n+\tboolean_t fd = !!(link_flags &\n+\t\t    (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));\n+\tboolean_t up = !!(link_flags &\n+\t\t    (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));\n+\n+\t_NOTE(ARGUNUSED(enp))\n+\n+\tif (!up)\n+\t\t*link_modep = EFX_LINK_DOWN;\n+\telse if (speed == 10000 && fd)\n+\t\t*link_modep = EFX_LINK_10000FDX;\n+\telse if (speed == 1000)\n+\t\t*link_modep = fd ? EFX_LINK_1000FDX : EFX_LINK_1000HDX;\n+\telse if (speed == 100)\n+\t\t*link_modep = fd ? EFX_LINK_100FDX : EFX_LINK_100HDX;\n+\telse if (speed == 10)\n+\t\t*link_modep = fd ? EFX_LINK_10FDX : EFX_LINK_10HDX;\n+\telse\n+\t\t*link_modep = EFX_LINK_UNKNOWN;\n+\n+\tif (fcntl == MC_CMD_FCNTL_OFF)\n+\t\t*fcntlp = 0;\n+\telse if (fcntl == MC_CMD_FCNTL_RESPOND)\n+\t\t*fcntlp = EFX_FCNTL_RESPOND;\n+\telse if (fcntl == MC_CMD_FCNTL_BIDIR)\n+\t\t*fcntlp = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;\n+\telse {\n+\t\tEFSYS_PROBE1(mc_pcol_error, int, fcntl);\n+\t\t*fcntlp = 0;\n+\t}\n+}\n+\n+\t\t\tvoid\n+siena_phy_link_ev(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_qword_t *eqp,\n+\t__out\t\tefx_link_mode_t *link_modep)\n+{\n+\tefx_port_t *epp = &(enp->en_port);\n+\tunsigned int link_flags;\n+\tunsigned int speed;\n+\tunsigned int fcntl;\n+\tefx_link_mode_t link_mode;\n+\tuint32_t lp_cap_mask;\n+\n+\t/*\n+\t * Convert the LINKCHANGE speed enumeration into mbit/s, in the\n+\t * same way as GET_LINK encodes the speed\n+\t */\n+\tswitch (MCDI_EV_FIELD(eqp, LINKCHANGE_SPEED)) {\n+\tcase MCDI_EVENT_LINKCHANGE_SPEED_100M:\n+\t\tspeed = 100;\n+\t\tbreak;\n+\tcase MCDI_EVENT_LINKCHANGE_SPEED_1G:\n+\t\tspeed = 1000;\n+\t\tbreak;\n+\tcase MCDI_EVENT_LINKCHANGE_SPEED_10G:\n+\t\tspeed = 10000;\n+\t\tbreak;\n+\tdefault:\n+\t\tspeed = 0;\n+\t\tbreak;\n+\t}\n+\n+\tlink_flags = MCDI_EV_FIELD(eqp, LINKCHANGE_LINK_FLAGS);\n+\tsiena_phy_decode_link_mode(enp, link_flags, speed,\n+\t\t\t\t    MCDI_EV_FIELD(eqp, LINKCHANGE_FCNTL),\n+\t\t\t\t    &link_mode, &fcntl);\n+\tsiena_phy_decode_cap(MCDI_EV_FIELD(eqp, LINKCHANGE_LP_CAP),\n+\t\t\t    &lp_cap_mask);\n+\n+\t/*\n+\t * It's safe to update ep_lp_cap_mask without the driver's port lock\n+\t * because presumably any concurrently running efx_port_poll() is\n+\t * only going to arrive at the same value.\n+\t *\n+\t * ep_fcntl has two meanings. It's either the link common fcntl\n+\t * (if the PHY supports AN), or it's the forced link state. If\n+\t * the former, it's safe to update the value for the same reason as\n+\t * for ep_lp_cap_mask. If the latter, then just ignore the value,\n+\t * because we can race with efx_mac_fcntl_set().\n+\t */\n+\tepp->ep_lp_cap_mask = lp_cap_mask;\n+\tif (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))\n+\t\tepp->ep_fcntl = fcntl;\n+\n+\t*link_modep = link_mode;\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_phy_power(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tboolean_t power)\n+{\n+\tefx_rc_t rc;\n+\n+\tif (!power)\n+\t\treturn (0);\n+\n+\t/* Check if the PHY is a zombie */\n+\tif ((rc = siena_phy_verify(enp)) != 0)\n+\t\tgoto fail1;\n+\n+\tenp->en_reset_flags |= EFX_RESET_PHY;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_phy_get_link(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tsiena_link_state_t *slsp)\n+{\n+\tefx_mcdi_req_t req;\n+\tuint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,\n+\t\t\t    MC_CMD_GET_LINK_OUT_LEN)];\n+\tefx_rc_t rc;\n+\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_GET_LINK;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_GET_LINK_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_GET_LINK_OUT_LEN;\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_LEN) {\n+\t\trc = EMSGSIZE;\n+\t\tgoto fail2;\n+\t}\n+\n+\tsiena_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_CAP),\n+\t\t\t    &slsp->sls_adv_cap_mask);\n+\tsiena_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP),\n+\t\t\t    &slsp->sls_lp_cap_mask);\n+\n+\tsiena_phy_decode_link_mode(enp, MCDI_OUT_DWORD(req, GET_LINK_OUT_FLAGS),\n+\t\t\t    MCDI_OUT_DWORD(req, GET_LINK_OUT_LINK_SPEED),\n+\t\t\t    MCDI_OUT_DWORD(req, GET_LINK_OUT_FCNTL),\n+\t\t\t    &slsp->sls_link_mode, &slsp->sls_fcntl);\n+\n+\tslsp->sls_mac_up = MCDI_OUT_DWORD(req, GET_LINK_OUT_MAC_FAULT) == 0;\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_phy_reconfigure(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_port_t *epp = &(enp->en_port);\n+\tefx_mcdi_req_t req;\n+\tuint8_t payload[MAX(MAX(MC_CMD_SET_ID_LED_IN_LEN,\n+\t\t\t\tMC_CMD_SET_ID_LED_OUT_LEN),\n+\t\t\t    MAX(MC_CMD_SET_LINK_IN_LEN,\n+\t\t\t\tMC_CMD_SET_LINK_OUT_LEN))];\n+\tuint32_t cap_mask;\n+\tunsigned int led_mode;\n+\tunsigned int speed;\n+\tefx_rc_t rc;\n+\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_SET_LINK;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_SET_LINK_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_SET_LINK_OUT_LEN;\n+\n+\tcap_mask = epp->ep_adv_cap_mask;\n+\tMCDI_IN_POPULATE_DWORD_10(req, SET_LINK_IN_CAP,\n+\t\tPHY_CAP_10HDX, (cap_mask >> EFX_PHY_CAP_10HDX) & 0x1,\n+\t\tPHY_CAP_10FDX, (cap_mask >> EFX_PHY_CAP_10FDX) & 0x1,\n+\t\tPHY_CAP_100HDX, (cap_mask >> EFX_PHY_CAP_100HDX) & 0x1,\n+\t\tPHY_CAP_100FDX, (cap_mask >> EFX_PHY_CAP_100FDX) & 0x1,\n+\t\tPHY_CAP_1000HDX, (cap_mask >> EFX_PHY_CAP_1000HDX) & 0x1,\n+\t\tPHY_CAP_1000FDX, (cap_mask >> EFX_PHY_CAP_1000FDX) & 0x1,\n+\t\tPHY_CAP_10000FDX, (cap_mask >> EFX_PHY_CAP_10000FDX) & 0x1,\n+\t\tPHY_CAP_PAUSE, (cap_mask >> EFX_PHY_CAP_PAUSE) & 0x1,\n+\t\tPHY_CAP_ASYM, (cap_mask >> EFX_PHY_CAP_ASYM) & 0x1,\n+\t\tPHY_CAP_AN, (cap_mask >> EFX_PHY_CAP_AN) & 0x1);\n+\n+\tMCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, MC_CMD_LOOPBACK_NONE);\n+\tspeed = 0;\n+\tMCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_SPEED, speed);\n+\n+\tMCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, 0);\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail1;\n+\t}\n+\n+\t/* And set the blink mode */\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_SET_ID_LED;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_SET_ID_LED_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN;\n+\n+\tMCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, MC_CMD_LED_DEFAULT);\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail2;\n+\t}\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_phy_verify(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_mcdi_req_t req;\n+\tuint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,\n+\t\t\t    MC_CMD_GET_PHY_STATE_OUT_LEN)];\n+\tuint32_t state;\n+\tefx_rc_t rc;\n+\n+\t(void) memset(payload, 0, sizeof (payload));\n+\treq.emr_cmd = MC_CMD_GET_PHY_STATE;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_GET_PHY_STATE_OUT_LEN;\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif (req.emr_out_length_used < MC_CMD_GET_PHY_STATE_OUT_LEN) {\n+\t\trc = EMSGSIZE;\n+\t\tgoto fail2;\n+\t}\n+\n+\tstate = MCDI_OUT_DWORD(req, GET_PHY_STATE_OUT_STATE);\n+\tif (state != MC_CMD_PHY_STATE_OK) {\n+\t\tif (state != MC_CMD_PHY_STATE_ZOMBIE)\n+\t\t\tEFSYS_PROBE1(mc_pcol_error, int, state);\n+\t\trc = ENOTACTIVE;\n+\t\tgoto fail3;\n+\t}\n+\n+\treturn (0);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+siena_phy_oui_get(\n+\t__in\t\tefx_nic_t *enp,\n+\t__out\t\tuint32_t *ouip)\n+{\n+\t_NOTE(ARGUNUSED(enp, ouip))\n+\n+\treturn (ENOTSUP);\n+}\n+\n+#endif\t/* EFSYS_OPT_SIENA */\ndiff --git a/drivers/net/sfc/efx/base/siena_sram.c b/drivers/net/sfc/efx/base/siena_sram.c\nnew file mode 100644\nindex 0000000..411ef9d\n--- /dev/null\n+++ b/drivers/net/sfc/efx/base/siena_sram.c\n@@ -0,0 +1,74 @@\n+/*\n+ * Copyright (c) 2009-2016 Solarflare Communications Inc.\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ * 1. Redistributions of source code must retain the above copyright notice,\n+ *    this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright notice,\n+ *    this list of conditions and the following disclaimer in the documentation\n+ *    and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ *\n+ * The views and conclusions contained in the software and documentation are\n+ * those of the authors and should not be interpreted as representing official\n+ * policies, either expressed or implied, of the FreeBSD Project.\n+ */\n+\n+#include \"efx.h\"\n+#include \"efx_impl.h\"\n+\n+#if EFSYS_OPT_SIENA\n+\n+\t\t\tvoid\n+siena_sram_init(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tefx_nic_cfg_t *encp = &(enp->en_nic_cfg);\n+\tefx_oword_t oword;\n+\tuint32_t rx_base, tx_base;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);\n+\n+\trx_base = encp->enc_buftbl_limit;\n+\ttx_base = rx_base + (encp->enc_rxq_limit *\n+\t    EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));\n+\n+\t/* Initialize the transmit descriptor cache */\n+\tEFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);\n+\n+\tEFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, EFX_TXQ_DC_SIZE);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword);\n+\n+\t/* Initialize the receive descriptor cache */\n+\tEFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);\n+\n+\tEFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, EFX_RXQ_DC_SIZE);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword);\n+\n+\t/* Set receive descriptor pre-fetch low water mark */\n+\tEFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword);\n+\n+\t/* Set the event queue to use for SRAM updates */\n+\tEFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0);\n+\tEFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword);\n+}\n+\n+#endif\t/* EFSYS_OPT_SIENA */\n",
    "prefixes": [
        "dpdk-dev",
        "09/56"
    ]
}