get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 3101,
    "url": "http://patches.dpdk.org/api/patches/3101/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1423551775-3604-2-git-send-email-jing.d.chen@intel.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<1423551775-3604-2-git-send-email-jing.d.chen@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1423551775-3604-2-git-send-email-jing.d.chen@intel.com",
    "date": "2015-02-10T07:02:41",
    "name": "[dpdk-dev,v3,01/15] fm10k: add base driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "615240cd22350d9ce319ac7b498908bfcb21989e",
    "submitter": {
        "id": 40,
        "url": "http://patches.dpdk.org/api/people/40/?format=api",
        "name": "Chen, Jing D",
        "email": "jing.d.chen@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1423551775-3604-2-git-send-email-jing.d.chen@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/3101/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/3101/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 B379958E8;\n\tTue, 10 Feb 2015 08:03:29 +0100 (CET)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id C992B5A32\n\tfor <dev@dpdk.org>; Tue, 10 Feb 2015 08:03:24 +0100 (CET)",
            "from orsmga001.jf.intel.com ([10.7.209.18])\n\tby fmsmga102.fm.intel.com with ESMTP; 09 Feb 2015 23:03:21 -0800",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby orsmga001.jf.intel.com with ESMTP; 09 Feb 2015 23:03:20 -0800",
            "from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com\n\t[10.239.29.90])\n\tby shvmail01.sh.intel.com with ESMTP id t1A73Gg8011891;\n\tTue, 10 Feb 2015 15:03:16 +0800",
            "from shecgisg003.sh.intel.com (localhost [127.0.0.1])\n\tby shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP\n\tid t1A73DA5003646; Tue, 10 Feb 2015 15:03:15 +0800",
            "(from jingche2@localhost)\n\tby shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id t1A73Dpv003642; \n\tTue, 10 Feb 2015 15:03:13 +0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.09,548,1418112000\"; d=\"scan'208\";a=\"649895537\"",
        "From": "\"Chen Jing D(Mark)\" <jing.d.chen@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Tue, 10 Feb 2015 15:02:41 +0800",
        "Message-Id": "<1423551775-3604-2-git-send-email-jing.d.chen@intel.com>",
        "X-Mailer": "git-send-email 1.7.12.2",
        "In-Reply-To": "<1423551775-3604-1-git-send-email-jing.d.chen@intel.com>",
        "References": "<1423046460-21141-2-git-send-email-jing.d.chen@intel.com>\n\t<1423551775-3604-1-git-send-email-jing.d.chen@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3 01/15] fm10k: add base driver",
        "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": "From: Jeff Shaw <jeffrey.b.shaw@intel.com>\n\nBase driver is developped and maintained by Intel ND team, includes\nbasic functional service to Intel Red Rock Canyon silicon.\nAny suggestion on bug fix and improvement within this directory is\nwelcome, but need this team to change and update.\n\nSigned-off-by: Chen Jing D(Mark) <jing.d.chen@intel.com>\n---\n lib/librte_pmd_fm10k/base/fm10k_api.c    |  341 +++++\n lib/librte_pmd_fm10k/base/fm10k_api.h    |   61 +\n lib/librte_pmd_fm10k/base/fm10k_common.c |  572 ++++++++\n lib/librte_pmd_fm10k/base/fm10k_common.h |   52 +\n lib/librte_pmd_fm10k/base/fm10k_mbx.c    | 2185 ++++++++++++++++++++++++++++++\n lib/librte_pmd_fm10k/base/fm10k_mbx.h    |  329 +++++\n lib/librte_pmd_fm10k/base/fm10k_osdep.h  |  148 ++\n lib/librte_pmd_fm10k/base/fm10k_pf.c     | 1992 +++++++++++++++++++++++++++\n lib/librte_pmd_fm10k/base/fm10k_pf.h     |  155 +++\n lib/librte_pmd_fm10k/base/fm10k_tlv.c    |  914 +++++++++++++\n lib/librte_pmd_fm10k/base/fm10k_tlv.h    |  199 +++\n lib/librte_pmd_fm10k/base/fm10k_type.h   |  937 +++++++++++++\n lib/librte_pmd_fm10k/base/fm10k_vf.c     |  641 +++++++++\n lib/librte_pmd_fm10k/base/fm10k_vf.h     |   91 ++\n 14 files changed, 8617 insertions(+), 0 deletions(-)\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_api.c\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_api.h\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_common.c\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_common.h\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_mbx.c\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_mbx.h\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_osdep.h\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_pf.c\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_pf.h\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_tlv.c\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_tlv.h\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_type.h\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_vf.c\n create mode 100644 lib/librte_pmd_fm10k/base/fm10k_vf.h",
    "diff": "diff --git a/lib/librte_pmd_fm10k/base/fm10k_api.c b/lib/librte_pmd_fm10k/base/fm10k_api.c\nnew file mode 100644\nindex 0000000..c0f555c\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_api.c\n@@ -0,0 +1,341 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#include \"fm10k_api.h\"\n+#include \"fm10k_common.h\"\n+\n+/**\n+ *  fm10k_set_mac_type - Sets MAC type\n+ *  @hw: pointer to the HW structure\n+ *\n+ *  This function sets the mac type of the adapter based on the\n+ *  vendor ID and device ID stored in the hw structure.\n+ **/\n+s32 fm10k_set_mac_type(struct fm10k_hw *hw)\n+{\n+\ts32 ret_val = FM10K_SUCCESS;\n+\n+\tDEBUGFUNC(\"fm10k_set_mac_type\");\n+\n+\tif (hw->vendor_id != FM10K_INTEL_VENDOR_ID) {\n+\t\tERROR_REPORT2(FM10K_ERROR_UNSUPPORTED,\n+\t\t\t     \"Unsupported vendor id: %x\\n\", hw->vendor_id);\n+\t\treturn FM10K_ERR_DEVICE_NOT_SUPPORTED;\n+\t}\n+\n+\tswitch (hw->device_id) {\n+\tcase FM10K_DEV_ID_PF:\n+\t\thw->mac.type = fm10k_mac_pf;\n+\t\tbreak;\n+\tcase FM10K_DEV_ID_VF:\n+\t\thw->mac.type = fm10k_mac_vf;\n+\t\tbreak;\n+\tdefault:\n+\t\tret_val = FM10K_ERR_DEVICE_NOT_SUPPORTED;\n+\t\tERROR_REPORT2(FM10K_ERROR_UNSUPPORTED,\n+\t\t\t     \"Unsupported device id: %x\\n\",\n+\t\t\t     hw->device_id);\n+\t\tbreak;\n+\t}\n+\n+\tDEBUGOUT2(\"fm10k_set_mac_type found mac: %d, returns: %d\\n\",\n+\t\t  hw->mac.type, ret_val);\n+\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  fm10k_init_shared_code - Initialize the shared code\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This will assign function pointers and assign the MAC type and PHY code.\n+ *  Does not touch the hardware. This function must be called prior to any\n+ *  other function in the shared code. The fm10k_hw structure should be\n+ *  memset to 0 prior to calling this function.  The following fields in\n+ *  hw structure should be filled in prior to calling this function:\n+ *  hw_addr, back, device_id, vendor_id, subsystem_device_id,\n+ *  subsystem_vendor_id, and revision_id\n+ **/\n+s32 fm10k_init_shared_code(struct fm10k_hw *hw)\n+{\n+\ts32 status;\n+\n+\tDEBUGFUNC(\"fm10k_init_shared_code\");\n+\n+\t/* Set the mac type */\n+\tfm10k_set_mac_type(hw);\n+\n+\tswitch (hw->mac.type) {\n+\tcase fm10k_mac_pf:\n+\t\tstatus = fm10k_init_ops_pf(hw);\n+\t\tbreak;\n+\tcase fm10k_mac_vf:\n+\t\tstatus = fm10k_init_ops_vf(hw);\n+\t\tbreak;\n+\tdefault:\n+\t\tstatus = FM10K_ERR_DEVICE_NOT_SUPPORTED;\n+\t\tbreak;\n+\t}\n+\n+\treturn status;\n+}\n+\n+#define fm10k_call_func(hw, func, params, error) \\\n+\t\t ((func) ? (func params) : (error))\n+\n+/**\n+ *  fm10k_reset_hw - Reset the hardware to known good state\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This function should return the hardware to a state similar to the\n+ *  one it is in after being powered on.\n+ **/\n+s32 fm10k_reset_hw(struct fm10k_hw *hw)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.reset_hw, (hw),\n+\t\t\t       FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_init_hw - Initialize the hardware\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Initialize the hardware by resetting and then starting the hardware\n+ **/\n+s32 fm10k_init_hw(struct fm10k_hw *hw)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.init_hw, (hw),\n+\t\t\t       FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_stop_hw - Prepares hardware to shutdown Rx/Tx\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Disables Rx/Tx queues and disables the DMA engine.\n+ **/\n+s32 fm10k_stop_hw(struct fm10k_hw *hw)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.stop_hw, (hw),\n+\t\t\t       FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_start_hw - Prepares hardware for Rx/Tx\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This function sets the flags indicating that the hardware is ready to\n+ *  begin operation.\n+ **/\n+s32 fm10k_start_hw(struct fm10k_hw *hw)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.start_hw, (hw),\n+\t\t\t       FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_get_bus_info - Set PCI bus info\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Sets the PCI bus info (speed, width, type) within the fm10k_hw structure\n+ **/\n+s32 fm10k_get_bus_info(struct fm10k_hw *hw)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.get_bus_info, (hw),\n+\t\t\t       FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_is_slot_appropriate - Indicate appropriate slot for this SKU\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Looks at the PCIe bus info to confirm whether or not this slot can support\n+ *  the necessary bandwidth for this device.\n+ **/\n+bool fm10k_is_slot_appropriate(struct fm10k_hw *hw)\n+{\n+\tif (hw->mac.ops.is_slot_appropriate)\n+\t\treturn hw->mac.ops.is_slot_appropriate(hw);\n+\treturn true;\n+}\n+\n+/**\n+ *  fm10k_update_vlan - Clear VLAN ID to VLAN filter table\n+ *  @hw: pointer to hardware structure\n+ *  @vid: VLAN ID to add to table\n+ *  @idx: Index indicating VF ID or PF ID in table\n+ *  @set: Indicates if this is a set or clear operation\n+ *\n+ *  This function adds or removes the corresponding VLAN ID from the VLAN\n+ *  filter table for the corresponding function.\n+ **/\n+s32 fm10k_update_vlan(struct fm10k_hw *hw, u32 vid, u8 idx, bool set)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.update_vlan, (hw, vid, idx, set),\n+\t\t\t       FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_read_mac_addr - Reads MAC address\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Reads the MAC address out of the interface and stores it in the HW\n+ *  structures.\n+ **/\n+s32 fm10k_read_mac_addr(struct fm10k_hw *hw)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.read_mac_addr, (hw),\n+\t\t\t       FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_update_hw_stats - Update hw statistics\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This function updates statistics that are related to hardware.\n+ * */\n+void fm10k_update_hw_stats(struct fm10k_hw *hw, struct fm10k_hw_stats *stats)\n+{\n+\tif (hw->mac.ops.update_hw_stats)\n+\t\thw->mac.ops.update_hw_stats(hw, stats);\n+}\n+\n+/**\n+ *  fm10k_rebind_hw_stats - Reset base for hw statistics\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This function resets the base for statistics that are related to hardware.\n+ * */\n+void fm10k_rebind_hw_stats(struct fm10k_hw *hw, struct fm10k_hw_stats *stats)\n+{\n+\tif (hw->mac.ops.rebind_hw_stats)\n+\t\thw->mac.ops.rebind_hw_stats(hw, stats);\n+}\n+\n+/**\n+ *  fm10k_configure_dglort_map - Configures GLORT entry and queues\n+ *  @hw: pointer to hardware structure\n+ *  @dglort: pointer to dglort configuration structure\n+ *\n+ *  Reads the configuration structure contained in dglort_cfg and uses\n+ *  that information to then populate a DGLORTMAP/DEC entry and the queues\n+ *  to which it has been assigned.\n+ **/\n+s32 fm10k_configure_dglort_map(struct fm10k_hw *hw,\n+\t\t\t       struct fm10k_dglort_cfg *dglort)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.configure_dglort_map,\n+\t\t\t       (hw, dglort), FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_set_dma_mask - Configures PhyAddrSpace to limit DMA to system\n+ *  @hw: pointer to hardware structure\n+ *  @dma_mask: 64 bit DMA mask required for platform\n+ *\n+ *  This function configures the endpoint to limit the access to memory\n+ *  beyond what is physically in the system.\n+ **/\n+void fm10k_set_dma_mask(struct fm10k_hw *hw, u64 dma_mask)\n+{\n+\tif (hw->mac.ops.set_dma_mask)\n+\t\thw->mac.ops.set_dma_mask(hw, dma_mask);\n+}\n+\n+/**\n+ *  fm10k_get_fault - Record a fault in one of the interface units\n+ *  @hw: pointer to hardware structure\n+ *  @type: pointer to fault type register offset\n+ *  @fault: pointer to memory location to record the fault\n+ *\n+ *  Record the fault register contents to the fault data structure and\n+ *  clear the entry from the register.\n+ *\n+ *  Returns ERR_PARAM if invalid register is specified or no error is present.\n+ **/\n+s32 fm10k_get_fault(struct fm10k_hw *hw, int type, struct fm10k_fault *fault)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.get_fault, (hw, type, fault),\n+\t\t\t       FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_update_uc_addr - Update device unicast address\n+ *  @hw: pointer to the HW structure\n+ *  @lport: logical port ID to update - unused\n+ *  @mac: MAC address to add/remove from table\n+ *  @vid: VLAN ID to add/remove from table\n+ *  @add: Indicates if this is an add or remove operation\n+ *  @flags: flags field to indicate add and secure - unused\n+ *\n+ *  This function is used to add or remove unicast MAC addresses\n+ **/\n+s32 fm10k_update_uc_addr(struct fm10k_hw *hw, u16 lport,\n+\t\t\t  const u8 *mac, u16 vid, bool add, u8 flags)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.update_uc_addr,\n+\t\t\t       (hw, lport, mac, vid, add, flags),\n+\t\t\t       FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_update_mc_addr - Update device multicast address\n+ *  @hw: pointer to the HW structure\n+ *  @lport: logical port ID to update - unused\n+ *  @mac: MAC address to add/remove from table\n+ *  @vid: VLAN ID to add/remove from table\n+ *  @add: Indicates if this is an add or remove operation\n+ *\n+ *  This function is used to add or remove multicast MAC addresses\n+ **/\n+s32 fm10k_update_mc_addr(struct fm10k_hw *hw, u16 lport,\n+\t\t\t const u8 *mac, u16 vid, bool add)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.update_mc_addr,\n+\t\t\t       (hw, lport, mac, vid, add),\n+\t\t\t       FM10K_NOT_IMPLEMENTED);\n+}\n+\n+/**\n+ *  fm10k_adjust_systime - Adjust systime frequency\n+ *  @hw: pointer to hardware structure\n+ *  @ppb: adjustment rate in parts per billion\n+ *\n+ *  This function is meant to update the frequency of the clock represented\n+ *  by the SYSTIME register.\n+ **/\n+s32 fm10k_adjust_systime(struct fm10k_hw *hw, s32 ppb)\n+{\n+\treturn fm10k_call_func(hw, hw->mac.ops.adjust_systime,\n+\t\t\t       (hw, ppb), FM10K_NOT_IMPLEMENTED);\n+}\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_api.h b/lib/librte_pmd_fm10k/base/fm10k_api.h\nnew file mode 100644\nindex 0000000..343d750\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_api.h\n@@ -0,0 +1,61 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#ifndef _FM10K_API_H_\n+#define _FM10K_API_H_\n+\n+#include \"fm10k_pf.h\"\n+#include \"fm10k_vf.h\"\n+\n+s32 fm10k_set_mac_type(struct fm10k_hw *hw);\n+s32 fm10k_reset_hw(struct fm10k_hw *hw);\n+s32 fm10k_init_hw(struct fm10k_hw *hw);\n+s32 fm10k_stop_hw(struct fm10k_hw *hw);\n+s32 fm10k_start_hw(struct fm10k_hw *hw);\n+s32 fm10k_init_shared_code(struct fm10k_hw *hw);\n+s32 fm10k_get_bus_info(struct fm10k_hw *hw);\n+bool fm10k_is_slot_appropriate(struct fm10k_hw *hw);\n+s32 fm10k_update_vlan(struct fm10k_hw *hw, u32 vid, u8 idx, bool set);\n+s32 fm10k_read_mac_addr(struct fm10k_hw *hw);\n+void fm10k_update_hw_stats(struct fm10k_hw *hw, struct fm10k_hw_stats *stats);\n+void fm10k_rebind_hw_stats(struct fm10k_hw *hw, struct fm10k_hw_stats *stats);\n+s32 fm10k_configure_dglort_map(struct fm10k_hw *hw,\n+\t\t\t       struct fm10k_dglort_cfg *dglort);\n+void fm10k_set_dma_mask(struct fm10k_hw *hw, u64 dma_mask);\n+s32 fm10k_get_fault(struct fm10k_hw *hw, int type, struct fm10k_fault *fault);\n+s32 fm10k_update_uc_addr(struct fm10k_hw *hw, u16 lport,\n+\t\t\t  const u8 *mac, u16 vid, bool add, u8 flags);\n+s32 fm10k_update_mc_addr(struct fm10k_hw *hw, u16 lport,\n+\t\t\t const u8 *mac, u16 vid, bool add);\n+s32 fm10k_adjust_systime(struct fm10k_hw *hw, s32 ppb);\n+#endif /* _FM10K_API_H_ */\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_common.c b/lib/librte_pmd_fm10k/base/fm10k_common.c\nnew file mode 100644\nindex 0000000..a90d2f0\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_common.c\n@@ -0,0 +1,572 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#include \"fm10k_common.h\"\n+\n+/**\n+ *  fm10k_get_bus_info_generic - Generic set PCI bus info\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Gets the PCI bus info (speed, width, type) then calls helper function to\n+ *  store this data within the fm10k_hw structure.\n+ **/\n+STATIC s32 fm10k_get_bus_info_generic(struct fm10k_hw *hw)\n+{\n+\tu16 link_cap, link_status, device_cap, device_control;\n+\n+\tDEBUGFUNC(\"fm10k_get_bus_info_generic\");\n+\n+\t/* Get the maximum link width and speed from PCIe config space */\n+\tlink_cap = FM10K_READ_PCI_WORD(hw, FM10K_PCIE_LINK_CAP);\n+\n+\tswitch (link_cap & FM10K_PCIE_LINK_WIDTH) {\n+\tcase FM10K_PCIE_LINK_WIDTH_1:\n+\t\thw->bus_caps.width = fm10k_bus_width_pcie_x1;\n+\t\tbreak;\n+\tcase FM10K_PCIE_LINK_WIDTH_2:\n+\t\thw->bus_caps.width = fm10k_bus_width_pcie_x2;\n+\t\tbreak;\n+\tcase FM10K_PCIE_LINK_WIDTH_4:\n+\t\thw->bus_caps.width = fm10k_bus_width_pcie_x4;\n+\t\tbreak;\n+\tcase FM10K_PCIE_LINK_WIDTH_8:\n+\t\thw->bus_caps.width = fm10k_bus_width_pcie_x8;\n+\t\tbreak;\n+\tdefault:\n+\t\thw->bus_caps.width = fm10k_bus_width_unknown;\n+\t\tbreak;\n+\t}\n+\n+\tswitch (link_cap & FM10K_PCIE_LINK_SPEED) {\n+\tcase FM10K_PCIE_LINK_SPEED_2500:\n+\t\thw->bus_caps.speed = fm10k_bus_speed_2500;\n+\t\tbreak;\n+\tcase FM10K_PCIE_LINK_SPEED_5000:\n+\t\thw->bus_caps.speed = fm10k_bus_speed_5000;\n+\t\tbreak;\n+\tcase FM10K_PCIE_LINK_SPEED_8000:\n+\t\thw->bus_caps.speed = fm10k_bus_speed_8000;\n+\t\tbreak;\n+\tdefault:\n+\t\thw->bus_caps.speed = fm10k_bus_speed_unknown;\n+\t\tbreak;\n+\t}\n+\n+\t/* Get the PCIe maximum payload size for the PCIe function */\n+\tdevice_cap = FM10K_READ_PCI_WORD(hw, FM10K_PCIE_DEV_CAP);\n+\n+\tswitch (device_cap & FM10K_PCIE_DEV_CAP_PAYLOAD) {\n+\tcase FM10K_PCIE_DEV_CAP_PAYLOAD_128:\n+\t\thw->bus_caps.payload = fm10k_bus_payload_128;\n+\t\tbreak;\n+\tcase FM10K_PCIE_DEV_CAP_PAYLOAD_256:\n+\t\thw->bus_caps.payload = fm10k_bus_payload_256;\n+\t\tbreak;\n+\tcase FM10K_PCIE_DEV_CAP_PAYLOAD_512:\n+\t\thw->bus_caps.payload = fm10k_bus_payload_512;\n+\t\tbreak;\n+\tdefault:\n+\t\thw->bus_caps.payload = fm10k_bus_payload_unknown;\n+\t\tbreak;\n+\t}\n+\n+\t/* Get the negotiated link width and speed from PCIe config space */\n+\tlink_status = FM10K_READ_PCI_WORD(hw, FM10K_PCIE_LINK_STATUS);\n+\n+\tswitch (link_status & FM10K_PCIE_LINK_WIDTH) {\n+\tcase FM10K_PCIE_LINK_WIDTH_1:\n+\t\thw->bus.width = fm10k_bus_width_pcie_x1;\n+\t\tbreak;\n+\tcase FM10K_PCIE_LINK_WIDTH_2:\n+\t\thw->bus.width = fm10k_bus_width_pcie_x2;\n+\t\tbreak;\n+\tcase FM10K_PCIE_LINK_WIDTH_4:\n+\t\thw->bus.width = fm10k_bus_width_pcie_x4;\n+\t\tbreak;\n+\tcase FM10K_PCIE_LINK_WIDTH_8:\n+\t\thw->bus.width = fm10k_bus_width_pcie_x8;\n+\t\tbreak;\n+\tdefault:\n+\t\thw->bus.width = fm10k_bus_width_unknown;\n+\t\tbreak;\n+\t}\n+\n+\tswitch (link_status & FM10K_PCIE_LINK_SPEED) {\n+\tcase FM10K_PCIE_LINK_SPEED_2500:\n+\t\thw->bus.speed = fm10k_bus_speed_2500;\n+\t\tbreak;\n+\tcase FM10K_PCIE_LINK_SPEED_5000:\n+\t\thw->bus.speed = fm10k_bus_speed_5000;\n+\t\tbreak;\n+\tcase FM10K_PCIE_LINK_SPEED_8000:\n+\t\thw->bus.speed = fm10k_bus_speed_8000;\n+\t\tbreak;\n+\tdefault:\n+\t\thw->bus.speed = fm10k_bus_speed_unknown;\n+\t\tbreak;\n+\t}\n+\n+\t/* Get the negotiated PCIe maximum payload size for the PCIe function */\n+\tdevice_control = FM10K_READ_PCI_WORD(hw, FM10K_PCIE_DEV_CTRL);\n+\n+\tswitch (device_control & FM10K_PCIE_DEV_CTRL_PAYLOAD) {\n+\tcase FM10K_PCIE_DEV_CTRL_PAYLOAD_128:\n+\t\thw->bus.payload = fm10k_bus_payload_128;\n+\t\tbreak;\n+\tcase FM10K_PCIE_DEV_CTRL_PAYLOAD_256:\n+\t\thw->bus.payload = fm10k_bus_payload_256;\n+\t\tbreak;\n+\tcase FM10K_PCIE_DEV_CTRL_PAYLOAD_512:\n+\t\thw->bus.payload = fm10k_bus_payload_512;\n+\t\tbreak;\n+\tdefault:\n+\t\thw->bus.payload = fm10k_bus_payload_unknown;\n+\t\tbreak;\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+u16 fm10k_get_pcie_msix_count_generic(struct fm10k_hw *hw)\n+{\n+\tu16 msix_count;\n+\n+\tDEBUGFUNC(\"fm10k_get_pcie_msix_count_generic\");\n+\n+\t/* read in value from MSI-X capability register */\n+\tmsix_count = FM10K_READ_PCI_WORD(hw, FM10K_PCI_MSIX_MSG_CTRL);\n+\tmsix_count &= FM10K_PCI_MSIX_MSG_CTRL_TBL_SZ_MASK;\n+\n+\t/* MSI-X count is zero-based in HW */\n+\tmsix_count++;\n+\n+\tif (msix_count > FM10K_MAX_MSIX_VECTORS)\n+\t\tmsix_count = FM10K_MAX_MSIX_VECTORS;\n+\n+\treturn msix_count;\n+}\n+\n+/**\n+ *  fm10k_init_ops_generic - Inits function ptrs\n+ *  @hw: pointer to the hardware structure\n+ *\n+ *  Initialize the function pointers.\n+ **/\n+s32 fm10k_init_ops_generic(struct fm10k_hw *hw)\n+{\n+\tstruct fm10k_mac_info *mac = &hw->mac;\n+\n+\tDEBUGFUNC(\"fm10k_init_ops_generic\");\n+\n+\t/* MAC */\n+\tmac->ops.get_bus_info = &fm10k_get_bus_info_generic;\n+\n+\t/* initialize GLORT state to avoid any false hits */\n+\tmac->dglort_map = FM10K_DGLORTMAP_NONE;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_start_hw_generic - Prepare hardware for Tx/Rx\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This function sets the Tx ready flag to indicate that the Tx path has\n+ *  been initialized.\n+ **/\n+s32 fm10k_start_hw_generic(struct fm10k_hw *hw)\n+{\n+\tDEBUGFUNC(\"fm10k_start_hw_generic\");\n+\n+\t/* set flag indicating we are beginning Tx */\n+\thw->mac.tx_ready = true;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_disable_queues_generic - Stop Tx/Rx queues\n+ *  @hw: pointer to hardware structure\n+ *  @q_cnt: number of queues to be disabled\n+ *\n+ **/\n+s32 fm10k_disable_queues_generic(struct fm10k_hw *hw, u16 q_cnt)\n+{\n+\tu32 reg;\n+\tu16 i, time;\n+\n+\tDEBUGFUNC(\"fm10k_disable_queues_generic\");\n+\n+\t/* clear tx_ready to prevent any false hits for reset */\n+\thw->mac.tx_ready = false;\n+\n+\t/* clear the enable bit for all rings */\n+\tfor (i = 0; i < q_cnt; i++) {\n+\t\treg = FM10K_READ_REG(hw, FM10K_TXDCTL(i));\n+\t\tFM10K_WRITE_REG(hw, FM10K_TXDCTL(i),\n+\t\t\t\treg & ~FM10K_TXDCTL_ENABLE);\n+\t\treg = FM10K_READ_REG(hw, FM10K_RXQCTL(i));\n+\t\tFM10K_WRITE_REG(hw, FM10K_RXQCTL(i),\n+\t\t\t\treg & ~FM10K_RXQCTL_ENABLE);\n+\t}\n+\n+\tFM10K_WRITE_FLUSH(hw);\n+\tusec_delay(1);\n+\n+\t/* loop through all queues to verify that they are all disabled */\n+\tfor (i = 0, time = FM10K_QUEUE_DISABLE_TIMEOUT; time;) {\n+\t\t/* if we are at end of rings all rings are disabled */\n+\t\tif (i == q_cnt)\n+\t\t\treturn FM10K_SUCCESS;\n+\n+\t\t/* if queue enables cleared, then move to next ring pair */\n+\t\treg = FM10K_READ_REG(hw, FM10K_TXDCTL(i));\n+\t\tif (!~reg || !(reg & FM10K_TXDCTL_ENABLE)) {\n+\t\t\treg = FM10K_READ_REG(hw, FM10K_RXQCTL(i));\n+\t\t\tif (!~reg || !(reg & FM10K_RXQCTL_ENABLE)) {\n+\t\t\t\ti++;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* decrement time and wait 1 usec */\n+\t\ttime--;\n+\t\tif (time)\n+\t\t\tusec_delay(1);\n+\t}\n+\n+\treturn FM10K_ERR_REQUESTS_PENDING;\n+}\n+\n+/**\n+ *  fm10k_stop_hw_generic - Stop Tx/Rx units\n+ *  @hw: pointer to hardware structure\n+ *\n+ **/\n+s32 fm10k_stop_hw_generic(struct fm10k_hw *hw)\n+{\n+\tDEBUGFUNC(\"fm10k_stop_hw_generic\");\n+\n+\treturn fm10k_disable_queues_generic(hw, hw->mac.max_queues);\n+}\n+\n+/**\n+ *  fm10k_read_hw_stats_32b - Reads value of 32-bit registers\n+ *  @hw: pointer to the hardware structure\n+ *  @addr: address of register containing a 32-bit value\n+ *\n+ *  Function reads the content of the register and returns the delta\n+ *  between the base and the current value.\n+ *  **/\n+u32 fm10k_read_hw_stats_32b(struct fm10k_hw *hw, u32 addr,\n+\t\t\t    struct fm10k_hw_stat *stat)\n+{\n+\tu32 delta = FM10K_READ_REG(hw, addr) - stat->base_l;\n+\n+\tDEBUGFUNC(\"fm10k_read_hw_stats_32b\");\n+\n+\tif (FM10K_REMOVED(hw->hw_addr))\n+\t\tstat->base_h = 0;\n+\n+\treturn delta;\n+}\n+\n+/**\n+ *  fm10k_read_hw_stats_48b - Reads value of 48-bit registers\n+ *  @hw: pointer to the hardware structure\n+ *  @addr: address of register containing the lower 32-bit value\n+ *\n+ *  Function reads the content of 2 registers, combined to represent a 48-bit\n+ *  statistical value. Extra processing is required to handle overflowing.\n+ *  Finally, a delta value is returned representing the difference between the\n+ *  values stored in registers and values stored in the statistic counters.\n+ *  **/\n+STATIC u64 fm10k_read_hw_stats_48b(struct fm10k_hw *hw, u32 addr,\n+\t\t\t\t   struct fm10k_hw_stat *stat)\n+{\n+\tu32 count_l;\n+\tu32 count_h;\n+\tu32 count_tmp;\n+\tu64 delta;\n+\n+\tDEBUGFUNC(\"fm10k_read_hw_stats_48b\");\n+\n+\tcount_h = FM10K_READ_REG(hw, addr + 1);\n+\n+\t/* Check for overflow */\n+\tdo {\n+\t\tcount_tmp = count_h;\n+\t\tcount_l = FM10K_READ_REG(hw, addr);\n+\t\tcount_h = FM10K_READ_REG(hw, addr + 1);\n+\t} while (count_h != count_tmp);\n+\n+\tdelta = ((u64)(count_h - stat->base_h) << 32) + count_l;\n+\tdelta -= stat->base_l;\n+\n+\treturn delta & FM10K_48_BIT_MASK;\n+}\n+\n+/**\n+ *  fm10k_update_hw_base_48b - Updates 48-bit statistic base value\n+ *  @stat: pointer to the hardware statistic structure\n+ *  @delta: value to be updated into the hardware statistic structure\n+ *\n+ *  Function receives a value and determines if an update is required based on\n+ *  a delta calculation. Only the base value will be updated.\n+ **/\n+STATIC void fm10k_update_hw_base_48b(struct fm10k_hw_stat *stat, u64 delta)\n+{\n+\tDEBUGFUNC(\"fm10k_update_hw_base_48b\");\n+\n+\tif (!delta)\n+\t\treturn;\n+\n+\t/* update lower 32 bits */\n+\tdelta += stat->base_l;\n+\tstat->base_l = (u32)delta;\n+\n+\t/* update upper 32 bits */\n+\tstat->base_h += (u32)(delta >> 32);\n+}\n+\n+/**\n+ *  fm10k_update_hw_stats_tx_q - Updates TX queue statistics counters\n+ *  @hw: pointer to the hardware structure\n+ *  @q: pointer to the ring of hardware statistics queue\n+ *  @idx: index pointing to the start of the ring iteration\n+ *\n+ *  Function updates the TX queue statistics counters that are related to the\n+ *  hardware.\n+ **/\n+STATIC void fm10k_update_hw_stats_tx_q(struct fm10k_hw *hw,\n+\t\t\t\t       struct fm10k_hw_stats_q *q,\n+\t\t\t\t       u32 idx)\n+{\n+\tu32 id_tx, id_tx_prev, tx_packets;\n+\tu64 tx_bytes = 0;\n+\n+\tDEBUGFUNC(\"fm10k_update_hw_stats_tx_q\");\n+\n+\t/* Retrieve TX Owner Data */\n+\tid_tx = FM10K_READ_REG(hw, FM10K_TXQCTL(idx));\n+\n+\t/* Process TX Ring */\n+\tdo {\n+\t\ttx_packets = fm10k_read_hw_stats_32b(hw, FM10K_QPTC(idx),\n+\t\t\t\t\t\t     &q->tx_packets);\n+\n+\t\tif (tx_packets)\n+\t\t\ttx_bytes = fm10k_read_hw_stats_48b(hw,\n+\t\t\t\t\t\t\t   FM10K_QBTC_L(idx),\n+\t\t\t\t\t\t\t   &q->tx_bytes);\n+\n+\t\t/* Re-Check Owner Data */\n+\t\tid_tx_prev = id_tx;\n+\t\tid_tx = FM10K_READ_REG(hw, FM10K_TXQCTL(idx));\n+\t} while ((id_tx ^ id_tx_prev) & FM10K_TXQCTL_ID_MASK);\n+\n+\t/* drop non-ID bits and set VALID ID bit */\n+\tid_tx &= FM10K_TXQCTL_ID_MASK;\n+\tid_tx |= FM10K_STAT_VALID;\n+\n+\t/* update packet counts */\n+\tif (q->tx_stats_idx == id_tx) {\n+\t\tq->tx_packets.count += tx_packets;\n+\t\tq->tx_bytes.count += tx_bytes;\n+\t}\n+\n+\t/* update bases and record ID */\n+\tfm10k_update_hw_base_32b(&q->tx_packets, tx_packets);\n+\tfm10k_update_hw_base_48b(&q->tx_bytes, tx_bytes);\n+\n+\tq->tx_stats_idx = id_tx;\n+}\n+\n+/**\n+ *  fm10k_update_hw_stats_rx_q - Updates RX queue statistics counters\n+ *  @hw: pointer to the hardware structure\n+ *  @q: pointer to the ring of hardware statistics queue\n+ *  @idx: index pointing to the start of the ring iteration\n+ *\n+ *  Function updates the RX queue statistics counters that are related to the\n+ *  hardware.\n+ **/\n+STATIC void fm10k_update_hw_stats_rx_q(struct fm10k_hw *hw,\n+\t\t\t\t       struct fm10k_hw_stats_q *q,\n+\t\t\t\t       u32 idx)\n+{\n+\tu32 id_rx, id_rx_prev, rx_packets, rx_drops;\n+\tu64 rx_bytes = 0;\n+\n+\tDEBUGFUNC(\"fm10k_update_hw_stats_rx_q\");\n+\n+\t/* Retrieve RX Owner Data */\n+\tid_rx = FM10K_READ_REG(hw, FM10K_RXQCTL(idx));\n+\n+\t/* Process RX Ring */\n+\tdo {\n+\t\trx_drops = fm10k_read_hw_stats_32b(hw, FM10K_QPRDC(idx),\n+\t\t\t\t\t\t   &q->rx_drops);\n+\n+\t\trx_packets = fm10k_read_hw_stats_32b(hw, FM10K_QPRC(idx),\n+\t\t\t\t\t\t     &q->rx_packets);\n+\n+\t\tif (rx_packets)\n+\t\t\trx_bytes = fm10k_read_hw_stats_48b(hw,\n+\t\t\t\t\t\t\t   FM10K_QBRC_L(idx),\n+\t\t\t\t\t\t\t   &q->rx_bytes);\n+\n+\t\t/* Re-Check Owner Data */\n+\t\tid_rx_prev = id_rx;\n+\t\tid_rx = FM10K_READ_REG(hw, FM10K_RXQCTL(idx));\n+\t} while ((id_rx ^ id_rx_prev) & FM10K_RXQCTL_ID_MASK);\n+\n+\t/* drop non-ID bits and set VALID ID bit */\n+\tid_rx &= FM10K_RXQCTL_ID_MASK;\n+\tid_rx |= FM10K_STAT_VALID;\n+\n+\t/* update packet counts */\n+\tif (q->rx_stats_idx == id_rx) {\n+\t\tq->rx_drops.count += rx_drops;\n+\t\tq->rx_packets.count += rx_packets;\n+\t\tq->rx_bytes.count += rx_bytes;\n+\t}\n+\n+\t/* update bases and record ID */\n+\tfm10k_update_hw_base_32b(&q->rx_drops, rx_drops);\n+\tfm10k_update_hw_base_32b(&q->rx_packets, rx_packets);\n+\tfm10k_update_hw_base_48b(&q->rx_bytes, rx_bytes);\n+\n+\tq->rx_stats_idx = id_rx;\n+}\n+\n+/**\n+ *  fm10k_update_hw_stats_q - Updates queue statistics counters\n+ *  @hw: pointer to the hardware structure\n+ *  @q: pointer to the ring of hardware statistics queue\n+ *  @idx: index pointing to the start of the ring iteration\n+ *  @count: number of queues to iterate over\n+ *\n+ *  Function updates the queue statistics counters that are related to the\n+ *  hardware.\n+ **/\n+void fm10k_update_hw_stats_q(struct fm10k_hw *hw, struct fm10k_hw_stats_q *q,\n+\t\t\t     u32 idx, u32 count)\n+{\n+\tu32 i;\n+\n+\tDEBUGFUNC(\"fm10k_update_hw_stats_q\");\n+\n+\tfor (i = 0; i < count; i++, idx++, q++) {\n+\t\tfm10k_update_hw_stats_tx_q(hw, q, idx);\n+\t\tfm10k_update_hw_stats_rx_q(hw, q, idx);\n+\t}\n+}\n+\n+/**\n+ *  fm10k_unbind_hw_stats_q - Unbind the queue counters from their queues\n+ *  @hw: pointer to the hardware structure\n+ *  @q: pointer to the ring of hardware statistics queue\n+ *  @idx: index pointing to the start of the ring iteration\n+ *  @count: number of queues to iterate over\n+ *\n+ *  Function invalidates the index values for the queues so any updates that\n+ *  may have happened are ignored and the base for the queue stats is reset.\n+ **/\n+void fm10k_unbind_hw_stats_q(struct fm10k_hw_stats_q *q, u32 idx, u32 count)\n+{\n+\tu32 i;\n+\n+\tfor (i = 0; i < count; i++, idx++, q++) {\n+\t\tq->rx_stats_idx = 0;\n+\t\tq->tx_stats_idx = 0;\n+\t}\n+}\n+\n+/**\n+ *  fm10k_get_host_state_generic - Returns the state of the host\n+ *  @hw: pointer to hardware structure\n+ *  @host_ready: pointer to boolean value that will record host state\n+ *\n+ *  This function will check the health of the mailbox and Tx queue 0\n+ *  in order to determine if we should report that the link is up or not.\n+ **/\n+s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tstruct fm10k_mac_info *mac = &hw->mac;\n+\ts32 ret_val = FM10K_SUCCESS;\n+\tu32 txdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(0));\n+\n+\tDEBUGFUNC(\"fm10k_get_host_state_generic\");\n+\n+\t/* process upstream mailbox in case interrupts were disabled */\n+\tmbx->ops.process(hw, mbx);\n+\n+\t/* If Tx is no longer enabled link should come down */\n+\tif (!(~txdctl) || !(txdctl & FM10K_TXDCTL_ENABLE))\n+\t\tmac->get_host_state = true;\n+\n+\t/* exit if not checking for link, or link cannot be changed */\n+\tif (!mac->get_host_state || !(~txdctl))\n+\t\tgoto out;\n+\n+\t/* if we somehow dropped the Tx enable we should reset */\n+\tif (hw->mac.tx_ready && !(txdctl & FM10K_TXDCTL_ENABLE)) {\n+\t\tret_val = FM10K_ERR_RESET_REQUESTED;\n+\t\tgoto out;\n+\t}\n+\n+\t/* if Mailbox timed out we should request reset */\n+\tif (!mbx->timeout) {\n+\t\tret_val = FM10K_ERR_RESET_REQUESTED;\n+\t\tgoto out;\n+\t}\n+\n+\t/* verify Mailbox is still valid */\n+\tif (!mbx->ops.tx_ready(mbx, FM10K_VFMBX_MSG_MTU))\n+\t\tgoto out;\n+\n+\t/* interface cannot receive traffic without logical ports */\n+\tif (mac->dglort_map == FM10K_DGLORTMAP_NONE)\n+\t\tgoto out;\n+\n+\t/* if we passed all the tests above then the switch is ready and we no\n+\t * longer need to check for link\n+\t */\n+\tmac->get_host_state = false;\n+\n+out:\n+\t*host_ready = !mac->get_host_state;\n+\treturn ret_val;\n+}\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_common.h b/lib/librte_pmd_fm10k/base/fm10k_common.h\nnew file mode 100644\nindex 0000000..45fbbc0\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_common.h\n@@ -0,0 +1,52 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#ifndef _FM10K_COMMON_H_\n+#define _FM10K_COMMON_H_\n+\n+#include \"fm10k_type.h\"\n+\n+u16 fm10k_get_pcie_msix_count_generic(struct fm10k_hw *hw);\n+s32 fm10k_init_ops_generic(struct fm10k_hw *hw);\n+s32 fm10k_disable_queues_generic(struct fm10k_hw *hw, u16 q_cnt);\n+s32 fm10k_start_hw_generic(struct fm10k_hw *hw);\n+s32 fm10k_stop_hw_generic(struct fm10k_hw *hw);\n+u32 fm10k_read_hw_stats_32b(struct fm10k_hw *hw, u32 addr,\n+\t\t\t    struct fm10k_hw_stat *stat);\n+#define fm10k_update_hw_base_32b(stat, delta) ((stat)->base_l += (delta))\n+void fm10k_update_hw_stats_q(struct fm10k_hw *hw, struct fm10k_hw_stats_q *q,\n+\t\t\t     u32 idx, u32 count);\n+#define fm10k_unbind_hw_stats_32b(s) ((s)->base_h = 0)\n+void fm10k_unbind_hw_stats_q(struct fm10k_hw_stats_q *q, u32 idx, u32 count);\n+s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready);\n+#endif /* _FM10K_COMMON_H_ */\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_mbx.c b/lib/librte_pmd_fm10k/base/fm10k_mbx.c\nnew file mode 100644\nindex 0000000..2081414\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_mbx.c\n@@ -0,0 +1,2185 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#include \"fm10k_common.h\"\n+\n+/**\n+ *  fm10k_fifo_init - Initialize a message FIFO\n+ *  @fifo: pointer to FIFO\n+ *  @buffer: pointer to memory to be used to store FIFO\n+ *  @size: maximum message size to store in FIFO, must be 2^n - 1\n+ **/\n+STATIC void fm10k_fifo_init(struct fm10k_mbx_fifo *fifo, u32 *buffer, u16 size)\n+{\n+\tfifo->buffer = buffer;\n+\tfifo->size = size;\n+\tfifo->head = 0;\n+\tfifo->tail = 0;\n+}\n+\n+/**\n+ *  fm10k_fifo_used - Retrieve used space in FIFO\n+ *  @fifo: pointer to FIFO\n+ *\n+ *  This function returns the number of DWORDs used in the FIFO\n+ **/\n+STATIC u16 fm10k_fifo_used(struct fm10k_mbx_fifo *fifo)\n+{\n+\treturn fifo->tail - fifo->head;\n+}\n+\n+/**\n+ *  fm10k_fifo_unused - Retrieve unused space in FIFO\n+ *  @fifo: pointer to FIFO\n+ *\n+ *  This function returns the number of unused DWORDs in the FIFO\n+ **/\n+STATIC u16 fm10k_fifo_unused(struct fm10k_mbx_fifo *fifo)\n+{\n+\treturn fifo->size + fifo->head - fifo->tail;\n+}\n+\n+/**\n+ *  fm10k_fifo_empty - Test to verify if fifo is empty\n+ *  @fifo: pointer to FIFO\n+ *\n+ *  This function returns true if the FIFO is empty, else false\n+ **/\n+STATIC bool fm10k_fifo_empty(struct fm10k_mbx_fifo *fifo)\n+{\n+\treturn fifo->head == fifo->tail;\n+}\n+\n+/**\n+ *  fm10k_fifo_head_offset - returns indices of head with given offset\n+ *  @fifo: pointer to FIFO\n+ *  @offset: offset to add to head\n+ *\n+ *  This function returns the indices into the fifo based on head + offset\n+ **/\n+STATIC u16 fm10k_fifo_head_offset(struct fm10k_mbx_fifo *fifo, u16 offset)\n+{\n+\treturn (fifo->head + offset) & (fifo->size - 1);\n+}\n+\n+/**\n+ *  fm10k_fifo_tail_offset - returns indices of tail with given offset\n+ *  @fifo: pointer to FIFO\n+ *  @offset: offset to add to tail\n+ *\n+ *  This function returns the indices into the fifo based on tail + offset\n+ **/\n+STATIC u16 fm10k_fifo_tail_offset(struct fm10k_mbx_fifo *fifo, u16 offset)\n+{\n+\treturn (fifo->tail + offset) & (fifo->size - 1);\n+}\n+\n+/**\n+ *  fm10k_fifo_head_len - Retrieve length of first message in FIFO\n+ *  @fifo: pointer to FIFO\n+ *\n+ *  This function returns the size of the first message in the FIFO\n+ **/\n+STATIC u16 fm10k_fifo_head_len(struct fm10k_mbx_fifo *fifo)\n+{\n+\tu32 *head = fifo->buffer + fm10k_fifo_head_offset(fifo, 0);\n+\n+\t/* verify there is at least 1 DWORD in the fifo so *head is valid */\n+\tif (fm10k_fifo_empty(fifo))\n+\t\treturn 0;\n+\n+\t/* retieve the message length */\n+\treturn FM10K_TLV_DWORD_LEN(*head);\n+}\n+\n+/**\n+ *  fm10k_fifo_head_drop - Drop the first message in FIFO\n+ *  @fifo: pointer to FIFO\n+ *\n+ *  This function returns the size of the message dropped from the FIFO\n+ **/\n+STATIC u16 fm10k_fifo_head_drop(struct fm10k_mbx_fifo *fifo)\n+{\n+\tu16 len = fm10k_fifo_head_len(fifo);\n+\n+\t/* update head so it is at the start of next frame */\n+\tfifo->head += len;\n+\n+\treturn len;\n+}\n+\n+/**\n+ *  fm10k_mbx_index_len - Convert a head/tail index into a length value\n+ *  @mbx: pointer to mailbox\n+ *  @head: head index\n+ *  @tail: head index\n+ *\n+ *  This function takes the head and tail index and determines the length\n+ *  of the data indicated by this pair.\n+ **/\n+STATIC u16 fm10k_mbx_index_len(struct fm10k_mbx_info *mbx, u16 head, u16 tail)\n+{\n+\tu16 len = tail - head;\n+\n+\t/* we wrapped so subtract 2, one for index 0, one for all 1s index */\n+\tif (len > tail)\n+\t\tlen -= 2;\n+\n+\treturn len & ((mbx->mbmem_len << 1) - 1);\n+}\n+\n+/**\n+ *  fm10k_mbx_tail_add - Determine new tail value with added offset\n+ *  @mbx: pointer to mailbox\n+ *  @offset: length to add to head offset\n+ *\n+ *  This function takes the local tail index and recomputes it for\n+ *  a given length added as an offset.\n+ **/\n+STATIC u16 fm10k_mbx_tail_add(struct fm10k_mbx_info *mbx, u16 offset)\n+{\n+\tu16 tail = (mbx->tail + offset + 1) & ((mbx->mbmem_len << 1) - 1);\n+\n+\t/* add/sub 1 because we cannot have offset 0 or all 1s */\n+\treturn (tail > mbx->tail) ? --tail : ++tail;\n+}\n+\n+/**\n+ *  fm10k_mbx_tail_sub - Determine new tail value with subtracted offset\n+ *  @mbx: pointer to mailbox\n+ *  @offset: length to add to head offset\n+ *\n+ *  This function takes the local tail index and recomputes it for\n+ *  a given length added as an offset.\n+ **/\n+STATIC u16 fm10k_mbx_tail_sub(struct fm10k_mbx_info *mbx, u16 offset)\n+{\n+\tu16 tail = (mbx->tail - offset - 1) & ((mbx->mbmem_len << 1) - 1);\n+\n+\t/* sub/add 1 because we cannot have offset 0 or all 1s */\n+\treturn (tail < mbx->tail) ? ++tail : --tail;\n+}\n+\n+/**\n+ *  fm10k_mbx_head_add - Determine new head value with added offset\n+ *  @mbx: pointer to mailbox\n+ *  @offset: length to add to head offset\n+ *\n+ *  This function takes the local head index and recomputes it for\n+ *  a given length added as an offset.\n+ **/\n+STATIC u16 fm10k_mbx_head_add(struct fm10k_mbx_info *mbx, u16 offset)\n+{\n+\tu16 head = (mbx->head + offset + 1) & ((mbx->mbmem_len << 1) - 1);\n+\n+\t/* add/sub 1 because we cannot have offset 0 or all 1s */\n+\treturn (head > mbx->head) ? --head : ++head;\n+}\n+\n+/**\n+ *  fm10k_mbx_head_sub - Determine new head value with subtracted offset\n+ *  @mbx: pointer to mailbox\n+ *  @offset: length to add to head offset\n+ *\n+ *  This function takes the local head index and recomputes it for\n+ *  a given length added as an offset.\n+ **/\n+STATIC u16 fm10k_mbx_head_sub(struct fm10k_mbx_info *mbx, u16 offset)\n+{\n+\tu16 head = (mbx->head - offset - 1) & ((mbx->mbmem_len << 1) - 1);\n+\n+\t/* sub/add 1 because we cannot have offset 0 or all 1s */\n+\treturn (head < mbx->head) ? ++head : --head;\n+}\n+\n+/**\n+ *  fm10k_mbx_pushed_tail_len - Retrieve the length of message being pushed\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will return the length of the message currently being\n+ *  pushed onto the tail of the Rx queue.\n+ **/\n+STATIC u16 fm10k_mbx_pushed_tail_len(struct fm10k_mbx_info *mbx)\n+{\n+\tu32 *tail = mbx->rx.buffer + fm10k_fifo_tail_offset(&mbx->rx, 0);\n+\n+\t/* pushed tail is only valid if pushed is set */\n+\tif (!mbx->pushed)\n+\t\treturn 0;\n+\n+\treturn FM10K_TLV_DWORD_LEN(*tail);\n+}\n+\n+/**\n+ *  fm10k_fifo_write_copy - pulls data off of msg and places it in fifo\n+ *  @fifo: pointer to FIFO\n+ *  @msg: message array to populate\n+ *  @tail_offset: additional offset to add to tail pointer\n+ *  @len: length of FIFO to copy into message header\n+ *\n+ *  This function will take a message and copy it into a section of the\n+ *  FIFO.  In order to get something into a location other than just\n+ *  the tail you can use tail_offset to adjust the pointer.\n+ **/\n+STATIC void fm10k_fifo_write_copy(struct fm10k_mbx_fifo *fifo,\n+\t\t\t\t  const u32 *msg, u16 tail_offset, u16 len)\n+{\n+\tu16 end = fm10k_fifo_tail_offset(fifo, tail_offset);\n+\tu32 *tail = fifo->buffer + end;\n+\n+\t/* track when we should cross the end of the FIFO */\n+\tend = fifo->size - end;\n+\n+\t/* copy end of message before start of message */\n+\tif (end < len)\n+\t\tmemcpy(fifo->buffer, msg + end, (len - end) << 2);\n+\telse\n+\t\tend = len;\n+\n+\t/* Copy remaining message into Tx FIFO */\n+\tmemcpy(tail, msg, end << 2);\n+}\n+\n+/**\n+ *  fm10k_fifo_enqueue - Enqueues the message to the tail of the FIFO\n+ *  @fifo: pointer to FIFO\n+ *  @msg: message array to read\n+ *\n+ *  This function enqueues a message up to the size specified by the length\n+ *  contained in the first DWORD of the message and will place at the tail\n+ *  of the FIFO.  It will return 0 on success, or a negative value on error.\n+ **/\n+STATIC s32 fm10k_fifo_enqueue(struct fm10k_mbx_fifo *fifo, const u32 *msg)\n+{\n+\tu16 len = FM10K_TLV_DWORD_LEN(*msg);\n+\n+\tDEBUGFUNC(\"fm10k_fifo_enqueue\");\n+\n+\t/* verify parameters */\n+\tif (len > fifo->size)\n+\t\treturn FM10K_MBX_ERR_SIZE;\n+\n+\t/* verify there is room for the message */\n+\tif (len > fm10k_fifo_unused(fifo))\n+\t\treturn FM10K_MBX_ERR_NO_SPACE;\n+\n+\t/* Copy message into FIFO */\n+\tfm10k_fifo_write_copy(fifo, msg, 0, len);\n+\n+\t/* memory barrier to guarantee FIFO is written before tail update */\n+\tFM10K_WMB();\n+\n+\t/* Update Tx FIFO tail */\n+\tfifo->tail += len;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_mbx_validate_msg_size - Validate incoming message based on size\n+ *  @mbx: pointer to mailbox\n+ *  @len: length of data pushed onto buffer\n+ *\n+ *  This function analyzes the frame and will return a non-zero value when\n+ *  the start of a message larger than the mailbox is detected.\n+ **/\n+STATIC u16 fm10k_mbx_validate_msg_size(struct fm10k_mbx_info *mbx, u16 len)\n+{\n+\tstruct fm10k_mbx_fifo *fifo = &mbx->rx;\n+\tu16 total_len = 0, msg_len;\n+\tu32 *msg;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_validate_msg\");\n+\n+\t/* length should include previous amounts pushed */\n+\tlen += mbx->pushed;\n+\n+\t/* offset in message is based off of current message size */\n+\tdo {\n+\t\tmsg = fifo->buffer + fm10k_fifo_tail_offset(fifo, total_len);\n+\t\tmsg_len = FM10K_TLV_DWORD_LEN(*msg);\n+\t\ttotal_len += msg_len;\n+\t} while (total_len < len);\n+\n+\t/* message extends out of pushed section, but fits in FIFO */\n+\tif ((len < total_len) && (msg_len <= mbx->rx.size))\n+\t\treturn 0;\n+\n+\t/* return length of invalid section */\n+\treturn (len < total_len) ? len : (len - total_len);\n+}\n+\n+/**\n+ *  fm10k_mbx_write_copy - pulls data off of Tx FIFO and places it in mbmem\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will take a section of the Rx FIFO and copy it into the\n+\t\tmbx->tail--;\n+ *  mailbox memory.  The offset in mbmem is based on the lower bits of the\n+ *  tail and len determines the length to copy.\n+ **/\n+STATIC void fm10k_mbx_write_copy(struct fm10k_hw *hw,\n+\t\t\t\t struct fm10k_mbx_info *mbx)\n+{\n+\tstruct fm10k_mbx_fifo *fifo = &mbx->tx;\n+\tu32 mbmem = mbx->mbmem_reg;\n+\tu32 *head = fifo->buffer;\n+\tu16 end, len, tail, mask;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_write_copy\");\n+\n+\tif (!mbx->tail_len)\n+\t\treturn;\n+\n+\t/* determine data length and mbmem tail index */\n+\tmask = mbx->mbmem_len - 1;\n+\tlen = mbx->tail_len;\n+\ttail = fm10k_mbx_tail_sub(mbx, len);\n+\tif (tail > mask)\n+\t\ttail++;\n+\n+\t/* determine offset in the ring */\n+\tend = fm10k_fifo_head_offset(fifo, mbx->pulled);\n+\thead += end;\n+\n+\t/* memory barrier to guarantee data is ready to be read */\n+\tFM10K_RMB();\n+\n+\t/* Copy message from Tx FIFO */\n+\tfor (end = fifo->size - end; len; head = fifo->buffer) {\n+\t\tdo {\n+\t\t\t/* adjust tail to match offset for FIFO */\n+\t\t\ttail &= mask;\n+\t\t\tif (!tail)\n+\t\t\t\ttail++;\n+\n+\t\t\t/* write message to hardware FIFO */\n+\t\t\tFM10K_WRITE_MBX(hw, mbmem + tail++, *(head++));\n+\t\t} while (--len && --end);\n+\t}\n+}\n+\n+/**\n+ *  fm10k_mbx_pull_head - Pulls data off of head of Tx FIFO\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *  @head: acknowledgement number last received\n+ *\n+ *  This function will push the tail index forward based on the remote\n+ *  head index.  It will then pull up to mbmem_len DWORDs off of the\n+ *  head of the FIFO and will place it in the MBMEM registers\n+ *  associated with the mailbox.\n+ **/\n+STATIC void fm10k_mbx_pull_head(struct fm10k_hw *hw,\n+\t\t\t\tstruct fm10k_mbx_info *mbx, u16 head)\n+{\n+\tu16 mbmem_len, len, ack = fm10k_mbx_index_len(mbx, head, mbx->tail);\n+\tstruct fm10k_mbx_fifo *fifo = &mbx->tx;\n+\n+\t/* update number of bytes pulled and update bytes in transit */\n+\tmbx->pulled += mbx->tail_len - ack;\n+\n+\t/* determine length of data to pull, reserve space for mbmem header */\n+\tmbmem_len = mbx->mbmem_len - 1;\n+\tlen = fm10k_fifo_used(fifo) - mbx->pulled;\n+\tif (len > mbmem_len)\n+\t\tlen = mbmem_len;\n+\n+\t/* update tail and record number of bytes in transit */\n+\tmbx->tail = fm10k_mbx_tail_add(mbx, len - ack);\n+\tmbx->tail_len = len;\n+\n+\t/* drop pulled messages from the FIFO */\n+\tfor (len = fm10k_fifo_head_len(fifo);\n+\t     len && (mbx->pulled >= len);\n+\t     len = fm10k_fifo_head_len(fifo)) {\n+\t\tmbx->pulled -= fm10k_fifo_head_drop(fifo);\n+\t\tmbx->tx_messages++;\n+\t\tmbx->tx_dwords += len;\n+\t}\n+\n+\t/* Copy message out from the Tx FIFO */\n+\tfm10k_mbx_write_copy(hw, mbx);\n+}\n+\n+/**\n+ *  fm10k_mbx_read_copy - pulls data off of mbmem and places it in Rx FIFO\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will take a section of the mailbox memory and copy it\n+ *  into the Rx FIFO.  The offset is based on the lower bits of the\n+ *  head and len determines the length to copy.\n+ **/\n+STATIC void fm10k_mbx_read_copy(struct fm10k_hw *hw,\n+\t\t\t\tstruct fm10k_mbx_info *mbx)\n+{\n+\tstruct fm10k_mbx_fifo *fifo = &mbx->rx;\n+\tu32 mbmem = mbx->mbmem_reg ^ mbx->mbmem_len;\n+\tu32 *tail = fifo->buffer;\n+\tu16 end, len, head;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_read_copy\");\n+\n+\t/* determine data length and mbmem head index */\n+\tlen = mbx->head_len;\n+\thead = fm10k_mbx_head_sub(mbx, len);\n+\tif (head >= mbx->mbmem_len)\n+\t\thead++;\n+\n+\t/* determine offset in the ring */\n+\tend = fm10k_fifo_tail_offset(fifo, mbx->pushed);\n+\ttail += end;\n+\n+\t/* Copy message into Rx FIFO */\n+\tfor (end = fifo->size - end; len; tail = fifo->buffer) {\n+\t\tdo {\n+\t\t\t/* adjust head to match offset for FIFO */\n+\t\t\thead &= mbx->mbmem_len - 1;\n+\t\t\tif (!head)\n+\t\t\t\thead++;\n+\n+\t\t\t/* read message from hardware FIFO */\n+\t\t\t*(tail++) = FM10K_READ_MBX(hw, mbmem + head++);\n+\t\t} while (--len && --end);\n+\t}\n+\n+\t/* memory barrier to guarantee FIFO is written before tail update */\n+\tFM10K_WMB();\n+}\n+\n+/**\n+ *  fm10k_mbx_push_tail - Pushes up to 15 DWORDs on to tail of FIFO\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *  @tail: tail index of message\n+ *\n+ *  This function will first validate the tail index and size for the\n+ *  incoming message.  It then updates the acknowledgment number and\n+ *  copies the data into the FIFO.  It will return the number of messages\n+ *  dequeued on success and a negative value on error.\n+ **/\n+STATIC s32 fm10k_mbx_push_tail(struct fm10k_hw *hw,\n+\t\t\t       struct fm10k_mbx_info *mbx,\n+\t\t\t       u16 tail)\n+{\n+\tstruct fm10k_mbx_fifo *fifo = &mbx->rx;\n+\tu16 len, seq = fm10k_mbx_index_len(mbx, mbx->head, tail);\n+\n+\tDEBUGFUNC(\"fm10k_mbx_push_tail\");\n+\n+\t/* determine length of data to push */\n+\tlen = fm10k_fifo_unused(fifo) - mbx->pushed;\n+\tif (len > seq)\n+\t\tlen = seq;\n+\n+\t/* update head and record bytes received */\n+\tmbx->head = fm10k_mbx_head_add(mbx, len);\n+\tmbx->head_len = len;\n+\n+\t/* nothing to do if there is no data */\n+\tif (!len)\n+\t\treturn FM10K_SUCCESS;\n+\n+\t/* Copy msg into Rx FIFO */\n+\tfm10k_mbx_read_copy(hw, mbx);\n+\n+\t/* determine if there are any invalid lengths in message */\n+\tif (fm10k_mbx_validate_msg_size(mbx, len))\n+\t\treturn FM10K_MBX_ERR_SIZE;\n+\n+\t/* Update pushed */\n+\tmbx->pushed += len;\n+\n+\t/* flush any completed messages */\n+\tfor (len = fm10k_mbx_pushed_tail_len(mbx);\n+\t     len && (mbx->pushed >= len);\n+\t     len = fm10k_mbx_pushed_tail_len(mbx)) {\n+\t\tfifo->tail += len;\n+\t\tmbx->pushed -= len;\n+\t\tmbx->rx_messages++;\n+\t\tmbx->rx_dwords += len;\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/* pre-generated data for generating the CRC based on the poly 0xAC9A. */\n+static const u16 fm10k_crc_16b_table[256] = {\n+\t0x0000, 0x7956, 0xF2AC, 0x8BFA, 0xBC6D, 0xC53B, 0x4EC1, 0x3797,\n+\t0x21EF, 0x58B9, 0xD343, 0xAA15, 0x9D82, 0xE4D4, 0x6F2E, 0x1678,\n+\t0x43DE, 0x3A88, 0xB172, 0xC824, 0xFFB3, 0x86E5, 0x0D1F, 0x7449,\n+\t0x6231, 0x1B67, 0x909D, 0xE9CB, 0xDE5C, 0xA70A, 0x2CF0, 0x55A6,\n+\t0x87BC, 0xFEEA, 0x7510, 0x0C46, 0x3BD1, 0x4287, 0xC97D, 0xB02B,\n+\t0xA653, 0xDF05, 0x54FF, 0x2DA9, 0x1A3E, 0x6368, 0xE892, 0x91C4,\n+\t0xC462, 0xBD34, 0x36CE, 0x4F98, 0x780F, 0x0159, 0x8AA3, 0xF3F5,\n+\t0xE58D, 0x9CDB, 0x1721, 0x6E77, 0x59E0, 0x20B6, 0xAB4C, 0xD21A,\n+\t0x564D, 0x2F1B, 0xA4E1, 0xDDB7, 0xEA20, 0x9376, 0x188C, 0x61DA,\n+\t0x77A2, 0x0EF4, 0x850E, 0xFC58, 0xCBCF, 0xB299, 0x3963, 0x4035,\n+\t0x1593, 0x6CC5, 0xE73F, 0x9E69, 0xA9FE, 0xD0A8, 0x5B52, 0x2204,\n+\t0x347C, 0x4D2A, 0xC6D0, 0xBF86, 0x8811, 0xF147, 0x7ABD, 0x03EB,\n+\t0xD1F1, 0xA8A7, 0x235D, 0x5A0B, 0x6D9C, 0x14CA, 0x9F30, 0xE666,\n+\t0xF01E, 0x8948, 0x02B2, 0x7BE4, 0x4C73, 0x3525, 0xBEDF, 0xC789,\n+\t0x922F, 0xEB79, 0x6083, 0x19D5, 0x2E42, 0x5714, 0xDCEE, 0xA5B8,\n+\t0xB3C0, 0xCA96, 0x416C, 0x383A, 0x0FAD, 0x76FB, 0xFD01, 0x8457,\n+\t0xAC9A, 0xD5CC, 0x5E36, 0x2760, 0x10F7, 0x69A1, 0xE25B, 0x9B0D,\n+\t0x8D75, 0xF423, 0x7FD9, 0x068F, 0x3118, 0x484E, 0xC3B4, 0xBAE2,\n+\t0xEF44, 0x9612, 0x1DE8, 0x64BE, 0x5329, 0x2A7F, 0xA185, 0xD8D3,\n+\t0xCEAB, 0xB7FD, 0x3C07, 0x4551, 0x72C6, 0x0B90, 0x806A, 0xF93C,\n+\t0x2B26, 0x5270, 0xD98A, 0xA0DC, 0x974B, 0xEE1D, 0x65E7, 0x1CB1,\n+\t0x0AC9, 0x739F, 0xF865, 0x8133, 0xB6A4, 0xCFF2, 0x4408, 0x3D5E,\n+\t0x68F8, 0x11AE, 0x9A54, 0xE302, 0xD495, 0xADC3, 0x2639, 0x5F6F,\n+\t0x4917, 0x3041, 0xBBBB, 0xC2ED, 0xF57A, 0x8C2C, 0x07D6, 0x7E80,\n+\t0xFAD7, 0x8381, 0x087B, 0x712D, 0x46BA, 0x3FEC, 0xB416, 0xCD40,\n+\t0xDB38, 0xA26E, 0x2994, 0x50C2, 0x6755, 0x1E03, 0x95F9, 0xECAF,\n+\t0xB909, 0xC05F, 0x4BA5, 0x32F3, 0x0564, 0x7C32, 0xF7C8, 0x8E9E,\n+\t0x98E6, 0xE1B0, 0x6A4A, 0x131C, 0x248B, 0x5DDD, 0xD627, 0xAF71,\n+\t0x7D6B, 0x043D, 0x8FC7, 0xF691, 0xC106, 0xB850, 0x33AA, 0x4AFC,\n+\t0x5C84, 0x25D2, 0xAE28, 0xD77E, 0xE0E9, 0x99BF, 0x1245, 0x6B13,\n+\t0x3EB5, 0x47E3, 0xCC19, 0xB54F, 0x82D8, 0xFB8E, 0x7074, 0x0922,\n+\t0x1F5A, 0x660C, 0xEDF6, 0x94A0, 0xA337, 0xDA61, 0x519B, 0x28CD };\n+\n+/**\n+ *  fm10k_crc_16b - Generate a 16 bit CRC for a region of 16 bit data\n+ *  @data: pointer to data to process\n+ *  @seed: seed value for CRC\n+ *  @len: length measured in 16 bits words\n+ *\n+ *  This function will generate a CRC based on the polynomial 0xAC9A and\n+ *  whatever value is stored in the seed variable.  Note that this\n+ *  value inverts the local seed and the result in order to capture all\n+ *  leading and trailing zeros.\n+ */\n+STATIC u16 fm10k_crc_16b(const u32 *data, u16 seed, u16 len)\n+{\n+\tu32 result = seed;\n+\n+\twhile (len--) {\n+\t\tresult ^= *(data++);\n+\t\tresult = (result >> 8) ^ fm10k_crc_16b_table[result & 0xFF];\n+\t\tresult = (result >> 8) ^ fm10k_crc_16b_table[result & 0xFF];\n+\n+\t\tif (!(len--))\n+\t\t\tbreak;\n+\n+\t\tresult = (result >> 8) ^ fm10k_crc_16b_table[result & 0xFF];\n+\t\tresult = (result >> 8) ^ fm10k_crc_16b_table[result & 0xFF];\n+\t}\n+\n+\treturn (u16)result;\n+}\n+\n+/**\n+ *  fm10k_fifo_crc - generate a CRC based off of FIFO data\n+ *  @fifo: pointer to FIFO\n+ *  @offset: offset point for start of FIFO\n+ *  @len: number of DWORDS words to process\n+ *  @seed: seed value for CRC\n+ *\n+ *  This function generates a CRC for some region of the FIFO\n+ **/\n+STATIC u16 fm10k_fifo_crc(struct fm10k_mbx_fifo *fifo, u16 offset,\n+\t\t\t  u16 len, u16 seed)\n+{\n+\tu32 *data = fifo->buffer + offset;\n+\n+\t/* track when we should cross the end of the FIFO */\n+\toffset = fifo->size - offset;\n+\n+\t/* if we are in 2 blocks process the end of the FIFO first */\n+\tif (offset < len) {\n+\t\tseed = fm10k_crc_16b(data, seed, offset * 2);\n+\t\tdata = fifo->buffer;\n+\t\tlen -= offset;\n+\t}\n+\n+\t/* process any remaining bits */\n+\treturn fm10k_crc_16b(data, seed, len * 2);\n+}\n+\n+/**\n+ *  fm10k_mbx_update_local_crc - Update the local CRC for outgoing data\n+ *  @mbx: pointer to mailbox\n+ *  @head: head index provided by remote mailbox\n+ *\n+ *  This function will generate the CRC for all data from the end of the\n+ *  last head update to the current one.  It uses the result of the\n+ *  previous CRC as the seed for this update.  The result is stored in\n+ *  mbx->local.\n+ **/\n+STATIC void fm10k_mbx_update_local_crc(struct fm10k_mbx_info *mbx, u16 head)\n+{\n+\tu16 len = mbx->tail_len - fm10k_mbx_index_len(mbx, head, mbx->tail);\n+\n+\t/* determine the offset for the start of the region to be pulled */\n+\thead = fm10k_fifo_head_offset(&mbx->tx, mbx->pulled);\n+\n+\t/* update local CRC to include all of the pulled data */\n+\tmbx->local = fm10k_fifo_crc(&mbx->tx, head, len, mbx->local);\n+}\n+\n+/**\n+ *  fm10k_mbx_verify_remote_crc - Verify the CRC is correct for current data\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will take all data that has been provided from the remote\n+ *  end and generate a CRC for it.  This is stored in mbx->remote.  The\n+ *  CRC for the header is then computed and if the result is non-zero this\n+ *  is an error and we signal an error dropping all data and resetting the\n+ *  connection.\n+ */\n+STATIC s32 fm10k_mbx_verify_remote_crc(struct fm10k_mbx_info *mbx)\n+{\n+\tstruct fm10k_mbx_fifo *fifo = &mbx->rx;\n+\tu16 len = mbx->head_len;\n+\tu16 offset = fm10k_fifo_tail_offset(fifo, mbx->pushed) - len;\n+\tu16 crc;\n+\n+\t/* update the remote CRC if new data has been received */\n+\tif (len)\n+\t\tmbx->remote = fm10k_fifo_crc(fifo, offset, len, mbx->remote);\n+\n+\t/* process the full header as we have to validate the CRC */\n+\tcrc = fm10k_crc_16b(&mbx->mbx_hdr, mbx->remote, 1);\n+\n+\t/* notify other end if we have a problem */\n+\treturn crc ? FM10K_MBX_ERR_CRC : FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_mbx_rx_ready - Indicates that a message is ready in the Rx FIFO\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function returns true if there is a message in the Rx FIFO to dequeue.\n+ **/\n+STATIC bool fm10k_mbx_rx_ready(struct fm10k_mbx_info *mbx)\n+{\n+\tu16 msg_size = fm10k_fifo_head_len(&mbx->rx);\n+\n+\treturn msg_size && (fm10k_fifo_used(&mbx->rx) >= msg_size);\n+}\n+\n+/**\n+ *  fm10k_mbx_tx_ready - Indicates that the mailbox is in state ready for Tx\n+ *  @mbx: pointer to mailbox\n+ *  @len: verify free space is >= this value\n+ *\n+ *  This function returns true if the mailbox is in a state ready to transmit.\n+ **/\n+STATIC bool fm10k_mbx_tx_ready(struct fm10k_mbx_info *mbx, u16 len)\n+{\n+\tu16 fifo_unused = fm10k_fifo_unused(&mbx->tx);\n+\n+\treturn (mbx->state == FM10K_STATE_OPEN) && (fifo_unused >= len);\n+}\n+\n+/**\n+ *  fm10k_mbx_tx_complete - Indicates that the Tx FIFO has been emptied\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function returns true if the Tx FIFO is empty.\n+ **/\n+STATIC bool fm10k_mbx_tx_complete(struct fm10k_mbx_info *mbx)\n+{\n+\treturn fm10k_fifo_empty(&mbx->tx);\n+}\n+\n+/**\n+ *  fm10k_mbx_deqeueue_rx - Dequeues the message from the head in the Rx FIFO\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function dequeues messages and hands them off to the tlv parser.\n+ *  It will return the number of messages processed when called.\n+ **/\n+STATIC u16 fm10k_mbx_dequeue_rx(struct fm10k_hw *hw,\n+\t\t\t\tstruct fm10k_mbx_info *mbx)\n+{\n+\tstruct fm10k_mbx_fifo *fifo = &mbx->rx;\n+\ts32 err;\n+\tu16 cnt;\n+\n+\t/* parse Rx messages out of the Rx FIFO to empty it */\n+\tfor (cnt = 0; !fm10k_fifo_empty(fifo); cnt++) {\n+\t\terr = fm10k_tlv_msg_parse(hw, fifo->buffer + fifo->head,\n+\t\t\t\t\t  mbx, mbx->msg_data);\n+\t\tif (err < 0)\n+\t\t\tmbx->rx_parse_err++;\n+\n+\t\tfm10k_fifo_head_drop(fifo);\n+\t}\n+\n+\t/* shift remaining bytes back to start of FIFO */\n+\tmemmove(fifo->buffer, fifo->buffer + fifo->tail, mbx->pushed << 2);\n+\n+\t/* shift head and tail based on the memory we moved */\n+\tfifo->tail -= fifo->head;\n+\tfifo->head = 0;\n+\n+\treturn cnt;\n+}\n+\n+/**\n+ *  fm10k_mbx_enqueue_tx - Enqueues the message to the tail of the Tx FIFO\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *  @msg: message array to read\n+ *\n+ *  This function enqueues a message up to the size specified by the length\n+ *  contained in the first DWORD of the message and will place at the tail\n+ *  of the FIFO.  It will return 0 on success, or a negative value on error.\n+ **/\n+STATIC s32 fm10k_mbx_enqueue_tx(struct fm10k_hw *hw,\n+\t\t\t\tstruct fm10k_mbx_info *mbx, const u32 *msg)\n+{\n+\tu32 countdown = mbx->timeout;\n+\ts32 err;\n+\n+\tswitch (mbx->state) {\n+\tcase FM10K_STATE_CLOSED:\n+\tcase FM10K_STATE_DISCONNECT:\n+\t\treturn FM10K_MBX_ERR_NO_MBX;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\t/* enqueue the message on the Tx FIFO */\n+\terr = fm10k_fifo_enqueue(&mbx->tx, msg);\n+\n+\t/* if it failed give the FIFO a chance to drain */\n+\twhile (err && countdown) {\n+\t\tcountdown--;\n+\t\tusec_delay(mbx->usec_delay);\n+\t\tmbx->ops.process(hw, mbx);\n+\t\terr = fm10k_fifo_enqueue(&mbx->tx, msg);\n+\t}\n+\n+\t/* if we failed treat the error */\n+\tif (err) {\n+\t\tmbx->timeout = 0;\n+\t\tmbx->tx_busy++;\n+\t}\n+\n+\t/* begin processing message, ignore errors as this is just meant\n+\t * to start the mailbox flow so we are not concerned if there\n+\t * is a bad error, or the mailbox is already busy with a request\n+\t */\n+\tif (!mbx->tail_len)\n+\t\tmbx->ops.process(hw, mbx);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_mbx_read - Copies the mbmem to local message buffer\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function copies the message from the mbmem to the message array\n+ **/\n+STATIC s32 fm10k_mbx_read(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx)\n+{\n+\tDEBUGFUNC(\"fm10k_mbx_read\");\n+\n+\t/* only allow one reader in here at a time */\n+\tif (mbx->mbx_hdr)\n+\t\treturn FM10K_MBX_ERR_BUSY;\n+\n+\t/* read to capture initial interrupt bits */\n+\tif (FM10K_READ_MBX(hw, mbx->mbx_reg) & FM10K_MBX_REQ_INTERRUPT)\n+\t\tmbx->mbx_lock = FM10K_MBX_ACK;\n+\n+\t/* write back interrupt bits to clear */\n+\tFM10K_WRITE_MBX(hw, mbx->mbx_reg,\n+\t\t\tFM10K_MBX_REQ_INTERRUPT | FM10K_MBX_ACK_INTERRUPT);\n+\n+\t/* read remote header */\n+\tmbx->mbx_hdr = FM10K_READ_MBX(hw, mbx->mbmem_reg ^ mbx->mbmem_len);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_mbx_write - Copies the local message buffer to mbmem\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function copies the message from the the message array to mbmem\n+ **/\n+STATIC void fm10k_mbx_write(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx)\n+{\n+\tu32 mbmem = mbx->mbmem_reg;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_write\");\n+\n+\t/* write new msg header to notify recipient of change */\n+\tFM10K_WRITE_MBX(hw, mbmem, mbx->mbx_hdr);\n+\n+\t/* write mailbox to send interrupt */\n+\tif (mbx->mbx_lock)\n+\t\tFM10K_WRITE_MBX(hw, mbx->mbx_reg, mbx->mbx_lock);\n+\n+\t/* we no longer are using the header so free it */\n+\tmbx->mbx_hdr = 0;\n+\tmbx->mbx_lock = 0;\n+}\n+\n+/**\n+ *  fm10k_mbx_create_connect_hdr - Generate a connect mailbox header\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function returns a connection mailbox header\n+ **/\n+STATIC void fm10k_mbx_create_connect_hdr(struct fm10k_mbx_info *mbx)\n+{\n+\tmbx->mbx_lock |= FM10K_MBX_REQ;\n+\n+\tmbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_CONNECT, TYPE) |\n+\t\t       FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD) |\n+\t\t       FM10K_MSG_HDR_FIELD_SET(mbx->rx.size - 1, CONNECT_SIZE);\n+}\n+\n+/**\n+ *  fm10k_mbx_create_data_hdr - Generate a data mailbox header\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function returns a data mailbox header\n+ **/\n+STATIC void fm10k_mbx_create_data_hdr(struct fm10k_mbx_info *mbx)\n+{\n+\tu32 hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_DATA, TYPE) |\n+\t\t  FM10K_MSG_HDR_FIELD_SET(mbx->tail, TAIL) |\n+\t\t  FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD);\n+\tstruct fm10k_mbx_fifo *fifo = &mbx->tx;\n+\tu16 crc;\n+\n+\tif (mbx->tail_len)\n+\t\tmbx->mbx_lock |= FM10K_MBX_REQ;\n+\n+\t/* generate CRC for data in flight and header */\n+\tcrc = fm10k_fifo_crc(fifo, fm10k_fifo_head_offset(fifo, mbx->pulled),\n+\t\t\t     mbx->tail_len, mbx->local);\n+\tcrc = fm10k_crc_16b(&hdr, crc, 1);\n+\n+\t/* load header to memory to be written */\n+\tmbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC);\n+}\n+\n+/**\n+ *  fm10k_mbx_create_disconnect_hdr - Generate a disconnect mailbox header\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function returns a disconnect mailbox header\n+ **/\n+STATIC void fm10k_mbx_create_disconnect_hdr(struct fm10k_mbx_info *mbx)\n+{\n+\tu32 hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_DISCONNECT, TYPE) |\n+\t\t  FM10K_MSG_HDR_FIELD_SET(mbx->tail, TAIL) |\n+\t\t  FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD);\n+\tu16 crc = fm10k_crc_16b(&hdr, mbx->local, 1);\n+\n+\tmbx->mbx_lock |= FM10K_MBX_ACK;\n+\n+\t/* load header to memory to be written */\n+\tmbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC);\n+}\n+\n+/**\n+ *  fm10k_mbx_create_error_msg - Generate a error message\n+ *  @mbx: pointer to mailbox\n+ *  @err: local error encountered\n+ *\n+ *  This function will interpret the error provided by err, and based on\n+ *  that it may shift the message by 1 DWORD and then place an error header\n+ *  at the start of the message.\n+ **/\n+STATIC void fm10k_mbx_create_error_msg(struct fm10k_mbx_info *mbx, s32 err)\n+{\n+\t/* only generate an error message for these types */\n+\tswitch (err) {\n+\tcase FM10K_MBX_ERR_TAIL:\n+\tcase FM10K_MBX_ERR_HEAD:\n+\tcase FM10K_MBX_ERR_TYPE:\n+\tcase FM10K_MBX_ERR_SIZE:\n+\tcase FM10K_MBX_ERR_RSVD0:\n+\tcase FM10K_MBX_ERR_CRC:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn;\n+\t}\n+\n+\tmbx->mbx_lock |= FM10K_MBX_REQ;\n+\n+\tmbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_ERROR, TYPE) |\n+\t\t       FM10K_MSG_HDR_FIELD_SET(err, ERR_NO) |\n+\t\t       FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD);\n+}\n+\n+/**\n+ *  fm10k_mbx_validate_msg_hdr - Validate common fields in the message header\n+ *  @mbx: pointer to mailbox\n+ *  @msg: message array to read\n+ *\n+ *  This function will parse up the fields in the mailbox header and return\n+ *  an error if the header contains any of a number of invalid configurations\n+ *  including unrecognized type, invalid route, or a malformed message.\n+ **/\n+STATIC s32 fm10k_mbx_validate_msg_hdr(struct fm10k_mbx_info *mbx)\n+{\n+\tu16 type, rsvd0, head, tail, size;\n+\tconst u32 *hdr = &mbx->mbx_hdr;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_validate_msg_hdr\");\n+\n+\ttype = FM10K_MSG_HDR_FIELD_GET(*hdr, TYPE);\n+\trsvd0 = FM10K_MSG_HDR_FIELD_GET(*hdr, RSVD0);\n+\ttail = FM10K_MSG_HDR_FIELD_GET(*hdr, TAIL);\n+\thead = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD);\n+\tsize = FM10K_MSG_HDR_FIELD_GET(*hdr, CONNECT_SIZE);\n+\n+\tif (rsvd0)\n+\t\treturn FM10K_MBX_ERR_RSVD0;\n+\n+\tswitch (type) {\n+\tcase FM10K_MSG_DISCONNECT:\n+\t\t/* validate that all data has been received */\n+\t\tif (tail != mbx->head)\n+\t\t\treturn FM10K_MBX_ERR_TAIL;\n+\n+\t\t/* fall through */\n+\tcase FM10K_MSG_DATA:\n+\t\t/* validate that head is moving correctly */\n+\t\tif (!head || (head == FM10K_MSG_HDR_MASK(HEAD)))\n+\t\t\treturn FM10K_MBX_ERR_HEAD;\n+\t\tif (fm10k_mbx_index_len(mbx, head, mbx->tail) > mbx->tail_len)\n+\t\t\treturn FM10K_MBX_ERR_HEAD;\n+\n+\t\t/* validate that tail is moving correctly */\n+\t\tif (!tail || (tail == FM10K_MSG_HDR_MASK(TAIL)))\n+\t\t\treturn FM10K_MBX_ERR_TAIL;\n+\t\tif (fm10k_mbx_index_len(mbx, mbx->head, tail) < mbx->mbmem_len)\n+\t\t\tbreak;\n+\n+\t\treturn FM10K_MBX_ERR_TAIL;\n+\tcase FM10K_MSG_CONNECT:\n+\t\t/* validate size is in range and is power of 2 mask */\n+\t\tif ((size < FM10K_VFMBX_MSG_MTU) || (size & (size + 1)))\n+\t\t\treturn FM10K_MBX_ERR_SIZE;\n+\n+\t\t/* fall through */\n+\tcase FM10K_MSG_ERROR:\n+\t\tif (!head || (head == FM10K_MSG_HDR_MASK(HEAD)))\n+\t\t\treturn FM10K_MBX_ERR_HEAD;\n+\t\t/* neither create nor error include a tail offset */\n+\t\tif (tail)\n+\t\t\treturn FM10K_MBX_ERR_TAIL;\n+\n+\t\tbreak;\n+\tdefault:\n+\t\treturn FM10K_MBX_ERR_TYPE;\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_mbx_create_reply - Generate reply based on state and remote head\n+ *  @mbx: pointer to mailbox\n+ *  @head: acknowledgement number\n+ *\n+ *  This function will generate an outgoing message based on the current\n+ *  mailbox state and the remote fifo head.  It will return the length\n+ *  of the outgoing message excluding header on success, and a negative value\n+ *  on error.\n+ **/\n+STATIC s32 fm10k_mbx_create_reply(struct fm10k_hw *hw,\n+\t\t\t\t  struct fm10k_mbx_info *mbx, u16 head)\n+{\n+\tswitch (mbx->state) {\n+\tcase FM10K_STATE_OPEN:\n+\tcase FM10K_STATE_DISCONNECT:\n+\t\t/* update our checksum for the outgoing data */\n+\t\tfm10k_mbx_update_local_crc(mbx, head);\n+\n+\t\t/* as long as other end recognizes us keep sending data */\n+\t\tfm10k_mbx_pull_head(hw, mbx, head);\n+\n+\t\t/* generate new header based on data */\n+\t\tif (mbx->tail_len || (mbx->state == FM10K_STATE_OPEN))\n+\t\t\tfm10k_mbx_create_data_hdr(mbx);\n+\t\telse\n+\t\t\tfm10k_mbx_create_disconnect_hdr(mbx);\n+\t\tbreak;\n+\tcase FM10K_STATE_CONNECT:\n+\t\t/* send disconnect even if we aren't connected */\n+\t\tfm10k_mbx_create_connect_hdr(mbx);\n+\t\tbreak;\n+\tcase FM10K_STATE_CLOSED:\n+\t\t/* generate new header based on data */\n+\t\tfm10k_mbx_create_disconnect_hdr(mbx);\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_mbx_reset_work- Reset internal pointers for any pending work\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will reset all internal pointers so any work in progress\n+ *  is dropped.  This call should occur every time we transition from the\n+ *  open state to the connect state.\n+ **/\n+STATIC void fm10k_mbx_reset_work(struct fm10k_mbx_info *mbx)\n+{\n+\t/* reset our outgoing max size back to Rx limits */\n+\tmbx->max_size = mbx->rx.size - 1;\n+\n+\t/* just do a quick resysnc to start of message */\n+\tmbx->pushed = 0;\n+\tmbx->pulled = 0;\n+\tmbx->tail_len = 0;\n+\tmbx->head_len = 0;\n+\tmbx->rx.tail = 0;\n+\tmbx->rx.head = 0;\n+}\n+\n+/**\n+ *  fm10k_mbx_update_max_size - Update the max_size and drop any large messages\n+ *  @mbx: pointer to mailbox\n+ *  @size: new value for max_size\n+ *\n+ *  This function will update the max_size value and drop any outgoing messages\n+ *  from the head of the Tx FIFO that are larger than max_size.\n+ **/\n+STATIC void fm10k_mbx_update_max_size(struct fm10k_mbx_info *mbx, u16 size)\n+{\n+\tu16 len;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_update_max_size_hdr\");\n+\n+\tmbx->max_size = size;\n+\n+\t/* flush any oversized messages from the queue */\n+\tfor (len = fm10k_fifo_head_len(&mbx->tx);\n+\t     len > size;\n+\t     len = fm10k_fifo_head_len(&mbx->tx)) {\n+\t\tfm10k_fifo_head_drop(&mbx->tx);\n+\t\tmbx->tx_dropped++;\n+\t}\n+}\n+\n+/**\n+ *  fm10k_mbx_connect_reset - Reset following request for reset\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function resets the mailbox to either a disconnected state\n+ *  or a connect state depending on the current mailbox state\n+ **/\n+STATIC void fm10k_mbx_connect_reset(struct fm10k_mbx_info *mbx)\n+{\n+\t/* just do a quick resysnc to start of frame */\n+\tfm10k_mbx_reset_work(mbx);\n+\n+\t/* reset CRC seeds */\n+\tmbx->local = FM10K_MBX_CRC_SEED;\n+\tmbx->remote = FM10K_MBX_CRC_SEED;\n+\n+\t/* we cannot exit connect until the size is good */\n+\tif (mbx->state == FM10K_STATE_OPEN)\n+\t\tmbx->state = FM10K_STATE_CONNECT;\n+\telse\n+\t\tmbx->state = FM10K_STATE_CLOSED;\n+}\n+\n+/**\n+ *  fm10k_mbx_process_connect - Process connect header\n+ *  @mbx: pointer to mailbox\n+ *  @msg: message array to process\n+ *\n+ *  This function will read an incoming connect header and reply with the\n+ *  appropriate message.  It will return a value indicating the number of\n+ *  data DWORDs on success, or will return a negative value on failure.\n+ **/\n+STATIC s32 fm10k_mbx_process_connect(struct fm10k_hw *hw,\n+\t\t\t\t     struct fm10k_mbx_info *mbx)\n+{\n+\tconst enum fm10k_mbx_state state = mbx->state;\n+\tconst u32 *hdr = &mbx->mbx_hdr;\n+\tu16 size, head;\n+\n+\t/* we will need to pull all of the fields for verification */\n+\tsize = FM10K_MSG_HDR_FIELD_GET(*hdr, CONNECT_SIZE);\n+\thead = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD);\n+\n+\tswitch (state) {\n+\tcase FM10K_STATE_DISCONNECT:\n+\tcase FM10K_STATE_OPEN:\n+\t\t/* reset any in-progress work */\n+\t\tfm10k_mbx_connect_reset(mbx);\n+\t\tbreak;\n+\tcase FM10K_STATE_CONNECT:\n+\t\t/* we cannot exit connect until the size is good */\n+\t\tif (size > mbx->rx.size) {\n+\t\t\tmbx->max_size = mbx->rx.size - 1;\n+\t\t} else {\n+\t\t\t/* record the remote system requesting connection */\n+\t\t\tmbx->state = FM10K_STATE_OPEN;\n+\n+\t\t\tfm10k_mbx_update_max_size(mbx, size);\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\t/* align our tail index to remote head index */\n+\tmbx->tail = head;\n+\n+\treturn fm10k_mbx_create_reply(hw, mbx, head);\n+}\n+\n+/**\n+ *  fm10k_mbx_process_data - Process data header\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will read an incoming data header and reply with the\n+ *  appropriate message.  It will return a value indicating the number of\n+ *  data DWORDs on success, or will return a negative value on failure.\n+ **/\n+STATIC s32 fm10k_mbx_process_data(struct fm10k_hw *hw,\n+\t\t\t\t  struct fm10k_mbx_info *mbx)\n+{\n+\tconst u32 *hdr = &mbx->mbx_hdr;\n+\tu16 head, tail;\n+\ts32 err;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_process_data\");\n+\n+\t/* we will need to pull all of the fields for verification */\n+\thead = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD);\n+\ttail = FM10K_MSG_HDR_FIELD_GET(*hdr, TAIL);\n+\n+\t/* if we are in connect just update our data and go */\n+\tif (mbx->state == FM10K_STATE_CONNECT) {\n+\t\tmbx->tail = head;\n+\t\tmbx->state = FM10K_STATE_OPEN;\n+\t}\n+\n+\t/* abort on message size errors */\n+\terr = fm10k_mbx_push_tail(hw, mbx, tail);\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\t/* verify the checksum on the incoming data */\n+\terr = fm10k_mbx_verify_remote_crc(mbx);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* process messages if we have received any */\n+\tfm10k_mbx_dequeue_rx(hw, mbx);\n+\n+\treturn fm10k_mbx_create_reply(hw, mbx, head);\n+}\n+\n+/**\n+ *  fm10k_mbx_process_disconnect - Process disconnect header\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will read an incoming disconnect header and reply with the\n+ *  appropriate message.  It will return a value indicating the number of\n+ *  data DWORDs on success, or will return a negative value on failure.\n+ **/\n+STATIC s32 fm10k_mbx_process_disconnect(struct fm10k_hw *hw,\n+\t\t\t\t\tstruct fm10k_mbx_info *mbx)\n+{\n+\tconst enum fm10k_mbx_state state = mbx->state;\n+\tconst u32 *hdr = &mbx->mbx_hdr;\n+\tu16 head;\n+\ts32 err;\n+\n+\t/* we will need to pull the header field for verification */\n+\thead = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD);\n+\n+\t/* We should not be receiving disconnect if Rx is incomplete */\n+\tif (mbx->pushed)\n+\t\treturn FM10K_MBX_ERR_TAIL;\n+\n+\t/* we have already verified mbx->head == tail so we know this is 0 */\n+\tmbx->head_len = 0;\n+\n+\t/* verify the checksum on the incoming header is correct */\n+\terr = fm10k_mbx_verify_remote_crc(mbx);\n+\tif (err)\n+\t\treturn err;\n+\n+\tswitch (state) {\n+\tcase FM10K_STATE_DISCONNECT:\n+\tcase FM10K_STATE_OPEN:\n+\t\t/* state doesn't change if we still have work to do */\n+\t\tif (!fm10k_mbx_tx_complete(mbx))\n+\t\t\tbreak;\n+\n+\t\t/* verify the head indicates we completed all transmits */\n+\t\tif (head != mbx->tail)\n+\t\t\treturn FM10K_MBX_ERR_HEAD;\n+\n+\t\t/* reset any in-progress work */\n+\t\tfm10k_mbx_connect_reset(mbx);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn fm10k_mbx_create_reply(hw, mbx, head);\n+}\n+\n+/**\n+ *  fm10k_mbx_process_error - Process error header\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will read an incoming error header and reply with the\n+ *  appropriate message.  It will return a value indicating the number of\n+ *  data DWORDs on success, or will return a negative value on failure.\n+ **/\n+STATIC s32 fm10k_mbx_process_error(struct fm10k_hw *hw,\n+\t\t\t\t   struct fm10k_mbx_info *mbx)\n+{\n+\tconst u32 *hdr = &mbx->mbx_hdr;\n+\ts32 err_no;\n+\tu16 head;\n+\n+\t/* we will need to pull all of the fields for verification */\n+\thead = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD);\n+\n+\t/* we only have lower 10 bits of error number so add upper bits */\n+\terr_no = FM10K_MSG_HDR_FIELD_GET(*hdr, ERR_NO);\n+\terr_no |= ~FM10K_MSG_HDR_MASK(ERR_NO);\n+\n+\tswitch (mbx->state) {\n+\tcase FM10K_STATE_OPEN:\n+\tcase FM10K_STATE_DISCONNECT:\n+\t\t/* flush any uncompleted work */\n+\t\tfm10k_mbx_reset_work(mbx);\n+\n+\t\t/* reset CRC seeds */\n+\t\tmbx->local = FM10K_MBX_CRC_SEED;\n+\t\tmbx->remote = FM10K_MBX_CRC_SEED;\n+\n+\t\t/* reset tail index and size to prepare for reconnect */\n+\t\tmbx->tail = head;\n+\n+\t\t/* if open then reset max_size and go back to connect */\n+\t\tif (mbx->state == FM10K_STATE_OPEN) {\n+\t\t\tmbx->state = FM10K_STATE_CONNECT;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* send a connect message to get data flowing again */\n+\t\tfm10k_mbx_create_connect_hdr(mbx);\n+\t\treturn FM10K_SUCCESS;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn fm10k_mbx_create_reply(hw, mbx, mbx->tail);\n+}\n+\n+/**\n+ *  fm10k_mbx_process - Process mailbox interrupt\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will process incoming mailbox events and generate mailbox\n+ *  replies.  It will return a value indicating the number of DWORDs\n+ *  transmitted excluding header on success or a negative value on error.\n+ **/\n+STATIC s32 fm10k_mbx_process(struct fm10k_hw *hw,\n+\t\t\t     struct fm10k_mbx_info *mbx)\n+{\n+\ts32 err;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_process\");\n+\n+\t/* we do not read mailbox if closed */\n+\tif (mbx->state == FM10K_STATE_CLOSED)\n+\t\treturn FM10K_SUCCESS;\n+\n+\t/* copy data from mailbox */\n+\terr = fm10k_mbx_read(hw, mbx);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* validate type, source, and destination */\n+\terr = fm10k_mbx_validate_msg_hdr(mbx);\n+\tif (err < 0)\n+\t\tgoto msg_err;\n+\n+\tswitch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, TYPE)) {\n+\tcase FM10K_MSG_CONNECT:\n+\t\terr = fm10k_mbx_process_connect(hw, mbx);\n+\t\tbreak;\n+\tcase FM10K_MSG_DATA:\n+\t\terr = fm10k_mbx_process_data(hw, mbx);\n+\t\tbreak;\n+\tcase FM10K_MSG_DISCONNECT:\n+\t\terr = fm10k_mbx_process_disconnect(hw, mbx);\n+\t\tbreak;\n+\tcase FM10K_MSG_ERROR:\n+\t\terr = fm10k_mbx_process_error(hw, mbx);\n+\t\tbreak;\n+\tdefault:\n+\t\terr = FM10K_MBX_ERR_TYPE;\n+\t\tbreak;\n+\t}\n+\n+msg_err:\n+\t/* notify partner of errors on our end */\n+\tif (err < 0)\n+\t\tfm10k_mbx_create_error_msg(mbx, err);\n+\n+\t/* copy data from mailbox */\n+\tfm10k_mbx_write(hw, mbx);\n+\n+\treturn err;\n+}\n+\n+/**\n+ *  fm10k_mbx_disconnect - Shutdown mailbox connection\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will shut down the mailbox.  It places the mailbox first\n+ *  in the disconnect state, it then allows up to a predefined timeout for\n+ *  the mailbox to transition to close on its own.  If this does not occur\n+ *  then the mailbox will be forced into the closed state.\n+ *\n+ *  Any mailbox transactions not completed before calling this function\n+ *  are not guaranteed to complete and may be dropped.\n+ **/\n+STATIC void fm10k_mbx_disconnect(struct fm10k_hw *hw,\n+\t\t\t\t struct fm10k_mbx_info *mbx)\n+{\n+\tint timeout = mbx->timeout ? FM10K_MBX_DISCONNECT_TIMEOUT : 0;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_disconnect\");\n+\n+\t/* Place mbx in ready to disconnect state */\n+\tmbx->state = FM10K_STATE_DISCONNECT;\n+\n+\t/* trigger interrupt to start shutdown process */\n+\tFM10K_WRITE_MBX(hw, mbx->mbx_reg, FM10K_MBX_REQ |\n+\t\t\t\t\t  FM10K_MBX_INTERRUPT_DISABLE);\n+\tdo {\n+\t\tusec_delay(FM10K_MBX_POLL_DELAY);\n+\t\tmbx->ops.process(hw, mbx);\n+\t\ttimeout -= FM10K_MBX_POLL_DELAY;\n+\t} while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED));\n+\n+\t/* in case we didn't close just force the mailbox into shutdown */\n+\tfm10k_mbx_connect_reset(mbx);\n+\tfm10k_mbx_update_max_size(mbx, 0);\n+\n+\tFM10K_WRITE_MBX(hw, mbx->mbmem_reg, 0);\n+}\n+\n+/**\n+ *  fm10k_mbx_connect - Start mailbox connection\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will initiate a mailbox connection.  It will populate the\n+ *  mailbox with a broadcast connect message and then initialize the lock.\n+ *  This is safe since the connect message is a single DWORD so the mailbox\n+ *  transaction is guaranteed to be atomic.\n+ *\n+ *  This function will return an error if the mailbox has not been initiated\n+ *  or is currently in use.\n+ **/\n+STATIC s32 fm10k_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx)\n+{\n+\tDEBUGFUNC(\"fm10k_mbx_connect\");\n+\n+\t/* we cannot connect an uninitialized mailbox */\n+\tif (!mbx->rx.buffer)\n+\t\treturn FM10K_MBX_ERR_NO_SPACE;\n+\n+\t/* we cannot connect an already connected mailbox */\n+\tif (mbx->state != FM10K_STATE_CLOSED)\n+\t\treturn FM10K_MBX_ERR_BUSY;\n+\n+\t/* mailbox timeout can now become active */\n+\tmbx->timeout = FM10K_MBX_INIT_TIMEOUT;\n+\n+\t/* Place mbx in ready to connect state */\n+\tmbx->state = FM10K_STATE_CONNECT;\n+\n+\t/* initialize header of remote mailbox */\n+\tfm10k_mbx_create_disconnect_hdr(mbx);\n+\tFM10K_WRITE_MBX(hw, mbx->mbmem_reg ^ mbx->mbmem_len, mbx->mbx_hdr);\n+\n+\t/* enable interrupt and notify other party of new message */\n+\tmbx->mbx_lock = FM10K_MBX_REQ_INTERRUPT | FM10K_MBX_ACK_INTERRUPT |\n+\t\t\tFM10K_MBX_INTERRUPT_ENABLE;\n+\n+\t/* generate and load connect header into mailbox */\n+\tfm10k_mbx_create_connect_hdr(mbx);\n+\tfm10k_mbx_write(hw, mbx);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_mbx_validate_handlers - Validate layout of message parsing data\n+ *  @msg_data: handlers for mailbox events\n+ *\n+ *  This function validates the layout of the message parsing data.  This\n+ *  should be mostly static, but it is important to catch any errors that\n+ *  are made when constructing the parsers.\n+ **/\n+STATIC s32 fm10k_mbx_validate_handlers(const struct fm10k_msg_data *msg_data)\n+{\n+\tconst struct fm10k_tlv_attr *attr;\n+\tunsigned int id;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_validate_handlers\");\n+\n+\t/* Allow NULL mailboxes that transmit but don't receive */\n+\tif (!msg_data)\n+\t\treturn FM10K_SUCCESS;\n+\n+\twhile (msg_data->id != FM10K_TLV_ERROR) {\n+\t\t/* all messages should have a function handler */\n+\t\tif (!msg_data->func)\n+\t\t\treturn FM10K_ERR_PARAM;\n+\n+\t\t/* parser is optional */\n+\t\tattr = msg_data->attr;\n+\t\tif (attr) {\n+\t\t\twhile (attr->id != FM10K_TLV_ERROR) {\n+\t\t\t\tid = attr->id;\n+\t\t\t\tattr++;\n+\t\t\t\t/* ID should always be increasing */\n+\t\t\t\tif (id >= attr->id)\n+\t\t\t\t\treturn FM10K_ERR_PARAM;\n+\t\t\t\t/* ID should fit in results array */\n+\t\t\t\tif (id >= FM10K_TLV_RESULTS_MAX)\n+\t\t\t\t\treturn FM10K_ERR_PARAM;\n+\t\t\t}\n+\n+\t\t\t/* verify terminator is in the list */\n+\t\t\tif (attr->id != FM10K_TLV_ERROR)\n+\t\t\t\treturn FM10K_ERR_PARAM;\n+\t\t}\n+\n+\t\tid = msg_data->id;\n+\t\tmsg_data++;\n+\t\t/* ID should always be increasing */\n+\t\tif (id >= msg_data->id)\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t}\n+\n+\t/* verify terminator is in the list */\n+\tif ((msg_data->id != FM10K_TLV_ERROR) || !msg_data->func)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_mbx_register_handlers - Register a set of handler ops for mailbox\n+ *  @mbx: pointer to mailbox\n+ *  @msg_data: handlers for mailbox events\n+ *\n+ *  This function associates a set of message handling ops with a mailbox.\n+ **/\n+STATIC s32 fm10k_mbx_register_handlers(struct fm10k_mbx_info *mbx,\n+\t\t\t\t       const struct fm10k_msg_data *msg_data)\n+{\n+\tDEBUGFUNC(\"fm10k_mbx_register_handlers\");\n+\n+\t/* validate layout of handlers before assigning them */\n+\tif (fm10k_mbx_validate_handlers(msg_data))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* initialize the message handlers */\n+\tmbx->msg_data = msg_data;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_pfvf_mbx_init - Initialize mailbox memory for PF/VF mailbox\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *  @msg_data: handlers for mailbox events\n+ *  @id: ID reference for PF as it supports up to 64 PF/VF mailboxes\n+ *\n+ *  This function initializes the mailbox for use.  It will split the\n+ *  buffer provided an use that th populate both the Tx and Rx FIFO by\n+ *  evenly splitting it.  In order to allow for easy masking of head/tail\n+ *  the value reported in size must be a power of 2 and is reported in\n+ *  DWORDs, not bytes.  Any invalid values will cause the mailbox to return\n+ *  error.\n+ **/\n+s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx,\n+\t\t\tconst struct fm10k_msg_data *msg_data, u8 id)\n+{\n+\tDEBUGFUNC(\"fm10k_pfvf_mbx_init\");\n+\n+\t/* initialize registers */\n+\tswitch (hw->mac.type) {\n+\tcase fm10k_mac_vf:\n+\t\tmbx->mbx_reg = FM10K_VFMBX;\n+\t\tmbx->mbmem_reg = FM10K_VFMBMEM(FM10K_VFMBMEM_VF_XOR);\n+\t\tbreak;\n+\tcase fm10k_mac_pf:\n+\t\t/* there are only 64 VF <-> PF mailboxes */\n+\t\tif (id < 64) {\n+\t\t\tmbx->mbx_reg = FM10K_MBX(id);\n+\t\t\tmbx->mbmem_reg = FM10K_MBMEM_VF(id, 0);\n+\t\t\tbreak;\n+\t\t}\n+\t\t/* fallthough */\n+\tdefault:\n+\t\treturn FM10K_MBX_ERR_NO_MBX;\n+\t}\n+\n+\t/* start out in closed state */\n+\tmbx->state = FM10K_STATE_CLOSED;\n+\n+\t/* validate layout of handlers before assigning them */\n+\tif (fm10k_mbx_validate_handlers(msg_data))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* initialize the message handlers */\n+\tmbx->msg_data = msg_data;\n+\n+\t/* start mailbox as timed out and let the reset_hw call\n+\t * set the timeout value to begin communications\n+\t */\n+\tmbx->timeout = 0;\n+\tmbx->usec_delay = FM10K_MBX_INIT_DELAY;\n+\n+\t/* initialize tail and head */\n+\tmbx->tail = 1;\n+\tmbx->head = 1;\n+\n+\t/* initialize CRC seeds */\n+\tmbx->local = FM10K_MBX_CRC_SEED;\n+\tmbx->remote = FM10K_MBX_CRC_SEED;\n+\n+\t/* Split buffer for use by Tx/Rx FIFOs */\n+\tmbx->max_size = FM10K_MBX_MSG_MAX_SIZE;\n+\tmbx->mbmem_len = FM10K_VFMBMEM_VF_XOR;\n+\n+\t/* initialize the FIFOs, sizes are in 4 byte increments */\n+\tfm10k_fifo_init(&mbx->tx, mbx->buffer, FM10K_MBX_TX_BUFFER_SIZE);\n+\tfm10k_fifo_init(&mbx->rx, &mbx->buffer[FM10K_MBX_TX_BUFFER_SIZE],\n+\t\t\tFM10K_MBX_RX_BUFFER_SIZE);\n+\n+\t/* initialize function pointers */\n+\tmbx->ops.connect = fm10k_mbx_connect;\n+\tmbx->ops.disconnect = fm10k_mbx_disconnect;\n+\tmbx->ops.rx_ready = fm10k_mbx_rx_ready;\n+\tmbx->ops.tx_ready = fm10k_mbx_tx_ready;\n+\tmbx->ops.tx_complete = fm10k_mbx_tx_complete;\n+\tmbx->ops.enqueue_tx = fm10k_mbx_enqueue_tx;\n+\tmbx->ops.process = fm10k_mbx_process;\n+\tmbx->ops.register_handlers = fm10k_mbx_register_handlers;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_create_data_hdr - Generate a mailbox header for local FIFO\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function returns a connection mailbox header\n+ **/\n+STATIC void fm10k_sm_mbx_create_data_hdr(struct fm10k_mbx_info *mbx)\n+{\n+\tif (mbx->tail_len)\n+\t\tmbx->mbx_lock |= FM10K_MBX_REQ;\n+\n+\tmbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(mbx->tail, SM_TAIL) |\n+\t\t       FM10K_MSG_HDR_FIELD_SET(mbx->remote, SM_VER) |\n+\t\t       FM10K_MSG_HDR_FIELD_SET(mbx->head, SM_HEAD);\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_create_connect_hdr - Generate a mailbox header for local FIFO\n+ *  @mbx: pointer to mailbox\n+ *  @err: error flags to report if any\n+ *\n+ *  This function returns a connection mailbox header\n+ **/\n+STATIC void fm10k_sm_mbx_create_connect_hdr(struct fm10k_mbx_info *mbx, u8 err)\n+{\n+\tif (mbx->local)\n+\t\tmbx->mbx_lock |= FM10K_MBX_REQ;\n+\n+\tmbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(mbx->tail, SM_TAIL) |\n+\t\t       FM10K_MSG_HDR_FIELD_SET(mbx->remote, SM_VER) |\n+\t\t       FM10K_MSG_HDR_FIELD_SET(mbx->head, SM_HEAD) |\n+\t\t       FM10K_MSG_HDR_FIELD_SET(err, SM_ERR);\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_connect_reset - Reset following request for reset\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function resets the mailbox to a just connected state\n+ **/\n+STATIC void fm10k_sm_mbx_connect_reset(struct fm10k_mbx_info *mbx)\n+{\n+\t/* flush any uncompleted work */\n+\tfm10k_mbx_reset_work(mbx);\n+\n+\t/* set local version to max and remote version to 0 */\n+\tmbx->local = FM10K_SM_MBX_VERSION;\n+\tmbx->remote = 0;\n+\n+\t/* initialize tail and head */\n+\tmbx->tail = 1;\n+\tmbx->head = 1;\n+\n+\t/* reset state back to connect */\n+\tmbx->state = FM10K_STATE_CONNECT;\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_connect - Start switch manager mailbox connection\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will initiate a mailbox connection with the switch\n+ *  manager.  To do this it will first disconnect the mailbox, and then\n+ *  reconnect it in order to complete a reset of the mailbox.\n+ *\n+ *  This function will return an error if the mailbox has not been initiated\n+ *  or is currently in use.\n+ **/\n+STATIC s32 fm10k_sm_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx)\n+{\n+\tDEBUGFUNC(\"fm10k_mbx_connect\");\n+\n+\t/* we cannot connect an uninitialized mailbox */\n+\tif (!mbx->rx.buffer)\n+\t\treturn FM10K_MBX_ERR_NO_SPACE;\n+\n+\t/* we cannot connect an already connected mailbox */\n+\tif (mbx->state != FM10K_STATE_CLOSED)\n+\t\treturn FM10K_MBX_ERR_BUSY;\n+\n+\t/* mailbox timeout can now become active */\n+\tmbx->timeout = FM10K_MBX_INIT_TIMEOUT;\n+\n+\t/* Place mbx in ready to connect state */\n+\tmbx->state = FM10K_STATE_CONNECT;\n+\tmbx->max_size = FM10K_MBX_MSG_MAX_SIZE;\n+\n+\t/* reset interface back to connect */\n+\tfm10k_sm_mbx_connect_reset(mbx);\n+\n+\t/* enable interrupt and notify other party of new message */\n+\tmbx->mbx_lock = FM10K_MBX_REQ_INTERRUPT | FM10K_MBX_ACK_INTERRUPT |\n+\t\t\tFM10K_MBX_INTERRUPT_ENABLE;\n+\n+\t/* generate and load connect header into mailbox */\n+\tfm10k_sm_mbx_create_connect_hdr(mbx, 0);\n+\tfm10k_mbx_write(hw, mbx);\n+\n+\t/* enable interrupt and notify other party of new message */\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_disconnect - Shutdown mailbox connection\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will shut down the mailbox.  It places the mailbox first\n+ *  in the disconnect state, it then allows up to a predefined timeout for\n+ *  the mailbox to transition to close on its own.  If this does not occur\n+ *  then the mailbox will be forced into the closed state.\n+ *\n+ *  Any mailbox transactions not completed before calling this function\n+ *  are not guaranteed to complete and may be dropped.\n+ **/\n+STATIC void fm10k_sm_mbx_disconnect(struct fm10k_hw *hw,\n+\t\t\t\t    struct fm10k_mbx_info *mbx)\n+{\n+\tint timeout = mbx->timeout ? FM10K_MBX_DISCONNECT_TIMEOUT : 0;\n+\n+\tDEBUGFUNC(\"fm10k_sm_mbx_disconnect\");\n+\n+\t/* Place mbx in ready to disconnect state */\n+\tmbx->state = FM10K_STATE_DISCONNECT;\n+\n+\t/* trigger interrupt to start shutdown process */\n+\tFM10K_WRITE_REG(hw, mbx->mbx_reg, FM10K_MBX_REQ |\n+\t\t\t\t\t  FM10K_MBX_INTERRUPT_DISABLE);\n+\tdo {\n+\t\tusec_delay(FM10K_MBX_POLL_DELAY);\n+\t\tmbx->ops.process(hw, mbx);\n+\t\ttimeout -= FM10K_MBX_POLL_DELAY;\n+\t} while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED));\n+\n+\t/* in case we didn't close just force the mailbox into shutdown */\n+\tmbx->state = FM10K_STATE_CLOSED;\n+\tmbx->remote = 0;\n+\tfm10k_mbx_reset_work(mbx);\n+\tfm10k_mbx_update_max_size(mbx, 0);\n+\n+\tFM10K_WRITE_REG(hw, mbx->mbmem_reg, 0);\n+}\n+\n+/**\n+ *  fm10k_mbx_validate_fifo_hdr - Validate fields in the remote FIFO header\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will parse up the fields in the mailbox header and return\n+ *  an error if the header contains any of a number of invalid configurations\n+ *  including unrecognized offsets or version numbers.\n+ **/\n+STATIC s32 fm10k_sm_mbx_validate_fifo_hdr(struct fm10k_mbx_info *mbx)\n+{\n+\tconst u32 *hdr = &mbx->mbx_hdr;\n+\tu16 tail, head, ver;\n+\n+\tDEBUGFUNC(\"fm10k_mbx_validate_msg_hdr\");\n+\n+\ttail = FM10K_MSG_HDR_FIELD_GET(*hdr, SM_TAIL);\n+\tver = FM10K_MSG_HDR_FIELD_GET(*hdr, SM_VER);\n+\thead = FM10K_MSG_HDR_FIELD_GET(*hdr, SM_HEAD);\n+\n+\tswitch (ver) {\n+\tcase 0:\n+\t\tbreak;\n+\tcase FM10K_SM_MBX_VERSION:\n+\t\tif (!head || head > FM10K_SM_MBX_FIFO_LEN)\n+\t\t\treturn FM10K_MBX_ERR_HEAD;\n+\t\tif (!tail || tail > FM10K_SM_MBX_FIFO_LEN)\n+\t\t\treturn FM10K_MBX_ERR_TAIL;\n+\t\tif (mbx->tail < head)\n+\t\t\thead += mbx->mbmem_len - 1;\n+\t\tif (tail < mbx->head)\n+\t\t\ttail += mbx->mbmem_len - 1;\n+\t\tif (fm10k_mbx_index_len(mbx, head, mbx->tail) > mbx->tail_len)\n+\t\t\treturn FM10K_MBX_ERR_HEAD;\n+\t\tif (fm10k_mbx_index_len(mbx, mbx->head, tail) < mbx->mbmem_len)\n+\t\t\tbreak;\n+\t\treturn FM10K_MBX_ERR_TAIL;\n+\tdefault:\n+\t\treturn FM10K_MBX_ERR_SRC;\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_process_error - Process header with error flag set\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function is meant to respond to a request where the error flag\n+ *  is set.  As a result we will terminate a connection if one is present\n+ *  and fall back into the reset state with a connection header of version\n+ *  0 (RESET).\n+ **/\n+STATIC void fm10k_sm_mbx_process_error(struct fm10k_mbx_info *mbx)\n+{\n+\tconst enum fm10k_mbx_state state = mbx->state;\n+\n+\tswitch (state) {\n+\tcase FM10K_STATE_DISCONNECT:\n+\t\t/* if there is an error just disconnect */\n+\t\tmbx->remote = 0;\n+\t\tbreak;\n+\tcase FM10K_STATE_OPEN:\n+\t\t/* flush any uncompleted work */\n+\t\tfm10k_sm_mbx_connect_reset(mbx);\n+\t\tbreak;\n+\tcase FM10K_STATE_CONNECT:\n+\t\t/* try connnecting at lower version */\n+\t\tif (mbx->remote) {\n+\t\t\twhile (mbx->local > 1)\n+\t\t\t\tmbx->local--;\n+\t\t\tmbx->remote = 0;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\tfm10k_sm_mbx_create_connect_hdr(mbx, 0);\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_create_error_message - Process an error in FIFO hdr\n+ *  @mbx: pointer to mailbox\n+ *  @err: local error encountered\n+ *\n+ *  This function will interpret the error provided by err, and based on\n+ *  that it may set the error bit in the local message header\n+ **/\n+STATIC void fm10k_sm_mbx_create_error_msg(struct fm10k_mbx_info *mbx, s32 err)\n+{\n+\t/* only generate an error message for these types */\n+\tswitch (err) {\n+\tcase FM10K_MBX_ERR_TAIL:\n+\tcase FM10K_MBX_ERR_HEAD:\n+\tcase FM10K_MBX_ERR_SRC:\n+\tcase FM10K_MBX_ERR_SIZE:\n+\tcase FM10K_MBX_ERR_RSVD0:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn;\n+\t}\n+\n+\t/* process it as though we received an error, and send error reply */\n+\tfm10k_sm_mbx_process_error(mbx);\n+\tfm10k_sm_mbx_create_connect_hdr(mbx, 1);\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_receive - Take message from Rx mailbox FIFO and put it in Rx\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will dequeue one message from the Rx switch manager mailbox\n+ *  FIFO and place it in the Rx mailbox FIFO for processing by software.\n+ **/\n+STATIC s32 fm10k_sm_mbx_receive(struct fm10k_hw *hw,\n+\t\t\t\tstruct fm10k_mbx_info *mbx,\n+\t\t\t\tu16 tail)\n+{\n+\t/* reduce length by 1 to convert to a mask */\n+\tu16 mbmem_len = mbx->mbmem_len - 1;\n+\ts32 err;\n+\n+\tDEBUGFUNC(\"fm10k_sm_mbx_receive\");\n+\n+\t/* push tail in front of head */\n+\tif (tail < mbx->head)\n+\t\ttail += mbmem_len;\n+\n+\t/* copy data to the Rx FIFO */\n+\terr = fm10k_mbx_push_tail(hw, mbx, tail);\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\t/* process messages if we have received any */\n+\tfm10k_mbx_dequeue_rx(hw, mbx);\n+\n+\t/* guarantee head aligns with the end of the last message */\n+\tmbx->head = fm10k_mbx_head_sub(mbx, mbx->pushed);\n+\tmbx->pushed = 0;\n+\n+\t/* clear any extra bits left over since index adds 1 extra bit */\n+\tif (mbx->head > mbmem_len)\n+\t\tmbx->head -= mbmem_len;\n+\n+\treturn err;\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_transmit - Take message from Tx and put it in Tx mailbox FIFO\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will dequeue one message from the Tx mailbox FIFO and place\n+ *  it in the Tx switch manager mailbox FIFO for processing by hardware.\n+ **/\n+STATIC void fm10k_sm_mbx_transmit(struct fm10k_hw *hw,\n+\t\t\t\t  struct fm10k_mbx_info *mbx, u16 head)\n+{\n+\tstruct fm10k_mbx_fifo *fifo = &mbx->tx;\n+\t/* reduce length by 1 to convert to a mask */\n+\tu16 mbmem_len = mbx->mbmem_len - 1;\n+\tu16 tail_len, len = 0;\n+\tu32 *msg;\n+\n+\tDEBUGFUNC(\"fm10k_sm_mbx_transmit\");\n+\n+\t/* push head behind tail */\n+\tif (mbx->tail < head)\n+\t\thead += mbmem_len;\n+\n+\tfm10k_mbx_pull_head(hw, mbx, head);\n+\n+\t/* determine msg aligned offset for end of buffer */\n+\tdo {\n+\t\tmsg = fifo->buffer + fm10k_fifo_head_offset(fifo, len);\n+\t\ttail_len = len;\n+\t\tlen += FM10K_TLV_DWORD_LEN(*msg);\n+\t} while ((len <= mbx->tail_len) && (len < mbmem_len));\n+\n+\t/* guarantee we stop on a message boundary */\n+\tif (mbx->tail_len > tail_len) {\n+\t\tmbx->tail = fm10k_mbx_tail_sub(mbx, mbx->tail_len - tail_len);\n+\t\tmbx->tail_len = tail_len;\n+\t}\n+\n+\t/* clear any extra bits left over since index adds 1 extra bit */\n+\tif (mbx->tail > mbmem_len)\n+\t\tmbx->tail -= mbmem_len;\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_create_reply - Generate reply based on state and remote head\n+ *  @mbx: pointer to mailbox\n+ *  @head: acknowledgement number\n+ *\n+ *  This function will generate an outgoing message based on the current\n+ *  mailbox state and the remote fifo head.  It will return the length\n+ *  of the outgoing message excluding header on success, and a negative value\n+ *  on error.\n+ **/\n+STATIC void fm10k_sm_mbx_create_reply(struct fm10k_hw *hw,\n+\t\t\t\t      struct fm10k_mbx_info *mbx, u16 head)\n+{\n+\tswitch (mbx->state) {\n+\tcase FM10K_STATE_OPEN:\n+\tcase FM10K_STATE_DISCONNECT:\n+\t\t/* flush out Tx data */\n+\t\tfm10k_sm_mbx_transmit(hw, mbx, head);\n+\n+\t\t/* generate new header based on data */\n+\t\tif (mbx->tail_len || (mbx->state == FM10K_STATE_OPEN)) {\n+\t\t\tfm10k_sm_mbx_create_data_hdr(mbx);\n+\t\t} else {\n+\t\t\tmbx->remote = 0;\n+\t\t\tfm10k_sm_mbx_create_connect_hdr(mbx, 0);\n+\t\t}\n+\t\tbreak;\n+\tcase FM10K_STATE_CONNECT:\n+\tcase FM10K_STATE_CLOSED:\n+\t\tfm10k_sm_mbx_create_connect_hdr(mbx, 0);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_process_reset - Process header with version == 0 (RESET)\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function is meant to respond to a request where the version data\n+ *  is set to 0.  As such we will either terminate the connection or go\n+ *  into the connect state in order to re-establish the connection.  This\n+ *  function can also be used to respond to an error as the connection\n+ *  resetting would also be a means of dealing with errors.\n+ **/\n+STATIC void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw,\n+\t\t\t\t       struct fm10k_mbx_info *mbx)\n+{\n+\tconst enum fm10k_mbx_state state = mbx->state;\n+\n+\tswitch (state) {\n+\tcase FM10K_STATE_DISCONNECT:\n+\t\t/* drop remote connections and disconnect */\n+\t\tmbx->state = FM10K_STATE_CLOSED;\n+\t\tmbx->remote = 0;\n+\t\tmbx->local = 0;\n+\t\tbreak;\n+\tcase FM10K_STATE_OPEN:\n+\t\t/* flush any incomplete work */\n+\t\tfm10k_sm_mbx_connect_reset(mbx);\n+\t\tbreak;\n+\tcase FM10K_STATE_CONNECT:\n+\t\t/* Update remote value to match local value */\n+\t\tmbx->remote = mbx->local;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\tfm10k_sm_mbx_create_reply(hw, mbx, mbx->tail);\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_process_version_1 - Process header with version == 1\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function is meant to process messages received when the remote\n+ *  mailbox is active.\n+ **/\n+STATIC s32 fm10k_sm_mbx_process_version_1(struct fm10k_hw *hw,\n+\t\t\t\t\t  struct fm10k_mbx_info *mbx)\n+{\n+\tconst u32 *hdr = &mbx->mbx_hdr;\n+\tu16 head, tail;\n+\ts32 len;\n+\n+\t/* pull all fields needed for verification */\n+\ttail = FM10K_MSG_HDR_FIELD_GET(*hdr, SM_TAIL);\n+\thead = FM10K_MSG_HDR_FIELD_GET(*hdr, SM_HEAD);\n+\n+\t/* if we are in connect and wanting version 1 then start up and go */\n+\tif (mbx->state == FM10K_STATE_CONNECT) {\n+\t\tif (!mbx->remote)\n+\t\t\tgoto send_reply;\n+\t\tif (mbx->remote != 1)\n+\t\t\treturn FM10K_MBX_ERR_SRC;\n+\n+\t\tmbx->state = FM10K_STATE_OPEN;\n+\t}\n+\n+\tdo {\n+\t\t/* abort on message size errors */\n+\t\tlen = fm10k_sm_mbx_receive(hw, mbx, tail);\n+\t\tif (len < 0)\n+\t\t\treturn len;\n+\n+\t\t/* continue until we have flushed the Rx FIFO */\n+\t} while (len);\n+\n+send_reply:\n+\tfm10k_sm_mbx_create_reply(hw, mbx, head);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_process - Process mailbox switch mailbox interrupt\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *\n+ *  This function will process incoming mailbox events and generate mailbox\n+ *  replies.  It will return a value indicating the number of DWORDs\n+ *  transmitted excluding header on success or a negative value on error.\n+ **/\n+STATIC s32 fm10k_sm_mbx_process(struct fm10k_hw *hw,\n+\t\t\t\tstruct fm10k_mbx_info *mbx)\n+{\n+\ts32 err;\n+\n+\tDEBUGFUNC(\"fm10k_sm_mbx_process\");\n+\n+\t/* we do not read mailbox if closed */\n+\tif (mbx->state == FM10K_STATE_CLOSED)\n+\t\treturn FM10K_SUCCESS;\n+\n+\t/* retrieve data from switch manager */\n+\terr = fm10k_mbx_read(hw, mbx);\n+\tif (err)\n+\t\treturn err;\n+\n+\terr = fm10k_sm_mbx_validate_fifo_hdr(mbx);\n+\tif (err < 0)\n+\t\tgoto fifo_err;\n+\n+\tif (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, SM_ERR)) {\n+\t\tfm10k_sm_mbx_process_error(mbx);\n+\t\tgoto fifo_err;\n+\t}\n+\n+\tswitch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, SM_VER)) {\n+\tcase 0:\n+\t\tfm10k_sm_mbx_process_reset(hw, mbx);\n+\t\tbreak;\n+\tcase FM10K_SM_MBX_VERSION:\n+\t\terr = fm10k_sm_mbx_process_version_1(hw, mbx);\n+\t\tbreak;\n+\t}\n+\n+fifo_err:\n+\tif (err < 0)\n+\t\tfm10k_sm_mbx_create_error_msg(mbx, err);\n+\n+\t/* report data to switch manager */\n+\tfm10k_mbx_write(hw, mbx);\n+\n+\treturn err;\n+}\n+\n+/**\n+ *  fm10k_sm_mbx_init - Initialize mailbox memory for PF/SM mailbox\n+ *  @hw: pointer to hardware structure\n+ *  @mbx: pointer to mailbox\n+ *  @msg_data: handlers for mailbox events\n+ *\n+ *  This function for now is used to stub out the PF/SM mailbox\n+ **/\n+s32 fm10k_sm_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx,\n+\t\t      const struct fm10k_msg_data *msg_data)\n+{\n+\tDEBUGFUNC(\"fm10k_sm_mbx_init\");\n+\tUNREFERENCED_1PARAMETER(hw);\n+\n+\tmbx->mbx_reg = FM10K_GMBX;\n+\tmbx->mbmem_reg = FM10K_MBMEM_PF(0);\n+\n+\t/* start out in closed state */\n+\tmbx->state = FM10K_STATE_CLOSED;\n+\n+\t/* validate layout of handlers before assigning them */\n+\tif (fm10k_mbx_validate_handlers(msg_data))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* initialize the message handlers */\n+\tmbx->msg_data = msg_data;\n+\n+\t/* start mailbox as timed out and let the reset_hw call\n+\t * set the timeout value to begin communications\n+\t */\n+\tmbx->timeout = 0;\n+\tmbx->usec_delay = FM10K_MBX_INIT_DELAY;\n+\n+\t/* Split buffer for use by Tx/Rx FIFOs */\n+\tmbx->max_size = FM10K_MBX_MSG_MAX_SIZE;\n+\tmbx->mbmem_len = FM10K_MBMEM_PF_XOR;\n+\n+\t/* initialize the FIFOs, sizes are in 4 byte increments */\n+\tfm10k_fifo_init(&mbx->tx, mbx->buffer, FM10K_MBX_TX_BUFFER_SIZE);\n+\tfm10k_fifo_init(&mbx->rx, &mbx->buffer[FM10K_MBX_TX_BUFFER_SIZE],\n+\t\t\tFM10K_MBX_RX_BUFFER_SIZE);\n+\n+\t/* initialize function pointers */\n+\tmbx->ops.connect = fm10k_sm_mbx_connect;\n+\tmbx->ops.disconnect = fm10k_sm_mbx_disconnect;\n+\tmbx->ops.rx_ready = fm10k_mbx_rx_ready;\n+\tmbx->ops.tx_ready = fm10k_mbx_tx_ready;\n+\tmbx->ops.tx_complete = fm10k_mbx_tx_complete;\n+\tmbx->ops.enqueue_tx = fm10k_mbx_enqueue_tx;\n+\tmbx->ops.process = fm10k_sm_mbx_process;\n+\tmbx->ops.register_handlers = fm10k_mbx_register_handlers;\n+\n+\treturn FM10K_SUCCESS;\n+}\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_mbx.h b/lib/librte_pmd_fm10k/base/fm10k_mbx.h\nnew file mode 100644\nindex 0000000..6332584\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_mbx.h\n@@ -0,0 +1,329 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#ifndef _FM10K_MBX_H_\n+#define _FM10K_MBX_H_\n+\n+/* forward declaration */\n+struct fm10k_mbx_info;\n+\n+#include \"fm10k_type.h\"\n+#include \"fm10k_tlv.h\"\n+\n+/* PF Mailbox Registers */\n+#define FM10K_MBMEM(_n)\t\t((_n) + 0x18000)\n+#define FM10K_MBMEM_VF(_n, _m)\t(((_n) * 0x10) + (_m) + 0x18000)\n+#define FM10K_MBMEM_SM(_n)\t((_n) + 0x18400)\n+#define FM10K_MBMEM_PF(_n)\t((_n) + 0x18600)\n+/* XOR provides means of switching from Tx to Rx FIFO */\n+#define FM10K_MBMEM_PF_XOR\t(FM10K_MBMEM_SM(0) ^ FM10K_MBMEM_PF(0))\n+#define FM10K_MBX(_n)\t\t((_n) + 0x18800)\n+#define FM10K_MBX_OWNER\t\t\t\t0x00000001\n+#define FM10K_MBX_REQ\t\t\t\t0x00000002\n+#define FM10K_MBX_ACK\t\t\t\t0x00000004\n+#define FM10K_MBX_REQ_INTERRUPT\t\t\t0x00000008\n+#define FM10K_MBX_ACK_INTERRUPT\t\t\t0x00000010\n+#define FM10K_MBX_INTERRUPT_ENABLE\t\t0x00000020\n+#define FM10K_MBX_INTERRUPT_DISABLE\t\t0x00000040\n+#define FM10K_MBICR(_n)\t\t((_n) + 0x18840)\n+#define FM10K_GMBX\t\t0x18842\n+\n+/* VF Mailbox Registers */\n+#define FM10K_VFMBX\t\t0x00010\n+#define FM10K_VFMBMEM(_n)\t((_n) + 0x00020)\n+#define FM10K_VFMBMEM_LEN\t16\n+#define FM10K_VFMBMEM_VF_XOR\t(FM10K_VFMBMEM_LEN / 2)\n+\n+/* Delays/timeouts */\n+#define FM10K_MBX_DISCONNECT_TIMEOUT\t\t500\n+#define FM10K_MBX_POLL_DELAY\t\t\t19\n+#define FM10K_MBX_INT_DELAY\t\t\t20\n+\n+#define FM10K_WRITE_MBX(hw, reg, value) FM10K_WRITE_REG(hw, reg, value)\n+\n+/* PF/VF Mailbox state machine\n+ *\n+ * +----------+\t    connect()\t+----------+\n+ * |  CLOSED  | --------------> |  CONNECT |\n+ * +----------+\t\t\t+----------+\n+ *   ^\t\t\t\t  ^\t |\n+ *   | rcv:\t      rcv:\t  |\t | rcv:\n+ *   |  Connect\t       Disconnect |\t |  Connect\n+ *   |  Disconnect     Error\t  |\t |  Data\n+ *   |\t\t\t\t  |\t |\n+ *   |\t\t\t\t  |\t V\n+ * +----------+   disconnect()\t+----------+\n+ * |DISCONNECT| <-------------- |   OPEN   |\n+ * +----------+\t\t\t+----------+\n+ *\n+ * The diagram above describes the PF/VF mailbox state machine.  There\n+ * are four main states to this machine.\n+ * Closed: This state represents a mailbox that is in a standby state\n+ *\t   with interrupts disabled.  In this state the mailbox should not\n+ *\t   read the mailbox or write any data.  The only means of exiting\n+ *\t   this state is for the system to make the connect() call for the\n+ *\t   mailbox, it will then transition to the connect state.\n+ * Connect: In this state the mailbox is seeking a connection.  It will\n+ *\t    post a connect message with no specified destination and will\n+ *\t    wait for a reply from the other side of the mailbox.  This state\n+ *\t    is exited when either a connect with the local mailbox as the\n+ *\t    destination is received or when a data message is received with\n+ *\t    a valid sequence number.\n+ * Open: In this state the mailbox is able to transfer data between the local\n+ *       entity and the remote.  It will fall back to connect in the event of\n+ *       receiving either an error message, or a disconnect message.  It will\n+ *       transition to disconnect on a call to disconnect();\n+ * Disconnect: In this state the mailbox is attempting to gracefully terminate\n+ *\t       the connection.  It will do so at the first point where it knows\n+ *\t       that the remote endpoint is either done sending, or when the\n+ *\t       remote endpoint has fallen back into connect.\n+ */\n+enum fm10k_mbx_state {\n+\tFM10K_STATE_CLOSED,\n+\tFM10K_STATE_CONNECT,\n+\tFM10K_STATE_OPEN,\n+\tFM10K_STATE_DISCONNECT,\n+};\n+\n+/* PF/VF Mailbox header format\n+ *    3\t\t\t  2\t\t      1\t\t\t  0\n+ *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ * |        Size/Err_no/CRC        | Rsvd0 | Head  | Tail  | Type  |\n+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ *\n+ * The layout above describes the format for the header used in the PF/VF\n+ * mailbox.  The header is broken out into the following fields:\n+ * Type: There are 4 supported message types\n+ *\t\t0x8: Data header - used to transport message data\n+ *\t\t0xC: Connect header - used to establish connection\n+ *\t\t0xD: Disconnect header - used to tear down a connection\n+ *\t\t0xE: Error header - used to address message exceptions\n+ * Tail: Tail index for local FIFO\n+ *\t\tTail index actually consists of two parts.  The MSB of\n+ *\t\tthe head is a loop tracker, it is 0 on an even numbered\n+ *\t\tloop through the FIFO, and 1 on the odd numbered loops.\n+ *\t\tTo get the actual mailbox offset based on the tail it\n+ *\t\tis necessary to add bit 3 to bit 0 and clear bit 3.  This\n+ *\t\tgives us a valid range of 0x1 - 0xE.\n+ * Head: Head index for remote FIFO\n+ *\t\tHead index follows the same format as the tail index.\n+ * Rsvd0: Reserved 0 portion of the mailbox header\n+ * CRC: Running CRC for all data since connect plus current message header\n+ * Size: Maximum message size - Applies only to connect headers\n+ *\t\tThe maximum message size is provided during connect to avoid\n+ *\t\tjamming the mailbox with messages that do not fit.\n+ * Err_no: Error number - Applies only to error headers\n+ *\t\tThe error number provides a indication of the type of error\n+ *\t\texperienced.\n+ */\n+\n+/* macros for retriving and setting header values */\n+#define FM10K_MSG_HDR_MASK(name) \\\n+\t((0x1u << FM10K_MSG_##name##_SIZE) - 1)\n+#define FM10K_MSG_HDR_FIELD_SET(value, name) \\\n+\t(((u32)(value) & FM10K_MSG_HDR_MASK(name)) << FM10K_MSG_##name##_SHIFT)\n+#define FM10K_MSG_HDR_FIELD_GET(value, name) \\\n+\t((u16)((value) >> FM10K_MSG_##name##_SHIFT) & FM10K_MSG_HDR_MASK(name))\n+\n+/* offsets shared between all headers */\n+#define FM10K_MSG_TYPE_SHIFT\t\t\t0\n+#define FM10K_MSG_TYPE_SIZE\t\t\t4\n+#define FM10K_MSG_TAIL_SHIFT\t\t\t4\n+#define FM10K_MSG_TAIL_SIZE\t\t\t4\n+#define FM10K_MSG_HEAD_SHIFT\t\t\t8\n+#define FM10K_MSG_HEAD_SIZE\t\t\t4\n+#define FM10K_MSG_RSVD0_SHIFT\t\t\t12\n+#define FM10K_MSG_RSVD0_SIZE\t\t\t4\n+\n+/* offsets for data/disconnect headers */\n+#define FM10K_MSG_CRC_SHIFT\t\t\t16\n+#define FM10K_MSG_CRC_SIZE\t\t\t16\n+\n+/* offsets for connect headers */\n+#define FM10K_MSG_CONNECT_SIZE_SHIFT\t\t16\n+#define FM10K_MSG_CONNECT_SIZE_SIZE\t\t16\n+\n+/* offsets for error headers */\n+#define FM10K_MSG_ERR_NO_SHIFT\t\t\t16\n+#define FM10K_MSG_ERR_NO_SIZE\t\t\t16\n+\n+enum fm10k_msg_type {\n+\tFM10K_MSG_DATA\t\t\t= 0x8,\n+\tFM10K_MSG_CONNECT\t\t= 0xC,\n+\tFM10K_MSG_DISCONNECT\t\t= 0xD,\n+\tFM10K_MSG_ERROR\t\t\t= 0xE,\n+};\n+\n+/* HNI/SM Mailbox FIFO format\n+ *    3                   2                   1                   0\n+ *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ * +-------+-----------------------+-------+-----------------------+\n+ * | Error |      Remote Head      |Version|      Local Tail       |\n+ * +-------+-----------------------+-------+-----------------------+\n+ * |                                                               |\n+ * .                        Local FIFO Data                        .\n+ * .                                                               .\n+ * +-------+-----------------------+-------+-----------------------+\n+ *\n+ * The layout above describes the format for the FIFOs used by the host\n+ * network interface and the switch manager to communicate messages back\n+ * and forth.  Both the HNI and the switch maintain one such FIFO.  The\n+ * layout in memory has the switch manager FIFO followed immediately by\n+ * the HNI FIFO.  For this reason I am using just the pointer to the\n+ * HNI FIFO in the mailbox ops as the offset between the two is fixed.\n+ *\n+ * The header for the FIFO is broken out into the following fields:\n+ * Local Tail:  Offset into FIFO region for next DWORD to write.\n+ * Version:  Version info for mailbox, only values of 0/1 are supported.\n+ * Remote Head:  Offset into remote FIFO to indicate how much we have read.\n+ * Error: Error indication, values TBD.\n+ */\n+\n+/* version number for switch manager mailboxes */\n+#define FM10K_SM_MBX_VERSION\t\t1\n+#define FM10K_SM_MBX_FIFO_LEN\t\t(FM10K_MBMEM_PF_XOR - 1)\n+#define FM10K_SM_MBX_FIFO_HDR_LEN\t1\n+\n+/* offsets shared between all SM FIFO headers */\n+#define FM10K_MSG_SM_TAIL_SHIFT\t\t\t0\n+#define FM10K_MSG_SM_TAIL_SIZE\t\t\t12\n+#define FM10K_MSG_SM_VER_SHIFT\t\t\t12\n+#define FM10K_MSG_SM_VER_SIZE\t\t\t4\n+#define FM10K_MSG_SM_HEAD_SHIFT\t\t\t16\n+#define FM10K_MSG_SM_HEAD_SIZE\t\t\t12\n+#define FM10K_MSG_SM_ERR_SHIFT\t\t\t28\n+#define FM10K_MSG_SM_ERR_SIZE\t\t\t4\n+\n+/* All error messages returned by mailbox functions\n+ * The value -511 is 0xFE01 in hex.  The idea is to order the errors\n+ * from 0xFE01 - 0xFEFF so error codes are easily visible in the mailbox\n+ * messages.  This also helps to avoid error number collisions as Linux\n+ * doesn't appear to use error numbers 256 - 511.\n+ */\n+#define FM10K_MBX_ERR(_n) ((_n) - 512)\n+#define FM10K_MBX_ERR_NO_MBX\t\tFM10K_MBX_ERR(0x01)\n+#define FM10K_MBX_ERR_NO_MSG\t\tFM10K_MBX_ERR(0x02)\n+#define FM10K_MBX_ERR_NO_SPACE\t\tFM10K_MBX_ERR(0x03)\n+#define FM10K_MBX_ERR_LOCK\t\tFM10K_MBX_ERR(0x04)\n+#define FM10K_MBX_ERR_TAIL\t\tFM10K_MBX_ERR(0x05)\n+#define FM10K_MBX_ERR_HEAD\t\tFM10K_MBX_ERR(0x06)\n+#define FM10K_MBX_ERR_DST\t\tFM10K_MBX_ERR(0x07)\n+#define FM10K_MBX_ERR_SRC\t\tFM10K_MBX_ERR(0x08)\n+#define FM10K_MBX_ERR_TYPE\t\tFM10K_MBX_ERR(0x09)\n+#define FM10K_MBX_ERR_LEN\t\tFM10K_MBX_ERR(0x0A)\n+#define FM10K_MBX_ERR_SIZE\t\tFM10K_MBX_ERR(0x0B)\n+#define FM10K_MBX_ERR_BUSY\t\tFM10K_MBX_ERR(0x0C)\n+#define FM10K_MBX_ERR_VALUE\t\tFM10K_MBX_ERR(0x0D)\n+#define FM10K_MBX_ERR_RSVD0\t\tFM10K_MBX_ERR(0x0E)\n+#define FM10K_MBX_ERR_CRC\t\tFM10K_MBX_ERR(0x0F)\n+\n+#define FM10K_MBX_CRC_SEED\t\t0xFFFF\n+\n+struct fm10k_mbx_ops {\n+\ts32 (*connect)(struct fm10k_hw *, struct fm10k_mbx_info *);\n+\tvoid (*disconnect)(struct fm10k_hw *, struct fm10k_mbx_info *);\n+\tbool (*rx_ready)(struct fm10k_mbx_info *);\n+\tbool (*tx_ready)(struct fm10k_mbx_info *, u16);\n+\tbool (*tx_complete)(struct fm10k_mbx_info *);\n+\ts32 (*enqueue_tx)(struct fm10k_hw *, struct fm10k_mbx_info *,\n+\t\t\t  const u32 *);\n+\ts32 (*process)(struct fm10k_hw *, struct fm10k_mbx_info *);\n+\ts32 (*register_handlers)(struct fm10k_mbx_info *,\n+\t\t\t\t const struct fm10k_msg_data *);\n+};\n+\n+struct fm10k_mbx_fifo {\n+\tu32 *buffer;\n+\tu16 head;\n+\tu16 tail;\n+\tu16 size;\n+};\n+\n+/* size of buffer to be stored in mailbox for FIFOs */\n+#define FM10K_MBX_TX_BUFFER_SIZE\t512\n+#define FM10K_MBX_RX_BUFFER_SIZE\t128\n+#define FM10K_MBX_BUFFER_SIZE \\\n+\t(FM10K_MBX_TX_BUFFER_SIZE + FM10K_MBX_RX_BUFFER_SIZE)\n+\n+/* minimum and maximum message size in dwords */\n+#define FM10K_MBX_MSG_MAX_SIZE \\\n+\t((FM10K_MBX_TX_BUFFER_SIZE - 1) & (FM10K_MBX_RX_BUFFER_SIZE - 1))\n+#define FM10K_VFMBX_MSG_MTU\t((FM10K_VFMBMEM_LEN / 2) - 1)\n+\n+#define FM10K_MBX_INIT_TIMEOUT\t2000 /* number of retries on mailbox */\n+#define FM10K_MBX_INIT_DELAY\t500  /* microseconds between retries */\n+\n+struct fm10k_mbx_info {\n+\t/* function pointers for mailbox operations */\n+\tstruct fm10k_mbx_ops ops;\n+\tconst struct fm10k_msg_data *msg_data;\n+\n+\t/* message FIFOs */\n+\tstruct fm10k_mbx_fifo rx;\n+\tstruct fm10k_mbx_fifo tx;\n+\n+\t/* delay for handling timeouts */\n+\tu32 timeout;\n+\tu32 usec_delay;\n+\n+\t/* mailbox state info */\n+\tu32 mbx_reg, mbmem_reg, mbx_lock, mbx_hdr;\n+\tu16 max_size, mbmem_len;\n+\tu16 tail, tail_len, pulled;\n+\tu16 head, head_len, pushed;\n+\tu16 local, remote;\n+\tenum fm10k_mbx_state state;\n+\n+\t/* result of last mailbox test */\n+\ts32 test_result;\n+\n+\t/* statistics */\n+\tu64 tx_busy;\n+\tu64 tx_dropped;\n+\tu64 tx_messages;\n+\tu64 tx_dwords;\n+\tu64 rx_messages;\n+\tu64 rx_dwords;\n+\tu64 rx_parse_err;\n+\n+\t/* Buffer to store messages */\n+\tu32 buffer[FM10K_MBX_BUFFER_SIZE];\n+};\n+\n+s32 fm10k_pfvf_mbx_init(struct fm10k_hw *, struct fm10k_mbx_info *,\n+\t\t\tconst struct fm10k_msg_data *, u8);\n+s32 fm10k_sm_mbx_init(struct fm10k_hw *, struct fm10k_mbx_info *,\n+\t\t      const struct fm10k_msg_data *);\n+\n+#endif /* _FM10K_MBX_H_ */\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_osdep.h b/lib/librte_pmd_fm10k/base/fm10k_osdep.h\nnew file mode 100644\nindex 0000000..04f8fe9\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_osdep.h\n@@ -0,0 +1,148 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013-2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#ifndef _FM10K_OSDEP_H_\n+#define _FM10K_OSDEP_H_\n+\n+#include <stdint.h>\n+#include <string.h>\n+#include <rte_atomic.h>\n+#include <rte_byteorder.h>\n+#include <rte_cycles.h>\n+#include \"../fm10k_logs.h\"\n+\n+/* TODO: this does not look like it should be used... */\n+#define ERROR_REPORT2(v1, v2, v3)   do { } while (0)\n+\n+#define STATIC                  static\n+#define DEBUGFUNC(F)            DEBUGOUT(F);\n+#define DEBUGOUT(S, args...)    PMD_DRV_LOG_RAW(DEBUG, S, ##args)\n+#define DEBUGOUT1(S, args...)   DEBUGOUT(S, ##args)\n+#define DEBUGOUT2(S, args...)   DEBUGOUT(S, ##args)\n+#define DEBUGOUT3(S, args...)   DEBUGOUT(S, ##args)\n+#define DEBUGOUT6(S, args...)   DEBUGOUT(S, ##args)\n+#define DEBUGOUT7(S, args...)   DEBUGOUT(S, ##args)\n+\n+#define FALSE      0\n+#define TRUE       1\n+#ifndef false\n+#define false      FALSE\n+#endif\n+#ifndef true\n+#define true       TRUE\n+#endif\n+\n+typedef uint8_t    u8;\n+typedef int8_t     s8;\n+typedef uint16_t   u16;\n+typedef int16_t    s16;\n+typedef uint32_t   u32;\n+typedef int32_t    s32;\n+typedef int64_t    s64;\n+typedef uint64_t   u64;\n+typedef int        bool;\n+\n+#ifndef __le16\n+#define __le16     u16\n+#define __le32     u32\n+#define __le64     u64\n+#endif\n+#ifndef __be16\n+#define __be16     u16\n+#define __be32     u32\n+#define __be64     u64\n+#endif\n+\n+/* offsets are WORD offsets, not BYTE offsets */\n+#define FM10K_WRITE_REG(hw, reg, val)    \\\n+\t((((volatile uint32_t *)(hw)->hw_addr)[(reg)]) = ((uint32_t)(val)))\n+#define FM10K_READ_REG(hw, reg)          \\\n+\t(((volatile uint32_t *)(hw)->hw_addr)[(reg)])\n+#define FM10K_WRITE_FLUSH(a) FM10K_READ_REG(a, FM10K_CTRL)\n+\n+#define FM10K_PCI_REG(reg) (*((volatile uint32_t *)(reg)))\n+\n+#define FM10K_PCI_REG_WRITE(reg, value) do { \\\n+\tFM10K_PCI_REG((reg)) = (value); \\\n+} while (0)\n+\n+/* not implemented */\n+#define FM10K_READ_PCI_WORD(hw, reg)     0\n+\n+#define FM10K_WRITE_MBX(hw, reg, value) FM10K_WRITE_REG(hw, reg, value)\n+#define FM10K_READ_MBX(hw, reg) FM10K_READ_REG(hw, reg)\n+\n+#define FM10K_LE16_TO_CPU    rte_le_to_cpu_16\n+#define FM10K_LE32_TO_CPU    rte_le_to_cpu_32\n+#define FM10K_CPU_TO_LE32    rte_cpu_to_le_32\n+#define FM10K_CPU_TO_LE16    rte_cpu_to_le_16\n+\n+#define FM10K_RMB            rte_rmb\n+#define FM10K_WMB            rte_wmb\n+\n+#define usec_delay           rte_delay_us\n+\n+#define FM10K_REMOVED(hw_addr) (!(hw_addr))\n+\n+#ifndef FM10K_IS_ZERO_ETHER_ADDR\n+/* make certain address is not 0 */\n+#define FM10K_IS_ZERO_ETHER_ADDR(addr) \\\n+(!((addr)[0] | (addr)[1] | (addr)[2] | (addr)[3] | (addr)[4] | (addr)[5]))\n+#endif\n+\n+#ifndef FM10K_IS_MULTICAST_ETHER_ADDR\n+#define FM10K_IS_MULTICAST_ETHER_ADDR(addr) ((addr)[0] & 0x1)\n+#endif\n+\n+#ifndef FM10K_IS_VALID_ETHER_ADDR\n+/* make certain address is not multicast or 0 */\n+#define FM10K_IS_VALID_ETHER_ADDR(addr) \\\n+(!FM10K_IS_MULTICAST_ETHER_ADDR(addr) && !FM10K_IS_ZERO_ETHER_ADDR(addr))\n+#endif\n+\n+#ifndef do_div\n+#define do_div(n, base) ({\\\n+\t(n) = (n) / (base);\\\n+})\n+#endif /* do_div */\n+\n+/* DPDK can't access IOMEM directly */\n+#ifndef FM10K_WRITE_SW_REG\n+#define FM10K_WRITE_SW_REG(v1, v2, v3)   do { } while (0)\n+#endif\n+\n+#ifndef fm10k_read_reg\n+#define fm10k_read_reg FM10K_READ_REG\n+#endif\n+\n+#endif /* _FM10K_OSDEP_H_ */\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_pf.c b/lib/librte_pmd_fm10k/base/fm10k_pf.c\nnew file mode 100644\nindex 0000000..3545a24\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_pf.c\n@@ -0,0 +1,1992 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#include \"fm10k_pf.h\"\n+#include \"fm10k_vf.h\"\n+\n+/**\n+ *  fm10k_reset_hw_pf - PF hardware reset\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This function should return the hardware to a state similar to the\n+ *  one it is in after being powered on.\n+ **/\n+STATIC s32 fm10k_reset_hw_pf(struct fm10k_hw *hw)\n+{\n+\ts32 err;\n+\tu32 reg;\n+\tu16 i;\n+\n+\tDEBUGFUNC(\"fm10k_reset_hw_pf\");\n+\n+\t/* Disable interrupts */\n+\tFM10K_WRITE_REG(hw, FM10K_EIMR, FM10K_EIMR_DISABLE(ALL));\n+\n+\t/* Lock ITR2 reg 0 into itself and disable interrupt moderation */\n+\tFM10K_WRITE_REG(hw, FM10K_ITR2(0), 0);\n+\tFM10K_WRITE_REG(hw, FM10K_INT_CTRL, 0);\n+\n+\t/* We assume here Tx and Rx queue 0 are owned by the PF */\n+\n+\t/* Shut off VF access to their queues forcing them to queue 0 */\n+\tfor (i = 0; i < FM10K_TQMAP_TABLE_SIZE; i++) {\n+\t\tFM10K_WRITE_REG(hw, FM10K_TQMAP(i), 0);\n+\t\tFM10K_WRITE_REG(hw, FM10K_RQMAP(i), 0);\n+\t}\n+\n+\t/* shut down all rings */\n+\terr = fm10k_disable_queues_generic(hw, FM10K_MAX_QUEUES);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* Verify that DMA is no longer active */\n+\treg = FM10K_READ_REG(hw, FM10K_DMA_CTRL);\n+\tif (reg & (FM10K_DMA_CTRL_TX_ACTIVE | FM10K_DMA_CTRL_RX_ACTIVE))\n+\t\treturn FM10K_ERR_DMA_PENDING;\n+\n+\t/* verify the switch is ready for reset */\n+\treg = FM10K_READ_REG(hw, FM10K_DMA_CTRL2);\n+\tif (!(reg & FM10K_DMA_CTRL2_SWITCH_READY))\n+\t\tgoto out;\n+\n+\t/* Inititate data path reset */\n+\treg |= FM10K_DMA_CTRL_DATAPATH_RESET;\n+\tFM10K_WRITE_REG(hw, FM10K_DMA_CTRL, reg);\n+\n+\t/* Flush write and allow 100us for reset to complete */\n+\tFM10K_WRITE_FLUSH(hw);\n+\tusec_delay(FM10K_RESET_TIMEOUT);\n+\n+\t/* Verify we made it out of reset */\n+\treg = FM10K_READ_REG(hw, FM10K_IP);\n+\tif (!(reg & FM10K_IP_NOTINRESET))\n+\t\terr = FM10K_ERR_RESET_FAILED;\n+\n+out:\n+\treturn err;\n+}\n+\n+/**\n+ *  fm10k_is_ari_hierarchy_pf - Indicate ARI hierarchy support\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Looks at the ARI hierarchy bit to determine whether ARI is supported or not.\n+ **/\n+STATIC bool fm10k_is_ari_hierarchy_pf(struct fm10k_hw *hw)\n+{\n+\tu16 sriov_ctrl = FM10K_READ_PCI_WORD(hw, FM10K_PCIE_SRIOV_CTRL);\n+\n+\tDEBUGFUNC(\"fm10k_is_ari_hierarchy_pf\");\n+\n+\treturn !!(sriov_ctrl & FM10K_PCIE_SRIOV_CTRL_VFARI);\n+}\n+\n+/**\n+ *  fm10k_init_hw_pf - PF hardware initialization\n+ *  @hw: pointer to hardware structure\n+ *\n+ **/\n+STATIC s32 fm10k_init_hw_pf(struct fm10k_hw *hw)\n+{\n+\tu32 dma_ctrl, txqctl;\n+\tu16 i;\n+\n+\tDEBUGFUNC(\"fm10k_init_hw_pf\");\n+\n+\t/* Establish default VSI as valid */\n+\tFM10K_WRITE_REG(hw, FM10K_DGLORTDEC(fm10k_dglort_default), 0);\n+\tFM10K_WRITE_REG(hw, FM10K_DGLORTMAP(fm10k_dglort_default),\n+\t\t\tFM10K_DGLORTMAP_ANY);\n+\n+\t/* Invalidate all other GLORT entries */\n+\tfor (i = 1; i < FM10K_DGLORT_COUNT; i++)\n+\t\tFM10K_WRITE_REG(hw, FM10K_DGLORTMAP(i), FM10K_DGLORTMAP_NONE);\n+\n+\t/* reset ITR2(0) to point to itself */\n+\tFM10K_WRITE_REG(hw, FM10K_ITR2(0), 0);\n+\n+\t/* reset VF ITR2(0) to point to 0 avoid PF registers */\n+\tFM10K_WRITE_REG(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), 0);\n+\n+\t/* loop through all PF ITR2 registers pointing them to the previous */\n+\tfor (i = 1; i < FM10K_ITR_REG_COUNT_PF; i++)\n+\t\tFM10K_WRITE_REG(hw, FM10K_ITR2(i), i - 1);\n+\n+\t/* Enable interrupt moderator if not already enabled */\n+\tFM10K_WRITE_REG(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);\n+\n+\t/* compute the default txqctl configuration */\n+\ttxqctl = FM10K_TXQCTL_PF | FM10K_TXQCTL_UNLIMITED_BW |\n+\t\t (hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT);\n+\n+\tfor (i = 0; i < FM10K_MAX_QUEUES; i++) {\n+\t\t/* configure rings for 256 Queue / 32 Descriptor cache mode */\n+\t\tFM10K_WRITE_REG(hw, FM10K_TQDLOC(i),\n+\t\t\t\t(i * FM10K_TQDLOC_BASE_32_DESC) |\n+\t\t\t\tFM10K_TQDLOC_SIZE_32_DESC);\n+\t\tFM10K_WRITE_REG(hw, FM10K_TXQCTL(i), txqctl);\n+\n+\t\t/* configure rings to provide TPH processing hints */\n+\t\tFM10K_WRITE_REG(hw, FM10K_TPH_TXCTRL(i),\n+\t\t\t\tFM10K_TPH_TXCTRL_DESC_TPHEN |\n+\t\t\t\tFM10K_TPH_TXCTRL_DESC_RROEN |\n+\t\t\t\tFM10K_TPH_TXCTRL_DESC_WROEN |\n+\t\t\t\tFM10K_TPH_TXCTRL_DATA_RROEN);\n+\t\tFM10K_WRITE_REG(hw, FM10K_TPH_RXCTRL(i),\n+\t\t\t\tFM10K_TPH_RXCTRL_DESC_TPHEN |\n+\t\t\t\tFM10K_TPH_RXCTRL_DESC_RROEN |\n+\t\t\t\tFM10K_TPH_RXCTRL_DATA_WROEN |\n+\t\t\t\tFM10K_TPH_RXCTRL_HDR_WROEN);\n+\t}\n+\n+\t/* set max hold interval to align with 1.024 usec in all modes */\n+\tswitch (hw->bus.speed) {\n+\tcase fm10k_bus_speed_2500:\n+\t\tdma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN1;\n+\t\tbreak;\n+\tcase fm10k_bus_speed_5000:\n+\t\tdma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN2;\n+\t\tbreak;\n+\tcase fm10k_bus_speed_8000:\n+\t\tdma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN3;\n+\t\tbreak;\n+\tdefault:\n+\t\tdma_ctrl = 0;\n+\t\tbreak;\n+\t}\n+\n+\t/* Configure TSO flags */\n+\tFM10K_WRITE_REG(hw, FM10K_DTXTCPFLGL, FM10K_TSO_FLAGS_LOW);\n+\tFM10K_WRITE_REG(hw, FM10K_DTXTCPFLGH, FM10K_TSO_FLAGS_HI);\n+\n+\t/* Enable DMA engine\n+\t * Set Rx Descriptor size to 32\n+\t * Set Minimum MSS to 64\n+\t * Set Maximum number of Rx queues to 256 / 32 Descriptor\n+\t */\n+\tdma_ctrl |= FM10K_DMA_CTRL_TX_ENABLE | FM10K_DMA_CTRL_RX_ENABLE |\n+\t\t    FM10K_DMA_CTRL_RX_DESC_SIZE | FM10K_DMA_CTRL_MINMSS_64 |\n+\t\t    FM10K_DMA_CTRL_32_DESC;\n+\n+\tFM10K_WRITE_REG(hw, FM10K_DMA_CTRL, dma_ctrl);\n+\n+\t/* record maximum queue count, we limit ourselves to 128 */\n+\thw->mac.max_queues = FM10K_MAX_QUEUES_PF;\n+\n+\t/* We support either 64 VFs or 7 VFs depending on if we have ARI */\n+\thw->iov.total_vfs = fm10k_is_ari_hierarchy_pf(hw) ? 64 : 7;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_is_slot_appropriate_pf - Indicate appropriate slot for this SKU\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Looks at the PCIe bus info to confirm whether or not this slot can support\n+ *  the necessary bandwidth for this device.\n+ **/\n+STATIC bool fm10k_is_slot_appropriate_pf(struct fm10k_hw *hw)\n+{\n+\tDEBUGFUNC(\"fm10k_is_slot_appropriate_pf\");\n+\n+\treturn (hw->bus.speed == hw->bus_caps.speed) &&\n+\t       (hw->bus.width == hw->bus_caps.width);\n+}\n+\n+/**\n+ *  fm10k_update_vlan_pf - Update status of VLAN ID in VLAN filter table\n+ *  @hw: pointer to hardware structure\n+ *  @vid: VLAN ID to add to table\n+ *  @vsi: Index indicating VF ID or PF ID in table\n+ *  @set: Indicates if this is a set or clear operation\n+ *\n+ *  This function adds or removes the corresponding VLAN ID from the VLAN\n+ *  filter table for the corresponding function.  In addition to the\n+ *  standard set/clear that supports one bit a multi-bit write is\n+ *  supported to set 64 bits at a time.\n+ **/\n+STATIC s32 fm10k_update_vlan_pf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)\n+{\n+\tu32 vlan_table, reg, mask, bit, len;\n+\n+\t/* verify the VSI index is valid */\n+\tif (vsi > FM10K_VLAN_TABLE_VSI_MAX)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* VLAN multi-bit write:\n+\t * The multi-bit write has several parts to it.\n+\t *    3\t\t\t  2\t\t      1\t\t\t  0\n+\t *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+\t * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+\t * | RSVD0 |         Length        |C|RSVD0|        VLAN ID        |\n+\t * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+\t *\n+\t * VLAN ID: Vlan Starting value\n+\t * RSVD0: Reserved section, must be 0\n+\t * C: Flag field, 0 is set, 1 is clear (Used in VF VLAN message)\n+\t * Length: Number of times to repeat the bit being set\n+\t */\n+\tlen = vid >> 16;\n+\tvid = (vid << 17) >> 17;\n+\n+\t/* verify the reserved 0 fields are 0 */\n+\tif (len >= FM10K_VLAN_TABLE_VID_MAX || vid >= FM10K_VLAN_TABLE_VID_MAX)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* Loop through the table updating all required VLANs */\n+\tfor (reg = FM10K_VLAN_TABLE(vsi, vid / 32), bit = vid % 32;\n+\t     len < FM10K_VLAN_TABLE_VID_MAX;\n+\t     len -= 32 - bit, reg++, bit = 0) {\n+\t\t/* record the initial state of the register */\n+\t\tvlan_table = FM10K_READ_REG(hw, reg);\n+\n+\t\t/* truncate mask if we are at the start or end of the run */\n+\t\tmask = (~(u32)0 >> ((len < 31) ? 31 - len : 0)) << bit;\n+\n+\t\t/* make necessary modifications to the register */\n+\t\tmask &= set ? ~vlan_table : vlan_table;\n+\t\tif (mask)\n+\t\t\tFM10K_WRITE_REG(hw, reg, vlan_table ^ mask);\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_read_mac_addr_pf - Read device MAC address\n+ *  @hw: pointer to the HW structure\n+ *\n+ *  Reads the device MAC address from the SM_AREA and stores the value.\n+ **/\n+STATIC s32 fm10k_read_mac_addr_pf(struct fm10k_hw *hw)\n+{\n+\tu8 perm_addr[ETH_ALEN];\n+\tu32 serial_num;\n+\tint i;\n+\n+\tDEBUGFUNC(\"fm10k_read_mac_addr_pf\");\n+\n+\tserial_num = FM10K_READ_REG(hw, FM10K_SM_AREA(1));\n+\n+\t/* last byte should be all 1's */\n+\tif ((~serial_num) << 24)\n+\t\treturn  FM10K_ERR_INVALID_MAC_ADDR;\n+\n+\tperm_addr[0] = (u8)(serial_num >> 24);\n+\tperm_addr[1] = (u8)(serial_num >> 16);\n+\tperm_addr[2] = (u8)(serial_num >> 8);\n+\n+\tserial_num = FM10K_READ_REG(hw, FM10K_SM_AREA(0));\n+\n+\t/* first byte should be all 1's */\n+\tif ((~serial_num) >> 24)\n+\t\treturn  FM10K_ERR_INVALID_MAC_ADDR;\n+\n+\tperm_addr[3] = (u8)(serial_num >> 16);\n+\tperm_addr[4] = (u8)(serial_num >> 8);\n+\tperm_addr[5] = (u8)(serial_num);\n+\n+\tfor (i = 0; i < ETH_ALEN; i++) {\n+\t\thw->mac.perm_addr[i] = perm_addr[i];\n+\t\thw->mac.addr[i] = perm_addr[i];\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_glort_valid_pf - Validate that the provided glort is valid\n+ *  @hw: pointer to the HW structure\n+ *  @glort: base glort to be validated\n+ *\n+ *  This function will return an error if the provided glort is invalid\n+ **/\n+bool fm10k_glort_valid_pf(struct fm10k_hw *hw, u16 glort)\n+{\n+\tglort &= hw->mac.dglort_map >> FM10K_DGLORTMAP_MASK_SHIFT;\n+\n+\treturn glort == (hw->mac.dglort_map & FM10K_DGLORTMAP_NONE);\n+}\n+\n+/**\n+ *  fm10k_update_xc_addr_pf - Update device addresses\n+ *  @hw: pointer to the HW structure\n+ *  @glort: base resource tag for this request\n+ *  @mac: MAC address to add/remove from table\n+ *  @vid: VLAN ID to add/remove from table\n+ *  @add: Indicates if this is an add or remove operation\n+ *  @flags: flags field to indicate add and secure\n+ *\n+ *  This function generates a message to the Switch API requesting\n+ *  that the given logical port add/remove the given L2 MAC/VLAN address.\n+ **/\n+STATIC s32 fm10k_update_xc_addr_pf(struct fm10k_hw *hw, u16 glort,\n+\t\t\t\t   const u8 *mac, u16 vid, bool add, u8 flags)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tstruct fm10k_mac_update mac_update;\n+\tu32 msg[5];\n+\n+\tDEBUGFUNC(\"fm10k_update_xc_addr_pf\");\n+\n+\t/* if glort or VLAN are not valid return error */\n+\tif (!fm10k_glort_valid_pf(hw, glort) || vid >= FM10K_VLAN_TABLE_VID_MAX)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* record fields */\n+\tmac_update.mac_lower = FM10K_CPU_TO_LE32(((u32)mac[2] << 24) |\n+\t\t\t\t\t\t ((u32)mac[3] << 16) |\n+\t\t\t\t\t\t ((u32)mac[4] << 8) |\n+\t\t\t\t\t\t ((u32)mac[5]));\n+\tmac_update.mac_upper = FM10K_CPU_TO_LE16(((u32)mac[0] << 8) |\n+\t\t\t\t\t\t ((u32)mac[1]));\n+\tmac_update.vlan = FM10K_CPU_TO_LE16(vid);\n+\tmac_update.glort = FM10K_CPU_TO_LE16(glort);\n+\tmac_update.action = add ? 0 : 1;\n+\tmac_update.flags = flags;\n+\n+\t/* populate mac_update fields */\n+\tfm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_UPDATE_MAC_FWD_RULE);\n+\tfm10k_tlv_attr_put_le_struct(msg, FM10K_PF_ATTR_ID_MAC_UPDATE,\n+\t\t\t\t     &mac_update, sizeof(mac_update));\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+/**\n+ *  fm10k_update_uc_addr_pf - Update device unicast addresses\n+ *  @hw: pointer to the HW structure\n+ *  @glort: base resource tag for this request\n+ *  @mac: MAC address to add/remove from table\n+ *  @vid: VLAN ID to add/remove from table\n+ *  @add: Indicates if this is an add or remove operation\n+ *  @flags: flags field to indicate add and secure\n+ *\n+ *  This function is used to add or remove unicast addresses for\n+ *  the PF.\n+ **/\n+STATIC s32 fm10k_update_uc_addr_pf(struct fm10k_hw *hw, u16 glort,\n+\t\t\t\t   const u8 *mac, u16 vid, bool add, u8 flags)\n+{\n+\tDEBUGFUNC(\"fm10k_update_uc_addr_pf\");\n+\n+\t/* verify MAC address is valid */\n+\tif (!FM10K_IS_VALID_ETHER_ADDR(mac))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\treturn fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, flags);\n+}\n+\n+/**\n+ *  fm10k_update_mc_addr_pf - Update device multicast addresses\n+ *  @hw: pointer to the HW structure\n+ *  @glort: base resource tag for this request\n+ *  @mac: MAC address to add/remove from table\n+ *  @vid: VLAN ID to add/remove from table\n+ *  @add: Indicates if this is an add or remove operation\n+ *\n+ *  This function is used to add or remove multicast MAC addresses for\n+ *  the PF.\n+ **/\n+STATIC s32 fm10k_update_mc_addr_pf(struct fm10k_hw *hw, u16 glort,\n+\t\t\t\t   const u8 *mac, u16 vid, bool add)\n+{\n+\tDEBUGFUNC(\"fm10k_update_mc_addr_pf\");\n+\n+\t/* verify multicast address is valid */\n+\tif (!FM10K_IS_MULTICAST_ETHER_ADDR(mac))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\treturn fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, 0);\n+}\n+\n+/**\n+ *  fm10k_update_xcast_mode_pf - Request update of multicast mode\n+ *  @hw: pointer to hardware structure\n+ *  @glort: base resource tag for this request\n+ *  @mode: integer value indicating mode being requested\n+ *\n+ *  This function will attempt to request a higher mode for the port\n+ *  so that it can enable either multicast, multicast promiscuous, or\n+ *  promiscuous mode of operation.\n+ **/\n+STATIC s32 fm10k_update_xcast_mode_pf(struct fm10k_hw *hw, u16 glort, u8 mode)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tu32 msg[3], xcast_mode;\n+\n+\tDEBUGFUNC(\"fm10k_update_xcast_mode_pf\");\n+\n+\tif (mode > FM10K_XCAST_MODE_NONE)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* if glort is not valid return error */\n+\tif (!fm10k_glort_valid_pf(hw, glort))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* write xcast mode as a single u32 value,\n+\t * lower 16 bits: glort\n+\t * upper 16 bits: mode\n+\t */\n+\txcast_mode = ((u32)mode << 16) | glort;\n+\n+\t/* generate message requesting to change xcast mode */\n+\tfm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_XCAST_MODES);\n+\tfm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_XCAST_MODE, xcast_mode);\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+/**\n+ *  fm10k_update_int_moderator_pf - Update interrupt moderator linked list\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This function walks through the MSI-X vector table to determine the\n+ *  number of active interrupts and based on that information updates the\n+ *  interrupt moderator linked list.\n+ **/\n+STATIC void fm10k_update_int_moderator_pf(struct fm10k_hw *hw)\n+{\n+\tu32 i;\n+\n+\t/* Disable interrupt moderator */\n+\tFM10K_WRITE_REG(hw, FM10K_INT_CTRL, 0);\n+\n+\t/* loop through PF from last to first looking enabled vectors */\n+\tfor (i = FM10K_ITR_REG_COUNT_PF - 1; i; i--) {\n+\t\tif (!FM10K_READ_REG(hw, FM10K_MSIX_VECTOR_MASK(i)))\n+\t\t\tbreak;\n+\t}\n+\n+\t/* always reset VFITR2[0] to point to last enabled PF vector */\n+\tFM10K_WRITE_REG(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), i);\n+\n+\t/* reset ITR2[0] to point to last enabled PF vector */\n+\tif (!hw->iov.num_vfs)\n+\t\tFM10K_WRITE_REG(hw, FM10K_ITR2(0), i);\n+\n+\t/* Enable interrupt moderator */\n+\tFM10K_WRITE_REG(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);\n+}\n+\n+/**\n+ *  fm10k_update_lport_state_pf - Notify the switch of a change in port state\n+ *  @hw: pointer to the HW structure\n+ *  @glort: base resource tag for this request\n+ *  @count: number of logical ports being updated\n+ *  @enable: boolean value indicating enable or disable\n+ *\n+ *  This function is used to add/remove a logical port from the switch.\n+ **/\n+STATIC s32 fm10k_update_lport_state_pf(struct fm10k_hw *hw, u16 glort,\n+\t\t\t\t       u16 count, bool enable)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tu32 msg[3], lport_msg;\n+\n+\tDEBUGFUNC(\"fm10k_lport_state_pf\");\n+\n+\t/* do nothing if we are being asked to create or destroy 0 ports */\n+\tif (!count)\n+\t\treturn FM10K_SUCCESS;\n+\n+\t/* if glort is not valid return error */\n+\tif (!fm10k_glort_valid_pf(hw, glort))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* construct the lport message from the 2 pieces of data we have */\n+\tlport_msg = ((u32)count << 16) | glort;\n+\n+\t/* generate lport create/delete message */\n+\tfm10k_tlv_msg_init(msg, enable ? FM10K_PF_MSG_ID_LPORT_CREATE :\n+\t\t\t\t\t FM10K_PF_MSG_ID_LPORT_DELETE);\n+\tfm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_PORT, lport_msg);\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+/**\n+ *  fm10k_configure_dglort_map_pf - Configures GLORT entry and queues\n+ *  @hw: pointer to hardware structure\n+ *  @dglort: pointer to dglort configuration structure\n+ *\n+ *  Reads the configuration structure contained in dglort_cfg and uses\n+ *  that information to then populate a DGLORTMAP/DEC entry and the queues\n+ *  to which it has been assigned.\n+ **/\n+STATIC s32 fm10k_configure_dglort_map_pf(struct fm10k_hw *hw,\n+\t\t\t\t\t struct fm10k_dglort_cfg *dglort)\n+{\n+\tu16 glort, queue_count, vsi_count, pc_count;\n+\tu16 vsi, queue, pc, q_idx;\n+\tu32 txqctl, dglortdec, dglortmap;\n+\n+\t/* verify the dglort pointer */\n+\tif (!dglort)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* verify the dglort values */\n+\tif ((dglort->idx > 7) || (dglort->rss_l > 7) || (dglort->pc_l > 3) ||\n+\t    (dglort->vsi_l > 6) || (dglort->vsi_b > 64) ||\n+\t    (dglort->queue_l > 8) || (dglort->queue_b >= 256))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* determine count of VSIs and queues */\n+\tqueue_count = 1 << (dglort->rss_l + dglort->pc_l);\n+\tvsi_count = 1 << (dglort->vsi_l + dglort->queue_l);\n+\tglort = dglort->glort;\n+\tq_idx = dglort->queue_b;\n+\n+\t/* configure SGLORT for queues */\n+\tfor (vsi = 0; vsi < vsi_count; vsi++, glort++) {\n+\t\tfor (queue = 0; queue < queue_count; queue++, q_idx++) {\n+\t\t\tif (q_idx >= FM10K_MAX_QUEUES)\n+\t\t\t\tbreak;\n+\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_TX_SGLORT(q_idx), glort);\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_RX_SGLORT(q_idx), glort);\n+\t\t}\n+\t}\n+\n+\t/* determine count of PCs and queues */\n+\tqueue_count = 1 << (dglort->queue_l + dglort->rss_l + dglort->vsi_l);\n+\tpc_count = 1 << dglort->pc_l;\n+\n+\t/* configure PC for Tx queues */\n+\tfor (pc = 0; pc < pc_count; pc++) {\n+\t\tq_idx = pc + dglort->queue_b;\n+\t\tfor (queue = 0; queue < queue_count; queue++) {\n+\t\t\tif (q_idx >= FM10K_MAX_QUEUES)\n+\t\t\t\tbreak;\n+\n+\t\t\ttxqctl = FM10K_READ_REG(hw, FM10K_TXQCTL(q_idx));\n+\t\t\ttxqctl &= ~FM10K_TXQCTL_PC_MASK;\n+\t\t\ttxqctl |= pc << FM10K_TXQCTL_PC_SHIFT;\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_TXQCTL(q_idx), txqctl);\n+\n+\t\t\tq_idx += pc_count;\n+\t\t}\n+\t}\n+\n+\t/* configure DGLORTDEC */\n+\tdglortdec = ((u32)(dglort->rss_l) << FM10K_DGLORTDEC_RSSLENGTH_SHIFT) |\n+\t\t    ((u32)(dglort->queue_b) << FM10K_DGLORTDEC_QBASE_SHIFT) |\n+\t\t    ((u32)(dglort->pc_l) << FM10K_DGLORTDEC_PCLENGTH_SHIFT) |\n+\t\t    ((u32)(dglort->vsi_b) << FM10K_DGLORTDEC_VSIBASE_SHIFT) |\n+\t\t    ((u32)(dglort->vsi_l) << FM10K_DGLORTDEC_VSILENGTH_SHIFT) |\n+\t\t    ((u32)(dglort->queue_l));\n+\tif (dglort->inner_rss)\n+\t\tdglortdec |=  FM10K_DGLORTDEC_INNERRSS_ENABLE;\n+\n+\t/* configure DGLORTMAP */\n+\tdglortmap = (dglort->idx == fm10k_dglort_default) ?\n+\t\t\tFM10K_DGLORTMAP_ANY : FM10K_DGLORTMAP_ZERO;\n+\tdglortmap <<= dglort->vsi_l + dglort->queue_l + dglort->shared_l;\n+\tdglortmap |= dglort->glort;\n+\n+\t/* write values to hardware */\n+\tFM10K_WRITE_REG(hw, FM10K_DGLORTDEC(dglort->idx), dglortdec);\n+\tFM10K_WRITE_REG(hw, FM10K_DGLORTMAP(dglort->idx), dglortmap);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+u16 fm10k_queues_per_pool(struct fm10k_hw *hw)\n+{\n+\tu16 num_pools = hw->iov.num_pools;\n+\n+\treturn (num_pools > 32) ? 2 : (num_pools > 16) ? 4 : (num_pools > 8) ?\n+\t       8 : FM10K_MAX_QUEUES_POOL;\n+}\n+\n+u16 fm10k_vf_queue_index(struct fm10k_hw *hw, u16 vf_idx)\n+{\n+\tu16 num_vfs = hw->iov.num_vfs;\n+\tu16 vf_q_idx = FM10K_MAX_QUEUES;\n+\n+\tvf_q_idx -= fm10k_queues_per_pool(hw) * (num_vfs - vf_idx);\n+\n+\treturn vf_q_idx;\n+}\n+\n+STATIC u16 fm10k_vectors_per_pool(struct fm10k_hw *hw)\n+{\n+\tu16 num_pools = hw->iov.num_pools;\n+\n+\treturn (num_pools > 32) ? 8 : (num_pools > 16) ? 16 :\n+\t       FM10K_MAX_VECTORS_POOL;\n+}\n+\n+STATIC u16 fm10k_vf_vector_index(struct fm10k_hw *hw, u16 vf_idx)\n+{\n+\tu16 vf_v_idx = FM10K_MAX_VECTORS_PF;\n+\n+\tvf_v_idx += fm10k_vectors_per_pool(hw) * vf_idx;\n+\n+\treturn vf_v_idx;\n+}\n+\n+/**\n+ *  fm10k_iov_assign_resources_pf - Assign pool resources for virtualization\n+ *  @hw: pointer to the HW structure\n+ *  @num_vfs: number of VFs to be allocated\n+ *  @num_pools: number of virtualization pools to be allocated\n+ *\n+ *  Allocates queues and traffic classes to virtualization entities to prepare\n+ *  the PF for SR-IOV and VMDq\n+ **/\n+STATIC s32 fm10k_iov_assign_resources_pf(struct fm10k_hw *hw, u16 num_vfs,\n+\t\t\t\t\t u16 num_pools)\n+{\n+\tu16 qmap_stride, qpp, vpp, vf_q_idx, vf_q_idx0, qmap_idx;\n+\tu32 vid = hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT;\n+\tint i, j;\n+\n+\t/* hardware only supports up to 64 pools */\n+\tif (num_pools > 64)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* the number of VFs cannot exceed the number of pools */\n+\tif ((num_vfs > num_pools) || (num_vfs > hw->iov.total_vfs))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* record number of virtualization entities */\n+\thw->iov.num_vfs = num_vfs;\n+\thw->iov.num_pools = num_pools;\n+\n+\t/* determine qmap offsets and counts */\n+\tqmap_stride = (num_vfs > 8) ? 32 : 256;\n+\tqpp = fm10k_queues_per_pool(hw);\n+\tvpp = fm10k_vectors_per_pool(hw);\n+\n+\t/* calculate starting index for queues */\n+\tvf_q_idx = fm10k_vf_queue_index(hw, 0);\n+\tqmap_idx = 0;\n+\n+\t/* establish TCs with -1 credits and no quanta to prevent transmit */\n+\tfor (i = 0; i < num_vfs; i++) {\n+\t\tFM10K_WRITE_REG(hw, FM10K_TC_MAXCREDIT(i), 0);\n+\t\tFM10K_WRITE_REG(hw, FM10K_TC_RATE(i), 0);\n+\t\tFM10K_WRITE_REG(hw, FM10K_TC_CREDIT(i),\n+\t\t\t\tFM10K_TC_CREDIT_CREDIT_MASK);\n+\t}\n+\n+\t/* zero out all mbmem registers */\n+\tfor (i = FM10K_VFMBMEM_LEN * num_vfs; i--;)\n+\t\tFM10K_WRITE_REG(hw, FM10K_MBMEM(i), 0);\n+\n+\t/* clear event notification of VF FLR */\n+\tFM10K_WRITE_REG(hw, FM10K_PFVFLREC(0), ~0);\n+\tFM10K_WRITE_REG(hw, FM10K_PFVFLREC(1), ~0);\n+\n+\t/* loop through unallocated rings assigning them back to PF */\n+\tfor (i = FM10K_MAX_QUEUES_PF; i < vf_q_idx; i++) {\n+\t\tFM10K_WRITE_REG(hw, FM10K_TXDCTL(i), 0);\n+\t\tFM10K_WRITE_REG(hw, FM10K_TXQCTL(i), FM10K_TXQCTL_PF | vid);\n+\t\tFM10K_WRITE_REG(hw, FM10K_RXQCTL(i), FM10K_RXQCTL_PF);\n+\t}\n+\n+\t/* PF should have already updated VFITR2[0] */\n+\n+\t/* update all ITR registers to flow to VFITR2[0] */\n+\tfor (i = FM10K_ITR_REG_COUNT_PF + 1; i < FM10K_ITR_REG_COUNT; i++) {\n+\t\tif (!(i & (vpp - 1)))\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_ITR2(i), i - vpp);\n+\t\telse\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_ITR2(i), i - 1);\n+\t}\n+\n+\t/* update PF ITR2[0] to reference the last vector */\n+\tFM10K_WRITE_REG(hw, FM10K_ITR2(0),\n+\t\t\tfm10k_vf_vector_index(hw, num_vfs - 1));\n+\n+\t/* loop through rings populating rings and TCs */\n+\tfor (i = 0; i < num_vfs; i++) {\n+\t\t/* record index for VF queue 0 for use in end of loop */\n+\t\tvf_q_idx0 = vf_q_idx;\n+\n+\t\tfor (j = 0; j < qpp; j++, qmap_idx++, vf_q_idx++) {\n+\t\t\t/* assign VF and locked TC to queues */\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_TXDCTL(vf_q_idx), 0);\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx),\n+\t\t\t\t\t(i << FM10K_TXQCTL_TC_SHIFT) | i |\n+\t\t\t\t\tFM10K_TXQCTL_VF | vid);\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_RXDCTL(vf_q_idx),\n+\t\t\t\t\tFM10K_RXDCTL_WRITE_BACK_MIN_DELAY |\n+\t\t\t\t\tFM10K_RXDCTL_DROP_ON_EMPTY);\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_RXQCTL(vf_q_idx),\n+\t\t\t\t\tFM10K_RXQCTL_VF |\n+\t\t\t\t\t(i << FM10K_RXQCTL_VF_SHIFT));\n+\n+\t\t\t/* map queue pair to VF */\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx), vf_q_idx);\n+\t\t}\n+\n+\t\t/* repeat the first ring for all of the remaining VF rings */\n+\t\tfor (; j < qmap_stride; j++, qmap_idx++) {\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx0);\n+\t\t\tFM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx), vf_q_idx0);\n+\t\t}\n+\t}\n+\n+\t/* loop through remaining indexes assigning all to queue 0 */\n+\twhile (qmap_idx < FM10K_TQMAP_TABLE_SIZE) {\n+\t\tFM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), 0);\n+\t\tFM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx), 0);\n+\t\tqmap_idx++;\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_iov_configure_tc_pf - Configure the shaping group for VF\n+ *  @hw: pointer to the HW structure\n+ *  @vf_idx: index of VF receiving GLORT\n+ *  @rate: Rate indicated in Mb/s\n+ *\n+ *  Configured the TC for a given VF to allow only up to a given number\n+ *  of Mb/s of outgoing Tx throughput.\n+ **/\n+STATIC s32 fm10k_iov_configure_tc_pf(struct fm10k_hw *hw, u16 vf_idx, int rate)\n+{\n+\t/* configure defaults */\n+\tu32 interval = FM10K_TC_RATE_INTERVAL_4US_GEN3;\n+\tu32 tc_rate = FM10K_TC_RATE_QUANTA_MASK;\n+\n+\t/* verify vf is in range */\n+\tif (vf_idx >= hw->iov.num_vfs)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* set interval to align with 4.096 usec in all modes */\n+\tswitch (hw->bus.speed) {\n+\tcase fm10k_bus_speed_2500:\n+\t\tinterval = FM10K_TC_RATE_INTERVAL_4US_GEN1;\n+\t\tbreak;\n+\tcase fm10k_bus_speed_5000:\n+\t\tinterval = FM10K_TC_RATE_INTERVAL_4US_GEN2;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\tif (rate) {\n+\t\tif (rate > FM10K_VF_TC_MAX || rate < FM10K_VF_TC_MIN)\n+\t\t\treturn FM10K_ERR_PARAM;\n+\n+\t\t/* The quanta is measured in Bytes per 4.096 or 8.192 usec\n+\t\t * The rate is provided in Mbits per second\n+\t\t * To tralslate from rate to quanta we need to multiply the\n+\t\t * rate by 8.192 usec and divide by 8 bits/byte.  To avoid\n+\t\t * dealing with floating point we can round the values up\n+\t\t * to the nearest whole number ratio which gives us 128 / 125.\n+\t\t */\n+\t\ttc_rate = (rate * 128) / 125;\n+\n+\t\t/* try to keep the rate limiting accurate by increasing\n+\t\t * the number of credits and interval for rates less than 4Gb/s\n+\t\t */\n+\t\tif (rate < 4000)\n+\t\t\tinterval <<= 1;\n+\t\telse\n+\t\t\ttc_rate >>= 1;\n+\t}\n+\n+\t/* update rate limiter with new values */\n+\tFM10K_WRITE_REG(hw, FM10K_TC_RATE(vf_idx), tc_rate | interval);\n+\tFM10K_WRITE_REG(hw, FM10K_TC_MAXCREDIT(vf_idx), FM10K_TC_MAXCREDIT_64K);\n+\tFM10K_WRITE_REG(hw, FM10K_TC_CREDIT(vf_idx), FM10K_TC_MAXCREDIT_64K);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_iov_assign_int_moderator_pf - Add VF interrupts to moderator list\n+ *  @hw: pointer to the HW structure\n+ *  @vf_idx: index of VF receiving GLORT\n+ *\n+ *  Update the interrupt moderator linked list to include any MSI-X\n+ *  interrupts which the VF has enabled in the MSI-X vector table.\n+ **/\n+STATIC s32 fm10k_iov_assign_int_moderator_pf(struct fm10k_hw *hw, u16 vf_idx)\n+{\n+\tu16 vf_v_idx, vf_v_limit, i;\n+\n+\t/* verify vf is in range */\n+\tif (vf_idx >= hw->iov.num_vfs)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* determine vector offset and count */\n+\tvf_v_idx = fm10k_vf_vector_index(hw, vf_idx);\n+\tvf_v_limit = vf_v_idx + fm10k_vectors_per_pool(hw);\n+\n+\t/* search for first vector that is not masked */\n+\tfor (i = vf_v_limit - 1; i > vf_v_idx; i--) {\n+\t\tif (!FM10K_READ_REG(hw, FM10K_MSIX_VECTOR_MASK(i)))\n+\t\t\tbreak;\n+\t}\n+\n+\t/* reset linked list so it now includes our active vectors */\n+\tif (vf_idx == (hw->iov.num_vfs - 1))\n+\t\tFM10K_WRITE_REG(hw, FM10K_ITR2(0), i);\n+\telse\n+\t\tFM10K_WRITE_REG(hw, FM10K_ITR2(vf_v_limit), i);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_iov_assign_default_mac_vlan_pf - Assign a MAC and VLAN to VF\n+ *  @hw: pointer to the HW structure\n+ *  @vf_info: pointer to VF information structure\n+ *\n+ *  Assign a MAC address and default VLAN to a VF and notify it of the update\n+ **/\n+STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,\n+\t\t\t\t\t\tstruct fm10k_vf_info *vf_info)\n+{\n+\tu16 qmap_stride, queues_per_pool, vf_q_idx, timeout, qmap_idx, i;\n+\tu32 msg[4], txdctl, txqctl, tdbal = 0, tdbah = 0;\n+\ts32 err = FM10K_SUCCESS;\n+\tu16 vf_idx, vf_vid;\n+\n+\t/* verify vf is in range */\n+\tif (!vf_info || vf_info->vf_idx >= hw->iov.num_vfs)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* determine qmap offsets and counts */\n+\tqmap_stride = (hw->iov.num_vfs > 8) ? 32 : 256;\n+\tqueues_per_pool = fm10k_queues_per_pool(hw);\n+\n+\t/* calculate starting index for queues */\n+\tvf_idx = vf_info->vf_idx;\n+\tvf_q_idx = fm10k_vf_queue_index(hw, vf_idx);\n+\tqmap_idx = qmap_stride * vf_idx;\n+\n+\t/* MAP Tx queue back to 0 temporarily, and disable it */\n+\tFM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), 0);\n+\tFM10K_WRITE_REG(hw, FM10K_TXDCTL(vf_q_idx), 0);\n+\n+\t/* determine correct default VLAN ID */\n+\tif (vf_info->pf_vid)\n+\t\tvf_vid = vf_info->pf_vid | FM10K_VLAN_CLEAR;\n+\telse\n+\t\tvf_vid = vf_info->sw_vid;\n+\n+\t/* generate MAC_ADDR request */\n+\tfm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);\n+\tfm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_DEFAULT_MAC,\n+\t\t\t\t    vf_info->mac, vf_vid);\n+\n+\t/* load onto outgoing mailbox, ignore any errors on enqueue */\n+\tif (vf_info->mbx.ops.enqueue_tx)\n+\t\tvf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);\n+\n+\t/* verify ring has disabled before modifying base address registers */\n+\ttxdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(vf_q_idx));\n+\tfor (timeout = 0; txdctl & FM10K_TXDCTL_ENABLE; timeout++) {\n+\t\t/* limit ourselves to a 1ms timeout */\n+\t\tif (timeout == 10) {\n+\t\t\terr = FM10K_ERR_DMA_PENDING;\n+\t\t\tgoto err_out;\n+\t\t}\n+\n+\t\tusec_delay(100);\n+\t\ttxdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(vf_q_idx));\n+\t}\n+\n+\t/* Update base address registers to contain MAC address */\n+\tif (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac)) {\n+\t\ttdbal = (((u32)vf_info->mac[3]) << 24) |\n+\t\t\t(((u32)vf_info->mac[4]) << 16) |\n+\t\t\t(((u32)vf_info->mac[5]) << 8);\n+\n+\t\ttdbah = (((u32)0xFF)\t        << 24) |\n+\t\t\t(((u32)vf_info->mac[0]) << 16) |\n+\t\t\t(((u32)vf_info->mac[1]) << 8) |\n+\t\t\t((u32)vf_info->mac[2]);\n+\t}\n+\n+\t/* Record the base address into queue 0 */\n+\tFM10K_WRITE_REG(hw, FM10K_TDBAL(vf_q_idx), tdbal);\n+\tFM10K_WRITE_REG(hw, FM10K_TDBAH(vf_q_idx), tdbah);\n+\n+err_out:\n+\t/* configure Queue control register */\n+\ttxqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &\n+\t\t FM10K_TXQCTL_VID_MASK;\n+\ttxqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |\n+\t\t  FM10K_TXQCTL_VF | vf_idx;\n+\n+\t/* assign VID */\n+\tfor (i = 0; i < queues_per_pool; i++)\n+\t\tFM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);\n+\n+\t/* restore the queue back to VF ownership */\n+\tFM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);\n+\treturn err;\n+}\n+\n+/**\n+ *  fm10k_iov_reset_resources_pf - Reassign queues and interrupts to a VF\n+ *  @hw: pointer to the HW structure\n+ *  @vf_info: pointer to VF information structure\n+ *\n+ *  Reassign the interrupts and queues to a VF following an FLR\n+ **/\n+STATIC s32 fm10k_iov_reset_resources_pf(struct fm10k_hw *hw,\n+\t\t\t\t\tstruct fm10k_vf_info *vf_info)\n+{\n+\tu16 qmap_stride, queues_per_pool, vf_q_idx, qmap_idx;\n+\tu32 tdbal = 0, tdbah = 0, txqctl, rxqctl;\n+\tu16 vf_v_idx, vf_v_limit, vf_vid;\n+\tu8 vf_idx = vf_info->vf_idx;\n+\tint i;\n+\n+\t/* verify vf is in range */\n+\tif (vf_idx >= hw->iov.num_vfs)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* clear event notification of VF FLR */\n+\tFM10K_WRITE_REG(hw, FM10K_PFVFLREC(vf_idx / 32), 1 << (vf_idx % 32));\n+\n+\t/* force timeout and then disconnect the mailbox */\n+\tvf_info->mbx.timeout = 0;\n+\tif (vf_info->mbx.ops.disconnect)\n+\t\tvf_info->mbx.ops.disconnect(hw, &vf_info->mbx);\n+\n+\t/* determine vector offset and count */\n+\tvf_v_idx = fm10k_vf_vector_index(hw, vf_idx);\n+\tvf_v_limit = vf_v_idx + fm10k_vectors_per_pool(hw);\n+\n+\t/* determine qmap offsets and counts */\n+\tqmap_stride = (hw->iov.num_vfs > 8) ? 32 : 256;\n+\tqueues_per_pool = fm10k_queues_per_pool(hw);\n+\tqmap_idx = qmap_stride * vf_idx;\n+\n+\t/* make all the queues inaccessible to the VF */\n+\tfor (i = qmap_idx; i < (qmap_idx + qmap_stride); i++) {\n+\t\tFM10K_WRITE_REG(hw, FM10K_TQMAP(i), 0);\n+\t\tFM10K_WRITE_REG(hw, FM10K_RQMAP(i), 0);\n+\t}\n+\n+\t/* calculate starting index for queues */\n+\tvf_q_idx = fm10k_vf_queue_index(hw, vf_idx);\n+\n+\t/* determine correct default VLAN ID */\n+\tif (vf_info->pf_vid)\n+\t\tvf_vid = vf_info->pf_vid;\n+\telse\n+\t\tvf_vid = vf_info->sw_vid;\n+\n+\t/* configure Queue control register */\n+\ttxqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) |\n+\t\t (vf_idx << FM10K_TXQCTL_TC_SHIFT) |\n+\t\t FM10K_TXQCTL_VF | vf_idx;\n+\trxqctl = FM10K_RXQCTL_VF | (vf_idx << FM10K_RXQCTL_VF_SHIFT);\n+\n+\t/* stop further DMA and reset queue ownership back to VF */\n+\tfor (i = vf_q_idx; i < (queues_per_pool + vf_q_idx); i++) {\n+\t\tFM10K_WRITE_REG(hw, FM10K_TXDCTL(i), 0);\n+\t\tFM10K_WRITE_REG(hw, FM10K_TXQCTL(i), txqctl);\n+\t\tFM10K_WRITE_REG(hw, FM10K_RXDCTL(i),\n+\t\t\t\tFM10K_RXDCTL_WRITE_BACK_MIN_DELAY |\n+\t\t\t\tFM10K_RXDCTL_DROP_ON_EMPTY);\n+\t\tFM10K_WRITE_REG(hw, FM10K_RXQCTL(i), rxqctl);\n+\t}\n+\n+\t/* reset TC with -1 credits and no quanta to prevent transmit */\n+\tFM10K_WRITE_REG(hw, FM10K_TC_MAXCREDIT(vf_idx), 0);\n+\tFM10K_WRITE_REG(hw, FM10K_TC_RATE(vf_idx), 0);\n+\tFM10K_WRITE_REG(hw, FM10K_TC_CREDIT(vf_idx),\n+\t\t\tFM10K_TC_CREDIT_CREDIT_MASK);\n+\n+\t/* update our first entry in the table based on previous VF */\n+\tif (!vf_idx)\n+\t\thw->mac.ops.update_int_moderator(hw);\n+\telse\n+\t\thw->iov.ops.assign_int_moderator(hw, vf_idx - 1);\n+\n+\t/* reset linked list so it now includes our active vectors */\n+\tif (vf_idx == (hw->iov.num_vfs - 1))\n+\t\tFM10K_WRITE_REG(hw, FM10K_ITR2(0), vf_v_idx);\n+\telse\n+\t\tFM10K_WRITE_REG(hw, FM10K_ITR2(vf_v_limit), vf_v_idx);\n+\n+\t/* link remaining vectors so that next points to previous */\n+\tfor (vf_v_idx++; vf_v_idx < vf_v_limit; vf_v_idx++)\n+\t\tFM10K_WRITE_REG(hw, FM10K_ITR2(vf_v_idx), vf_v_idx - 1);\n+\n+\t/* zero out MBMEM, VLAN_TABLE, RETA, RSSRK, and MRQC registers */\n+\tfor (i = FM10K_VFMBMEM_LEN; i--;)\n+\t\tFM10K_WRITE_REG(hw, FM10K_MBMEM_VF(vf_idx, i), 0);\n+\tfor (i = FM10K_VLAN_TABLE_SIZE; i--;)\n+\t\tFM10K_WRITE_REG(hw, FM10K_VLAN_TABLE(vf_info->vsi, i), 0);\n+\tfor (i = FM10K_RETA_SIZE; i--;)\n+\t\tFM10K_WRITE_REG(hw, FM10K_RETA(vf_info->vsi, i), 0);\n+\tfor (i = FM10K_RSSRK_SIZE; i--;)\n+\t\tFM10K_WRITE_REG(hw, FM10K_RSSRK(vf_info->vsi, i), 0);\n+\tFM10K_WRITE_REG(hw, FM10K_MRQC(vf_info->vsi), 0);\n+\n+\t/* Update base address registers to contain MAC address */\n+\tif (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac)) {\n+\t\ttdbal = (((u32)vf_info->mac[3]) << 24) |\n+\t\t\t(((u32)vf_info->mac[4]) << 16) |\n+\t\t\t(((u32)vf_info->mac[5]) << 8);\n+\t\ttdbah = (((u32)0xFF)\t   << 24) |\n+\t\t\t(((u32)vf_info->mac[0]) << 16) |\n+\t\t\t(((u32)vf_info->mac[1]) << 8) |\n+\t\t\t((u32)vf_info->mac[2]);\n+\t}\n+\n+\t/* map queue pairs back to VF from last to first */\n+\tfor (i = queues_per_pool; i--;) {\n+\t\tFM10K_WRITE_REG(hw, FM10K_TDBAL(vf_q_idx + i), tdbal);\n+\t\tFM10K_WRITE_REG(hw, FM10K_TDBAH(vf_q_idx + i), tdbah);\n+\t\tFM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx + i), vf_q_idx + i);\n+\t\tFM10K_WRITE_REG(hw, FM10K_RQMAP(qmap_idx + i), vf_q_idx + i);\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_iov_set_lport_pf - Assign and enable a logical port for a given VF\n+ *  @hw: pointer to hardware structure\n+ *  @vf_info: pointer to VF information structure\n+ *  @lport_idx: Logical port offset from the hardware glort\n+ *  @flags: Set of capability flags to extend port beyond basic functionality\n+ *\n+ *  This function allows enabling a VF port by assigning it a GLORT and\n+ *  setting the flags so that it can enable an Rx mode.\n+ **/\n+STATIC s32 fm10k_iov_set_lport_pf(struct fm10k_hw *hw,\n+\t\t\t\t  struct fm10k_vf_info *vf_info,\n+\t\t\t\t  u16 lport_idx, u8 flags)\n+{\n+\tu16 glort = (hw->mac.dglort_map + lport_idx) & FM10K_DGLORTMAP_NONE;\n+\n+\tDEBUGFUNC(\"fm10k_iov_set_lport_state_pf\");\n+\n+\t/* if glort is not valid return error */\n+\tif (!fm10k_glort_valid_pf(hw, glort))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tvf_info->vf_flags = flags | FM10K_VF_FLAG_NONE_CAPABLE;\n+\tvf_info->glort = glort;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_iov_reset_lport_pf - Disable a logical port for a given VF\n+ *  @hw: pointer to hardware structure\n+ *  @vf_info: pointer to VF information structure\n+ *\n+ *  This function disables a VF port by stripping it of a GLORT and\n+ *  setting the flags so that it cannot enable any Rx mode.\n+ **/\n+STATIC void fm10k_iov_reset_lport_pf(struct fm10k_hw *hw,\n+\t\t\t\t     struct fm10k_vf_info *vf_info)\n+{\n+\tu32 msg[1];\n+\n+\tDEBUGFUNC(\"fm10k_iov_reset_lport_state_pf\");\n+\n+\t/* need to disable the port if it is already enabled */\n+\tif (FM10K_VF_FLAG_ENABLED(vf_info)) {\n+\t\t/* notify switch that this port has been disabled */\n+\t\tfm10k_update_lport_state_pf(hw, vf_info->glort, 1, false);\n+\n+\t\t/* generate port state response to notify VF it is not ready */\n+\t\tfm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);\n+\t\tvf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);\n+\t}\n+\n+\t/* clear flags and glort if it exists */\n+\tvf_info->vf_flags = 0;\n+\tvf_info->glort = 0;\n+}\n+\n+/**\n+ *  fm10k_iov_update_stats_pf - Updates hardware related statistics for VFs\n+ *  @hw: pointer to hardware structure\n+ *  @q: stats for all queues of a VF\n+ *  @vf_idx: index of VF\n+ *\n+ *  This function collects queue stats for VFs.\n+ **/\n+STATIC void fm10k_iov_update_stats_pf(struct fm10k_hw *hw,\n+\t\t\t\t      struct fm10k_hw_stats_q *q,\n+\t\t\t\t      u16 vf_idx)\n+{\n+\tu32 idx, qpp;\n+\n+\t/* get stats for all of the queues */\n+\tqpp = fm10k_queues_per_pool(hw);\n+\tidx = fm10k_vf_queue_index(hw, vf_idx);\n+\tfm10k_update_hw_stats_q(hw, q, idx, qpp);\n+}\n+\n+STATIC s32 fm10k_iov_report_timestamp_pf(struct fm10k_hw *hw,\n+\t\t\t\t\t struct fm10k_vf_info *vf_info,\n+\t\t\t\t\t u64 timestamp)\n+{\n+\tu32 msg[4];\n+\n+\t/* generate port state response to notify VF it is not ready */\n+\tfm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_1588);\n+\tfm10k_tlv_attr_put_u64(msg, FM10K_1588_MSG_TIMESTAMP, timestamp);\n+\n+\treturn vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);\n+}\n+\n+/**\n+ *  fm10k_iov_msg_msix_pf - Message handler for MSI-X request from VF\n+ *  @hw: Pointer to hardware structure\n+ *  @results: Pointer array to message, results[0] is pointer to message\n+ *  @mbx: Pointer to mailbox information structure\n+ *\n+ *  This function is a default handler for MSI-X requests from the VF.  The\n+ *  assumption is that in this case it is acceptable to just directly\n+ *  hand off the message from the VF to the underlying shared code.\n+ **/\n+s32 fm10k_iov_msg_msix_pf(struct fm10k_hw *hw, u32 **results,\n+\t\t\t  struct fm10k_mbx_info *mbx)\n+{\n+\tstruct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;\n+\tu8 vf_idx = vf_info->vf_idx;\n+\n+\tUNREFERENCED_1PARAMETER(results);\n+\tDEBUGFUNC(\"fm10k_iov_msg_msix_pf\");\n+\n+\treturn hw->iov.ops.assign_int_moderator(hw, vf_idx);\n+}\n+\n+/**\n+ *  fm10k_iov_msg_mac_vlan_pf - Message handler for MAC/VLAN request from VF\n+ *  @hw: Pointer to hardware structure\n+ *  @results: Pointer array to message, results[0] is pointer to message\n+ *  @mbx: Pointer to mailbox information structure\n+ *\n+ *  This function is a default handler for MAC/VLAN requests from the VF.\n+ *  The assumption is that in this case it is acceptable to just directly\n+ *  hand off the message from the VF to the underlying shared code.\n+ **/\n+s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results,\n+\t\t\t      struct fm10k_mbx_info *mbx)\n+{\n+\tstruct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;\n+\tint err = FM10K_SUCCESS;\n+\tu8 mac[ETH_ALEN];\n+\tu32 *result;\n+\tu16 vlan;\n+\tu32 vid;\n+\n+\tDEBUGFUNC(\"fm10k_iov_msg_mac_vlan_pf\");\n+\n+\t/* we shouldn't be updating rules on a disabled interface */\n+\tif (!FM10K_VF_FLAG_ENABLED(vf_info))\n+\t\terr = FM10K_ERR_PARAM;\n+\n+\tif (!err && !!results[FM10K_MAC_VLAN_MSG_VLAN]) {\n+\t\tresult = results[FM10K_MAC_VLAN_MSG_VLAN];\n+\n+\t\t/* record VLAN id requested */\n+\t\terr = fm10k_tlv_attr_get_u32(result, &vid);\n+\t\tif (err)\n+\t\t\treturn err;\n+\n+\t\t/* if VLAN ID is 0, set the default VLAN ID instead of 0 */\n+\t\tif (!vid || (vid == FM10K_VLAN_CLEAR)) {\n+\t\t\tif (vf_info->pf_vid)\n+\t\t\t\tvid |= vf_info->pf_vid;\n+\t\t\telse\n+\t\t\t\tvid |= vf_info->sw_vid;\n+\t\t} else if (vid != vf_info->pf_vid) {\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t\t}\n+\n+\t\t/* update VSI info for VF in regards to VLAN table */\n+\t\terr = hw->mac.ops.update_vlan(hw, vid, vf_info->vsi,\n+\t\t\t\t\t      !(vid & FM10K_VLAN_CLEAR));\n+\t}\n+\n+\tif (!err && !!results[FM10K_MAC_VLAN_MSG_MAC]) {\n+\t\tresult = results[FM10K_MAC_VLAN_MSG_MAC];\n+\n+\t\t/* record unicast MAC address requested */\n+\t\terr = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);\n+\t\tif (err)\n+\t\t\treturn err;\n+\n+\t\t/* block attempts to set MAC for a locked device */\n+\t\tif (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac) &&\n+\t\t    memcmp(mac, vf_info->mac, ETH_ALEN))\n+\t\t\treturn FM10K_ERR_PARAM;\n+\n+\t\t/* if VLAN ID is 0, set the default VLAN ID instead of 0 */\n+\t\tif (!vlan || (vlan == FM10K_VLAN_CLEAR)) {\n+\t\t\tif (vf_info->pf_vid)\n+\t\t\t\tvlan |= vf_info->pf_vid;\n+\t\t\telse\n+\t\t\t\tvlan |= vf_info->sw_vid;\n+\t\t} else if (vf_info->pf_vid) {\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t\t}\n+\n+\t\t/* notify switch of request for new unicast address */\n+\t\terr = hw->mac.ops.update_uc_addr(hw, vf_info->glort, mac, vlan,\n+\t\t\t\t\t\t !(vlan & FM10K_VLAN_CLEAR), 0);\n+\t}\n+\n+\tif (!err && !!results[FM10K_MAC_VLAN_MSG_MULTICAST]) {\n+\t\tresult = results[FM10K_MAC_VLAN_MSG_MULTICAST];\n+\n+\t\t/* record multicast MAC address requested */\n+\t\terr = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);\n+\t\tif (err)\n+\t\t\treturn err;\n+\n+\t\t/* verify that the VF is allowed to request multicast */\n+\t\tif (!(vf_info->vf_flags & FM10K_VF_FLAG_MULTI_ENABLED))\n+\t\t\treturn FM10K_ERR_PARAM;\n+\n+\t\t/* if VLAN ID is 0, set the default VLAN ID instead of 0 */\n+\t\tif (!vlan || (vlan == FM10K_VLAN_CLEAR)) {\n+\t\t\tif (vf_info->pf_vid)\n+\t\t\t\tvlan |= vf_info->pf_vid;\n+\t\t\telse\n+\t\t\t\tvlan |= vf_info->sw_vid;\n+\t\t} else if (vf_info->pf_vid) {\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t\t}\n+\n+\t\t/* notify switch of request for new multicast address */\n+\t\terr = hw->mac.ops.update_mc_addr(hw, vf_info->glort, mac,\n+\t\t\t\t\t\t !(vlan & FM10K_VLAN_CLEAR), 0);\n+\t}\n+\n+\treturn err;\n+}\n+\n+/**\n+ *  fm10k_iov_supported_xcast_mode_pf - Determine best match for xcast mode\n+ *  @vf_info: VF info structure containing capability flags\n+ *  @mode: Requested xcast mode\n+ *\n+ *  This function outputs the mode that most closely matches the requested\n+ *  mode.  If not modes match it will request we disable the port\n+ **/\n+STATIC u8 fm10k_iov_supported_xcast_mode_pf(struct fm10k_vf_info *vf_info,\n+\t\t\t\t\t    u8 mode)\n+{\n+\tu8 vf_flags = vf_info->vf_flags;\n+\n+\t/* match up mode to capabilities as best as possible */\n+\tswitch (mode) {\n+\tcase FM10K_XCAST_MODE_PROMISC:\n+\t\tif (vf_flags & FM10K_VF_FLAG_PROMISC_CAPABLE)\n+\t\t\treturn FM10K_XCAST_MODE_PROMISC;\n+\t\t/* fallthough */\n+\tcase FM10K_XCAST_MODE_ALLMULTI:\n+\t\tif (vf_flags & FM10K_VF_FLAG_ALLMULTI_CAPABLE)\n+\t\t\treturn FM10K_XCAST_MODE_ALLMULTI;\n+\t\t/* fallthough */\n+\tcase FM10K_XCAST_MODE_MULTI:\n+\t\tif (vf_flags & FM10K_VF_FLAG_MULTI_CAPABLE)\n+\t\t\treturn FM10K_XCAST_MODE_MULTI;\n+\t\t/* fallthough */\n+\tcase FM10K_XCAST_MODE_NONE:\n+\t\tif (vf_flags & FM10K_VF_FLAG_NONE_CAPABLE)\n+\t\t\treturn FM10K_XCAST_MODE_NONE;\n+\t\t/* fallthough */\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\t/* disable interface as it should not be able to request any */\n+\treturn FM10K_XCAST_MODE_DISABLE;\n+}\n+\n+/**\n+ *  fm10k_iov_msg_lport_state_pf - Message handler for port state requests\n+ *  @hw: Pointer to hardware structure\n+ *  @results: Pointer array to message, results[0] is pointer to message\n+ *  @mbx: Pointer to mailbox information structure\n+ *\n+ *  This function is a default handler for port state requests.  The port\n+ *  state requests for now are basic and consist of enabling or disabling\n+ *  the port.\n+ **/\n+s32 fm10k_iov_msg_lport_state_pf(struct fm10k_hw *hw, u32 **results,\n+\t\t\t\t struct fm10k_mbx_info *mbx)\n+{\n+\tstruct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;\n+\tu32 *result;\n+\ts32 err = FM10K_SUCCESS;\n+\tu32 msg[2];\n+\tu8 mode = 0;\n+\n+\tDEBUGFUNC(\"fm10k_iov_msg_lport_state_pf\");\n+\n+\t/* verify VF is allowed to enable even minimal mode */\n+\tif (!(vf_info->vf_flags & FM10K_VF_FLAG_NONE_CAPABLE))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tif (!!results[FM10K_LPORT_STATE_MSG_XCAST_MODE]) {\n+\t\tresult = results[FM10K_LPORT_STATE_MSG_XCAST_MODE];\n+\n+\t\t/* XCAST mode update requested */\n+\t\terr = fm10k_tlv_attr_get_u8(result, &mode);\n+\t\tif (err)\n+\t\t\treturn FM10K_ERR_PARAM;\n+\n+\t\t/* prep for possible demotion depending on capabilities */\n+\t\tmode = fm10k_iov_supported_xcast_mode_pf(vf_info, mode);\n+\n+\t\t/* if mode is not currently enabled, enable it */\n+\t\tif (!(FM10K_VF_FLAG_ENABLED(vf_info) & (1 << mode)))\n+\t\t\tfm10k_update_xcast_mode_pf(hw, vf_info->glort, mode);\n+\n+\t\t/* swap mode back to a bit flag */\n+\t\tmode = FM10K_VF_FLAG_SET_MODE(mode);\n+\t} else if (!results[FM10K_LPORT_STATE_MSG_DISABLE]) {\n+\t\t/* need to disable the port if it is already enabled */\n+\t\tif (FM10K_VF_FLAG_ENABLED(vf_info))\n+\t\t\terr = fm10k_update_lport_state_pf(hw, vf_info->glort,\n+\t\t\t\t\t\t\t  1, false);\n+\n+\t\t/* when enabling the port we should reset the rate limiters */\n+\t\thw->iov.ops.configure_tc(hw, vf_info->vf_idx, vf_info->rate);\n+\n+\t\t/* set mode for minimal functionality */\n+\t\tmode = FM10K_VF_FLAG_SET_MODE_NONE;\n+\n+\t\t/* generate port state response to notify VF it is ready */\n+\t\tfm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);\n+\t\tfm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_READY);\n+\t\tmbx->ops.enqueue_tx(hw, mbx, msg);\n+\t}\n+\n+\t/* if enable state toggled note the update */\n+\tif (!err && (!FM10K_VF_FLAG_ENABLED(vf_info) != !mode))\n+\t\terr = fm10k_update_lport_state_pf(hw, vf_info->glort, 1,\n+\t\t\t\t\t\t  !!mode);\n+\n+\t/* if state change succeeded, then update our stored state */\n+\tmode |= FM10K_VF_FLAG_CAPABLE(vf_info);\n+\tif (!err)\n+\t\tvf_info->vf_flags = mode;\n+\n+\treturn err;\n+}\n+\n+const struct fm10k_msg_data fm10k_iov_msg_data_pf[] = {\n+\tFM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),\n+\tFM10K_VF_MSG_MSIX_HANDLER(fm10k_iov_msg_msix_pf),\n+\tFM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_iov_msg_mac_vlan_pf),\n+\tFM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_iov_msg_lport_state_pf),\n+\tFM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),\n+};\n+\n+/**\n+ *  fm10k_update_stats_hw_pf - Updates hardware related statistics of PF\n+ *  @hw: pointer to hardware structure\n+ *  @stats: pointer to the stats structure to update\n+ *\n+ *  This function collects and aggregates global and per queue hardware\n+ *  statistics.\n+ **/\n+STATIC void fm10k_update_hw_stats_pf(struct fm10k_hw *hw,\n+\t\t\t\t     struct fm10k_hw_stats *stats)\n+{\n+\tu32 timeout, ur, ca, um, xec, vlan_drop, loopback_drop, nodesc_drop;\n+\tu32 id, id_prev;\n+\n+\tDEBUGFUNC(\"fm10k_update_hw_stats_pf\");\n+\n+\t/* Use Tx queue 0 as a canary to detect a reset */\n+\tid = FM10K_READ_REG(hw, FM10K_TXQCTL(0));\n+\n+\t/* Read Global Statistics */\n+\tdo {\n+\t\ttimeout = fm10k_read_hw_stats_32b(hw, FM10K_STATS_TIMEOUT,\n+\t\t\t\t\t\t  &stats->timeout);\n+\t\tur = fm10k_read_hw_stats_32b(hw, FM10K_STATS_UR, &stats->ur);\n+\t\tca = fm10k_read_hw_stats_32b(hw, FM10K_STATS_CA, &stats->ca);\n+\t\tum = fm10k_read_hw_stats_32b(hw, FM10K_STATS_UM, &stats->um);\n+\t\txec = fm10k_read_hw_stats_32b(hw, FM10K_STATS_XEC, &stats->xec);\n+\t\tvlan_drop = fm10k_read_hw_stats_32b(hw, FM10K_STATS_VLAN_DROP,\n+\t\t\t\t\t\t    &stats->vlan_drop);\n+\t\tloopback_drop = fm10k_read_hw_stats_32b(hw,\n+\t\t\t\t\t\t\tFM10K_STATS_LOOPBACK_DROP,\n+\t\t\t\t\t\t\t&stats->loopback_drop);\n+\t\tnodesc_drop = fm10k_read_hw_stats_32b(hw,\n+\t\t\t\t\t\t      FM10K_STATS_NODESC_DROP,\n+\t\t\t\t\t\t      &stats->nodesc_drop);\n+\n+\t\t/* if value has not changed then we have consistent data */\n+\t\tid_prev = id;\n+\t\tid = FM10K_READ_REG(hw, FM10K_TXQCTL(0));\n+\t} while ((id ^ id_prev) & FM10K_TXQCTL_ID_MASK);\n+\n+\t/* drop non-ID bits and set VALID ID bit */\n+\tid &= FM10K_TXQCTL_ID_MASK;\n+\tid |= FM10K_STAT_VALID;\n+\n+\t/* Update Global Statistics */\n+\tif (stats->stats_idx == id) {\n+\t\tstats->timeout.count += timeout;\n+\t\tstats->ur.count += ur;\n+\t\tstats->ca.count += ca;\n+\t\tstats->um.count += um;\n+\t\tstats->xec.count += xec;\n+\t\tstats->vlan_drop.count += vlan_drop;\n+\t\tstats->loopback_drop.count += loopback_drop;\n+\t\tstats->nodesc_drop.count += nodesc_drop;\n+\t}\n+\n+\t/* Update bases and record current PF id */\n+\tfm10k_update_hw_base_32b(&stats->timeout, timeout);\n+\tfm10k_update_hw_base_32b(&stats->ur, ur);\n+\tfm10k_update_hw_base_32b(&stats->ca, ca);\n+\tfm10k_update_hw_base_32b(&stats->um, um);\n+\tfm10k_update_hw_base_32b(&stats->xec, xec);\n+\tfm10k_update_hw_base_32b(&stats->vlan_drop, vlan_drop);\n+\tfm10k_update_hw_base_32b(&stats->loopback_drop, loopback_drop);\n+\tfm10k_update_hw_base_32b(&stats->nodesc_drop, nodesc_drop);\n+\tstats->stats_idx = id;\n+\n+\t/* Update Queue Statistics */\n+\tfm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);\n+}\n+\n+/**\n+ *  fm10k_rebind_hw_stats_pf - Resets base for hardware statistics of PF\n+ *  @hw: pointer to hardware structure\n+ *  @stats: pointer to the stats structure to update\n+ *\n+ *  This function resets the base for global and per queue hardware\n+ *  statistics.\n+ **/\n+STATIC void fm10k_rebind_hw_stats_pf(struct fm10k_hw *hw,\n+\t\t\t\t     struct fm10k_hw_stats *stats)\n+{\n+\tDEBUGFUNC(\"fm10k_rebind_hw_stats_pf\");\n+\n+\t/* Unbind Global Statistics */\n+\tfm10k_unbind_hw_stats_32b(&stats->timeout);\n+\tfm10k_unbind_hw_stats_32b(&stats->ur);\n+\tfm10k_unbind_hw_stats_32b(&stats->ca);\n+\tfm10k_unbind_hw_stats_32b(&stats->um);\n+\tfm10k_unbind_hw_stats_32b(&stats->xec);\n+\tfm10k_unbind_hw_stats_32b(&stats->vlan_drop);\n+\tfm10k_unbind_hw_stats_32b(&stats->loopback_drop);\n+\tfm10k_unbind_hw_stats_32b(&stats->nodesc_drop);\n+\n+\t/* Unbind Queue Statistics */\n+\tfm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);\n+\n+\t/* Reinitialize bases for all stats */\n+\tfm10k_update_hw_stats_pf(hw, stats);\n+}\n+\n+/**\n+ *  fm10k_set_dma_mask_pf - Configures PhyAddrSpace to limit DMA to system\n+ *  @hw: pointer to hardware structure\n+ *  @dma_mask: 64 bit DMA mask required for platform\n+ *\n+ *  This function sets the PHYADDR.PhyAddrSpace bits for the endpoint in order\n+ *  to limit the access to memory beyond what is physically in the system.\n+ **/\n+STATIC void fm10k_set_dma_mask_pf(struct fm10k_hw *hw, u64 dma_mask)\n+{\n+\t/* we need to write the upper 32 bits of DMA mask to PhyAddrSpace */\n+\tu32 phyaddr = (u32)(dma_mask >> 32);\n+\n+\tDEBUGFUNC(\"fm10k_set_dma_mask_pf\");\n+\n+\tFM10K_WRITE_REG(hw, FM10K_PHYADDR, phyaddr);\n+}\n+\n+/**\n+ *  fm10k_get_fault_pf - Record a fault in one of the interface units\n+ *  @hw: pointer to hardware structure\n+ *  @type: pointer to fault type register offset\n+ *  @fault: pointer to memory location to record the fault\n+ *\n+ *  Record the fault register contents to the fault data structure and\n+ *  clear the entry from the register.\n+ *\n+ *  Returns ERR_PARAM if invalid register is specified or no error is present.\n+ **/\n+STATIC s32 fm10k_get_fault_pf(struct fm10k_hw *hw, int type,\n+\t\t\t      struct fm10k_fault *fault)\n+{\n+\tu32 func;\n+\n+\tDEBUGFUNC(\"fm10k_get_fault_pf\");\n+\n+\t/* verify the fault register is in range and is aligned */\n+\tswitch (type) {\n+\tcase FM10K_PCA_FAULT:\n+\tcase FM10K_THI_FAULT:\n+\tcase FM10K_FUM_FAULT:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn FM10K_ERR_PARAM;\n+\t}\n+\n+\t/* only service faults that are valid */\n+\tfunc = FM10K_READ_REG(hw, type + FM10K_FAULT_FUNC);\n+\tif (!(func & FM10K_FAULT_FUNC_VALID))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* read remaining fields */\n+\tfault->address = FM10K_READ_REG(hw, type + FM10K_FAULT_ADDR_HI);\n+\tfault->address <<= 32;\n+\tfault->address = FM10K_READ_REG(hw, type + FM10K_FAULT_ADDR_LO);\n+\tfault->specinfo = FM10K_READ_REG(hw, type + FM10K_FAULT_SPECINFO);\n+\n+\t/* clear valid bit to allow for next error */\n+\tFM10K_WRITE_REG(hw, type + FM10K_FAULT_FUNC, FM10K_FAULT_FUNC_VALID);\n+\n+\t/* Record which function triggered the error */\n+\tif (func & FM10K_FAULT_FUNC_PF)\n+\t\tfault->func = 0;\n+\telse\n+\t\tfault->func = 1 + ((func & FM10K_FAULT_FUNC_VF_MASK) >>\n+\t\t\t\t   FM10K_FAULT_FUNC_VF_SHIFT);\n+\n+\t/* record fault type */\n+\tfault->type = func & FM10K_FAULT_FUNC_TYPE_MASK;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_request_lport_map_pf - Request LPORT map from the switch API\n+ *  @hw: pointer to hardware structure\n+ *\n+ **/\n+STATIC s32 fm10k_request_lport_map_pf(struct fm10k_hw *hw)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tu32 msg[1];\n+\n+\tDEBUGFUNC(\"fm10k_request_lport_pf\");\n+\n+\t/* issue request asking for LPORT map */\n+\tfm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_LPORT_MAP);\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+/**\n+ *  fm10k_get_host_state_pf - Returns the state of the switch and mailbox\n+ *  @hw: pointer to hardware structure\n+ *  @switch_ready: pointer to boolean value that will record switch state\n+ *\n+ *  This funciton will check the DMA_CTRL2 register and mailbox in order\n+ *  to determine if the switch is ready for the PF to begin requesting\n+ *  addresses and mapping traffic to the local interface.\n+ **/\n+STATIC s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready)\n+{\n+\ts32 ret_val = FM10K_SUCCESS;\n+\tu32 dma_ctrl2;\n+\n+\tDEBUGFUNC(\"fm10k_get_host_state_pf\");\n+\n+\t/* verify the switch is ready for interaction */\n+\tdma_ctrl2 = FM10K_READ_REG(hw, FM10K_DMA_CTRL2);\n+\tif (!(dma_ctrl2 & FM10K_DMA_CTRL2_SWITCH_READY))\n+\t\tgoto out;\n+\n+\t/* retrieve generic host state info */\n+\tret_val = fm10k_get_host_state_generic(hw, switch_ready);\n+\tif (ret_val)\n+\t\tgoto out;\n+\n+\t/* interface cannot receive traffic without logical ports */\n+\tif (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE)\n+\t\tret_val = fm10k_request_lport_map_pf(hw);\n+\n+out:\n+\treturn ret_val;\n+}\n+\n+/* This structure defines the attibutes to be parsed below */\n+const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[] = {\n+\tFM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_LPORT_MAP),\n+\tFM10K_TLV_ATTR_LAST\n+};\n+\n+/**\n+ *  fm10k_msg_lport_map_pf - Message handler for lport_map message from SM\n+ *  @hw: Pointer to hardware structure\n+ *  @results: pointer array containing parsed data\n+ *  @mbx: Pointer to mailbox information structure\n+ *\n+ *  This handler configures the lport mapping based on the reply from the\n+ *  switch API.\n+ **/\n+s32 fm10k_msg_lport_map_pf(struct fm10k_hw *hw, u32 **results,\n+\t\t\t   struct fm10k_mbx_info *mbx)\n+{\n+\tu16 glort, mask;\n+\tu32 dglort_map;\n+\ts32 err;\n+\n+\tUNREFERENCED_1PARAMETER(mbx);\n+\tDEBUGFUNC(\"fm10k_msg_lport_map_pf\");\n+\n+\terr = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_LPORT_MAP],\n+\t\t\t\t     &dglort_map);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* extract values out of the header */\n+\tglort = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_GLORT);\n+\tmask = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_MASK);\n+\n+\t/* verify mask is set and none of the masked bits in glort are set */\n+\tif (!mask || (glort & ~mask))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* verify the mask is contiguous, and that it is 1's followed by 0's */\n+\tif (((~(mask - 1) & mask) + mask) & FM10K_DGLORTMAP_NONE)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* record the glort, mask, and port count */\n+\thw->mac.dglort_map = dglort_map;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+const struct fm10k_tlv_attr fm10k_update_pvid_msg_attr[] = {\n+\tFM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_UPDATE_PVID),\n+\tFM10K_TLV_ATTR_LAST\n+};\n+\n+/**\n+ *  fm10k_msg_update_pvid_pf - Message handler for port VLAN message from SM\n+ *  @hw: Pointer to hardware structure\n+ *  @results: pointer array containing parsed data\n+ *  @mbx: Pointer to mailbox information structure\n+ *\n+ *  This handler configures the default VLAN for the PF\n+ **/\n+s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *hw, u32 **results,\n+\t\t\t     struct fm10k_mbx_info *mbx)\n+{\n+\tu16 glort, pvid;\n+\tu32 pvid_update;\n+\ts32 err;\n+\n+\tUNREFERENCED_1PARAMETER(mbx);\n+\tDEBUGFUNC(\"fm10k_msg_update_pvid_pf\");\n+\n+\terr = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_UPDATE_PVID],\n+\t\t\t\t     &pvid_update);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* extract values from the pvid update */\n+\tglort = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_GLORT);\n+\tpvid = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_PVID);\n+\n+\t/* if glort is not valid return error */\n+\tif (!fm10k_glort_valid_pf(hw, glort))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* verify VID is valid */\n+\tif (pvid >= FM10K_VLAN_TABLE_VID_MAX)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* record the port VLAN ID value */\n+\thw->mac.default_vid = pvid;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_record_global_table_data - Move global table data to swapi table info\n+ *  @from: pointer to source table data structure\n+ *  @to: pointer to destination table info structure\n+ *\n+ *  This function is will copy table_data to the table_info contained in\n+ *  the hw struct.\n+ **/\n+static void fm10k_record_global_table_data(struct fm10k_global_table_data *from,\n+\t\t\t\t\t   struct fm10k_swapi_table_info *to)\n+{\n+\t/* convert from le32 struct to CPU byte ordered values */\n+\tto->used = FM10K_LE32_TO_CPU(from->used);\n+\tto->avail = FM10K_LE32_TO_CPU(from->avail);\n+}\n+\n+const struct fm10k_tlv_attr fm10k_err_msg_attr[] = {\n+\tFM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_ERR,\n+\t\t\t\t sizeof(struct fm10k_swapi_error)),\n+\tFM10K_TLV_ATTR_LAST\n+};\n+\n+/**\n+ *  fm10k_msg_err_pf - Message handler for error reply\n+ *  @hw: Pointer to hardware structure\n+ *  @results: pointer array containing parsed data\n+ *  @mbx: Pointer to mailbox information structure\n+ *\n+ *  This handler will capture the data for any error replies to previous\n+ *  messages that the PF has sent.\n+ **/\n+s32 fm10k_msg_err_pf(struct fm10k_hw *hw, u32 **results,\n+\t\t     struct fm10k_mbx_info *mbx)\n+{\n+\tstruct fm10k_swapi_error err_msg;\n+\ts32 err;\n+\n+\tUNREFERENCED_1PARAMETER(mbx);\n+\tDEBUGFUNC(\"fm10k_msg_err_pf\");\n+\n+\t/* extract structure from message */\n+\terr = fm10k_tlv_attr_get_le_struct(results[FM10K_PF_ATTR_ID_ERR],\n+\t\t\t\t\t   &err_msg, sizeof(err_msg));\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* record table status */\n+\tfm10k_record_global_table_data(&err_msg.mac, &hw->swapi.mac);\n+\tfm10k_record_global_table_data(&err_msg.nexthop, &hw->swapi.nexthop);\n+\tfm10k_record_global_table_data(&err_msg.ffu, &hw->swapi.ffu);\n+\n+\t/* record SW API status value */\n+\thw->swapi.status = FM10K_LE32_TO_CPU(err_msg.status);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+const struct fm10k_tlv_attr fm10k_1588_timestamp_msg_attr[] = {\n+\tFM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_1588_TIMESTAMP,\n+\t\t\t\t sizeof(struct fm10k_swapi_1588_timestamp)),\n+\tFM10K_TLV_ATTR_LAST\n+};\n+\n+/* currently there is no shared 1588 timestamp handler */\n+\n+/**\n+ *  fm10k_request_tx_timestamp_mode_pf - Request a specific Tx timestamping mode\n+ *  @hw: pointer to hardware structure\n+ *  @glort: base resource tag for this request\n+ *  @mode: integer value indicating the requested mode\n+ *\n+ *  This function will attempt to request a specific timestamp mode for the\n+ *  port so that it can receive Tx timestamp messages.\n+ **/\n+STATIC s32 fm10k_request_tx_timestamp_mode_pf(struct fm10k_hw *hw,\n+\t\t\t\t\t      u16 glort,\n+\t\t\t\t\t      u8 mode)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tu32 msg[3], timestamp_mode;\n+\n+\tDEBUGFUNC(\"fm10k_request_timestamp_mode_pf\");\n+\n+\tif (mode > FM10K_TIMESTAMP_MODE_PEP_TO_ANY)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* if glort is not valid return error */\n+\tif (!fm10k_glort_valid_pf(hw, glort))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* write timestamp mode as a single u32 value,\n+\t * lower 16 bits: glort\n+\t * upper 16 bits: mode\n+\t */\n+\ttimestamp_mode = ((u32)mode << 16) | glort;\n+\n+\t/* generate message requesting change to xcast mode */\n+\tfm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_TX_TIMESTAMP_MODE);\n+\tfm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_TIMESTAMP_MODE_REQ, timestamp_mode);\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+/**\n+ *  fm10k_adjust_systime_pf - Adjust systime frequency\n+ *  @hw: pointer to hardware structure\n+ *  @ppb: adjustment rate in parts per billion\n+ *\n+ *  This function will adjust the SYSTIME_CFG register contained in BAR 4\n+ *  if this function is supported for BAR 4 access.  The adjustment amount\n+ *  is based on the parts per billion value provided and adjusted to a\n+ *  value based on parts per 2^48 clock cycles.\n+ *\n+ *  If adjustment is not supported or the requested value is too large\n+ *  we will return an error.\n+ **/\n+STATIC s32 fm10k_adjust_systime_pf(struct fm10k_hw *hw, s32 ppb)\n+{\n+\tu64 systime_adjust;\n+\n+\tDEBUGFUNC(\"fm10k_adjust_systime_vf\");\n+\n+\t/* if sw_addr is not set we don't have switch register access */\n+\tif (!hw->sw_addr)\n+\t\treturn ppb ? FM10K_ERR_PARAM : FM10K_SUCCESS;\n+\n+\t/* we must convert the value from parts per billion to parts per\n+\t * 2^48 cycles.  In addition I have opted to only use the 30 most\n+\t * significant bits of the adjustment value as the 8 least\n+\t * significant bits are located in another register and represent\n+\t * a value significantly less than a part per billion, the result\n+\t * of dropping the 8 least significant bits is that the adjustment\n+\t * value is effectively multiplied by 2^8 when we write it.\n+\t *\n+\t * As a result of all this the math for this breaks down as follows:\n+\t *\tppb / 10^9 == adjust * 2^8 / 2^48\n+\t * If we solve this for adjust, and simplify it comes out as:\n+\t *\tppb * 2^31 / 5^9 == adjust\n+\t */\n+\tsystime_adjust = (ppb < 0) ? -ppb : ppb;\n+\tsystime_adjust <<= 31;\n+\tdo_div(systime_adjust, 1953125);\n+\n+\t/* verify the requested adjustment value is in range */\n+\tif (systime_adjust > FM10K_SW_SYSTIME_ADJUST_MASK)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tif (ppb < 0)\n+\t\tsystime_adjust |= FM10K_SW_SYSTIME_ADJUST_DIR_NEGATIVE;\n+\n+\tFM10K_WRITE_SW_REG(hw, FM10K_SW_SYSTIME_ADJUST, (u32)systime_adjust);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_read_systime_pf - Reads value of systime registers\n+ *  @hw: pointer to the hardware structure\n+ *\n+ *  Function reads the content of 2 registers, combined to represent a 64 bit\n+ *  value measured in nanosecods.  In order to guarantee the value is accurate\n+ *  we check the 32 most significant bits both before and after reading the\n+ *  32 least significant bits to verify they didn't change as we were reading\n+ *  the registers.\n+ **/\n+static u64 fm10k_read_systime_pf(struct fm10k_hw *hw)\n+{\n+\tu32 systime_l, systime_h, systime_tmp;\n+\n+\tsystime_h = fm10k_read_reg(hw, FM10K_SYSTIME + 1);\n+\n+\tdo {\n+\t\tsystime_tmp = systime_h;\n+\t\tsystime_l = fm10k_read_reg(hw, FM10K_SYSTIME);\n+\t\tsystime_h = fm10k_read_reg(hw, FM10K_SYSTIME + 1);\n+\t} while (systime_tmp != systime_h);\n+\n+\treturn ((u64)systime_h << 32) | systime_l;\n+}\n+\n+static const struct fm10k_msg_data fm10k_msg_data_pf[] = {\n+\tFM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf),\n+\tFM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf),\n+\tFM10K_PF_MSG_LPORT_MAP_HANDLER(fm10k_msg_lport_map_pf),\n+\tFM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf),\n+\tFM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf),\n+\tFM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_msg_update_pvid_pf),\n+\tFM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),\n+};\n+\n+/**\n+ *  fm10k_init_ops_pf - Inits func ptrs and MAC type\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Initialize the function pointers and assign the MAC type for PF.\n+ *  Does not touch the hardware.\n+ **/\n+s32 fm10k_init_ops_pf(struct fm10k_hw *hw)\n+{\n+\tstruct fm10k_mac_info *mac = &hw->mac;\n+\tstruct fm10k_iov_info *iov = &hw->iov;\n+\n+\tDEBUGFUNC(\"fm10k_init_ops_pf\");\n+\n+\tfm10k_init_ops_generic(hw);\n+\n+\tmac->ops.reset_hw = &fm10k_reset_hw_pf;\n+\tmac->ops.init_hw = &fm10k_init_hw_pf;\n+\tmac->ops.start_hw = &fm10k_start_hw_generic;\n+\tmac->ops.stop_hw = &fm10k_stop_hw_generic;\n+\tmac->ops.is_slot_appropriate = &fm10k_is_slot_appropriate_pf;\n+\tmac->ops.update_vlan = &fm10k_update_vlan_pf;\n+\tmac->ops.read_mac_addr = &fm10k_read_mac_addr_pf;\n+\tmac->ops.update_uc_addr = &fm10k_update_uc_addr_pf;\n+\tmac->ops.update_mc_addr = &fm10k_update_mc_addr_pf;\n+\tmac->ops.update_xcast_mode = &fm10k_update_xcast_mode_pf;\n+\tmac->ops.update_int_moderator = &fm10k_update_int_moderator_pf;\n+\tmac->ops.update_lport_state = &fm10k_update_lport_state_pf;\n+\tmac->ops.update_hw_stats = &fm10k_update_hw_stats_pf;\n+\tmac->ops.rebind_hw_stats = &fm10k_rebind_hw_stats_pf;\n+\tmac->ops.configure_dglort_map = &fm10k_configure_dglort_map_pf;\n+\tmac->ops.set_dma_mask = &fm10k_set_dma_mask_pf;\n+\tmac->ops.get_fault = &fm10k_get_fault_pf;\n+\tmac->ops.get_host_state = &fm10k_get_host_state_pf;\n+\tmac->ops.adjust_systime = &fm10k_adjust_systime_pf;\n+\tmac->ops.read_systime = &fm10k_read_systime_pf;\n+\tmac->ops.request_tx_timestamp_mode = &fm10k_request_tx_timestamp_mode_pf;\n+\n+\tmac->max_msix_vectors = fm10k_get_pcie_msix_count_generic(hw);\n+\n+\tiov->ops.assign_resources = &fm10k_iov_assign_resources_pf;\n+\tiov->ops.configure_tc = &fm10k_iov_configure_tc_pf;\n+\tiov->ops.assign_int_moderator = &fm10k_iov_assign_int_moderator_pf;\n+\tiov->ops.assign_default_mac_vlan = fm10k_iov_assign_default_mac_vlan_pf;\n+\tiov->ops.reset_resources = &fm10k_iov_reset_resources_pf;\n+\tiov->ops.set_lport = &fm10k_iov_set_lport_pf;\n+\tiov->ops.reset_lport = &fm10k_iov_reset_lport_pf;\n+\tiov->ops.update_stats = &fm10k_iov_update_stats_pf;\n+\tiov->ops.report_timestamp = &fm10k_iov_report_timestamp_pf;\n+\n+\treturn fm10k_sm_mbx_init(hw, &hw->mbx, fm10k_msg_data_pf);\n+}\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_pf.h b/lib/librte_pmd_fm10k/base/fm10k_pf.h\nnew file mode 100644\nindex 0000000..f6c290a\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_pf.h\n@@ -0,0 +1,155 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#ifndef _FM10K_PF_H_\n+#define _FM10K_PF_H_\n+\n+#include \"fm10k_type.h\"\n+#include \"fm10k_common.h\"\n+\n+bool fm10k_glort_valid_pf(struct fm10k_hw *hw, u16 glort);\n+u16 fm10k_queues_per_pool(struct fm10k_hw *hw);\n+u16 fm10k_vf_queue_index(struct fm10k_hw *hw, u16 vf_idx);\n+\n+enum fm10k_pf_tlv_msg_id_v1 {\n+\tFM10K_PF_MSG_ID_TEST\t\t\t= 0x000, /* msg ID reserved */\n+\tFM10K_PF_MSG_ID_XCAST_MODES\t\t= 0x001,\n+\tFM10K_PF_MSG_ID_UPDATE_MAC_FWD_RULE\t= 0x002,\n+\tFM10K_PF_MSG_ID_LPORT_MAP\t\t= 0x100,\n+\tFM10K_PF_MSG_ID_LPORT_CREATE\t\t= 0x200,\n+\tFM10K_PF_MSG_ID_LPORT_DELETE\t\t= 0x201,\n+\tFM10K_PF_MSG_ID_CONFIG\t\t\t= 0x300,\n+\tFM10K_PF_MSG_ID_UPDATE_PVID\t\t= 0x400,\n+\tFM10K_PF_MSG_ID_CREATE_FLOW_TABLE\t= 0x501,\n+\tFM10K_PF_MSG_ID_DELETE_FLOW_TABLE\t= 0x502,\n+\tFM10K_PF_MSG_ID_UPDATE_FLOW\t\t= 0x503,\n+\tFM10K_PF_MSG_ID_DELETE_FLOW\t\t= 0x504,\n+\tFM10K_PF_MSG_ID_SET_FLOW_STATE\t\t= 0x505,\n+\tFM10K_PF_MSG_ID_GET_1588_INFO\t\t= 0x506,\n+\tFM10K_PF_MSG_ID_1588_TIMESTAMP\t\t= 0x701,\n+\tFM10K_PF_MSG_ID_TX_TIMESTAMP_MODE\t= 0x702,\n+};\n+\n+enum fm10k_pf_tlv_attr_id_v1 {\n+\tFM10K_PF_ATTR_ID_ERR\t\t\t= 0x00,\n+\tFM10K_PF_ATTR_ID_LPORT_MAP\t\t= 0x01,\n+\tFM10K_PF_ATTR_ID_XCAST_MODE\t\t= 0x02,\n+\tFM10K_PF_ATTR_ID_MAC_UPDATE\t\t= 0x03,\n+\tFM10K_PF_ATTR_ID_VLAN_UPDATE\t\t= 0x04,\n+\tFM10K_PF_ATTR_ID_CONFIG\t\t\t= 0x05,\n+\tFM10K_PF_ATTR_ID_CREATE_FLOW_TABLE\t= 0x06,\n+\tFM10K_PF_ATTR_ID_DELETE_FLOW_TABLE\t= 0x07,\n+\tFM10K_PF_ATTR_ID_UPDATE_FLOW\t\t= 0x08,\n+\tFM10K_PF_ATTR_ID_FLOW_STATE\t\t= 0x09,\n+\tFM10K_PF_ATTR_ID_FLOW_HANDLE\t\t= 0x0A,\n+\tFM10K_PF_ATTR_ID_DELETE_FLOW\t\t= 0x0B,\n+\tFM10K_PF_ATTR_ID_PORT\t\t\t= 0x0C,\n+\tFM10K_PF_ATTR_ID_UPDATE_PVID\t\t= 0x0D,\n+\tFM10K_PF_ATTR_ID_1588_TIMESTAMP\t\t= 0x10,\n+\tFM10K_PF_ATTR_ID_TIMESTAMP_MODE_REQ\t= 0x11,\n+\tFM10K_PF_ATTR_ID_TIMESTAMP_MODE_RESP\t= 0x12,\n+};\n+\n+#define FM10K_MSG_LPORT_MAP_GLORT_SHIFT\t0\n+#define FM10K_MSG_LPORT_MAP_GLORT_SIZE\t16\n+#define FM10K_MSG_LPORT_MAP_MASK_SHIFT\t16\n+#define FM10K_MSG_LPORT_MAP_MASK_SIZE\t16\n+\n+#define FM10K_MSG_UPDATE_PVID_GLORT_SHIFT\t0\n+#define FM10K_MSG_UPDATE_PVID_GLORT_SIZE\t16\n+#define FM10K_MSG_UPDATE_PVID_PVID_SHIFT\t16\n+#define FM10K_MSG_UPDATE_PVID_PVID_SIZE\t\t16\n+\n+struct fm10k_mac_update {\n+\t__le32\tmac_lower;\n+\t__le16\tmac_upper;\n+\t__le16\tvlan;\n+\t__le16\tglort;\n+\tu8\tflags;\n+\tu8\taction;\n+};\n+\n+struct fm10k_global_table_data {\n+\t__le32\tused;\n+\t__le32\tavail;\n+};\n+\n+struct fm10k_swapi_error {\n+\t__le32\t\t\t\tstatus;\n+\tstruct fm10k_global_table_data\tmac;\n+\tstruct fm10k_global_table_data\tnexthop;\n+\tstruct fm10k_global_table_data\tffu;\n+};\n+\n+struct fm10k_swapi_1588_timestamp {\n+\t__le64 egress;\n+\t__le64 ingress;\n+\t__le16 dglort;\n+\t__le16 sglort;\n+};\n+\n+#define FM10K_PF_MSG_LPORT_CREATE_HANDLER(func) \\\n+\tFM10K_MSG_HANDLER(FM10K_PF_MSG_ID_LPORT_CREATE, NULL, func)\n+#define FM10K_PF_MSG_LPORT_DELETE_HANDLER(func) \\\n+\tFM10K_MSG_HANDLER(FM10K_PF_MSG_ID_LPORT_DELETE, NULL, func)\n+s32 fm10k_msg_lport_map_pf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);\n+extern const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[];\n+#define FM10K_PF_MSG_LPORT_MAP_HANDLER(func) \\\n+\tFM10K_MSG_HANDLER(FM10K_PF_MSG_ID_LPORT_MAP, \\\n+\t\t\t  fm10k_lport_map_msg_attr, func)\n+s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *, u32 **,\n+\t\t\t     struct fm10k_mbx_info *);\n+extern const struct fm10k_tlv_attr fm10k_update_pvid_msg_attr[];\n+#define FM10K_PF_MSG_UPDATE_PVID_HANDLER(func) \\\n+\tFM10K_MSG_HANDLER(FM10K_PF_MSG_ID_UPDATE_PVID, \\\n+\t\t\t  fm10k_update_pvid_msg_attr, func)\n+\n+s32 fm10k_msg_err_pf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);\n+extern const struct fm10k_tlv_attr fm10k_err_msg_attr[];\n+#define FM10K_PF_MSG_ERR_HANDLER(msg, func) \\\n+\tFM10K_MSG_HANDLER(FM10K_PF_MSG_ID_##msg, fm10k_err_msg_attr, func)\n+\n+extern const struct fm10k_tlv_attr fm10k_1588_timestamp_msg_attr[];\n+#define FM10K_PF_MSG_1588_TIMESTAMP_HANDLER(func) \\\n+\tFM10K_MSG_HANDLER(FM10K_PF_MSG_ID_1588_TIMESTAMP, \\\n+\t\t\t  fm10k_1588_timestamp_msg_attr, func)\n+\n+s32 fm10k_iov_msg_msix_pf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);\n+s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *, u32 **,\n+\t\t\t      struct fm10k_mbx_info *);\n+s32 fm10k_iov_msg_lport_state_pf(struct fm10k_hw *, u32 **,\n+\t\t\t\t struct fm10k_mbx_info *);\n+extern const struct fm10k_msg_data fm10k_iov_msg_data_pf[];\n+\n+s32 fm10k_init_ops_pf(struct fm10k_hw *hw);\n+#endif /* _FM10K_PF_H */\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_tlv.c b/lib/librte_pmd_fm10k/base/fm10k_tlv.c\nnew file mode 100644\nindex 0000000..1d9d7d8\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_tlv.c\n@@ -0,0 +1,914 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#include \"fm10k_tlv.h\"\n+\n+/**\n+ *  fm10k_tlv_msg_init - Initialize message block for TLV data storage\n+ *  @msg: Pointer to message block\n+ *  @msg_id: Message ID indicating message type\n+ *\n+ *  This function return success if provided with a valid message pointer\n+ **/\n+s32 fm10k_tlv_msg_init(u32 *msg, u16 msg_id)\n+{\n+\tDEBUGFUNC(\"fm10k_tlv_msg_init\");\n+\n+\t/* verify pointer is not NULL */\n+\tif (!msg)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t*msg = (FM10K_TLV_FLAGS_MSG << FM10K_TLV_FLAGS_SHIFT) | msg_id;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_put_null_string - Place null terminated string on message\n+ *  @msg: Pointer to message block\n+ *  @attr_id: Attribute ID\n+ *  @string: Pointer to string to be stored in attribute\n+ *\n+ *  This function will reorder a string to be CPU endian and store it in\n+ *  the attribute buffer.  It will return success if provided with a valid\n+ *  pointers.\n+ **/\n+s32 fm10k_tlv_attr_put_null_string(u32 *msg, u16 attr_id,\n+\t\t\t\t   const unsigned char *string)\n+{\n+\tu32 attr_data = 0, len = 0;\n+\tu32 *attr;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_attr_put_null_string\");\n+\n+\t/* verify pointers are not NULL */\n+\tif (!string || !msg)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tattr = &msg[FM10K_TLV_DWORD_LEN(*msg)];\n+\n+\t/* copy string into local variable and then write to msg */\n+\tdo {\n+\t\t/* write data to message */\n+\t\tif (len && !(len % 4)) {\n+\t\t\tattr[len / 4] = attr_data;\n+\t\t\tattr_data = 0;\n+\t\t}\n+\n+\t\t/* record character to offset location */\n+\t\tattr_data |= (u32)(*string) << (8 * (len % 4));\n+\t\tlen++;\n+\n+\t\t/* test for NULL and then increment */\n+\t} while (*(string++));\n+\n+\t/* write last piece of data to message */\n+\tattr[(len + 3) / 4] = attr_data;\n+\n+\t/* record attribute header, update message length */\n+\tlen <<= FM10K_TLV_LEN_SHIFT;\n+\tattr[0] = len | attr_id;\n+\n+\t/* add header length to length */\n+\tlen += FM10K_TLV_HDR_LEN << FM10K_TLV_LEN_SHIFT;\n+\t*msg += FM10K_TLV_LEN_ALIGN(len);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_get_null_string - Get null terminated string from attribute\n+ *  @attr: Pointer to attribute\n+ *  @string: Pointer to location of destination string\n+ *\n+ *  This function pulls the string back out of the attribute and will place\n+ *  it in the array pointed by by string.  It will return success if provided\n+ *  with a valid pointers.\n+ **/\n+s32 fm10k_tlv_attr_get_null_string(u32 *attr, unsigned char *string)\n+{\n+\tu32 len;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_attr_get_null_string\");\n+\n+\t/* verify pointers are not NULL */\n+\tif (!string || !attr)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tlen = *attr >> FM10K_TLV_LEN_SHIFT;\n+\tattr++;\n+\n+\twhile (len--)\n+\t\tstring[len] = (u8)(attr[len / 4] >> (8 * (len % 4)));\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_put_mac_vlan - Store MAC/VLAN attribute in message\n+ *  @msg: Pointer to message block\n+ *  @attr_id: Attribute ID\n+ *  @mac_addr: MAC address to be stored\n+ *\n+ *  This function will reorder a MAC address to be CPU endian and store it\n+ *  in the attribute buffer.  It will return success if provided with a\n+ *  valid pointers.\n+ **/\n+s32 fm10k_tlv_attr_put_mac_vlan(u32 *msg, u16 attr_id,\n+\t\t\t\tconst u8 *mac_addr, u16 vlan)\n+{\n+\tu32 len = ETH_ALEN << FM10K_TLV_LEN_SHIFT;\n+\tu32 *attr;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_attr_put_mac_vlan\");\n+\n+\t/* verify pointers are not NULL */\n+\tif (!msg || !mac_addr)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tattr = &msg[FM10K_TLV_DWORD_LEN(*msg)];\n+\n+\t/* record attribute header, update message length */\n+\tattr[0] = len | attr_id;\n+\n+\t/* copy value into local variable and then write to msg */\n+\tattr[1] = FM10K_LE32_TO_CPU(*(const __le32 *)&mac_addr[0]);\n+\tattr[2] = FM10K_LE16_TO_CPU(*(const __le16 *)&mac_addr[4]);\n+\tattr[2] |= (u32)vlan << 16;\n+\n+\t/* add header length to length */\n+\tlen += FM10K_TLV_HDR_LEN << FM10K_TLV_LEN_SHIFT;\n+\t*msg += FM10K_TLV_LEN_ALIGN(len);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_get_mac_vlan - Get MAC/VLAN stored in attribute\n+ *  @attr: Pointer to attribute\n+ *  @attr_id: Attribute ID\n+ *  @mac_addr: location of buffer to store MAC address\n+ *\n+ *  This function pulls the MAC address back out of the attribute and will\n+ *  place it in the array pointed by by mac_addr.  It will return success\n+ *  if provided with a valid pointers.\n+ **/\n+s32 fm10k_tlv_attr_get_mac_vlan(u32 *attr, u8 *mac_addr, u16 *vlan)\n+{\n+\tDEBUGFUNC(\"fm10k_tlv_attr_get_mac_vlan\");\n+\n+\t/* verify pointers are not NULL */\n+\tif (!mac_addr || !attr)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t*(__le32 *)&mac_addr[0] = FM10K_CPU_TO_LE32(attr[1]);\n+\t*(__le16 *)&mac_addr[4] = FM10K_CPU_TO_LE16((u16)(attr[2]));\n+\t*vlan = (u16)(attr[2] >> 16);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_put_bool - Add header indicating value \"true\"\n+ *  @msg: Pointer to message block\n+ *  @attr_id: Attribute ID\n+ *\n+ *  This function will simply add an attribute header, the fact\n+ *  that the header is here means the attribute value is true, else\n+ *  it is false.  The function will return success if provided with a\n+ *  valid pointers.\n+ **/\n+s32 fm10k_tlv_attr_put_bool(u32 *msg, u16 attr_id)\n+{\n+\tDEBUGFUNC(\"fm10k_tlv_attr_put_bool\");\n+\n+\t/* verify pointers are not NULL */\n+\tif (!msg)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* record attribute header */\n+\tmsg[FM10K_TLV_DWORD_LEN(*msg)] = attr_id;\n+\n+\t/* add header length to length */\n+\t*msg += FM10K_TLV_HDR_LEN << FM10K_TLV_LEN_SHIFT;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_put_value - Store integer value attribute in message\n+ *  @msg: Pointer to message block\n+ *  @attr_id: Attribute ID\n+ *  @value: Value to be written\n+ *  @len: Size of value\n+ *\n+ *  This function will place an integer value of up to 8 bytes in size\n+ *  in a message attribute.  The function will return success provided\n+ *  that msg is a valid pointer, and len is 1, 2, 4, or 8.\n+ **/\n+s32 fm10k_tlv_attr_put_value(u32 *msg, u16 attr_id, s64 value, u32 len)\n+{\n+\tu32 *attr;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_attr_put_value\");\n+\n+\t/* verify non-null msg and len is 1, 2, 4, or 8 */\n+\tif (!msg || !len || len > 8 || (len & (len - 1)))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tattr = &msg[FM10K_TLV_DWORD_LEN(*msg)];\n+\n+\tif (len < 4) {\n+\t\tattr[1] = (u32)value & ((0x1ul << (8 * len)) - 1);\n+\t} else {\n+\t\tattr[1] = (u32)value;\n+\t\tif (len > 4)\n+\t\t\tattr[2] = (u32)(value >> 32);\n+\t}\n+\n+\t/* record attribute header, update message length */\n+\tlen <<= FM10K_TLV_LEN_SHIFT;\n+\tattr[0] = len | attr_id;\n+\n+\t/* add header length to length */\n+\tlen += FM10K_TLV_HDR_LEN << FM10K_TLV_LEN_SHIFT;\n+\t*msg += FM10K_TLV_LEN_ALIGN(len);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_get_value - Get integer value stored in attribute\n+ *  @attr: Pointer to attribute\n+ *  @value: Pointer to destination buffer\n+ *  @len: Size of value\n+ *\n+ *  This function will place an integer value of up to 8 bytes in size\n+ *  in the offset pointed to by value.  The function will return success\n+ *  provided that pointers are valid and the len value matches the\n+ *  attribute length.\n+ **/\n+s32 fm10k_tlv_attr_get_value(u32 *attr, void *value, u32 len)\n+{\n+\tDEBUGFUNC(\"fm10k_tlv_attr_get_value\");\n+\n+\t/* verify pointers are not NULL */\n+\tif (!attr || !value)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tif ((*attr >> FM10K_TLV_LEN_SHIFT) != len)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tif (len == 8)\n+\t\t*(u64 *)value = ((u64)attr[2] << 32) | attr[1];\n+\telse if (len == 4)\n+\t\t*(u32 *)value = attr[1];\n+\telse if (len == 2)\n+\t\t*(u16 *)value = (u16)attr[1];\n+\telse\n+\t\t*(u8 *)value = (u8)attr[1];\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_put_le_struct - Store little endian structure in message\n+ *  @msg: Pointer to message block\n+ *  @attr_id: Attribute ID\n+ *  @le_struct: Pointer to structure to be written\n+ *  @len: Size of le_struct\n+ *\n+ *  This function will place a little endian structure value in a message\n+ *  attribute.  The function will return success provided that all pointers\n+ *  are valid and length is a non-zero multiple of 4.\n+ **/\n+s32 fm10k_tlv_attr_put_le_struct(u32 *msg, u16 attr_id,\n+\t\t\t\t const void *le_struct, u32 len)\n+{\n+\tconst __le32 *le32_ptr = (const __le32 *)le_struct;\n+\tu32 *attr;\n+\tu32 i;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_attr_put_le_struct\");\n+\n+\t/* verify non-null msg and len is in 32 bit words */\n+\tif (!msg || !len || (len % 4))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tattr = &msg[FM10K_TLV_DWORD_LEN(*msg)];\n+\n+\t/* copy le32 structure into host byte order at 32b boundaries */\n+\tfor (i = 0; i < (len / 4); i++)\n+\t\tattr[i + 1] = FM10K_LE32_TO_CPU(le32_ptr[i]);\n+\n+\t/* record attribute header, update message length */\n+\tlen <<= FM10K_TLV_LEN_SHIFT;\n+\tattr[0] = len | attr_id;\n+\n+\t/* add header length to length */\n+\tlen += FM10K_TLV_HDR_LEN << FM10K_TLV_LEN_SHIFT;\n+\t*msg += FM10K_TLV_LEN_ALIGN(len);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_get_le_struct - Get little endian struct form attribute\n+ *  @attr: Pointer to attribute\n+ *  @le_struct: Pointer to structure to be written\n+ *  @len: Size of structure\n+ *\n+ *  This function will place a little endian structure in the buffer\n+ *  pointed to by le_struct.  The function will return success\n+ *  provided that pointers are valid and the len value matches the\n+ *  attribute length.\n+ **/\n+s32 fm10k_tlv_attr_get_le_struct(u32 *attr, void *le_struct, u32 len)\n+{\n+\t__le32 *le32_ptr = (__le32 *)le_struct;\n+\tu32 i;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_attr_get_le_struct\");\n+\n+\t/* verify pointers are not NULL */\n+\tif (!le_struct || !attr)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tif ((*attr >> FM10K_TLV_LEN_SHIFT) != len)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\tattr++;\n+\n+\tfor (i = 0; len; i++, len -= 4)\n+\t\tle32_ptr[i] = FM10K_CPU_TO_LE32(attr[i]);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_nest_start - Start a set of nested attributes\n+ *  @msg: Pointer to message block\n+ *  @attr_id: Attribute ID\n+ *\n+ *  This function will mark off a new nested region for encapsulating\n+ *  a given set of attributes.  The idea is if you wish to place a secondary\n+ *  structure within the message this mechanism allows for that.  The\n+ *  function will return NULL on failure, and a pointer to the start\n+ *  of the nested attributes on success.\n+ **/\n+u32 *fm10k_tlv_attr_nest_start(u32 *msg, u16 attr_id)\n+{\n+\tu32 *attr;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_attr_nest_start\");\n+\n+\t/* verify pointer is not NULL */\n+\tif (!msg)\n+\t\treturn NULL;\n+\n+\tattr = &msg[FM10K_TLV_DWORD_LEN(*msg)];\n+\n+\tattr[0] = attr_id;\n+\n+\t/* return pointer to nest header */\n+\treturn attr;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_nest_start - Start a set of nested attributes\n+ *  @msg: Pointer to message block\n+ *\n+ *  This function closes off an existing set of nested attributes.  The\n+ *  message pointer should be pointing to the parent of the nest.  So in\n+ *  the case of a nest within the nest this would be the outer nest pointer.\n+ *  This function will return success provided all pointers are valid.\n+ **/\n+s32 fm10k_tlv_attr_nest_stop(u32 *msg)\n+{\n+\tu32 *attr;\n+\tu32 len;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_attr_nest_stop\");\n+\n+\t/* verify pointer is not NULL */\n+\tif (!msg)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* locate the nested header and retrieve its length */\n+\tattr = &msg[FM10K_TLV_DWORD_LEN(*msg)];\n+\tlen = (attr[0] >> FM10K_TLV_LEN_SHIFT) << FM10K_TLV_LEN_SHIFT;\n+\n+\t/* only include nest if data was added to it */\n+\tif (len) {\n+\t\tlen += FM10K_TLV_HDR_LEN << FM10K_TLV_LEN_SHIFT;\n+\t\t*msg += len;\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_validate - Validate attribute metadata\n+ *  @attr: Pointer to attribute\n+ *  @tlv_attr: Type and length info for attribute\n+ *\n+ *  This function does some basic validation of the input TLV.  It\n+ *  verifies the length, and in the case of null terminated strings\n+ *  it verifies that the last byte is null.  The function will\n+ *  return FM10K_ERR_PARAM if any attribute is malformed, otherwise\n+ *  it returns 0.\n+ **/\n+STATIC s32 fm10k_tlv_attr_validate(u32 *attr,\n+\t\t\t\t   const struct fm10k_tlv_attr *tlv_attr)\n+{\n+\tu32 attr_id = *attr & FM10K_TLV_ID_MASK;\n+\tu16 len = *attr >> FM10K_TLV_LEN_SHIFT;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_attr_validate\");\n+\n+\t/* verify this is an attribute and not a message */\n+\tif (*attr & (FM10K_TLV_FLAGS_MSG << FM10K_TLV_FLAGS_SHIFT))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* search through the list of attributes to find a matching ID */\n+\twhile (tlv_attr->id < attr_id)\n+\t\ttlv_attr++;\n+\n+\t/* if didn't find a match then we should exit */\n+\tif (tlv_attr->id != attr_id)\n+\t\treturn FM10K_NOT_IMPLEMENTED;\n+\n+\t/* move to start of attribute data */\n+\tattr++;\n+\n+\tswitch (tlv_attr->type) {\n+\tcase FM10K_TLV_NULL_STRING:\n+\t\tif (!len ||\n+\t\t    (attr[(len - 1) / 4] & (0xFF << (8 * ((len - 1) % 4)))))\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t\tif (len > tlv_attr->len)\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t\tbreak;\n+\tcase FM10K_TLV_MAC_ADDR:\n+\t\tif (len != ETH_ALEN)\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t\tbreak;\n+\tcase FM10K_TLV_BOOL:\n+\t\tif (len)\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t\tbreak;\n+\tcase FM10K_TLV_UNSIGNED:\n+\tcase FM10K_TLV_SIGNED:\n+\t\tif (len != tlv_attr->len)\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t\tbreak;\n+\tcase FM10K_TLV_LE_STRUCT:\n+\t\t/* struct must be 4 byte aligned */\n+\t\tif ((len % 4) || len != tlv_attr->len)\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t\tbreak;\n+\tcase FM10K_TLV_NESTED:\n+\t\t/* nested attributes must be 4 byte aligned */\n+\t\tif (len % 4)\n+\t\t\treturn FM10K_ERR_PARAM;\n+\t\tbreak;\n+\tdefault:\n+\t\t/* attribute id is mapped to bad value */\n+\t\treturn FM10K_ERR_PARAM;\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_attr_parse - Parses stream of attribute data\n+ *  @attr: Pointer to attribute list\n+ *  @results: Pointer array to store pointers to attributes\n+ *  @tlv_attr: Type and length info for attributes\n+ *\n+ *  This function validates a stream of attributes and parses them\n+ *  up into an array of pointers stored in results.  The function will\n+ *  return FM10K_ERR_PARAM on any input or message error,\n+ *  FM10K_NOT_IMPLEMENTED for any attribute that is outside of the array\n+ *  and 0 on success.\n+ **/\n+s32 fm10k_tlv_attr_parse(u32 *attr, u32 **results,\n+\t\t\t const struct fm10k_tlv_attr *tlv_attr)\n+{\n+\tu32 i, attr_id, offset = 0;\n+\ts32 err = 0;\n+\tu16 len;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_attr_parse\");\n+\n+\t/* verify pointers are not NULL */\n+\tif (!attr || !results)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* initialize results to NULL */\n+\tfor (i = 0; i < FM10K_TLV_RESULTS_MAX; i++)\n+\t\tresults[i] = NULL;\n+\n+\t/* pull length from the message header */\n+\tlen = *attr >> FM10K_TLV_LEN_SHIFT;\n+\n+\t/* no attributes to parse if there is no length */\n+\tif (!len)\n+\t\treturn FM10K_SUCCESS;\n+\n+\t/* no attributes to parse, just raw data, message becomes attribute */\n+\tif (!tlv_attr) {\n+\t\tresults[0] = attr;\n+\t\treturn FM10K_SUCCESS;\n+\t}\n+\n+\t/* move to start of attribute data */\n+\tattr++;\n+\n+\t/* run through list parsing all attributes */\n+\twhile (offset < len) {\n+\t\tattr_id = *attr & FM10K_TLV_ID_MASK;\n+\n+\t\tif (attr_id < FM10K_TLV_RESULTS_MAX)\n+\t\t\terr = fm10k_tlv_attr_validate(attr, tlv_attr);\n+\t\telse\n+\t\t\terr = FM10K_NOT_IMPLEMENTED;\n+\n+\t\tif (err < 0)\n+\t\t\treturn err;\n+\t\tif (!err)\n+\t\t\tresults[attr_id] = attr;\n+\n+\t\t/* update offset */\n+\t\toffset += FM10K_TLV_DWORD_LEN(*attr) * 4;\n+\n+\t\t/* move to next attribute */\n+\t\tattr = &attr[FM10K_TLV_DWORD_LEN(*attr)];\n+\t}\n+\n+\t/* we should find ourselves at the end of the list */\n+\tif (offset != len)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_tlv_msg_parse - Parses message header and calls function handler\n+ *  @hw: Pointer to hardware structure\n+ *  @msg: Pointer to message\n+ *  @mbx: Pointer to mailbox information structure\n+ *  @func: Function array containing list of message handling functions\n+ *\n+ *  This function should be the first function called upon receiving a\n+ *  message.  The handler will identify the message type and call the correct\n+ *  handler for the given message.  It will return the value from the function\n+ *  call on a recognized message type, otherwise it will return\n+ *  FM10K_NOT_IMPLEMENTED on an unrecognized type.\n+ **/\n+s32 fm10k_tlv_msg_parse(struct fm10k_hw *hw, u32 *msg,\n+\t\t\tstruct fm10k_mbx_info *mbx,\n+\t\t\tconst struct fm10k_msg_data *data)\n+{\n+\tu32 *results[FM10K_TLV_RESULTS_MAX];\n+\tu32 msg_id;\n+\ts32 err;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_msg_parse\");\n+\n+\t/* verify pointer is not NULL */\n+\tif (!msg || !data)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* verify this is a message and not an attribute */\n+\tif (!(*msg & (FM10K_TLV_FLAGS_MSG << FM10K_TLV_FLAGS_SHIFT)))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* grab message ID */\n+\tmsg_id = *msg & FM10K_TLV_ID_MASK;\n+\n+\twhile (data->id < msg_id)\n+\t\tdata++;\n+\n+\t/* if we didn't find it then pass it up as an error */\n+\tif (data->id != msg_id) {\n+\t\twhile (data->id != FM10K_TLV_ERROR)\n+\t\t\tdata++;\n+\t}\n+\n+\t/* parse the attributes into the results list */\n+\terr = fm10k_tlv_attr_parse(msg, results, data->attr);\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\treturn data->func(hw, results, mbx);\n+}\n+\n+/**\n+ *  fm10k_tlv_msg_error - Default handler for unrecognized TLV message IDs\n+ *  @hw: Pointer to hardware structure\n+ *  @results: Pointer array to message, results[0] is pointer to message\n+ *  @mbx: Unused mailbox pointer\n+ *\n+ *  This function is a default handler for unrecognized messages.  At a\n+ *  a minimum it just indicates that the message requested was\n+ *  unimplemented.\n+ **/\n+s32 fm10k_tlv_msg_error(struct fm10k_hw *hw, u32 **results,\n+\t\t\tstruct fm10k_mbx_info *mbx)\n+{\n+\tUNREFERENCED_3PARAMETER(hw, results, mbx);\n+\tDEBUGOUT1(\"Unknown message ID %u\\n\", **results & FM10K_TLV_ID_MASK);\n+\treturn FM10K_NOT_IMPLEMENTED;\n+}\n+\n+STATIC const unsigned char test_str[] =\t\"fm10k\";\n+STATIC const unsigned char test_mac[ETH_ALEN] = { 0x12, 0x34, 0x56,\n+\t\t\t\t\t\t  0x78, 0x9a, 0xbc };\n+STATIC const u16 test_vlan = 0x0FED;\n+STATIC const u64 test_u64 = 0xfedcba9876543210ull;\n+STATIC const u32 test_u32 = 0x87654321;\n+STATIC const u16 test_u16 = 0x8765;\n+STATIC const u8  test_u8  = 0x87;\n+STATIC const s64 test_s64 = -0x123456789abcdef0ll;\n+STATIC const s32 test_s32 = -0x1235678;\n+STATIC const s16 test_s16 = -0x1234;\n+STATIC const s8  test_s8  = -0x12;\n+STATIC const __le32 test_le[2] = { FM10K_CPU_TO_LE32(0x12345678),\n+\t\t\t\t   FM10K_CPU_TO_LE32(0x9abcdef0)};\n+\n+/* The message below is meant to be used as a test message to demonstrate\n+ * how to use the TLV interface and to test the types.  Normally this code\n+ * be compiled out by stripping the code wrapped in FM10K_TLV_TEST_MSG\n+ */\n+const struct fm10k_tlv_attr fm10k_tlv_msg_test_attr[] = {\n+\tFM10K_TLV_ATTR_NULL_STRING(FM10K_TEST_MSG_STRING, 80),\n+\tFM10K_TLV_ATTR_MAC_ADDR(FM10K_TEST_MSG_MAC_ADDR),\n+\tFM10K_TLV_ATTR_U8(FM10K_TEST_MSG_U8),\n+\tFM10K_TLV_ATTR_U16(FM10K_TEST_MSG_U16),\n+\tFM10K_TLV_ATTR_U32(FM10K_TEST_MSG_U32),\n+\tFM10K_TLV_ATTR_U64(FM10K_TEST_MSG_U64),\n+\tFM10K_TLV_ATTR_S8(FM10K_TEST_MSG_S8),\n+\tFM10K_TLV_ATTR_S16(FM10K_TEST_MSG_S16),\n+\tFM10K_TLV_ATTR_S32(FM10K_TEST_MSG_S32),\n+\tFM10K_TLV_ATTR_S64(FM10K_TEST_MSG_S64),\n+\tFM10K_TLV_ATTR_LE_STRUCT(FM10K_TEST_MSG_LE_STRUCT, 8),\n+\tFM10K_TLV_ATTR_NESTED(FM10K_TEST_MSG_NESTED),\n+\tFM10K_TLV_ATTR_S32(FM10K_TEST_MSG_RESULT),\n+\tFM10K_TLV_ATTR_LAST\n+};\n+\n+/**\n+ *  fm10k_tlv_msg_test_generate_data - Stuff message with data\n+ *  @msg: Pointer to message\n+ *  @attr_flags: List of flags indicating what attributes to add\n+ *\n+ *  This function is meant to load a message buffer with attribute data\n+ **/\n+STATIC void fm10k_tlv_msg_test_generate_data(u32 *msg, u32 attr_flags)\n+{\n+\tDEBUGFUNC(\"fm10k_tlv_msg_test_generate_data\");\n+\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_STRING))\n+\t\tfm10k_tlv_attr_put_null_string(msg, FM10K_TEST_MSG_STRING,\n+\t\t\t\t\t       test_str);\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_MAC_ADDR))\n+\t\tfm10k_tlv_attr_put_mac_vlan(msg, FM10K_TEST_MSG_MAC_ADDR,\n+\t\t\t\t\t    test_mac, test_vlan);\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_U8))\n+\t\tfm10k_tlv_attr_put_u8(msg, FM10K_TEST_MSG_U8,  test_u8);\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_U16))\n+\t\tfm10k_tlv_attr_put_u16(msg, FM10K_TEST_MSG_U16, test_u16);\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_U32))\n+\t\tfm10k_tlv_attr_put_u32(msg, FM10K_TEST_MSG_U32, test_u32);\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_U64))\n+\t\tfm10k_tlv_attr_put_u64(msg, FM10K_TEST_MSG_U64, test_u64);\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_S8))\n+\t\tfm10k_tlv_attr_put_s8(msg, FM10K_TEST_MSG_S8,  test_s8);\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_S16))\n+\t\tfm10k_tlv_attr_put_s16(msg, FM10K_TEST_MSG_S16, test_s16);\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_S32))\n+\t\tfm10k_tlv_attr_put_s32(msg, FM10K_TEST_MSG_S32, test_s32);\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_S64))\n+\t\tfm10k_tlv_attr_put_s64(msg, FM10K_TEST_MSG_S64, test_s64);\n+\tif (attr_flags & (1 << FM10K_TEST_MSG_LE_STRUCT))\n+\t\tfm10k_tlv_attr_put_le_struct(msg, FM10K_TEST_MSG_LE_STRUCT,\n+\t\t\t\t\t     test_le, 8);\n+}\n+\n+/**\n+ *  fm10k_tlv_msg_test_create - Create a test message testing all attributes\n+ *  @msg: Pointer to message\n+ *  @attr_flags: List of flags indicating what attributes to add\n+ *\n+ *  This function is meant to load a message buffer with all attribute types\n+ *  including a nested attribute.\n+ **/\n+void fm10k_tlv_msg_test_create(u32 *msg, u32 attr_flags)\n+{\n+\tu32 *nest = NULL;\n+\n+\tDEBUGFUNC(\"fm10k_tlv_msg_test_create\");\n+\n+\tfm10k_tlv_msg_init(msg, FM10K_TLV_MSG_ID_TEST);\n+\n+\tfm10k_tlv_msg_test_generate_data(msg, attr_flags);\n+\n+\t/* check for nested attributes */\n+\tattr_flags >>= FM10K_TEST_MSG_NESTED;\n+\n+\tif (attr_flags) {\n+\t\tnest = fm10k_tlv_attr_nest_start(msg, FM10K_TEST_MSG_NESTED);\n+\n+\t\tfm10k_tlv_msg_test_generate_data(nest, attr_flags);\n+\n+\t\tfm10k_tlv_attr_nest_stop(msg);\n+\t}\n+}\n+\n+/**\n+ *  fm10k_tlv_msg_test - Validate all results on test message receive\n+ *  @hw: Pointer to hardware structure\n+ *  @results: Pointer array to attributes in the message\n+ *  @mbx: Pointer to mailbox information structure\n+ *\n+ *  This function does a check to verify all attributes match what the test\n+ *  message placed in the message buffer.  It is the default handler\n+ *  for TLV test messages.\n+ **/\n+s32 fm10k_tlv_msg_test(struct fm10k_hw *hw, u32 **results,\n+\t\t       struct fm10k_mbx_info *mbx)\n+{\n+\tu32 *nest_results[FM10K_TLV_RESULTS_MAX];\n+\tunsigned char result_str[80];\n+\tunsigned char result_mac[ETH_ALEN];\n+\ts32 err = FM10K_SUCCESS;\n+\t__le32 result_le[2];\n+\tu16 result_vlan;\n+\tu64 result_u64;\n+\tu32 result_u32;\n+\tu16 result_u16;\n+\tu8  result_u8;\n+\ts64 result_s64;\n+\ts32 result_s32;\n+\ts16 result_s16;\n+\ts8  result_s8;\n+\tu32 reply[3];\n+\n+\tDEBUGFUNC(\"fm10k_tlv_msg_test\");\n+\n+\t/* retrieve results of a previous test */\n+\tif (!!results[FM10K_TEST_MSG_RESULT])\n+\t\treturn fm10k_tlv_attr_get_s32(results[FM10K_TEST_MSG_RESULT],\n+\t\t\t\t\t      &mbx->test_result);\n+\n+parse_nested:\n+\tif (!!results[FM10K_TEST_MSG_STRING]) {\n+\t\terr = fm10k_tlv_attr_get_null_string(\n+\t\t\t\t\tresults[FM10K_TEST_MSG_STRING],\n+\t\t\t\t\tresult_str);\n+\t\tif (!err && memcmp(test_str, result_str, sizeof(test_str)))\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\tif (!!results[FM10K_TEST_MSG_MAC_ADDR]) {\n+\t\terr = fm10k_tlv_attr_get_mac_vlan(\n+\t\t\t\t\tresults[FM10K_TEST_MSG_MAC_ADDR],\n+\t\t\t\t\tresult_mac, &result_vlan);\n+\t\tif (!err && memcmp(test_mac, result_mac, ETH_ALEN))\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (!err && test_vlan != result_vlan)\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\tif (!!results[FM10K_TEST_MSG_U8]) {\n+\t\terr = fm10k_tlv_attr_get_u8(results[FM10K_TEST_MSG_U8],\n+\t\t\t\t\t    &result_u8);\n+\t\tif (!err && test_u8 != result_u8)\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\tif (!!results[FM10K_TEST_MSG_U16]) {\n+\t\terr = fm10k_tlv_attr_get_u16(results[FM10K_TEST_MSG_U16],\n+\t\t\t\t\t     &result_u16);\n+\t\tif (!err && test_u16 != result_u16)\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\tif (!!results[FM10K_TEST_MSG_U32]) {\n+\t\terr = fm10k_tlv_attr_get_u32(results[FM10K_TEST_MSG_U32],\n+\t\t\t\t\t     &result_u32);\n+\t\tif (!err && test_u32 != result_u32)\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\tif (!!results[FM10K_TEST_MSG_U64]) {\n+\t\terr = fm10k_tlv_attr_get_u64(results[FM10K_TEST_MSG_U64],\n+\t\t\t\t\t     &result_u64);\n+\t\tif (!err && test_u64 != result_u64)\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\tif (!!results[FM10K_TEST_MSG_S8]) {\n+\t\terr = fm10k_tlv_attr_get_s8(results[FM10K_TEST_MSG_S8],\n+\t\t\t\t\t    &result_s8);\n+\t\tif (!err && test_s8 != result_s8)\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\tif (!!results[FM10K_TEST_MSG_S16]) {\n+\t\terr = fm10k_tlv_attr_get_s16(results[FM10K_TEST_MSG_S16],\n+\t\t\t\t\t     &result_s16);\n+\t\tif (!err && test_s16 != result_s16)\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\tif (!!results[FM10K_TEST_MSG_S32]) {\n+\t\terr = fm10k_tlv_attr_get_s32(results[FM10K_TEST_MSG_S32],\n+\t\t\t\t\t     &result_s32);\n+\t\tif (!err && test_s32 != result_s32)\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\tif (!!results[FM10K_TEST_MSG_S64]) {\n+\t\terr = fm10k_tlv_attr_get_s64(results[FM10K_TEST_MSG_S64],\n+\t\t\t\t\t     &result_s64);\n+\t\tif (!err && test_s64 != result_s64)\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\tif (!!results[FM10K_TEST_MSG_LE_STRUCT]) {\n+\t\terr = fm10k_tlv_attr_get_le_struct(\n+\t\t\t\t\tresults[FM10K_TEST_MSG_LE_STRUCT],\n+\t\t\t\t\tresult_le,\n+\t\t\t\t\tsizeof(result_le));\n+\t\tif (!err && memcmp(test_le, result_le, sizeof(test_le)))\n+\t\t\terr = FM10K_ERR_INVALID_VALUE;\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\t}\n+\n+\tif (!!results[FM10K_TEST_MSG_NESTED]) {\n+\t\t/* clear any pointers */\n+\t\tmemset(nest_results, 0, sizeof(nest_results));\n+\n+\t\t/* parse the nested attributes into the nest results list */\n+\t\terr = fm10k_tlv_attr_parse(results[FM10K_TEST_MSG_NESTED],\n+\t\t\t\t\t   nest_results,\n+\t\t\t\t\t   fm10k_tlv_msg_test_attr);\n+\t\tif (err)\n+\t\t\tgoto report_result;\n+\n+\t\t/* loop back through to the start */\n+\t\tresults = nest_results;\n+\t\tgoto parse_nested;\n+\t}\n+\n+report_result:\n+\t/* generate reply with test result */\n+\tfm10k_tlv_msg_init(reply, FM10K_TLV_MSG_ID_TEST);\n+\tfm10k_tlv_attr_put_s32(reply, FM10K_TEST_MSG_RESULT, err);\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, reply);\n+}\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_tlv.h b/lib/librte_pmd_fm10k/base/fm10k_tlv.h\nnew file mode 100644\nindex 0000000..ad97236\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_tlv.h\n@@ -0,0 +1,199 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#ifndef _FM10K_TLV_H_\n+#define _FM10K_TLV_H_\n+\n+/* forward declaration */\n+struct fm10k_msg_data;\n+\n+#include \"fm10k_type.h\"\n+\n+/* Message / Argument header format\n+ *    3\t\t\t  2\t\t      1\t\t\t  0\n+ *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ * |\t     Length\t   | Flags |\t      Type / ID\t\t   |\n+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ *\n+ * The message header format described here is used for messages that are\n+ * passed between the PF and the VF.  To allow for messages larger then\n+ * mailbox size we will provide a message with the above header and it\n+ * will be segmented and transported to the mailbox to the other side where\n+ * it is reassembled.  It contains the following fields:\n+ * Len: Length of the message in bytes excluding the message header\n+ * Flags: TBD\n+ * Rule: These will be the message/argument types we pass\n+ */\n+/* message data header */\n+#define FM10K_TLV_ID_SHIFT\t\t0\n+#define FM10K_TLV_ID_SIZE\t\t16\n+#define FM10K_TLV_ID_MASK\t\t((1u << FM10K_TLV_ID_SIZE) - 1)\n+#define FM10K_TLV_FLAGS_SHIFT\t\t16\n+#define FM10K_TLV_FLAGS_MSG\t\t0x1\n+#define FM10K_TLV_FLAGS_SIZE\t\t4\n+#define FM10K_TLV_LEN_SHIFT\t\t20\n+#define FM10K_TLV_LEN_SIZE\t\t12\n+\n+#define FM10K_TLV_HDR_LEN\t\t4ul\n+#define FM10K_TLV_LEN_ALIGN_MASK \\\n+\t((FM10K_TLV_HDR_LEN - 1) << FM10K_TLV_LEN_SHIFT)\n+#define FM10K_TLV_LEN_ALIGN(tlv) \\\n+\t(((tlv) + FM10K_TLV_LEN_ALIGN_MASK) & ~FM10K_TLV_LEN_ALIGN_MASK)\n+#define FM10K_TLV_DWORD_LEN(tlv) \\\n+\t((u16)((FM10K_TLV_LEN_ALIGN(tlv)) >> (FM10K_TLV_LEN_SHIFT + 2)) + 1)\n+\n+#define FM10K_TLV_RESULTS_MAX\t\t32\n+\n+enum fm10k_tlv_type {\n+\tFM10K_TLV_NULL_STRING,\n+\tFM10K_TLV_MAC_ADDR,\n+\tFM10K_TLV_BOOL,\n+\tFM10K_TLV_UNSIGNED,\n+\tFM10K_TLV_SIGNED,\n+\tFM10K_TLV_LE_STRUCT,\n+\tFM10K_TLV_NESTED,\n+\tFM10K_TLV_MAX_TYPE\n+};\n+\n+#define FM10K_TLV_ERROR (~0u)\n+\n+struct fm10k_tlv_attr {\n+\tunsigned int\t\tid;\n+\tenum fm10k_tlv_type\ttype;\n+\tu16\t\t\tlen;\n+};\n+\n+#define FM10K_TLV_ATTR_NULL_STRING(id, len) { id, FM10K_TLV_NULL_STRING, len }\n+#define FM10K_TLV_ATTR_MAC_ADDR(id)\t    { id, FM10K_TLV_MAC_ADDR, 6 }\n+#define FM10K_TLV_ATTR_BOOL(id)\t\t    { id, FM10K_TLV_BOOL, 0 }\n+#define FM10K_TLV_ATTR_U8(id)\t\t    { id, FM10K_TLV_UNSIGNED, 1 }\n+#define FM10K_TLV_ATTR_U16(id)\t\t    { id, FM10K_TLV_UNSIGNED, 2 }\n+#define FM10K_TLV_ATTR_U32(id)\t\t    { id, FM10K_TLV_UNSIGNED, 4 }\n+#define FM10K_TLV_ATTR_U64(id)\t\t    { id, FM10K_TLV_UNSIGNED, 8 }\n+#define FM10K_TLV_ATTR_S8(id)\t\t    { id, FM10K_TLV_SIGNED, 1 }\n+#define FM10K_TLV_ATTR_S16(id)\t\t    { id, FM10K_TLV_SIGNED, 2 }\n+#define FM10K_TLV_ATTR_S32(id)\t\t    { id, FM10K_TLV_SIGNED, 4 }\n+#define FM10K_TLV_ATTR_S64(id)\t\t    { id, FM10K_TLV_SIGNED, 8 }\n+#define FM10K_TLV_ATTR_LE_STRUCT(id, len)   { id, FM10K_TLV_LE_STRUCT, len }\n+#define FM10K_TLV_ATTR_NESTED(id)\t    { id, FM10K_TLV_NESTED }\n+#define FM10K_TLV_ATTR_LAST\t\t    { FM10K_TLV_ERROR }\n+\n+struct fm10k_msg_data {\n+\tunsigned int\t\t    id;\n+\tconst struct fm10k_tlv_attr *attr;\n+\ts32\t\t\t    (*func)(struct fm10k_hw *, u32 **,\n+\t\t\t\t\t    struct fm10k_mbx_info *);\n+};\n+\n+#define FM10K_MSG_HANDLER(id, attr, func) { id, attr, func }\n+\n+s32 fm10k_tlv_msg_init(u32 *, u16);\n+s32 fm10k_tlv_attr_put_null_string(u32 *, u16, const unsigned char *);\n+s32 fm10k_tlv_attr_get_null_string(u32 *, unsigned char *);\n+s32 fm10k_tlv_attr_put_mac_vlan(u32 *, u16, const u8 *, u16);\n+s32 fm10k_tlv_attr_get_mac_vlan(u32 *, u8 *, u16 *);\n+s32 fm10k_tlv_attr_put_bool(u32 *, u16);\n+s32 fm10k_tlv_attr_put_value(u32 *, u16, s64, u32);\n+#define fm10k_tlv_attr_put_u8(msg, attr_id, val) \\\n+\t\tfm10k_tlv_attr_put_value(msg, attr_id, val, 1)\n+#define fm10k_tlv_attr_put_u16(msg, attr_id, val) \\\n+\t\tfm10k_tlv_attr_put_value(msg, attr_id, val, 2)\n+#define fm10k_tlv_attr_put_u32(msg, attr_id, val) \\\n+\t\tfm10k_tlv_attr_put_value(msg, attr_id, val, 4)\n+#define fm10k_tlv_attr_put_u64(msg, attr_id, val) \\\n+\t\tfm10k_tlv_attr_put_value(msg, attr_id, val, 8)\n+#define fm10k_tlv_attr_put_s8(msg, attr_id, val) \\\n+\t\tfm10k_tlv_attr_put_value(msg, attr_id, val, 1)\n+#define fm10k_tlv_attr_put_s16(msg, attr_id, val) \\\n+\t\tfm10k_tlv_attr_put_value(msg, attr_id, val, 2)\n+#define fm10k_tlv_attr_put_s32(msg, attr_id, val) \\\n+\t\tfm10k_tlv_attr_put_value(msg, attr_id, val, 4)\n+#define fm10k_tlv_attr_put_s64(msg, attr_id, val) \\\n+\t\tfm10k_tlv_attr_put_value(msg, attr_id, val, 8)\n+s32 fm10k_tlv_attr_get_value(u32 *, void *, u32);\n+#define fm10k_tlv_attr_get_u8(attr, ptr) \\\n+\t\tfm10k_tlv_attr_get_value(attr, ptr, sizeof(u8))\n+#define fm10k_tlv_attr_get_u16(attr, ptr) \\\n+\t\tfm10k_tlv_attr_get_value(attr, ptr, sizeof(u16))\n+#define fm10k_tlv_attr_get_u32(attr, ptr) \\\n+\t\tfm10k_tlv_attr_get_value(attr, ptr, sizeof(u32))\n+#define fm10k_tlv_attr_get_u64(attr, ptr) \\\n+\t\tfm10k_tlv_attr_get_value(attr, ptr, sizeof(u64))\n+#define fm10k_tlv_attr_get_s8(attr, ptr) \\\n+\t\tfm10k_tlv_attr_get_value(attr, ptr, sizeof(s8))\n+#define fm10k_tlv_attr_get_s16(attr, ptr) \\\n+\t\tfm10k_tlv_attr_get_value(attr, ptr, sizeof(s16))\n+#define fm10k_tlv_attr_get_s32(attr, ptr) \\\n+\t\tfm10k_tlv_attr_get_value(attr, ptr, sizeof(s32))\n+#define fm10k_tlv_attr_get_s64(attr, ptr) \\\n+\t\tfm10k_tlv_attr_get_value(attr, ptr, sizeof(s64))\n+s32 fm10k_tlv_attr_put_le_struct(u32 *, u16, const void *, u32);\n+s32 fm10k_tlv_attr_get_le_struct(u32 *, void *, u32);\n+u32 *fm10k_tlv_attr_nest_start(u32 *, u16);\n+s32 fm10k_tlv_attr_nest_stop(u32 *);\n+s32 fm10k_tlv_attr_parse(u32 *, u32 **, const struct fm10k_tlv_attr *);\n+s32 fm10k_tlv_msg_parse(struct fm10k_hw *, u32 *, struct fm10k_mbx_info *,\n+\t\t\tconst struct fm10k_msg_data *);\n+s32 fm10k_tlv_msg_error(struct fm10k_hw *hw, u32 **results,\n+\t\t\tstruct fm10k_mbx_info *);\n+\n+#define FM10K_TLV_MSG_ID_TEST\t0\n+\n+enum fm10k_tlv_test_attr_id {\n+\tFM10K_TEST_MSG_UNSET,\n+\tFM10K_TEST_MSG_STRING,\n+\tFM10K_TEST_MSG_MAC_ADDR,\n+\tFM10K_TEST_MSG_U8,\n+\tFM10K_TEST_MSG_U16,\n+\tFM10K_TEST_MSG_U32,\n+\tFM10K_TEST_MSG_U64,\n+\tFM10K_TEST_MSG_S8,\n+\tFM10K_TEST_MSG_S16,\n+\tFM10K_TEST_MSG_S32,\n+\tFM10K_TEST_MSG_S64,\n+\tFM10K_TEST_MSG_LE_STRUCT,\n+\tFM10K_TEST_MSG_NESTED,\n+\tFM10K_TEST_MSG_RESULT,\n+\tFM10K_TEST_MSG_MAX\n+};\n+\n+extern const struct fm10k_tlv_attr fm10k_tlv_msg_test_attr[];\n+void fm10k_tlv_msg_test_create(u32 *, u32);\n+s32 fm10k_tlv_msg_test(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);\n+\n+#define FM10K_TLV_MSG_TEST_HANDLER(func) \\\n+\tFM10K_MSG_HANDLER(FM10K_TLV_MSG_ID_TEST, fm10k_tlv_msg_test_attr, func)\n+#define FM10K_TLV_MSG_ERROR_HANDLER(func) \\\n+\tFM10K_MSG_HANDLER(FM10K_TLV_ERROR, NULL, func)\n+#endif /* _FM10K_MSG_H_ */\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_type.h b/lib/librte_pmd_fm10k/base/fm10k_type.h\nnew file mode 100644\nindex 0000000..534fab4\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_type.h\n@@ -0,0 +1,937 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#ifndef _FM10K_TYPE_H_\n+#define _FM10K_TYPE_H_\n+\n+/* forward declaration */\n+struct fm10k_hw;\n+\n+#include \"fm10k_osdep.h\"\n+#include \"fm10k_mbx.h\"\n+\n+#define FM10K_INTEL_VENDOR_ID\t\t0x8086\n+#define FM10K_DEV_ID_PF\t\t\t0x15A4\n+#define FM10K_DEV_ID_VF\t\t\t0x15A5\n+\n+#define FM10K_MAX_QUEUES\t\t256\n+#define FM10K_MAX_QUEUES_PF\t\t128\n+#define FM10K_MAX_QUEUES_POOL\t\t16\n+\n+#define FM10K_48_BIT_MASK\t\t0x0000FFFFFFFFFFFFull\n+#define FM10K_STAT_VALID\t\t0x80000000\n+\n+/* PCI Bus Info */\n+#define FM10K_PCIE_LINK_CAP\t\t0x7C\n+#define FM10K_PCIE_LINK_STATUS\t\t0x82\n+#define FM10K_PCIE_LINK_WIDTH\t\t0x3F0\n+#define FM10K_PCIE_LINK_WIDTH_1\t\t0x10\n+#define FM10K_PCIE_LINK_WIDTH_2\t\t0x20\n+#define FM10K_PCIE_LINK_WIDTH_4\t\t0x40\n+#define FM10K_PCIE_LINK_WIDTH_8\t\t0x80\n+#define FM10K_PCIE_LINK_SPEED\t\t0xF\n+#define FM10K_PCIE_LINK_SPEED_2500\t0x1\n+#define FM10K_PCIE_LINK_SPEED_5000\t0x2\n+#define FM10K_PCIE_LINK_SPEED_8000\t0x3\n+\n+/* PCIe payload size */\n+#define FM10K_PCIE_DEV_CAP\t\t\t0x74\n+#define FM10K_PCIE_DEV_CAP_PAYLOAD\t\t0x07\n+#define FM10K_PCIE_DEV_CAP_PAYLOAD_128\t\t0x00\n+#define FM10K_PCIE_DEV_CAP_PAYLOAD_256\t\t0x01\n+#define FM10K_PCIE_DEV_CAP_PAYLOAD_512\t\t0x02\n+#define FM10K_PCIE_DEV_CTRL\t\t\t0x78\n+#define FM10K_PCIE_DEV_CTRL_PAYLOAD\t\t0xE0\n+#define FM10K_PCIE_DEV_CTRL_PAYLOAD_128\t\t0x00\n+#define FM10K_PCIE_DEV_CTRL_PAYLOAD_256\t\t0x20\n+#define FM10K_PCIE_DEV_CTRL_PAYLOAD_512\t\t0x40\n+\n+/* PCIe MSI-X Capability info */\n+#define FM10K_PCI_MSIX_MSG_CTRL\t\t\t0xB2\n+#define FM10K_PCI_MSIX_MSG_CTRL_TBL_SZ_MASK\t0x7FF\n+#define FM10K_MAX_MSIX_VECTORS\t\t\t256\n+#define FM10K_MAX_VECTORS_PF\t\t\t256\n+#define FM10K_MAX_VECTORS_POOL\t\t\t32\n+\n+/* PCIe SR-IOV Info */\n+#define FM10K_PCIE_SRIOV_CTRL\t\t\t0x190\n+#define FM10K_PCIE_SRIOV_CTRL_VFARI\t\t0x10\n+\n+#define FM10K_SUCCESS\t\t\t\t0\n+#define FM10K_ERR_DEVICE_NOT_SUPPORTED\t\t-1\n+#define FM10K_ERR_PARAM\t\t\t\t-2\n+#define FM10K_ERR_NO_RESOURCES\t\t\t-3\n+#define FM10K_ERR_REQUESTS_PENDING\t\t-4\n+#define FM10K_ERR_RESET_REQUESTED\t\t-5\n+#define FM10K_ERR_DMA_PENDING\t\t\t-6\n+#define FM10K_ERR_RESET_FAILED\t\t\t-7\n+#define FM10K_ERR_INVALID_MAC_ADDR\t\t-8\n+#define FM10K_ERR_INVALID_VALUE\t\t\t-9\n+#define FM10K_NOT_IMPLEMENTED\t\t\t0x7FFFFFFF\n+\n+#define UNREFERENCED_XPARAMETER\n+#define UNREFERENCED_1PARAMETER(_p) (_p)\n+#define UNREFERENCED_2PARAMETER(_p, _q)\t    do { (_p); (_q); } while (0)\n+#define UNREFERENCED_3PARAMETER(_p, _q, _r) do { (_p); (_q); (_r); } while (0)\n+\n+/* Start of PF registers */\n+#define FM10K_CTRL\t\t0x0000\n+#define FM10K_CTRL_BAR4_ALLOWED\t\t\t0x00000004\n+\n+#define FM10K_CTRL_EXT\t\t0x0001\n+#define FM10K_CTRL_EXT_NS_DIS\t\t\t0x00000001\n+#define FM10K_CTRL_EXT_RO_DIS\t\t\t0x00000002\n+#define FM10K_CTRL_EXT_SWITCH_LOOPBACK\t\t0x00000004\n+#define FM10K_EXVET\t\t0x0002\n+#define FM10K_EXVET_ETHERTYPE_MASK\t\t0x000000FF\n+#define FM10K_EXVET_TAG_SIZE_SHIFT\t\t16\n+#define FM10K_EXVET_AFTER_VLAN\t\t\t0x00040000\n+#define FM10K_GCR\t\t0x0003\n+#define FM10K_FACTPS\t\t0x0004\n+#define FM10K_GCR_EXT\t\t0x0005\n+\n+/* Interrupt control registers */\n+#define FM10K_EICR\t\t0x0006\n+#define FM10K_EICR_PCA_FAULT\t\t\t0x00000001\n+#define FM10K_EICR_THI_FAULT\t\t\t0x00000004\n+#define FM10K_EICR_FUM_FAULT\t\t\t0x00000020\n+#define FM10K_EICR_FAULT_MASK\t\t\t0x0000003F\n+#define FM10K_EICR_MAILBOX\t\t\t0x00000040\n+#define FM10K_EICR_SWITCHREADY\t\t\t0x00000080\n+#define FM10K_EICR_SWITCHNOTREADY\t\t0x00000100\n+#define FM10K_EICR_SWITCHINTERRUPT\t\t0x00000200\n+#define FM10K_EICR_SRAMERROR\t\t\t0x00000400\n+#define FM10K_EICR_VFLR\t\t\t\t0x00000800\n+#define FM10K_EICR_MAXHOLDTIME\t\t\t0x00001000\n+#define FM10K_EIMR\t\t0x0007\n+#define FM10K_EIMR_PCA_FAULT\t\t\t0x00000001\n+#define FM10K_EIMR_THI_FAULT\t\t\t0x00000010\n+#define FM10K_EIMR_FUM_FAULT\t\t\t0x00000400\n+#define FM10K_EIMR_MAILBOX\t\t\t0x00001000\n+#define FM10K_EIMR_SWITCHREADY\t\t\t0x00004000\n+#define FM10K_EIMR_SWITCHNOTREADY\t\t0x00010000\n+#define FM10K_EIMR_SWITCHINTERRUPT\t\t0x00040000\n+#define FM10K_EIMR_SRAMERROR\t\t\t0x00100000\n+#define FM10K_EIMR_VFLR\t\t\t\t0x00400000\n+#define FM10K_EIMR_MAXHOLDTIME\t\t\t0x01000000\n+#define FM10K_EIMR_ALL\t\t\t\t0x55555555\n+#define FM10K_EIMR_DISABLE(NAME)\t\t((FM10K_EIMR_ ## NAME) << 0)\n+#define FM10K_EIMR_ENABLE(NAME)\t\t\t((FM10K_EIMR_ ## NAME) << 1)\n+#define FM10K_FAULT_ADDR_LO\t\t0x0\n+#define FM10K_FAULT_ADDR_HI\t\t0x1\n+#define FM10K_FAULT_SPECINFO\t\t0x2\n+#define FM10K_FAULT_FUNC\t\t0x3\n+#define FM10K_FAULT_SIZE\t\t0x4\n+#define FM10K_FAULT_FUNC_VALID\t\t\t0x00008000\n+#define FM10K_FAULT_FUNC_PF\t\t\t0x00004000\n+#define FM10K_FAULT_FUNC_VF_MASK\t\t0x00003F00\n+#define FM10K_FAULT_FUNC_VF_SHIFT\t\t8\n+#define FM10K_FAULT_FUNC_TYPE_MASK\t\t0x000000FF\n+\n+#define FM10K_PCA_FAULT\t\t0x0008\n+#define FM10K_THI_FAULT\t\t0x0010\n+#define FM10K_FUM_FAULT\t\t0x001C\n+\n+/* Rx queue timeout indicator */\n+#define FM10K_MAXHOLDQ(_n)\t((_n) + 0x0020)\n+\n+/* Switch Manager info */\n+#define FM10K_SM_AREA(_n)\t((_n) + 0x0028)\n+\n+/* GLORT mapping registers */\n+#define FM10K_DGLORTMAP(_n)\t((_n) + 0x0030)\n+#define FM10K_DGLORT_COUNT\t\t\t8\n+#define FM10K_DGLORTMAP_MASK_SHIFT\t\t16\n+#define FM10K_DGLORTMAP_ANY\t\t\t0x00000000\n+#define FM10K_DGLORTMAP_NONE\t\t\t0x0000FFFF\n+#define FM10K_DGLORTMAP_ZERO\t\t\t0xFFFF0000\n+#define FM10K_DGLORTDEC(_n)\t((_n) + 0x0038)\n+#define FM10K_DGLORTDEC_VSILENGTH_SHIFT\t\t4\n+#define FM10K_DGLORTDEC_VSIBASE_SHIFT\t\t7\n+#define FM10K_DGLORTDEC_PCLENGTH_SHIFT\t\t14\n+#define FM10K_DGLORTDEC_QBASE_SHIFT\t\t16\n+#define FM10K_DGLORTDEC_RSSLENGTH_SHIFT\t\t24\n+#define FM10K_DGLORTDEC_INNERRSS_ENABLE\t\t0x08000000\n+#define FM10K_TUNNEL_CFG\t0x0040\n+#define FM10K_TUNNEL_CFG_NVGRE_SHIFT\t\t16\n+#define FM10K_TUNNEL_CFG_GENEVE\t0x0041\n+#define FM10K_SWPRI_MAP(_n)\t((_n) + 0x0050)\n+#define FM10K_SWPRI_MAX\t\t16\n+#define FM10K_RSSRK(_n, _m)\t(((_n) * 0x10) + (_m) + 0x0800)\n+#define FM10K_RSSRK_SIZE\t10\n+#define FM10K_RSSRK_ENTRIES_PER_REG\t\t4\n+#define FM10K_RETA(_n, _m)\t(((_n) * 0x20) + (_m) + 0x1000)\n+#define FM10K_RETA_SIZE\t\t32\n+#define FM10K_RETA_ENTRIES_PER_REG\t\t4\n+#define FM10K_MAX_RSS_INDICES\t128\n+\n+/* Rate limiting registers */\n+#define FM10K_TC_CREDIT(_n)\t((_n) + 0x2000)\n+#define FM10K_TC_CREDIT_CREDIT_MASK\t\t0x001FFFFF\n+#define FM10K_TC_MAXCREDIT(_n)\t((_n) + 0x2040)\n+#define FM10K_TC_MAXCREDIT_64K\t\t\t0x00010000\n+#define FM10K_TC_RATE(_n)\t((_n) + 0x2080)\n+#define FM10K_TC_RATE_QUANTA_MASK\t\t0x0000FFFF\n+#define FM10K_TC_RATE_INTERVAL_4US_GEN1\t\t0x00020000\n+#define FM10K_TC_RATE_INTERVAL_4US_GEN2\t\t0x00040000\n+#define FM10K_TC_RATE_INTERVAL_4US_GEN3\t\t0x00080000\n+#define FM10K_TC_RATE_STATUS\t0x20C0\n+#define FM10K_PAUSE\t\t0x20C2\n+\n+/* DMA control registers */\n+#define FM10K_DMA_CTRL\t\t0x20C3\n+#define FM10K_DMA_CTRL_TX_ENABLE\t\t0x00000001\n+#define FM10K_DMA_CTRL_TX_HOST_PENDING\t\t0x00000002\n+#define FM10K_DMA_CTRL_TX_DATA\t\t\t0x00000004\n+#define FM10K_DMA_CTRL_TX_ACTIVE\t\t0x00000008\n+#define FM10K_DMA_CTRL_RX_ENABLE\t\t0x00000010\n+#define FM10K_DMA_CTRL_RX_HOST_PENDING\t\t0x00000020\n+#define FM10K_DMA_CTRL_RX_DATA\t\t\t0x00000040\n+#define FM10K_DMA_CTRL_RX_ACTIVE\t\t0x00000080\n+#define FM10K_DMA_CTRL_RX_DESC_SIZE\t\t0x00000100\n+#define FM10K_DMA_CTRL_MINMSS_SHIFT\t\t9\n+#define FM10K_DMA_CTRL_MINMSS_64\t\t0x00008000\n+#define FM10K_DMA_CTRL_MAX_HOLD_TIME_SHIFT\t23\n+#define FM10K_DMA_CTRL_MAX_HOLD_1US_GEN3\t0x04800000\n+#define FM10K_DMA_CTRL_MAX_HOLD_1US_GEN2\t0x04000000\n+#define FM10K_DMA_CTRL_MAX_HOLD_1US_GEN1\t0x03800000\n+#define FM10K_DMA_CTRL_DATAPATH_RESET\t\t0x20000000\n+#define FM10K_DMA_CTRL_MAXNUMOFQ_MASK\t\t0xC0000000\n+#define FM10K_DMA_CTRL_32_DESC\t\t\t0x00000000\n+#define FM10K_DMA_CTRL_64_DESC\t\t\t0x40000000\n+#define FM10K_DMA_CTRL_128_DESC\t\t\t0x80000000\n+\n+#define FM10K_DMA_CTRL2\t\t0x20C4\n+#define FM10K_DMA_CTRL2_TX_FRAME_SPACING_SHIFT\t5\n+#define FM10K_DMA_CTRL2_SWITCH_READY\t\t0x00002000\n+#define FM10K_DMA_CTRL2_RX_DESC_READ_PRIO_SHIFT\t14\n+#define FM10K_DMA_CTRL2_TX_DESC_READ_PRIO_SHIFT\t17\n+#define FM10K_DMA_CTRL2_TX_DATA_READ_PRIO_SHIFT\t20\n+\n+/* TSO flags configuration\n+ * First packet contains all flags except for fin and psh\n+ * Middle packet contains only urg and ack\n+ * Last packet contains urg, ack, fin, and psh\n+ */\n+#define FM10K_TSO_FLAGS_LOW\t\t0x00300FF6\n+#define FM10K_TSO_FLAGS_HI\t\t0x00000039\n+#define FM10K_DTXTCPFLGL\t0x20C5\n+#define FM10K_DTXTCPFLGH\t0x20C6\n+\n+#define FM10K_TPH_CTRL\t\t0x20C7\n+#define FM10K_TPH_CTRL_DISABLE_READ_HINT\t0x00000080\n+#define FM10K_MRQC(_n)\t\t((_n) + 0x2100)\n+#define FM10K_MRQC_TCP_IPV4\t\t\t0x00000001\n+#define FM10K_MRQC_IPV4\t\t\t\t0x00000002\n+#define FM10K_MRQC_IPV6\t\t\t\t0x00000010\n+#define FM10K_MRQC_TCP_IPV6\t\t\t0x00000020\n+#define FM10K_MRQC_UDP_IPV4\t\t\t0x00000040\n+#define FM10K_MRQC_UDP_IPV6\t\t\t0x00000080\n+\n+#define FM10K_TQMAP(_n)\t\t((_n) + 0x2800)\n+#define FM10K_TQMAP_TABLE_SIZE\t\t\t2048\n+#define FM10K_RQMAP(_n)\t\t((_n) + 0x3000)\n+#define FM10K_RQMAP_TABLE_SIZE\t\t\t2048\n+\n+/* Hardware Statistics */\n+#define FM10K_STATS_TIMEOUT\t\t0x3800\n+#define FM10K_STATS_UR\t\t\t0x3801\n+#define FM10K_STATS_CA\t\t\t0x3802\n+#define FM10K_STATS_UM\t\t\t0x3803\n+#define FM10K_STATS_XEC\t\t\t0x3804\n+#define FM10K_STATS_VLAN_DROP\t\t0x3805\n+#define FM10K_STATS_LOOPBACK_DROP\t0x3806\n+#define FM10K_STATS_NODESC_DROP\t\t0x3807\n+\n+/* Timesync registers */\n+#define FM10K_RRTIME_CFG\t0x3808\n+#define FM10K_RRTIME_LIMIT(_n)\t((_n) + 0x380C)\n+#define FM10K_RRTIME_COUNT(_n)\t((_n) + 0x3810)\n+#define FM10K_SYSTIME\t\t0x3814\n+#define FM10K_SYSTIME0\t\t0x3816\n+#define FM10K_SYSTIME_CFG\t0x3818\n+#define FM10K_SYSTIME_CFG_STEP_MASK\t\t0x0000000F\n+\n+/* PCIe state registers */\n+#define FM10K_PFVFBME(_n)\t((_n) + 0x381A)\n+#define FM10K_PHYADDR\t\t0x381C\n+\n+/* Rx ring registers */\n+#define FM10K_RDBAL(_n)\t\t((0x40 * (_n)) + 0x4000)\n+#define FM10K_RDBAH(_n)\t\t((0x40 * (_n)) + 0x4001)\n+#define FM10K_RDLEN(_n)\t\t((0x40 * (_n)) + 0x4002)\n+#define FM10K_TPH_RXCTRL(_n)\t((0x40 * (_n)) + 0x4003)\n+#define FM10K_TPH_RXCTRL_DESC_TPHEN\t\t0x00000020\n+#define FM10K_TPH_RXCTRL_HDR_TPHEN\t\t0x00000040\n+#define FM10K_TPH_RXCTRL_DATA_TPHEN\t\t0x00000080\n+#define FM10K_TPH_RXCTRL_DESC_RROEN\t\t0x00000200\n+#define FM10K_TPH_RXCTRL_DATA_WROEN\t\t0x00002000\n+#define FM10K_TPH_RXCTRL_HDR_WROEN\t\t0x00008000\n+#define FM10K_RDH(_n)\t\t((0x40 * (_n)) + 0x4004)\n+#define FM10K_RDT(_n)\t\t((0x40 * (_n)) + 0x4005)\n+#define FM10K_RXQCTL(_n)\t((0x40 * (_n)) + 0x4006)\n+#define FM10K_RXQCTL_ENABLE\t\t\t0x00000001\n+#define FM10K_RXQCTL_PF\t\t\t\t0x000000FC\n+#define FM10K_RXQCTL_VF_SHIFT\t\t\t2\n+#define FM10K_RXQCTL_VF\t\t\t\t0x00000100\n+#define FM10K_RXQCTL_ID_MASK\t(FM10K_RXQCTL_PF | FM10K_RXQCTL_VF)\n+#define FM10K_RXDCTL(_n)\t((0x40 * (_n)) + 0x4007)\n+#define FM10K_RXDCTL_WRITE_BACK_MIN_DELAY\t0x00000001\n+#define FM10K_RXDCTL_WRITE_BACK_IMM\t\t0x00000100\n+#define FM10K_RXDCTL_DROP_ON_EMPTY\t\t0x00000200\n+#define FM10K_RXINT(_n)\t\t((0x40 * (_n)) + 0x4008)\n+#define FM10K_RXINT_TIMER_SHIFT\t\t\t8\n+#define FM10K_SRRCTL(_n)\t((0x40 * (_n)) + 0x4009)\n+#define FM10K_SRRCTL_BSIZEPKT_SHIFT\t\t8 /* shift _right_ */\n+#define FM10K_SRRCTL_BSIZEHDR_SHIFT\t\t2 /* shift _left_ */\n+#define FM10K_SRRCTL_BSIZEHDR_MASK\t\t0x00003F00\n+#define FM10K_SRRCTL_DESCTYPE_HDR_SPLIT\t\t0x00004000\n+#define FM10K_SRRCTL_DESCTYPE_SIZE_SPLIT\t0x00008000\n+#define FM10K_SRRCTL_PSRTYPE_INNER_TCPHDR\t0x00010000\n+#define FM10K_SRRCTL_PSRTYPE_INNER_UDPHDR\t0x00020000\n+#define FM10K_SRRCTL_PSRTYPE_INNER_IPV4HDR\t0x00040000\n+#define FM10K_SRRCTL_PSRTYPE_INNER_IPV6HDR\t0x00080000\n+#define FM10K_SRRCTL_PSRTYPE_INNER_L2HDR\t0x00100000\n+#define FM10K_SRRCTL_PSRTYPE_ENCAPHDR\t\t0x00200000\n+#define FM10K_SRRCTL_PSRTYPE_TCPHDR\t\t0x00400000\n+#define FM10K_SRRCTL_PSRTYPE_UDPHDR\t\t0x00800000\n+#define FM10K_SRRCTL_PSRTYPE_IPV4HDR\t\t0x01000000\n+#define FM10K_SRRCTL_PSRTYPE_IPV6HDR\t\t0x02000000\n+#define FM10K_SRRCTL_PSRTYPE_L2HDR\t\t0x04000000\n+#define FM10K_SRRCTL_LOOPBACK_SUPPRESS\t\t0x40000000\n+#define FM10K_SRRCTL_BUFFER_CHAINING_EN\t\t0x80000000\n+\n+/* Rx Statistics */\n+#define FM10K_QPRC(_n)\t\t((0x40 * (_n)) + 0x400A)\n+#define FM10K_QPRDC(_n)\t\t((0x40 * (_n)) + 0x400B)\n+#define FM10K_QBRC_L(_n)\t((0x40 * (_n)) + 0x400C)\n+#define FM10K_QBRC_H(_n)\t((0x40 * (_n)) + 0x400D)\n+\n+/* Rx GLORT register */\n+#define FM10K_RX_SGLORT(_n)\t\t((0x40 * (_n)) + 0x400E)\n+\n+/* Tx ring registers */\n+#define FM10K_TDBAL(_n)\t\t((0x40 * (_n)) + 0x8000)\n+#define FM10K_TDBAH(_n)\t\t((0x40 * (_n)) + 0x8001)\n+#define FM10K_TDLEN(_n)\t\t((0x40 * (_n)) + 0x8002)\n+#define FM10K_TPH_TXCTRL(_n)\t((0x40 * (_n)) + 0x8003)\n+#define FM10K_TPH_TXCTRL_DESC_TPHEN\t\t0x00000020\n+#define FM10K_TPH_TXCTRL_DESC_RROEN\t\t0x00000200\n+#define FM10K_TPH_TXCTRL_DESC_WROEN\t\t0x00000800\n+#define FM10K_TPH_TXCTRL_DATA_RROEN\t\t0x00002000\n+#define FM10K_TDH(_n)\t\t((0x40 * (_n)) + 0x8004)\n+#define FM10K_TDT(_n)\t\t((0x40 * (_n)) + 0x8005)\n+#define FM10K_TXDCTL(_n)\t((0x40 * (_n)) + 0x8006)\n+#define FM10K_TXDCTL_ENABLE\t\t\t0x00004000\n+#define FM10K_TXDCTL_MAX_TIME_SHIFT\t\t16\n+#define FM10K_TXDCTL_PUSH_DESC\t\t\t0x10000000\n+#define FM10K_TXQCTL(_n)\t((0x40 * (_n)) + 0x8007)\n+#define FM10K_TXQCTL_PF\t\t\t\t0x0000003F\n+#define FM10K_TXQCTL_VF\t\t\t\t0x00000040\n+#define FM10K_TXQCTL_ID_MASK\t(FM10K_TXQCTL_PF | FM10K_TXQCTL_VF)\n+#define FM10K_TXQCTL_PC_SHIFT\t\t\t7\n+#define FM10K_TXQCTL_PC_MASK\t\t\t0x00000380\n+#define FM10K_TXQCTL_TC_SHIFT\t\t\t10\n+#define FM10K_TXQCTL_TC_MASK\t\t\t0x0000FC00\n+#define FM10K_TXQCTL_VID_SHIFT\t\t\t16\n+#define FM10K_TXQCTL_VID_MASK\t\t\t0x0FFF0000\n+#define FM10K_TXQCTL_UNLIMITED_BW\t\t0x10000000\n+#define FM10K_TXQCTL_PUSHMODEDIS\t\t0x20000000\n+#define FM10K_TXINT(_n)\t\t((0x40 * (_n)) + 0x8008)\n+#define FM10K_TXINT_TIMER_SHIFT\t\t\t8\n+\n+/* Tx Statistics */\n+#define FM10K_QPTC(_n)\t\t((0x40 * (_n)) + 0x8009)\n+#define FM10K_QBTC_L(_n)\t((0x40 * (_n)) + 0x800A)\n+#define FM10K_QBTC_H(_n)\t((0x40 * (_n)) + 0x800B)\n+\n+/* Tx Push registers */\n+#define FM10K_TQDLOC(_n)\t((0x40 * (_n)) + 0x800C)\n+#define FM10K_TQDLOC_BASE_32_DESC\t\t0x08\n+#define FM10K_TQDLOC_BASE_64_DESC\t\t0x10\n+#define FM10K_TQDLOC_BASE_128_DESC\t\t0x20\n+#define FM10K_TQDLOC_SIZE_32_DESC\t\t0x00050000\n+#define FM10K_TQDLOC_SIZE_64_DESC\t\t0x00060000\n+#define FM10K_TQDLOC_SIZE_128_DESC\t\t0x00070000\n+#define FM10K_TQDLOC_SIZE_SHIFT\t\t\t16\n+#define FM10K_TX_DCACHE(_n, _m)\t((0x400 * (_n)) + (0x4 * (_m)) + 0x40000)\n+\n+/* Tx GLORT registers */\n+#define FM10K_TX_SGLORT(_n)\t((0x40 * (_n)) + 0x800D)\n+#define FM10K_PFVTCTL(_n)\t((0x40 * (_n)) + 0x800E)\n+#define FM10K_PFVTCTL_FTAG_DESC_ENABLE\t\t0x00000001\n+\n+/* Interrupt moderation and control registers */\n+#define FM10K_PBACL(_n)\t\t((_n) + 0x10000)\n+#define FM10K_INT_MAP(_n)\t((_n) + 0x10080)\n+#define FM10K_INT_MAP_TIMER0\t\t\t0x00000000\n+#define FM10K_INT_MAP_TIMER1\t\t\t0x00000100\n+#define FM10K_INT_MAP_IMMEDIATE\t\t\t0x00000200\n+#define FM10K_INT_MAP_DISABLE\t\t\t0x00000300\n+#define FM10K_MSIX_VECTOR_ADDR_LO(_n)\t((0x4 * (_n)) + 0x11000)\n+#define FM10K_MSIX_VECTOR_ADDR_HI(_n)\t((0x4 * (_n)) + 0x11001)\n+#define FM10K_MSIX_VECTOR_DATA(_n)\t((0x4 * (_n)) + 0x11002)\n+#define FM10K_MSIX_VECTOR_MASK(_n)\t((0x4 * (_n)) + 0x11003)\n+#define FM10K_INT_CTRL\t\t0x12000\n+#define FM10K_INT_CTRL_ENABLEMODERATOR\t\t0x00000400\n+#define FM10K_ITR(_n)\t\t((_n) + 0x12400)\n+#define FM10K_ITR_INTERVAL1_SHIFT\t\t12\n+#define FM10K_ITR_TIMER0_EXPIRED\t\t0x01000000\n+#define FM10K_ITR_TIMER1_EXPIRED\t\t0x02000000\n+#define FM10K_ITR_PENDING0\t\t\t0x04000000\n+#define FM10K_ITR_PENDING1\t\t\t0x08000000\n+#define FM10K_ITR_PENDING2\t\t\t0x10000000\n+#define FM10K_ITR_AUTOMASK\t\t\t0x20000000\n+#define FM10K_ITR_MASK_SET\t\t\t0x40000000\n+#define FM10K_ITR_MASK_CLEAR\t\t\t0x80000000\n+#define FM10K_ITR2(_n)\t\t((0x2 * (_n)) + 0x12800)\n+#define FM10K_ITR2_LP(_n)\t((0x2 * (_n)) + 0x12801)\n+#define FM10K_ITR_REG_COUNT\t\t\t768\n+#define FM10K_ITR_REG_COUNT_PF\t\t\t256\n+\n+/* Switch manager interrupt registers */\n+#define FM10K_IP\t\t0x13000\n+#define FM10K_IP_HOT_RESET\t\t\t0x00000001\n+#define FM10K_IP_DEVICE_STATE_CHANGE\t\t0x00000002\n+#define FM10K_IP_MAILBOX\t\t\t0x00000004\n+#define FM10K_IP_VPD_REQUEST\t\t\t0x00000008\n+#define FM10K_IP_SRAMERROR\t\t\t0x00000010\n+#define FM10K_IP_PFLR\t\t\t\t0x00000020\n+#define FM10K_IP_DATAPATHRESET\t\t\t0x00000040\n+#define FM10K_IP_OUTOFRESET\t\t\t0x00000080\n+#define FM10K_IP_NOTINRESET\t\t\t0x00000100\n+#define FM10K_IP_TIMEOUT\t\t\t0x00000200\n+#define FM10K_IP_VFLR\t\t\t\t0x00000400\n+#define FM10K_IM\t\t0x13001\n+#define FM10K_IB\t\t0x13002\n+#define FM10K_SRAM_IP\t\t0x13003\n+#define FM10K_SRAM_IM\t\t0x13004\n+\n+/* VLAN registers */\n+#define FM10K_VLAN_TABLE(_n, _m)\t((0x80 * (_n)) + (_m) + 0x14000)\n+#define FM10K_VLAN_TABLE_SIZE\t\t\t128\n+\n+/* VLAN specific message offsets */\n+#define FM10K_VLAN_TABLE_VID_MAX\t\t4096\n+#define FM10K_VLAN_TABLE_VSI_MAX\t\t64\n+#define FM10K_VLAN_LENGTH_SHIFT\t\t\t16\n+#define FM10K_VLAN_CLEAR\t\t\t(1 << 15)\n+#define FM10K_VLAN_ALL \\\n+\t((FM10K_VLAN_TABLE_VID_MAX - 1) << FM10K_VLAN_LENGTH_SHIFT)\n+\n+/* VF FLR event notification registers */\n+#define FM10K_PFVFLRE(_n)\t((0x1 * (_n)) + 0x18844)\n+#define FM10K_PFVFLREC(_n)\t((0x1 * (_n)) + 0x18846)\n+\n+/* Defines for size of uncacheable and write-combining memories */\n+#define FM10K_UC_ADDR_START\t0x000000\t/* start of standard regs */\n+#define FM10K_WC_ADDR_START\t0x100000\t/* start of Tx Desc Cache */\n+#define FM10K_DBI_ADDR_START\t0x200000\t/* start of debug registers */\n+#define FM10K_UC_ADDR_SIZE\t(FM10K_WC_ADDR_START - FM10K_UC_ADDR_START)\n+#define FM10K_WC_ADDR_SIZE\t(FM10K_DBI_ADDR_START - FM10K_WC_ADDR_START)\n+\n+/* Define timeouts for resets and disables */\n+#define FM10K_QUEUE_DISABLE_TIMEOUT\t\t100\n+#define FM10K_RESET_TIMEOUT\t\t\t150\n+\n+/* Maximum supported combined inner and outer header length for encapsulation */\n+#define FM10K_TUNNEL_HEADER_LENGTH\t184\n+\n+/* VF registers */\n+#define FM10K_VFCTRL\t\t0x00000\n+#define FM10K_VFCTRL_RST\t\t\t0x00000008\n+#define FM10K_VFINT_MAP\t\t0x00030\n+#define FM10K_VFSYSTIME\t\t0x00040\n+#define FM10K_VFITR(_n)\t\t((_n) + 0x00060)\n+#define FM10K_VFPBACL(_n)\t((_n) + 0x00008)\n+\n+/* Registers contained in BAR 4 for Switch management */\n+#define FM10K_SW_SYSTIME_CFG\t0x0224C\n+#define FM10K_SW_SYSTIME_CFG_STEP_SHIFT\t\t4\n+#define FM10K_SW_SYSTIME_CFG_ADJUST_MASK\t0xFF000000\n+#define FM10K_SW_SYSTIME_ADJUST\t0x0224D\n+#define FM10K_SW_SYSTIME_ADJUST_MASK\t\t0x3FFFFFFF\n+#define FM10K_SW_SYSTIME_ADJUST_DIR_NEGATIVE\t0x80000000\n+#define FM10K_SW_SYSTIME_PULSE(_n)\t((_n) + 0x02252)\n+\n+#ifndef ETH_ALEN\n+#define ETH_ALEN\t6\n+#endif /* ETH_ALEN */\n+\n+\n+\n+\n+enum fm10k_int_source {\n+\tfm10k_int_Mailbox\t= 0,\n+\tfm10k_int_PCIeFault\t= 1,\n+\tfm10k_int_SwitchUpDown\t= 2,\n+\tfm10k_int_SwitchEvent\t= 3,\n+\tfm10k_int_SRAM\t\t= 4,\n+\tfm10k_int_VFLR\t\t= 5,\n+\tfm10k_int_MaxHoldTime\t= 6,\n+\tfm10k_int_sources_max_pf\n+};\n+\n+/* PCIe bus speeds */\n+enum fm10k_bus_speed {\n+\tfm10k_bus_speed_unknown\t= 0,\n+\tfm10k_bus_speed_2500\t= 2500,\n+\tfm10k_bus_speed_5000\t= 5000,\n+\tfm10k_bus_speed_8000\t= 8000,\n+\tfm10k_bus_speed_reserved\n+};\n+\n+/* PCIe bus widths */\n+enum fm10k_bus_width {\n+\tfm10k_bus_width_unknown\t= 0,\n+\tfm10k_bus_width_pcie_x1\t= 1,\n+\tfm10k_bus_width_pcie_x2\t= 2,\n+\tfm10k_bus_width_pcie_x4\t= 4,\n+\tfm10k_bus_width_pcie_x8\t= 8,\n+\tfm10k_bus_width_reserved\n+};\n+\n+/* PCIe payload sizes */\n+enum fm10k_bus_payload {\n+\tfm10k_bus_payload_unknown = 0,\n+\tfm10k_bus_payload_128\t  = 1,\n+\tfm10k_bus_payload_256\t  = 2,\n+\tfm10k_bus_payload_512\t  = 3,\n+\tfm10k_bus_payload_reserved\n+};\n+\n+/* Bus parameters */\n+struct fm10k_bus_info {\n+\tenum fm10k_bus_speed speed;\n+\tenum fm10k_bus_width width;\n+\tenum fm10k_bus_payload payload;\n+};\n+\n+/* Statistics related declarations */\n+struct fm10k_hw_stat {\n+\tu64 count;\n+\tu32 base_l;\n+\tu32 base_h;\n+};\n+\n+struct fm10k_hw_stats_q {\n+\tstruct fm10k_hw_stat tx_bytes;\n+\tstruct fm10k_hw_stat tx_packets;\n+#define tx_stats_idx\ttx_packets.base_h\n+\tstruct fm10k_hw_stat rx_bytes;\n+\tstruct fm10k_hw_stat rx_packets;\n+#define rx_stats_idx\trx_packets.base_h\n+\tstruct fm10k_hw_stat rx_drops;\n+};\n+\n+struct fm10k_hw_stats {\n+\tstruct fm10k_hw_stat\ttimeout;\n+#define stats_idx\ttimeout.base_h\n+\tstruct fm10k_hw_stat\tur;\n+\tstruct fm10k_hw_stat\tca;\n+\tstruct fm10k_hw_stat\tum;\n+\tstruct fm10k_hw_stat\txec;\n+\tstruct fm10k_hw_stat\tvlan_drop;\n+\tstruct fm10k_hw_stat\tloopback_drop;\n+\tstruct fm10k_hw_stat\tnodesc_drop;\n+\tstruct fm10k_hw_stats_q q[FM10K_MAX_QUEUES_PF];\n+};\n+\n+/* Establish DGLORT feature priority */\n+enum fm10k_dglortdec_idx {\n+\tfm10k_dglort_default\t= 0,\n+\tfm10k_dglort_vf_rsvd0\t= 1,\n+\tfm10k_dglort_vf_rss\t= 2,\n+\tfm10k_dglort_pf_rsvd0\t= 3,\n+\tfm10k_dglort_pf_queue\t= 4,\n+\tfm10k_dglort_pf_vsi\t= 5,\n+\tfm10k_dglort_pf_rsvd1\t= 6,\n+\tfm10k_dglort_pf_rss\t= 7\n+};\n+\n+struct fm10k_dglort_cfg {\n+\tu16 glort;\t/* GLORT base */\n+\tu16 queue_b;\t/* Base value for queue */\n+\tu8  vsi_b;\t/* Base value for VSI */\n+\tu8  idx;\t/* index of DGLORTDEC entry */\n+\tu8  rss_l;\t/* RSS indices */\n+\tu8  pc_l;\t/* Priority Class indices */\n+\tu8  vsi_l;\t/* Number of bits from GLORT used to determine VSI */\n+\tu8  queue_l;\t/* Number of bits from GLORT used to determine queue */\n+\tu8  shared_l;\t/* Ignored bits from GLORT resulting in shared VSI */\n+\tu8  inner_rss;\t/* Boolean value if inner header is used for RSS */\n+};\n+\n+enum fm10k_pca_fault {\n+\tPCA_NO_FAULT,\n+\tPCA_UNMAPPED_ADDR,\n+\tPCA_BAD_QACCESS_PF,\n+\tPCA_BAD_QACCESS_VF,\n+\tPCA_MALICIOUS_REQ,\n+\tPCA_POISONED_TLP,\n+\tPCA_TLP_ABORT,\n+\t__PCA_MAX\n+};\n+\n+enum fm10k_thi_fault {\n+\tTHI_NO_FAULT,\n+\tTHI_MAL_DIS_Q_FAULT,\n+\t__THI_MAX\n+};\n+\n+enum fm10k_fum_fault {\n+\tFUM_NO_FAULT,\n+\tFUM_UNMAPPED_ADDR,\n+\tFUM_POISONED_TLP,\n+\tFUM_BAD_VF_QACCESS,\n+\tFUM_ADD_DECODE_ERR,\n+\tFUM_RO_ERROR,\n+\tFUM_QPRC_CRC_ERROR,\n+\tFUM_CSR_TIMEOUT,\n+\tFUM_INVALID_TYPE,\n+\tFUM_INVALID_LENGTH,\n+\tFUM_INVALID_BE,\n+\tFUM_INVALID_ALIGN,\n+\t__FUM_MAX\n+};\n+\n+struct fm10k_fault {\n+\tu64 address;\t/* Address at the time fault was detected */\n+\tu32 specinfo;\t/* Extra info on this fault (fault dependent) */\n+\tu8 type;\t/* Fault value dependent on subunit */\n+\tu8 func;\t/* Function number of the fault */\n+};\n+\n+struct fm10k_mac_ops {\n+\t/* basic bring-up and tear-down */\n+\ts32 (*reset_hw)(struct fm10k_hw *);\n+\ts32 (*init_hw)(struct fm10k_hw *);\n+\ts32 (*start_hw)(struct fm10k_hw *);\n+\ts32 (*stop_hw)(struct fm10k_hw *);\n+\ts32 (*get_bus_info)(struct fm10k_hw *);\n+\ts32 (*get_host_state)(struct fm10k_hw *, bool *);\n+\tbool (*is_slot_appropriate)(struct fm10k_hw *);\n+\ts32 (*update_vlan)(struct fm10k_hw *, u32, u8, bool);\n+\ts32 (*read_mac_addr)(struct fm10k_hw *);\n+\ts32 (*update_uc_addr)(struct fm10k_hw *, u16, const u8 *,\n+\t\t\t      u16, bool, u8);\n+\ts32 (*update_mc_addr)(struct fm10k_hw *, u16, const u8 *, u16, bool);\n+\ts32 (*update_xcast_mode)(struct fm10k_hw *, u16, u8);\n+\tvoid (*update_int_moderator)(struct fm10k_hw *);\n+\ts32  (*update_lport_state)(struct fm10k_hw *, u16, u16, bool);\n+\tvoid (*update_hw_stats)(struct fm10k_hw *, struct fm10k_hw_stats *);\n+\tvoid (*rebind_hw_stats)(struct fm10k_hw *, struct fm10k_hw_stats *);\n+\ts32 (*configure_dglort_map)(struct fm10k_hw *,\n+\t\t\t\t    struct fm10k_dglort_cfg *);\n+\tvoid (*set_dma_mask)(struct fm10k_hw *, u64);\n+\ts32 (*get_fault)(struct fm10k_hw *, int, struct fm10k_fault *);\n+\tvoid (*request_lport_map)(struct fm10k_hw *);\n+\ts32 (*adjust_systime)(struct fm10k_hw *, s32 ppb);\n+\tu64 (*read_systime)(struct fm10k_hw *);\n+\ts32 (*request_tx_timestamp_mode)(struct fm10k_hw *, u16, u8);\n+};\n+\n+enum fm10k_mac_type {\n+\tfm10k_mac_unknown = 0,\n+\tfm10k_mac_pf,\n+\tfm10k_mac_vf,\n+\tfm10k_num_macs\n+};\n+\n+struct fm10k_mac_info {\n+\tstruct fm10k_mac_ops ops;\n+\tenum fm10k_mac_type type;\n+\tu8 addr[ETH_ALEN];\n+\tu8 perm_addr[ETH_ALEN];\n+\tu16 default_vid;\n+\tu16 max_msix_vectors;\n+\tu16 max_queues;\n+\tbool vlan_override;\n+\tbool get_host_state;\n+\tbool tx_ready;\n+\tu32 dglort_map;\n+};\n+\n+struct fm10k_swapi_table_info {\n+\tu32 used;\n+\tu32 avail;\n+};\n+\n+struct fm10k_swapi_info {\n+\tu32 status;\n+\tstruct fm10k_swapi_table_info mac;\n+\tstruct fm10k_swapi_table_info nexthop;\n+\tstruct fm10k_swapi_table_info ffu;\n+};\n+\n+enum fm10k_xcast_modes {\n+\tFM10K_XCAST_MODE_ALLMULTI\t= 0,\n+\tFM10K_XCAST_MODE_MULTI\t\t= 1,\n+\tFM10K_XCAST_MODE_PROMISC\t= 2,\n+\tFM10K_XCAST_MODE_NONE\t\t= 3,\n+\tFM10K_XCAST_MODE_DISABLE\t= 4\n+};\n+\n+enum fm10k_timestamp_modes {\n+\tFM10K_TIMESTAMP_MODE_NONE\t= 0,\n+\tFM10K_TIMESTAMP_MODE_PEP_TO_PEP\t= 1,\n+\tFM10K_TIMESTAMP_MODE_PEP_TO_ANY\t= 2,\n+};\n+\n+#define FM10K_VF_TC_MAX\t\t100000\t/* 100,000 Mb/s aka 100Gb/s */\n+#define FM10K_VF_TC_MIN\t\t1\t/* 1 Mb/s is the slowest rate */\n+\n+struct fm10k_vf_info {\n+\t/* mbx must be first field in struct unless all default IOV message\n+\t * handlers are redone as the assumption is that vf_info starts\n+\t * at the same offset as the mailbox\n+\t */\n+\tstruct fm10k_mbx_info\tmbx;\t\t/* PF side of VF mailbox */\n+\tint\t\t\trate;\t\t/* Tx BW cap as defined by OS */\n+\tu16\t\t\tglort;\t\t/* resource tag for this VF */\n+\tu16\t\t\tsw_vid;\t\t/* Switch API assigned VLAN */\n+\tu16\t\t\tpf_vid;\t\t/* PF assigned Default VLAN */\n+\tu8\t\t\tmac[ETH_ALEN];\t/* PF Default MAC address */\n+\tu8\t\t\tvsi;\t\t/* VSI identifier */\n+\tu8\t\t\tvf_idx;\t\t/* which VF this is */\n+\tu8\t\t\tvf_flags;\t/* flags indicating what modes\n+\t\t\t\t\t\t * are supported for the port\n+\t\t\t\t\t\t */\n+};\n+\n+#define FM10K_VF_FLAG_ALLMULTI_CAPABLE\t((u8)1 << FM10K_XCAST_MODE_ALLMULTI)\n+#define FM10K_VF_FLAG_MULTI_CAPABLE\t((u8)1 << FM10K_XCAST_MODE_MULTI)\n+#define FM10K_VF_FLAG_PROMISC_CAPABLE\t((u8)1 << FM10K_XCAST_MODE_PROMISC)\n+#define FM10K_VF_FLAG_NONE_CAPABLE\t((u8)1 << FM10K_XCAST_MODE_NONE)\n+#define FM10K_VF_FLAG_CAPABLE(vf_info)\t((vf_info)->vf_flags & (u8)0xF)\n+#define FM10K_VF_FLAG_ENABLED(vf_info)\t((vf_info)->vf_flags >> 4)\n+#define FM10K_VF_FLAG_SET_MODE(mode)\t((u8)0x10 << (mode))\n+#define FM10K_VF_FLAG_ENABLED_MODE_SHIFT\t4\n+#define FM10K_VF_FLAG_SET_MODE_MASK\t((u8)0xF0)\n+#define FM10K_VF_FLAG_SET_MODE_NONE \\\n+\tFM10K_VF_FLAG_SET_MODE(FM10K_XCAST_MODE_NONE)\n+#define FM10K_VF_FLAG_MULTI_ENABLED \\\n+\t(FM10K_VF_FLAG_SET_MODE(FM10K_XCAST_MODE_ALLMULTI) | \\\n+\t FM10K_VF_FLAG_SET_MODE(FM10K_XCAST_MODE_MULTI) | \\\n+\t FM10K_VF_FLAG_SET_MODE(FM10K_XCAST_MODE_PROMISC))\n+\n+struct fm10k_iov_ops {\n+\t/* IOV related bring-up and tear-down */\n+\ts32 (*assign_resources)(struct fm10k_hw *, u16, u16);\n+\ts32 (*configure_tc)(struct fm10k_hw *, u16, int);\n+\ts32 (*assign_int_moderator)(struct fm10k_hw *, u16);\n+\ts32 (*assign_default_mac_vlan)(struct fm10k_hw *,\n+\t\t\t\t       struct fm10k_vf_info *);\n+\ts32 (*reset_resources)(struct fm10k_hw *,\n+\t\t\t       struct fm10k_vf_info *);\n+\ts32 (*set_lport)(struct fm10k_hw *, struct fm10k_vf_info *, u16, u8);\n+\tvoid (*reset_lport)(struct fm10k_hw *, struct fm10k_vf_info *);\n+\tvoid (*update_stats)(struct fm10k_hw *, struct fm10k_hw_stats_q *, u16);\n+\ts32 (*report_timestamp)(struct fm10k_hw *, struct fm10k_vf_info *, u64);\n+};\n+\n+struct fm10k_iov_info {\n+\tstruct fm10k_iov_ops ops;\n+\tu16 total_vfs;\n+\tu16 num_vfs;\n+\tu16 num_pools;\n+};\n+\n+struct fm10k_hw {\n+\tu32 *hw_addr;\n+\tu32 *sw_addr;\n+\tvoid *back;\n+\tstruct fm10k_mac_info mac;\n+\tstruct fm10k_bus_info bus;\n+\tstruct fm10k_bus_info bus_caps;\n+\tstruct fm10k_iov_info iov;\n+\tstruct fm10k_mbx_info mbx;\n+\tstruct fm10k_swapi_info swapi;\n+\tu16 device_id;\n+\tu16 vendor_id;\n+\tu16 subsystem_device_id;\n+\tu16 subsystem_vendor_id;\n+\tu8 revision_id;\n+};\n+\n+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */\n+#define FM10K_REQ_TX_DESCRIPTOR_MULTIPLE\t8\n+#define FM10K_REQ_RX_DESCRIPTOR_MULTIPLE\t8\n+\n+/* Transmit Descriptor */\n+struct fm10k_tx_desc {\n+\t__le64 buffer_addr;\t/* Address of the descriptor's data buffer */\n+\t__le16 buflen;\t\t/* Length of data to be DMAed */\n+\t__le16 vlan;\t\t/* VLAN_ID and VPRI to be inserted in FTAG */\n+\t__le16 mss;\t\t/* MSS for segmentation offload */\n+\tu8 hdrlen;\t\t/* Header size for segmentation offload */\n+\tu8 flags;\t\t/* Status and offload request flags */\n+};\n+\n+/* Transmit Descriptor Cache Structure */\n+struct fm10k_tx_desc_cache {\n+\tstruct fm10k_tx_desc tx_desc[256];\n+};\n+\n+#define FM10K_TXD_FLAG_INT\t0x01\n+#define FM10K_TXD_FLAG_TIME\t0x02\n+#define FM10K_TXD_FLAG_CSUM\t0x04\n+#define FM10K_TXD_FLAG_CSUM2\t0x08\n+#define FM10K_TXD_FLAG_FTAG\t0x10\n+#define FM10K_TXD_FLAG_RS\t0x20\n+#define FM10K_TXD_FLAG_LAST\t0x40\n+#define FM10K_TXD_FLAG_DONE\t0x80\n+\n+#define FM10K_TXD_VLAN_PRI_SHIFT\t12\n+\n+/* These macros are meant to enable optimal placement of the RS and INT\n+ * bits.  It will point us to the last descriptor in the cache for either the\n+ * start of the packet, or the end of the packet.  If the index is actually\n+ * at the start of the FIFO it will point to the offset for the last index\n+ * in the FIFO to prevent an unnecessary write.\n+ */\n+#define FM10K_TXD_WB_FIFO_SIZE\t4\n+#define FM10K_TXD_WB_IDX(idx) \\\n+\t(((idx) - 1) | (FM10K_TXD_WB_FIFO_SIZE - 1))\n+\n+/* Receive Descriptor - 32B */\n+union fm10k_rx_desc {\n+\tstruct {\n+\t\t__le64 pkt_addr; /* Packet buffer address */\n+\t\t__le64 hdr_addr; /* Header buffer address */\n+\t\t__le64 reserved; /* Empty space, RSS hash */\n+\t\t__le64 timestamp;\n+\t} q; /* Read, Writeback, 64b quad-words */\n+\tstruct {\n+\t\t__le32 data; /* RSS and header data */\n+\t\t__le32 rss;  /* RSS Hash */\n+\t\t__le32 staterr;\n+\t\t__le32 vlan_len;\n+\t\t__le32 glort; /* sglort/dglort */\n+\t} d; /* Writeback, 32b double-words */\n+\tstruct {\n+\t\t__le16 pkt_info; /* RSS, Pkt type */\n+\t\t__le16 hdr_info; /* Splithdr, hdrlen, xC */\n+\t\t__le16 rss_lower;\n+\t\t__le16 rss_upper;\n+\t\t__le16 status; /* status/error */\n+\t\t__le16 csum_err; /* checksum or extended error value */\n+\t\t__le16 length; /* Packet length */\n+\t\t__le16 vlan; /* VLAN tag */\n+\t\t__le16 dglort;\n+\t\t__le16 sglort;\n+\t} w; /* Writeback, 16b words */\n+};\n+\n+#define FM10K_RXD_RSSTYPE_MASK\t\t0x000F\n+enum fm10k_rdesc_rss_type {\n+\tFM10K_RSSTYPE_NONE\t= 0x0,\n+\tFM10K_RSSTYPE_IPV4_TCP\t= 0x1,\n+\tFM10K_RSSTYPE_IPV4\t= 0x2,\n+\tFM10K_RSSTYPE_IPV6_TCP\t= 0x3,\n+\t/* Reserved 0x4 */\n+\tFM10K_RSSTYPE_IPV6\t= 0x5,\n+\t/* Reserved 0x6 */\n+\tFM10K_RSSTYPE_IPV4_UDP\t= 0x7,\n+\tFM10K_RSSTYPE_IPV6_UDP\t= 0x8\n+\t/* Reserved 0x9 - 0xF */\n+};\n+\n+#define FM10K_RXD_PKTTYPE_MASK\t\t0x03F0\n+#define FM10K_RXD_PKTTYPE_MASK_L3\t0x0070\n+#define FM10K_RXD_PKTTYPE_MASK_L4\t0x0380\n+#define FM10K_RXD_PKTTYPE_SHIFT\t\t4\n+#define FM10K_RXD_PKTTYPE_INNER_MASK_L3\t0x1C00\n+#define FM10K_RXD_PKTTYPE_INNER_MASK_L4\t0xE000\n+#define FM10K_RXD_PKTTYPE_INNER_SHIFT\t10\n+enum fm10k_rdesc_pkt_type {\n+\t/* L3 type */\n+\tFM10K_PKTTYPE_OTHER\t= 0x00,\n+\tFM10K_PKTTYPE_IPV4\t= 0x01,\n+\tFM10K_PKTTYPE_IPV4_EX\t= 0x02,\n+\tFM10K_PKTTYPE_IPV6\t= 0x03,\n+\tFM10K_PKTTYPE_IPV6_EX\t= 0x04,\n+\n+\t/* L4 type */\n+\tFM10K_PKTTYPE_TCP\t= 0x08,\n+\tFM10K_PKTTYPE_UDP\t= 0x10,\n+\tFM10K_PKTTYPE_GRE\t= 0x18,\n+\tFM10K_PKTTYPE_VXLAN\t= 0x20,\n+\tFM10K_PKTTYPE_NVGRE\t= 0x28,\n+\tFM10K_PKTTYPE_GENEVE\t= 0x30\n+};\n+\n+#define FM10K_RXD_HDR_INFO_XC_MASK\t0x0006\n+enum fm10k_rxdesc_xc {\n+\tFM10K_XC_UNICAST\t= 0x0,\n+\tFM10K_XC_MULTICAST\t= 0x4,\n+\tFM10K_XC_BROADCAST\t= 0x6\n+};\n+\n+#define FM10K_RXD_HDR_INFO_LEN_SHIFT\t5\n+#define FM10K_RXD_HDR_INFO_SPH\t\t0x8000\n+\n+#define FM10K_RXD_STATUS_DD\t\t0x0001 /* Descriptor done */\n+#define FM10K_RXD_STATUS_EOP\t\t0x0002 /* End of packet */\n+#define FM10K_RXD_STATUS_VEXT\t\t0x0004 /* A VLAN tag is present */\n+#define FM10K_RXD_STATUS_IPCS\t\t0x0008 /* Indicates IPv4 csum */\n+#define FM10K_RXD_STATUS_L4CS\t\t0x0010 /* Indicates an L4 csum */\n+#define FM10K_RXD_STATUS_IPCS2\t\t0x0020 /* Inner header IPv4 csum */\n+#define FM10K_RXD_STATUS_L4CS2\t\t0x0040 /* Inner header L4 csum */\n+#define FM10K_RXD_STATUS_IPFRAG_MASK\t0x0180 /* Fragment mask */\n+#define FM10K_RXD_STATUS_IPFRAG_CSUM\t0x0100 /* Fragment w/ CSUM field */\n+#define FM10K_RXD_STATUS_VEXT2\t\t0x0200 /* A custom tag is present */\n+#define FM10K_RXD_STATUS_HBO\t\t0x0400 /* header buffer overrun */\n+#define FM10K_RXD_STATUS_L4E2\t\t0x0800 /* Inner header L4 csum err */\n+#define FM10K_RXD_STATUS_IPE2\t\t0x1000 /* Inner header IPv4 csum err */\n+#define FM10K_RXD_STATUS_RXE\t\t0x2000 /* Generic Rx error */\n+#define FM10K_RXD_STATUS_L4E\t\t0x4000 /* L4 csum error */\n+#define FM10K_RXD_STATUS_IPE\t\t0x8000 /* IPv4 csum error */\n+\n+#define FM10K_RXD_ERR_SWITCH_ERROR\t0x0001 /* Switch found bad packet */\n+#define FM10K_RXD_ERR_NO_DESCRIPTOR\t0x0002 /* No descriptor available */\n+#define FM10K_RXD_ERR_PP_ERROR\t\t0x0004 /* RAM error during processing */\n+#define FM10K_RXD_ERR_SWITCH_READY\t0x0008 /* Link transition mid-packet */\n+#define FM10K_RXD_ERR_TOO_BIG\t\t0x0010 /* Pkt too big for single buf */\n+\n+#define FM10K_RXD_VLAN_ID_MASK\t\t0x0FFF\n+#define FM10K_RXD_VLAN_PRI_SHIFT\tFM10K_TXD_VLAN_PRI_SHIFT\n+\n+struct fm10k_ftag {\n+\t__be16 swpri_type_user;\n+\t__be16 vlan;\n+\t__be16 sglort;\n+\t__be16 dglort;\n+};\n+\n+#endif /* _FM10K_TYPE_H */\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_vf.c b/lib/librte_pmd_fm10k/base/fm10k_vf.c\nnew file mode 100644\nindex 0000000..2246688\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_vf.c\n@@ -0,0 +1,641 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#include \"fm10k_vf.h\"\n+\n+/**\n+ *  fm10k_stop_hw_vf - Stop Tx/Rx units\n+ *  @hw: pointer to hardware structure\n+ *\n+ **/\n+STATIC s32 fm10k_stop_hw_vf(struct fm10k_hw *hw)\n+{\n+\tu8 *perm_addr = hw->mac.perm_addr;\n+\tu32 bal = 0, bah = 0;\n+\ts32 err;\n+\tu16 i;\n+\n+\tDEBUGFUNC(\"fm10k_stop_hw_vf\");\n+\n+\t/* we need to disable the queues before taking further steps */\n+\terr = fm10k_stop_hw_generic(hw);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* If permanent address is set then we need to restore it */\n+\tif (FM10K_IS_VALID_ETHER_ADDR(perm_addr)) {\n+\t\tbal = (((u32)perm_addr[3]) << 24) |\n+\t\t      (((u32)perm_addr[4]) << 16) |\n+\t\t      (((u32)perm_addr[5]) << 8);\n+\t\tbah = (((u32)0xFF)\t   << 24) |\n+\t\t      (((u32)perm_addr[0]) << 16) |\n+\t\t      (((u32)perm_addr[1]) << 8) |\n+\t\t       ((u32)perm_addr[2]);\n+\t}\n+\n+\t/* The queues have already been disabled so we just need to\n+\t * update their base address registers\n+\t */\n+\tfor (i = 0; i < hw->mac.max_queues; i++) {\n+\t\tFM10K_WRITE_REG(hw, FM10K_TDBAL(i), bal);\n+\t\tFM10K_WRITE_REG(hw, FM10K_TDBAH(i), bah);\n+\t\tFM10K_WRITE_REG(hw, FM10K_RDBAL(i), bal);\n+\t\tFM10K_WRITE_REG(hw, FM10K_RDBAH(i), bah);\n+\t}\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_reset_hw_vf - VF hardware reset\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This function should return the hardware to a state similar to the\n+ *  one it is in after just being initialized.\n+ **/\n+STATIC s32 fm10k_reset_hw_vf(struct fm10k_hw *hw)\n+{\n+\ts32 err;\n+\n+\tDEBUGFUNC(\"fm10k_reset_hw_vf\");\n+\n+\t/* shut down queues we own and reset DMA configuration */\n+\terr = fm10k_stop_hw_vf(hw);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* Inititate VF reset */\n+\tFM10K_WRITE_REG(hw, FM10K_VFCTRL, FM10K_VFCTRL_RST);\n+\n+\t/* Flush write and allow 100us for reset to complete */\n+\tFM10K_WRITE_FLUSH(hw);\n+\tusec_delay(FM10K_RESET_TIMEOUT);\n+\n+\t/* Clear reset bit and verify it was cleared */\n+\tFM10K_WRITE_REG(hw, FM10K_VFCTRL, 0);\n+\tif (FM10K_READ_REG(hw, FM10K_VFCTRL) & FM10K_VFCTRL_RST)\n+\t\terr = FM10K_ERR_RESET_FAILED;\n+\n+\treturn err;\n+}\n+\n+/**\n+ *  fm10k_init_hw_vf - VF hardware initialization\n+ *  @hw: pointer to hardware structure\n+ *\n+ **/\n+STATIC s32 fm10k_init_hw_vf(struct fm10k_hw *hw)\n+{\n+\tu32 tqdloc, tqdloc0 = ~FM10K_READ_REG(hw, FM10K_TQDLOC(0));\n+\ts32 err;\n+\tu16 i;\n+\n+\tDEBUGFUNC(\"fm10k_init_hw_vf\");\n+\n+\t/* assume we always have at least 1 queue */\n+\tfor (i = 1; tqdloc0 && (i < FM10K_MAX_QUEUES_POOL); i++) {\n+\t\t/* verify the Descriptor cache offsets are increasing */\n+\t\ttqdloc = ~FM10K_READ_REG(hw, FM10K_TQDLOC(i));\n+\t\tif (!tqdloc || (tqdloc == tqdloc0))\n+\t\t\tbreak;\n+\n+\t\t/* check to verify the PF doesn't own any of our queues */\n+\t\tif (!~FM10K_READ_REG(hw, FM10K_TXQCTL(i)) ||\n+\t\t    !~FM10K_READ_REG(hw, FM10K_RXQCTL(i)))\n+\t\t\tbreak;\n+\t}\n+\n+\t/* shut down queues we own and reset DMA configuration */\n+\terr = fm10k_disable_queues_generic(hw, i);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* record maximum queue count */\n+\thw->mac.max_queues = i;\n+\n+\t/* fetch default VLAN */\n+\thw->mac.default_vid = (FM10K_READ_REG(hw, FM10K_TXQCTL(0)) &\n+\t\t\t       FM10K_TXQCTL_VID_MASK) >> FM10K_TXQCTL_VID_SHIFT;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_is_slot_appropriate_vf - Indicate appropriate slot for this SKU\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Looks at the PCIe bus info to confirm whether or not this slot can support\n+ *  the necessary bandwidth for this device. Since the VF has no control over\n+ *  the \"slot\" it is in, always indicate that the slot is appropriate.\n+ **/\n+STATIC bool fm10k_is_slot_appropriate_vf(struct fm10k_hw *hw)\n+{\n+\tUNREFERENCED_1PARAMETER(hw);\n+\tDEBUGFUNC(\"fm10k_is_slot_appropriate_vf\");\n+\n+\treturn TRUE;\n+}\n+\n+/* This structure defines the attibutes to be parsed below */\n+const struct fm10k_tlv_attr fm10k_mac_vlan_msg_attr[] = {\n+\tFM10K_TLV_ATTR_U32(FM10K_MAC_VLAN_MSG_VLAN),\n+\tFM10K_TLV_ATTR_BOOL(FM10K_MAC_VLAN_MSG_SET),\n+\tFM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MAC),\n+\tFM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_DEFAULT_MAC),\n+\tFM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MULTICAST),\n+\tFM10K_TLV_ATTR_LAST\n+};\n+\n+/**\n+ *  fm10k_update_vlan_vf - Update status of VLAN ID in VLAN filter table\n+ *  @hw: pointer to hardware structure\n+ *  @vid: VLAN ID to add to table\n+ *  @vsi: Reserved, should always be 0\n+ *  @set: Indicates if this is a set or clear operation\n+ *\n+ *  This function adds or removes the corresponding VLAN ID from the VLAN\n+ *  filter table for this VF.\n+ **/\n+STATIC s32 fm10k_update_vlan_vf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tu32 msg[4];\n+\n+\t/* verify the index is not set */\n+\tif (vsi)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* verify upper 4 bits of vid and length are 0 */\n+\tif ((vid << 16 | vid) >> 28)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* encode set bit into the VLAN ID */\n+\tif (!set)\n+\t\tvid |= FM10K_VLAN_CLEAR;\n+\n+\t/* generate VLAN request */\n+\tfm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);\n+\tfm10k_tlv_attr_put_u32(msg, FM10K_MAC_VLAN_MSG_VLAN, vid);\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+/**\n+ *  fm10k_msg_mac_vlan_vf - Read device MAC address from mailbox message\n+ *  @hw: pointer to the HW structure\n+ *  @results: Attributes for message\n+ *  @mbx: unused mailbox data\n+ *\n+ *  This function should determine the MAC address for the VF\n+ **/\n+s32 fm10k_msg_mac_vlan_vf(struct fm10k_hw *hw, u32 **results,\n+\t\t\t  struct fm10k_mbx_info *mbx)\n+{\n+\tu8 perm_addr[ETH_ALEN];\n+\tu16 vid;\n+\ts32 err;\n+\n+\tUNREFERENCED_1PARAMETER(mbx);\n+\tDEBUGFUNC(\"fm10k_msg_mac_vlan_vf\");\n+\n+\t/* record MAC address requested */\n+\terr = fm10k_tlv_attr_get_mac_vlan(\n+\t\t\t\t\tresults[FM10K_MAC_VLAN_MSG_DEFAULT_MAC],\n+\t\t\t\t\tperm_addr, &vid);\n+\tif (err)\n+\t\treturn err;\n+\n+\tmemcpy(hw->mac.perm_addr, perm_addr, ETH_ALEN);\n+\thw->mac.default_vid = vid & (FM10K_VLAN_TABLE_VID_MAX - 1);\n+\thw->mac.vlan_override = !!(vid & FM10K_VLAN_CLEAR);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_read_mac_addr_vf - Read device MAC address\n+ *  @hw: pointer to the HW structure\n+ *\n+ *  This function should determine the MAC address for the VF\n+ **/\n+STATIC s32 fm10k_read_mac_addr_vf(struct fm10k_hw *hw)\n+{\n+\tu8 perm_addr[ETH_ALEN];\n+\tu32 base_addr;\n+\n+\tDEBUGFUNC(\"fm10k_read_mac_addr_vf\");\n+\n+\tbase_addr = FM10K_READ_REG(hw, FM10K_TDBAL(0));\n+\n+\t/* last byte should be 0 */\n+\tif (base_addr << 24)\n+\t\treturn  FM10K_ERR_INVALID_MAC_ADDR;\n+\n+\tperm_addr[3] = (u8)(base_addr >> 24);\n+\tperm_addr[4] = (u8)(base_addr >> 16);\n+\tperm_addr[5] = (u8)(base_addr >> 8);\n+\n+\tbase_addr = FM10K_READ_REG(hw, FM10K_TDBAH(0));\n+\n+\t/* first byte should be all 1's */\n+\tif ((~base_addr) >> 24)\n+\t\treturn  FM10K_ERR_INVALID_MAC_ADDR;\n+\n+\tperm_addr[0] = (u8)(base_addr >> 16);\n+\tperm_addr[1] = (u8)(base_addr >> 8);\n+\tperm_addr[2] = (u8)(base_addr);\n+\n+\tmemcpy(hw->mac.perm_addr, perm_addr, ETH_ALEN);\n+\tmemcpy(hw->mac.addr, perm_addr, ETH_ALEN);\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_update_uc_addr_vf - Update device unicast addresses\n+ *  @hw: pointer to the HW structure\n+ *  @glort: unused\n+ *  @mac: MAC address to add/remove from table\n+ *  @vid: VLAN ID to add/remove from table\n+ *  @add: Indicates if this is an add or remove operation\n+ *  @flags: flags field to indicate add and secure - unused\n+ *\n+ *  This function is used to add or remove unicast MAC addresses for\n+ *  the VF.\n+ **/\n+STATIC s32 fm10k_update_uc_addr_vf(struct fm10k_hw *hw, u16 glort,\n+\t\t\t\t   const u8 *mac, u16 vid, bool add, u8 flags)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tu32 msg[7];\n+\n+\tDEBUGFUNC(\"fm10k_update_uc_addr_vf\");\n+\n+\tUNREFERENCED_2PARAMETER(glort, flags);\n+\n+\t/* verify VLAN ID is valid */\n+\tif (vid >= FM10K_VLAN_TABLE_VID_MAX)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* verify MAC address is valid */\n+\tif (!FM10K_IS_VALID_ETHER_ADDR(mac))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* verify we are not locked down on the MAC address */\n+\tif (FM10K_IS_VALID_ETHER_ADDR(hw->mac.perm_addr) &&\n+\t    memcmp(hw->mac.perm_addr, mac, ETH_ALEN))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* add bit to notify us if this is a set or clear operation */\n+\tif (!add)\n+\t\tvid |= FM10K_VLAN_CLEAR;\n+\n+\t/* generate VLAN request */\n+\tfm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);\n+\tfm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MAC, mac, vid);\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+/**\n+ *  fm10k_update_mc_addr_vf - Update device multicast addresses\n+ *  @hw: pointer to the HW structure\n+ *  @glort: unused\n+ *  @mac: MAC address to add/remove from table\n+ *  @vid: VLAN ID to add/remove from table\n+ *  @add: Indicates if this is an add or remove operation\n+ *\n+ *  This function is used to add or remove multicast MAC addresses for\n+ *  the VF.\n+ **/\n+STATIC s32 fm10k_update_mc_addr_vf(struct fm10k_hw *hw, u16 glort,\n+\t\t\t\t   const u8 *mac, u16 vid, bool add)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tu32 msg[7];\n+\n+\tDEBUGFUNC(\"fm10k_update_uc_addr_vf\");\n+\n+\tUNREFERENCED_1PARAMETER(glort);\n+\n+\t/* verify VLAN ID is valid */\n+\tif (vid >= FM10K_VLAN_TABLE_VID_MAX)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* verify multicast address is valid */\n+\tif (!FM10K_IS_MULTICAST_ETHER_ADDR(mac))\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* add bit to notify us if this is a set or clear operation */\n+\tif (!add)\n+\t\tvid |= FM10K_VLAN_CLEAR;\n+\n+\t/* generate VLAN request */\n+\tfm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);\n+\tfm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MULTICAST,\n+\t\t\t\t    mac, vid);\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+/**\n+ *  fm10k_update_int_moderator_vf - Request update of interrupt moderator list\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This function will issue a request to the PF to rescan our MSI-X table\n+ *  and to update the interrupt moderator linked list.\n+ **/\n+STATIC void fm10k_update_int_moderator_vf(struct fm10k_hw *hw)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tu32 msg[1];\n+\n+\t/* generate MSI-X request */\n+\tfm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MSIX);\n+\n+\t/* load onto outgoing mailbox */\n+\tmbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+/* This structure defines the attibutes to be parsed below */\n+const struct fm10k_tlv_attr fm10k_lport_state_msg_attr[] = {\n+\tFM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_DISABLE),\n+\tFM10K_TLV_ATTR_U8(FM10K_LPORT_STATE_MSG_XCAST_MODE),\n+\tFM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_READY),\n+\tFM10K_TLV_ATTR_LAST\n+};\n+\n+/**\n+ *  fm10k_msg_lport_state_vf - Message handler for lport_state message from PF\n+ *  @hw: Pointer to hardware structure\n+ *  @results: pointer array containing parsed data\n+ *  @mbx: Pointer to mailbox information structure\n+ *\n+ *  This handler is meant to capture the indication from the PF that we\n+ *  are ready to bring up the interface.\n+ **/\n+s32 fm10k_msg_lport_state_vf(struct fm10k_hw *hw, u32 **results,\n+\t\t\t     struct fm10k_mbx_info *mbx)\n+{\n+\tUNREFERENCED_1PARAMETER(mbx);\n+\tDEBUGFUNC(\"fm10k_msg_lport_state_vf\");\n+\n+\thw->mac.dglort_map = !results[FM10K_LPORT_STATE_MSG_READY] ?\n+\t\t\t     FM10K_DGLORTMAP_NONE : FM10K_DGLORTMAP_ZERO;\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_update_lport_state_vf - Update device state in lower device\n+ *  @hw: pointer to the HW structure\n+ *  @glort: unused\n+ *  @count: number of logical ports to enable - unused (always 1)\n+ *  @enable: boolean value indicating if this is an enable or disable request\n+ *\n+ *  Notify the lower device of a state change.  If the lower device is\n+ *  enabled we can add filters, if it is disabled all filters for this\n+ *  logical port are flushed.\n+ **/\n+STATIC s32 fm10k_update_lport_state_vf(struct fm10k_hw *hw, u16 glort,\n+\t\t\t\t       u16 count, bool enable)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tu32 msg[2];\n+\n+\tUNREFERENCED_2PARAMETER(glort, count);\n+\tDEBUGFUNC(\"fm10k_update_lport_state_vf\");\n+\n+\t/* reset glort mask 0 as we have to wait to be enabled */\n+\thw->mac.dglort_map = FM10K_DGLORTMAP_NONE;\n+\n+\t/* generate port state request */\n+\tfm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);\n+\tif (!enable)\n+\t\tfm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_DISABLE);\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+/**\n+ *  fm10k_update_xcast_mode_vf - Request update of multicast mode\n+ *  @hw: pointer to hardware structure\n+ *  @glort: unused\n+ *  @mode: integer value indicating mode being requested\n+ *\n+ *  This function will attempt to request a higher mode for the port\n+ *  so that it can enable either multicast, multicast promiscuous, or\n+ *  promiscuous mode of operation.\n+ **/\n+STATIC s32 fm10k_update_xcast_mode_vf(struct fm10k_hw *hw, u16 glort, u8 mode)\n+{\n+\tstruct fm10k_mbx_info *mbx = &hw->mbx;\n+\tu32 msg[3];\n+\n+\tUNREFERENCED_1PARAMETER(glort);\n+\tDEBUGFUNC(\"fm10k_update_xcast_mode_vf\");\n+\n+\tif (mode > FM10K_XCAST_MODE_NONE)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* generate message requesting to change xcast mode */\n+\tfm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);\n+\tfm10k_tlv_attr_put_u8(msg, FM10K_LPORT_STATE_MSG_XCAST_MODE, mode);\n+\n+\t/* load onto outgoing mailbox */\n+\treturn mbx->ops.enqueue_tx(hw, mbx, msg);\n+}\n+\n+const struct fm10k_tlv_attr fm10k_1588_msg_attr[] = {\n+\tFM10K_TLV_ATTR_U64(FM10K_1588_MSG_TIMESTAMP),\n+\tFM10K_TLV_ATTR_LAST\n+};\n+\n+/* currently there is no shared 1588 timestamp handler */\n+\n+/**\n+ *  fm10k_update_hw_stats_vf - Updates hardware related statistics of VF\n+ *  @hw: pointer to hardware structure\n+ *  @stats: pointer to statistics structure\n+ *\n+ *  This function collects and aggregates per queue hardware statistics.\n+ **/\n+STATIC void fm10k_update_hw_stats_vf(struct fm10k_hw *hw,\n+\t\t\t\t     struct fm10k_hw_stats *stats)\n+{\n+\tDEBUGFUNC(\"fm10k_update_hw_stats_vf\");\n+\n+\tfm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);\n+}\n+\n+/**\n+ *  fm10k_rebind_hw_stats_vf - Resets base for hardware statistics of VF\n+ *  @hw: pointer to hardware structure\n+ *  @stats: pointer to the stats structure to update\n+ *\n+ *  This function resets the base for queue hardware statistics.\n+ **/\n+STATIC void fm10k_rebind_hw_stats_vf(struct fm10k_hw *hw,\n+\t\t\t\t     struct fm10k_hw_stats *stats)\n+{\n+\tDEBUGFUNC(\"fm10k_rebind_hw_stats_vf\");\n+\n+\t/* Unbind Queue Statistics */\n+\tfm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);\n+\n+\t/* Reinitialize bases for all stats */\n+\tfm10k_update_hw_stats_vf(hw, stats);\n+}\n+\n+/**\n+ *  fm10k_configure_dglort_map_vf - Configures GLORT entry and queues\n+ *  @hw: pointer to hardware structure\n+ *  @dglort: pointer to dglort configuration structure\n+ *\n+ *  Reads the configuration structure contained in dglort_cfg and uses\n+ *  that information to then populate a DGLORTMAP/DEC entry and the queues\n+ *  to which it has been assigned.\n+ **/\n+STATIC s32 fm10k_configure_dglort_map_vf(struct fm10k_hw *hw,\n+\t\t\t\t\t struct fm10k_dglort_cfg *dglort)\n+{\n+\tUNREFERENCED_1PARAMETER(hw);\n+\tDEBUGFUNC(\"fm10k_configure_dglort_map_vf\");\n+\n+\t/* verify the dglort pointer */\n+\tif (!dglort)\n+\t\treturn FM10K_ERR_PARAM;\n+\n+\t/* stub for now until we determine correct message for this */\n+\n+\treturn FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_adjust_systime_vf - Adjust systime frequency\n+ *  @hw: pointer to hardware structure\n+ *  @ppb: adjustment rate in parts per billion\n+ *\n+ *  This function takes an adjustment rate in parts per billion and will\n+ *  verify that this value is 0 as the VF cannot support adjusting the\n+ *  systime clock.\n+ *\n+ *  If the ppb value is non-zero the return is ERR_PARAM else success\n+ **/\n+STATIC s32 fm10k_adjust_systime_vf(struct fm10k_hw *hw, s32 ppb)\n+{\n+\tUNREFERENCED_1PARAMETER(hw);\n+\tDEBUGFUNC(\"fm10k_adjust_systime_vf\");\n+\n+\t/* The VF cannot adjust the clock frequency, however it should\n+\t * already have a syntonic clock with whichever host interface is\n+\t * running as the master for the host interface clock domain so\n+\t * there should be not frequency adjustment necessary.\n+\t */\n+\treturn ppb ? FM10K_ERR_PARAM : FM10K_SUCCESS;\n+}\n+\n+/**\n+ *  fm10k_read_systime_vf - Reads value of systime registers\n+ *  @hw: pointer to the hardware structure\n+ *\n+ *  Function reads the content of 2 registers, combined to represent a 64 bit\n+ *  value measured in nanoseconds.  In order to guarantee the value is accurate\n+ *  we check the 32 most significant bits both before and after reading the\n+ *  32 least significant bits to verify they didn't change as we were reading\n+ *  the registers.\n+ **/\n+static u64 fm10k_read_systime_vf(struct fm10k_hw *hw)\n+{\n+\tu32 systime_l, systime_h, systime_tmp;\n+\n+\tsystime_h = fm10k_read_reg(hw, FM10K_VFSYSTIME + 1);\n+\n+\tdo {\n+\t\tsystime_tmp = systime_h;\n+\t\tsystime_l = fm10k_read_reg(hw, FM10K_VFSYSTIME);\n+\t\tsystime_h = fm10k_read_reg(hw, FM10K_VFSYSTIME + 1);\n+\t} while (systime_tmp != systime_h);\n+\n+\treturn ((u64)systime_h << 32) | systime_l;\n+}\n+\n+static const struct fm10k_msg_data fm10k_msg_data_vf[] = {\n+\tFM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),\n+\tFM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_msg_mac_vlan_vf),\n+\tFM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),\n+\tFM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),\n+};\n+\n+/**\n+ *  fm10k_init_ops_vf - Inits func ptrs and MAC type\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Initialize the function pointers and assign the MAC type for VF.\n+ *  Does not touch the hardware.\n+ **/\n+s32 fm10k_init_ops_vf(struct fm10k_hw *hw)\n+{\n+\tstruct fm10k_mac_info *mac = &hw->mac;\n+\n+\tDEBUGFUNC(\"fm10k_init_ops_vf\");\n+\n+\tfm10k_init_ops_generic(hw);\n+\n+\tmac->ops.reset_hw = &fm10k_reset_hw_vf;\n+\tmac->ops.init_hw = &fm10k_init_hw_vf;\n+\tmac->ops.start_hw = &fm10k_start_hw_generic;\n+\tmac->ops.stop_hw = &fm10k_stop_hw_vf;\n+\tmac->ops.is_slot_appropriate = &fm10k_is_slot_appropriate_vf;\n+\tmac->ops.update_vlan = &fm10k_update_vlan_vf;\n+\tmac->ops.read_mac_addr = &fm10k_read_mac_addr_vf;\n+\tmac->ops.update_uc_addr = &fm10k_update_uc_addr_vf;\n+\tmac->ops.update_mc_addr = &fm10k_update_mc_addr_vf;\n+\tmac->ops.update_xcast_mode = &fm10k_update_xcast_mode_vf;\n+\tmac->ops.update_int_moderator = &fm10k_update_int_moderator_vf;\n+\tmac->ops.update_lport_state = &fm10k_update_lport_state_vf;\n+\tmac->ops.update_hw_stats = &fm10k_update_hw_stats_vf;\n+\tmac->ops.rebind_hw_stats = &fm10k_rebind_hw_stats_vf;\n+\tmac->ops.configure_dglort_map = &fm10k_configure_dglort_map_vf;\n+\tmac->ops.get_host_state = &fm10k_get_host_state_generic;\n+\tmac->ops.adjust_systime = &fm10k_adjust_systime_vf;\n+\tmac->ops.read_systime = &fm10k_read_systime_vf,\n+\n+\tmac->max_msix_vectors = fm10k_get_pcie_msix_count_generic(hw);\n+\n+\treturn fm10k_pfvf_mbx_init(hw, &hw->mbx, fm10k_msg_data_vf, 0);\n+}\ndiff --git a/lib/librte_pmd_fm10k/base/fm10k_vf.h b/lib/librte_pmd_fm10k/base/fm10k_vf.h\nnew file mode 100644\nindex 0000000..0438542\n--- /dev/null\n+++ b/lib/librte_pmd_fm10k/base/fm10k_vf.h\n@@ -0,0 +1,91 @@\n+/*******************************************************************************\n+\n+Copyright (c) 2013 - 2015, Intel Corporation\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+\n+ 2. Redistributions in binary form must reproduce the above copyright\n+    notice, this list of conditions and the following disclaimer in the\n+    documentation and/or other materials provided with the distribution.\n+\n+ 3. Neither the name of the Intel Corporation nor the names of its\n+    contributors may be used to endorse or promote products derived from\n+    this software without specific prior written permission.\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, THE\n+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+POSSIBILITY OF SUCH DAMAGE.\n+\n+***************************************************************************/\n+\n+#ifndef _FM10K_VF_H_\n+#define _FM10K_VF_H_\n+\n+#include \"fm10k_type.h\"\n+#include \"fm10k_common.h\"\n+\n+enum fm10k_vf_tlv_msg_id {\n+\tFM10K_VF_MSG_ID_TEST = 0,\t/* msg ID reserved for testing */\n+\tFM10K_VF_MSG_ID_MSIX,\n+\tFM10K_VF_MSG_ID_MAC_VLAN,\n+\tFM10K_VF_MSG_ID_LPORT_STATE,\n+\tFM10K_VF_MSG_ID_1588,\n+\tFM10K_VF_MSG_ID_MAX,\n+};\n+\n+enum fm10k_tlv_mac_vlan_attr_id {\n+\tFM10K_MAC_VLAN_MSG_VLAN,\n+\tFM10K_MAC_VLAN_MSG_SET,\n+\tFM10K_MAC_VLAN_MSG_MAC,\n+\tFM10K_MAC_VLAN_MSG_DEFAULT_MAC,\n+\tFM10K_MAC_VLAN_MSG_MULTICAST,\n+\tFM10K_MAC_VLAN_MSG_ID_MAX\n+};\n+\n+enum fm10k_tlv_lport_state_attr_id {\n+\tFM10K_LPORT_STATE_MSG_DISABLE,\n+\tFM10K_LPORT_STATE_MSG_XCAST_MODE,\n+\tFM10K_LPORT_STATE_MSG_READY,\n+\tFM10K_LPORT_STATE_MSG_MAX\n+};\n+\n+enum fm10k_tlv_1588_attr_id {\n+\tFM10K_1588_MSG_TIMESTAMP,\n+\tFM10K_1588_MSG_MAX\n+};\n+\n+#define FM10K_VF_MSG_MSIX_HANDLER(func) \\\n+\t FM10K_MSG_HANDLER(FM10K_VF_MSG_ID_MSIX, NULL, func)\n+\n+s32 fm10k_msg_mac_vlan_vf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);\n+extern const struct fm10k_tlv_attr fm10k_mac_vlan_msg_attr[];\n+#define FM10K_VF_MSG_MAC_VLAN_HANDLER(func) \\\n+\tFM10K_MSG_HANDLER(FM10K_VF_MSG_ID_MAC_VLAN, \\\n+\t\t\t  fm10k_mac_vlan_msg_attr, func)\n+\n+s32 fm10k_msg_lport_state_vf(struct fm10k_hw *, u32 **,\n+\t\t\t     struct fm10k_mbx_info *);\n+extern const struct fm10k_tlv_attr fm10k_lport_state_msg_attr[];\n+#define FM10K_VF_MSG_LPORT_STATE_HANDLER(func) \\\n+\tFM10K_MSG_HANDLER(FM10K_VF_MSG_ID_LPORT_STATE, \\\n+\t\t\t  fm10k_lport_state_msg_attr, func)\n+\n+extern const struct fm10k_tlv_attr fm10k_1588_msg_attr[];\n+#define FM10K_VF_MSG_1588_HANDLER(func) \\\n+\tFM10K_MSG_HANDLER(FM10K_VF_MSG_ID_1588, fm10k_1588_msg_attr, func)\n+\n+s32 fm10k_init_ops_vf(struct fm10k_hw *hw);\n+#endif /* _FM10K_VF_H */\n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "01/15"
    ]
}