get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 982287,
    "url": "http://patchwork.ozlabs.org/api/patches/982287/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20181011071713.1667-1-sasha.neftin@intel.com/",
    "project": {
        "id": 46,
        "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api",
        "name": "Intel Wired Ethernet development",
        "link_name": "intel-wired-lan",
        "list_id": "intel-wired-lan.osuosl.org",
        "list_email": "intel-wired-lan@osuosl.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20181011071713.1667-1-sasha.neftin@intel.com>",
    "list_archive_url": null,
    "date": "2018-10-11T07:17:13",
    "name": "[v8,03/11] igc: Add netdev",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "e02d7ddd815d189a97c46e9d9a7af561010b29c3",
    "submitter": {
        "id": 69860,
        "url": "http://patchwork.ozlabs.org/api/people/69860/?format=api",
        "name": "Sasha Neftin",
        "email": "sasha.neftin@intel.com"
    },
    "delegate": {
        "id": 68,
        "url": "http://patchwork.ozlabs.org/api/users/68/?format=api",
        "username": "jtkirshe",
        "first_name": "Jeff",
        "last_name": "Kirsher",
        "email": "jeffrey.t.kirsher@intel.com"
    },
    "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20181011071713.1667-1-sasha.neftin@intel.com/mbox/",
    "series": [
        {
            "id": 70170,
            "url": "http://patchwork.ozlabs.org/api/series/70170/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=70170",
            "date": "2018-10-11T07:17:13",
            "name": "[v8,01/11] igc: Add skeletal frame for Intel(R) 2.5G Ethernet Controller support.",
            "version": 8,
            "mbox": "http://patchwork.ozlabs.org/series/70170/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/982287/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/982287/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<intel-wired-lan-bounces@osuosl.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "intel-wired-lan@lists.osuosl.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "intel-wired-lan@lists.osuosl.org"
        ],
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.138; helo=whitealder.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)",
            "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=intel.com"
        ],
        "Received": [
            "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 42W2NT2kWCz9s8F\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 11 Oct 2018 18:17:28 +1100 (AEDT)",
            "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 194A687298;\n\tThu, 11 Oct 2018 07:17:27 +0000 (UTC)",
            "from whitealder.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id Py3WbBu+ps7B; Thu, 11 Oct 2018 07:17:22 +0000 (UTC)",
            "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id DD4D887080;\n\tThu, 11 Oct 2018 07:17:22 +0000 (UTC)",
            "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\tby ash.osuosl.org (Postfix) with ESMTP id 32C761C1507\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 11 Oct 2018 07:17:21 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 2F45A85BDF\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 11 Oct 2018 07:17:21 +0000 (UTC)",
            "from fraxinus.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id mIVHWf_snEVJ for <intel-wired-lan@lists.osuosl.org>;\n\tThu, 11 Oct 2018 07:17:19 +0000 (UTC)",
            "from mga01.intel.com (mga01.intel.com [192.55.52.88])\n\tby fraxinus.osuosl.org (Postfix) with ESMTPS id BBA1385773\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 11 Oct 2018 07:17:19 +0000 (UTC)",
            "from orsmga005.jf.intel.com ([10.7.209.41])\n\tby fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t11 Oct 2018 00:17:19 -0700",
            "from ccdlinuxdev08.iil.intel.com ([143.185.161.150])\n\tby orsmga005.jf.intel.com with ESMTP; 11 Oct 2018 00:17:13 -0700"
        ],
        "X-Virus-Scanned": [
            "amavisd-new at osuosl.org",
            "amavisd-new at osuosl.org"
        ],
        "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6",
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.54,367,1534834800\"; d=\"scan'208\";a=\"264752357\"",
        "From": "Sasha Neftin <sasha.neftin@intel.com>",
        "To": "sasha.neftin@intel.com,\n\tintel-wired-lan@lists.osuosl.org",
        "Date": "Thu, 11 Oct 2018 10:17:13 +0300",
        "Message-Id": "<20181011071713.1667-1-sasha.neftin@intel.com>",
        "X-Mailer": "git-send-email 2.11.0",
        "Subject": "[Intel-wired-lan] [PATCH v8 03/11] igc: Add netdev",
        "X-BeenThere": "intel-wired-lan@osuosl.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>",
        "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>",
        "List-Post": "<mailto:intel-wired-lan@osuosl.org>",
        "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>",
        "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "intel-wired-lan-bounces@osuosl.org",
        "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>"
    },
    "content": "Now that we have the ability to configure the basic settings on the device\nwe can start allocating and configuring a netdev for the interface.\n\nSasha Neftin (v2):\nadd description\n\nSasha Neftin (v3):\nminor cosmetic changes\n\nSasha Neftin (v4):\naddress comments\nfix code indentation\nreplace e1000_ prefix with igc_ prefix\noptimize pcie access\n\nSasha Neftin (v5):\nchange return value of igc_up() method to void\n\nSasha Neftin (v6):\nfix define of MAX_Q_VECTORS\nfix code indentation\nminor cosmetic changes\n\nSasha Neftin (v7):\nfix setting netdev->name\nmove MODULE macro defines to begin of the file\n\nSasha Neftin (v8):\nfix whitespaces in comments\nfix igc_update_stats method location\nreplace spaces with tab\nremove unneeded blank line\nfix few comments and add correct explanation of code\n\nSigned-off-by: Sasha Neftin <sasha.neftin@intel.com>\n---\n drivers/net/ethernet/intel/igc/igc.h         |  48 +++\n drivers/net/ethernet/intel/igc/igc_defines.h |  15 +\n drivers/net/ethernet/intel/igc/igc_hw.h      |   1 +\n drivers/net/ethernet/intel/igc/igc_main.c    | 471 ++++++++++++++++++++++++++-\n 4 files changed, 534 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h\nindex 481b2ee694fa..2e819cac19e5 100644\n--- a/drivers/net/ethernet/intel/igc/igc.h\n+++ b/drivers/net/ethernet/intel/igc/igc.h\n@@ -28,15 +28,63 @@\n extern char igc_driver_name[];\n extern char igc_driver_version[];\n \n+/* Transmit and receive queues */\n+#define IGC_MAX_RX_QUEUES\t\t4\n+#define IGC_MAX_TX_QUEUES\t\t4\n+\n+#define MAX_Q_VECTORS\t\t\t8\n+#define MAX_STD_JUMBO_FRAME_SIZE\t9216\n+\n+enum igc_state_t {\n+\t__IGC_TESTING,\n+\t__IGC_RESETTING,\n+\t__IGC_DOWN,\n+\t__IGC_PTP_TX_IN_PROGRESS,\n+};\n+\n+struct igc_q_vector {\n+\tstruct igc_adapter *adapter;    /* backlink */\n+\n+\tstruct napi_struct napi;\n+};\n+\n+struct igc_mac_addr {\n+\tu8 addr[ETH_ALEN];\n+\tu8 queue;\n+\tu8 state; /* bitmask */\n+};\n+\n+#define IGC_MAC_STATE_DEFAULT\t0x1\n+#define IGC_MAC_STATE_MODIFIED\t0x2\n+#define IGC_MAC_STATE_IN_USE\t0x4\n+\n /* Board specific private data structure */\n struct igc_adapter {\n+\tstruct net_device *netdev;\n+\n+\tunsigned long state;\n+\tunsigned int flags;\n+\tunsigned int num_q_vectors;\n+\tu16 link_speed;\n+\tu16 link_duplex;\n+\n+\tu8 port_num;\n+\n \tu8 __iomem *io_addr;\n+\tstruct work_struct watchdog_task;\n+\n+\tint msg_enable;\n+\tu32 max_frame_size;\n \n \t/* OS defined structs */\n \tstruct pci_dev *pdev;\n \n \t/* structs defined in igc_hw.h */\n \tstruct igc_hw hw;\n+\n+\tstruct igc_q_vector *q_vector[MAX_Q_VECTORS];\n+\n+\tstruct igc_mac_addr *mac_table;\n };\n \n #endif /* _IGC_H_ */\ndiff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h\nindex d19dff1d6b74..c25f75ed9cd4 100644\n--- a/drivers/net/ethernet/intel/igc/igc_defines.h\n+++ b/drivers/net/ethernet/intel/igc/igc_defines.h\n@@ -4,10 +4,22 @@\n #ifndef _IGC_DEFINES_H_\n #define _IGC_DEFINES_H_\n \n+#define IGC_CTRL_EXT_DRV_LOAD\t0x10000000 /* Drv loaded bit for FW */\n+\n /* PCI Bus Info */\n #define PCIE_DEVICE_CONTROL2\t\t0x28\n #define PCIE_DEVICE_CONTROL2_16ms\t0x0005\n \n+/* Receive Address\n+ * Number of high/low register pairs in the RAR. The RAR (Receive Address\n+ * Registers) holds the directed and multicast addresses that we monitor.\n+ * Technically, we have 16 spots.  However, we reserve one of these spots\n+ * (RAR[15]) for our directed address used by controllers with\n+ * manageability enabled, allowing us room for 15 multicast addresses.\n+ */\n+#define IGC_RAH_AV\t\t0x80000000 /* Receive descriptor valid */\n+#define IGC_RAH_POOL_1\t\t0x00040000\n+\n /* Error Codes */\n #define IGC_SUCCESS\t\t\t0\n #define IGC_ERR_NVM\t\t\t1\n@@ -17,6 +29,9 @@\n #define IGC_ERR_MAC_INIT\t\t5\n #define IGC_ERR_RESET\t\t\t9\n \n+/* PBA constants */\n+#define IGC_PBA_34K\t\t0x0022\n+\n /* Device Status */\n #define IGC_STATUS_FD\t\t0x00000001      /* Full duplex.0=half,1=full */\n #define IGC_STATUS_LU\t\t0x00000002      /* Link up.0=no,1=link */\ndiff --git a/drivers/net/ethernet/intel/igc/igc_hw.h b/drivers/net/ethernet/intel/igc/igc_hw.h\nindex 84b6067a2476..4cac2e8868e0 100644\n--- a/drivers/net/ethernet/intel/igc/igc_hw.h\n+++ b/drivers/net/ethernet/intel/igc/igc_hw.h\n@@ -59,6 +59,7 @@ struct igc_mac_info {\n \n \tbool autoneg;\n \tbool autoneg_failed;\n+\tbool get_link_status;\n };\n \n struct igc_bus_info {\ndiff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c\nindex 6a881753f5ce..7c5b0d2f16bf 100644\n--- a/drivers/net/ethernet/intel/igc/igc_main.c\n+++ b/drivers/net/ethernet/intel/igc/igc_main.c\n@@ -3,6 +3,8 @@\n \n #include <linux/module.h>\n #include <linux/types.h>\n+#include <linux/if_vlan.h>\n+#include <linux/aer.h>\n \n #include \"igc.h\"\n #include \"igc_hw.h\"\n@@ -10,10 +12,14 @@\n #define DRV_VERSION\t\"0.0.1-k\"\n #define DRV_SUMMARY\t\"Intel(R) 2.5G Ethernet Linux Driver\"\n \n+static int debug = -1;\n+\n MODULE_AUTHOR(\"Intel Corporation, <linux.nics@intel.com>\");\n MODULE_DESCRIPTION(DRV_SUMMARY);\n MODULE_LICENSE(\"GPL v2\");\n MODULE_VERSION(DRV_VERSION);\n+module_param(debug, int, 0);\n+MODULE_PARM_DESC(debug, \"Debug level (0=none,...,16=all)\");\n \n char igc_driver_name[] = \"igc\";\n char igc_driver_version[] = DRV_VERSION;\n@@ -32,6 +38,364 @@ MODULE_DEVICE_TABLE(pci, igc_pci_tbl);\n \n /* forward declaration */\n static int igc_sw_init(struct igc_adapter *);\n+static void igc_configure(struct igc_adapter *adapter);\n+static void igc_power_down_link(struct igc_adapter *adapter);\n+static void igc_set_default_mac_filter(struct igc_adapter *adapter);\n+\n+static void igc_reset(struct igc_adapter *adapter)\n+{\n+\tif (!netif_running(adapter->netdev))\n+\t\tigc_power_down_link(adapter);\n+}\n+\n+/**\n+ * igc_power_up_link - Power up the phy/serdes link\n+ * @adapter: address of board private structure\n+ */\n+static void igc_power_up_link(struct igc_adapter *adapter)\n+{\n+}\n+\n+/**\n+ * igc_power_down_link - Power down the phy/serdes link\n+ * @adapter: address of board private structure\n+ */\n+static void igc_power_down_link(struct igc_adapter *adapter)\n+{\n+}\n+\n+/**\n+ * igc_release_hw_control - release control of the h/w to f/w\n+ * @adapter: address of board private structure\n+ *\n+ * igc_release_hw_control resets CTRL_EXT:DRV_LOAD bit.\n+ * For ASF and Pass Through versions of f/w this means that the\n+ * driver is no longer loaded.\n+ */\n+static void igc_release_hw_control(struct igc_adapter *adapter)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 ctrl_ext;\n+\n+\t/* Let firmware take over control of h/w */\n+\tctrl_ext = rd32(IGC_CTRL_EXT);\n+\twr32(IGC_CTRL_EXT,\n+\t     ctrl_ext & ~IGC_CTRL_EXT_DRV_LOAD);\n+}\n+\n+/**\n+ * igc_get_hw_control - get control of the h/w from f/w\n+ * @adapter: address of board private structure\n+ *\n+ * igc_get_hw_control sets CTRL_EXT:DRV_LOAD bit.\n+ * For ASF and Pass Through versions of f/w this means that\n+ * the driver is loaded.\n+ */\n+static void igc_get_hw_control(struct igc_adapter *adapter)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 ctrl_ext;\n+\n+\t/* Let firmware know the driver has taken over */\n+\tctrl_ext = rd32(IGC_CTRL_EXT);\n+\twr32(IGC_CTRL_EXT,\n+\t     ctrl_ext | IGC_CTRL_EXT_DRV_LOAD);\n+}\n+\n+/**\n+ * igc_set_mac - Change the Ethernet Address of the NIC\n+ * @netdev: network interface device structure\n+ * @p: pointer to an address structure\n+ *\n+ * Returns 0 on success, negative on failure\n+ */\n+static int igc_set_mac(struct net_device *netdev, void *p)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tstruct sockaddr *addr = p;\n+\n+\tif (!is_valid_ether_addr(addr->sa_data))\n+\t\treturn -EADDRNOTAVAIL;\n+\n+\tmemcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);\n+\tmemcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);\n+\n+\t/* set the correct pool for the new PF MAC address in entry 0 */\n+\tigc_set_default_mac_filter(adapter);\n+\n+\treturn 0;\n+}\n+\n+static netdev_tx_t igc_xmit_frame(struct sk_buff *skb,\n+\t\t\t\t  struct net_device *netdev)\n+{\n+\tdev_kfree_skb_any(skb);\n+\treturn NETDEV_TX_OK;\n+}\n+\n+/**\n+ * igc_ioctl - I/O control method\n+ * @netdev: network interface device structure\n+ * @ifreq: frequency\n+ * @cmd: command\n+ */\n+static int igc_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)\n+{\n+\tswitch (cmd) {\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+}\n+\n+/**\n+ * igc_up - Open the interface and prepare it to handle traffic\n+ * @adapter: board private structure\n+ */\n+static void igc_up(struct igc_adapter *adapter)\n+{\n+\tint i = 0;\n+\n+\t/* hardware has been reset, we need to reload some things */\n+\tigc_configure(adapter);\n+\n+\tclear_bit(__IGC_DOWN, &adapter->state);\n+\n+\tfor (i = 0; i < adapter->num_q_vectors; i++)\n+\t\tnapi_enable(&adapter->q_vector[i]->napi);\n+}\n+\n+/**\n+ * igc_update_stats - Update the board statistics counters\n+ * @adapter: board private structure\n+ */\n+static void igc_update_stats(struct igc_adapter *adapter)\n+{\n+}\n+\n+/**\n+ * igc_down - Close the interface\n+ * @adapter: board private structure\n+ */\n+static void igc_down(struct igc_adapter *adapter)\n+{\n+\tstruct net_device *netdev = adapter->netdev;\n+\tint i = 0;\n+\n+\tset_bit(__IGC_DOWN, &adapter->state);\n+\n+\t/* set trans_start so we don't get spurious watchdogs during reset */\n+\tnetif_trans_update(netdev);\n+\n+\tnetif_carrier_off(netdev);\n+\tnetif_tx_stop_all_queues(netdev);\n+\n+\tfor (i = 0; i < adapter->num_q_vectors; i++)\n+\t\tnapi_disable(&adapter->q_vector[i]->napi);\n+\n+\tadapter->link_speed = 0;\n+\tadapter->link_duplex = 0;\n+}\n+\n+/**\n+ * igc_change_mtu - Change the Maximum Transfer Unit\n+ * @netdev: network interface device structure\n+ * @new_mtu: new value for maximum frame size\n+ *\n+ * Returns 0 on success, negative on failure\n+ */\n+static int igc_change_mtu(struct net_device *netdev, int new_mtu)\n+{\n+\tint max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct pci_dev *pdev = adapter->pdev;\n+\n+\t/* adjust max frame to be at least the size of a standard frame */\n+\tif (max_frame < (ETH_FRAME_LEN + ETH_FCS_LEN))\n+\t\tmax_frame = ETH_FRAME_LEN + ETH_FCS_LEN;\n+\n+\twhile (test_and_set_bit(__IGC_RESETTING, &adapter->state))\n+\t\tusleep_range(1000, 2000);\n+\n+\t/* igc_down has a dependency on max_frame_size */\n+\tadapter->max_frame_size = max_frame;\n+\n+\tif (netif_running(netdev))\n+\t\tigc_down(adapter);\n+\n+\tdev_info(&pdev->dev, \"changing MTU from %d to %d\\n\",\n+\t\t netdev->mtu, new_mtu);\n+\tnetdev->mtu = new_mtu;\n+\n+\tif (netif_running(netdev))\n+\t\tigc_up(adapter);\n+\telse\n+\t\tigc_reset(adapter);\n+\n+\tclear_bit(__IGC_RESETTING, &adapter->state);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * igc_get_stats - Get System Network Statistics\n+ * @netdev: network interface device structure\n+ *\n+ * Returns the address of the device statistics structure.\n+ * The statistics are updated here and also from the timer callback.\n+ */\n+static struct net_device_stats *igc_get_stats(struct net_device *netdev)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\tif (!test_bit(__IGC_RESETTING, &adapter->state))\n+\t\tigc_update_stats(adapter);\n+\n+\t/* only return the current stats */\n+\treturn &netdev->stats;\n+}\n+\n+/**\n+ * igc_configure - configure the hardware for RX and TX\n+ * @adapter: private board structure\n+ */\n+static void igc_configure(struct igc_adapter *adapter)\n+{\n+\tigc_get_hw_control(adapter);\n+}\n+\n+/**\n+ * igc_rar_set_index - Sync RAL[index] and RAH[index] registers with MAC table\n+ * @adapter: Pointer to adapter structure\n+ * @index: Index of the RAR entry which need to be synced with MAC table\n+ */\n+static void igc_rar_set_index(struct igc_adapter *adapter, u32 index)\n+{\n+\tu8 *addr = adapter->mac_table[index].addr;\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 rar_low, rar_high;\n+\n+\t/* HW expects these to be in network order when they are plugged\n+\t * into the registers which are little endian.  In order to guarantee\n+\t * that ordering we need to do an leXX_to_cpup here in order to be\n+\t * ready for the byteswap that occurs with writel\n+\t */\n+\trar_low = le32_to_cpup((__le32 *)(addr));\n+\trar_high = le16_to_cpup((__le16 *)(addr + 4));\n+\n+\t/* Indicate to hardware the Address is Valid. */\n+\tif (adapter->mac_table[index].state & IGC_MAC_STATE_IN_USE) {\n+\t\tif (is_valid_ether_addr(addr))\n+\t\t\trar_high |= IGC_RAH_AV;\n+\n+\t\trar_high |= IGC_RAH_POOL_1 <<\n+\t\t\tadapter->mac_table[index].queue;\n+\t}\n+\n+\twr32(IGC_RAL(index), rar_low);\n+\twrfl();\n+\twr32(IGC_RAH(index), rar_high);\n+\twrfl();\n+}\n+\n+/* Set default MAC address for the PF in the first RAR entry */\n+static void igc_set_default_mac_filter(struct igc_adapter *adapter)\n+{\n+\tstruct igc_mac_addr *mac_table = &adapter->mac_table[0];\n+\n+\tether_addr_copy(mac_table->addr, adapter->hw.mac.addr);\n+\tmac_table->state = IGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE;\n+\n+\tigc_rar_set_index(adapter, 0);\n+}\n+\n+/**\n+ * igc_open - Called when a network interface is made active\n+ * @netdev: network interface device structure\n+ *\n+ * Returns 0 on success, negative value on failure\n+ *\n+ * The open entry point is called when a network interface is made\n+ * active by the system (IFF_UP).  At this point all resources needed\n+ * for transmit and receive operations are allocated, the interrupt\n+ * handler is registered with the OS, the watchdog timer is started,\n+ * and the stack is notified that the interface is ready.\n+ */\n+static int __igc_open(struct net_device *netdev, bool resuming)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tint i = 0;\n+\n+\t/* disallow open during test */\n+\n+\tif (test_bit(__IGC_TESTING, &adapter->state)) {\n+\t\tWARN_ON(resuming);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tnetif_carrier_off(netdev);\n+\n+\tigc_power_up_link(adapter);\n+\n+\tigc_configure(adapter);\n+\n+\tclear_bit(__IGC_DOWN, &adapter->state);\n+\n+\tfor (i = 0; i < adapter->num_q_vectors; i++)\n+\t\tnapi_enable(&adapter->q_vector[i]->napi);\n+\n+\t/* start the watchdog. */\n+\thw->mac.get_link_status = 1;\n+\n+\treturn IGC_SUCCESS;\n+}\n+\n+static int igc_open(struct net_device *netdev)\n+{\n+\treturn __igc_open(netdev, false);\n+}\n+\n+/**\n+ * igc_close - Disables a network interface\n+ * @netdev: network interface device structure\n+ *\n+ * Returns 0, this is not allowed to fail\n+ *\n+ * The close entry point is called when an interface is de-activated\n+ * by the OS.  The hardware is still under the driver's control, but\n+ * needs to be disabled.  A global MAC reset is issued to stop the\n+ * hardware, and all transmit and receive resources are freed.\n+ */\n+static int __igc_close(struct net_device *netdev, bool suspending)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\tWARN_ON(test_bit(__IGC_RESETTING, &adapter->state));\n+\n+\tigc_down(adapter);\n+\n+\tigc_release_hw_control(adapter);\n+\n+\treturn 0;\n+}\n+\n+static int igc_close(struct net_device *netdev)\n+{\n+\tif (netif_device_present(netdev) || netdev->dismantle)\n+\t\treturn __igc_close(netdev, false);\n+\treturn 0;\n+}\n+\n+static const struct net_device_ops igc_netdev_ops = {\n+\t.ndo_open\t\t= igc_open,\n+\t.ndo_stop\t\t= igc_close,\n+\t.ndo_start_xmit\t\t= igc_xmit_frame,\n+\t.ndo_set_mac_address\t= igc_set_mac,\n+\t.ndo_change_mtu\t\t= igc_change_mtu,\n+\t.ndo_get_stats\t\t= igc_get_stats,\n+\t.ndo_do_ioctl\t\t= igc_ioctl,\n+};\n \n /* PCIe configuration access */\n void igc_read_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value)\n@@ -78,6 +442,7 @@ s32 igc_write_pcie_cap_reg(struct igc_hw *hw, u32 reg, u16 *value)\n \n u32 igc_rd32(struct igc_hw *hw, u32 reg)\n {\n+\tstruct igc_adapter *igc = container_of(hw, struct igc_adapter, hw);\n \tu8 __iomem *hw_addr = READ_ONCE(hw->hw_addr);\n \tu32 value = 0;\n \n@@ -87,8 +452,13 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg)\n \tvalue = readl(&hw_addr[reg]);\n \n \t/* reads should not return all F's */\n-\tif (!(~value) && (!reg || !(~readl(hw_addr))))\n+\tif (!(~value) && (!reg || !(~readl(hw_addr)))) {\n+\t\tstruct net_device *netdev = igc->netdev;\n+\n \t\thw->hw_addr = NULL;\n+\t\tnetif_device_detach(netdev);\n+\t\tnetdev_err(netdev, \"PCIe link lost, device now detached\\n\");\n+\t}\n \n \treturn value;\n }\n@@ -108,6 +478,8 @@ static int igc_probe(struct pci_dev *pdev,\n \t\t     const struct pci_device_id *ent)\n {\n \tstruct igc_adapter *adapter;\n+\tstruct net_device *netdev;\n+\tstruct igc_hw *hw;\n \tint err, pci_using_dac;\n \n \terr = pci_enable_device_mem(pdev);\n@@ -140,17 +512,94 @@ static int igc_probe(struct pci_dev *pdev,\n \tif (err)\n \t\tgoto err_pci_reg;\n \n+\tpci_enable_pcie_error_reporting(pdev);\n+\n \tpci_set_master(pdev);\n+\n+\terr = -ENOMEM;\n+\tnetdev = alloc_etherdev_mq(sizeof(struct igc_adapter),\n+\t\t\t\t   IGC_MAX_TX_QUEUES);\n+\n+\tif (!netdev)\n+\t\tgoto err_alloc_etherdev;\n+\n+\tSET_NETDEV_DEV(netdev, &pdev->dev);\n+\n+\tpci_set_drvdata(pdev, netdev);\n+\tadapter = netdev_priv(netdev);\n+\tadapter->netdev = netdev;\n+\tadapter->pdev = pdev;\n+\thw = &adapter->hw;\n+\thw->back = adapter;\n+\tadapter->port_num = hw->bus.func;\n+\tadapter->msg_enable = GENMASK(debug - 1, 0);\n+\n \terr = pci_save_state(pdev);\n+\tif (err)\n+\t\tgoto err_ioremap;\n+\n+\terr = -EIO;\n+\tadapter->io_addr = ioremap(pci_resource_start(pdev, 0),\n+\t\t\t\t   pci_resource_len(pdev, 0));\n+\tif (!adapter->io_addr)\n+\t\tgoto err_ioremap;\n+\n+\t/* hw->hw_addr can be zeroed, so use adapter->io_addr for unmap */\n+\thw->hw_addr = adapter->io_addr;\n+\n+\tnetdev->netdev_ops = &igc_netdev_ops;\n+\n+\tnetdev->watchdog_timeo = 5 * HZ;\n+\n+\tnetdev->mem_start = pci_resource_start(pdev, 0);\n+\tnetdev->mem_end = pci_resource_end(pdev, 0);\n+\n+\t/* PCI config space info */\n+\thw->vendor_id = pdev->vendor;\n+\thw->device_id = pdev->device;\n+\thw->revision_id = pdev->revision;\n+\thw->subsystem_vendor_id = pdev->subsystem_vendor;\n+\thw->subsystem_device_id = pdev->subsystem_device;\n \n \t/* setup the private structure */\n \terr = igc_sw_init(adapter);\n \tif (err)\n \t\tgoto err_sw_init;\n \n+\t/* MTU range: 68 - 9216 */\n+\tnetdev->min_mtu = ETH_MIN_MTU;\n+\tnetdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE;\n+\n+\t/* reset the hardware with the new settings */\n+\tigc_reset(adapter);\n+\n+\t/* let the f/w know that the h/w is now under the control of the\n+\t * driver.\n+\t */\n+\tigc_get_hw_control(adapter);\n+\n+\tstrncpy(netdev->name, \"eth%d\", IFNAMSIZ);\n+\terr = register_netdev(netdev);\n+\tif (err)\n+\t\tgoto err_register;\n+\n+\t /* carrier off reporting is important to ethtool even BEFORE open */\n+\tnetif_carrier_off(netdev);\n+\n+\t/* print pcie link status and MAC address */\n+\tpcie_print_link_status(pdev);\n+\tnetdev_info(netdev, \"MAC: %pM\\n\", netdev->dev_addr);\n+\n \treturn 0;\n \n+err_register:\n+\tigc_release_hw_control(adapter);\n err_sw_init:\n+err_ioremap:\n+\tfree_netdev(netdev);\n+err_alloc_etherdev:\n+\tpci_release_selected_regions(pdev,\n+\t\t\t\t     pci_select_bars(pdev, IORESOURCE_MEM));\n err_pci_reg:\n err_dma:\n \tpci_disable_device(pdev);\n@@ -168,9 +617,22 @@ static int igc_probe(struct pci_dev *pdev,\n  */\n static void igc_remove(struct pci_dev *pdev)\n {\n+\tstruct net_device *netdev = pci_get_drvdata(pdev);\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\tset_bit(__IGC_DOWN, &adapter->state);\n+\tflush_scheduled_work();\n+\n+\t/* Release control of h/w to f/w.  If f/w is AMT enabled, this\n+\t * would have already happened in close and is redundant.\n+\t */\n+\tigc_release_hw_control(adapter);\n+\tunregister_netdev(netdev);\n+\n \tpci_release_selected_regions(pdev,\n \t\t\t\t     pci_select_bars(pdev, IORESOURCE_MEM));\n \n+\tfree_netdev(netdev);\n \tpci_disable_device(pdev);\n }\n \n@@ -191,6 +653,7 @@ static struct pci_driver igc_driver = {\n  */\n static int igc_sw_init(struct igc_adapter *adapter)\n {\n+\tstruct net_device *netdev = adapter->netdev;\n \tstruct pci_dev *pdev = adapter->pdev;\n \tstruct igc_hw *hw = &adapter->hw;\n \n@@ -205,6 +668,12 @@ static int igc_sw_init(struct igc_adapter *adapter)\n \n \tpci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);\n \n+\t/* adjust max frame to be at least the size of a standard frame */\n+\tadapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN +\n+\t\t\t\t\tVLAN_HLEN;\n+\n+\tset_bit(__IGC_DOWN, &adapter->state);\n+\n \treturn 0;\n }\n \n",
    "prefixes": [
        "v8",
        "03/11"
    ]
}