162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/* Copyright(c) 1999 - 2006 Intel Corporation. */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include "e1000.h"
562306a36Sopenharmony_ci#include <net/ip6_checksum.h>
662306a36Sopenharmony_ci#include <linux/io.h>
762306a36Sopenharmony_ci#include <linux/prefetch.h>
862306a36Sopenharmony_ci#include <linux/bitops.h>
962306a36Sopenharmony_ci#include <linux/if_vlan.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cichar e1000_driver_name[] = "e1000";
1262306a36Sopenharmony_cistatic char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
1362306a36Sopenharmony_cistatic const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/* e1000_pci_tbl - PCI Device ID Table
1662306a36Sopenharmony_ci *
1762306a36Sopenharmony_ci * Last entry must be all 0s
1862306a36Sopenharmony_ci *
1962306a36Sopenharmony_ci * Macro expands to...
2062306a36Sopenharmony_ci *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_cistatic const struct pci_device_id e1000_pci_tbl[] = {
2362306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1000),
2462306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1001),
2562306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1004),
2662306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1008),
2762306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1009),
2862306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x100C),
2962306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x100D),
3062306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x100E),
3162306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x100F),
3262306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1010),
3362306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1011),
3462306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1012),
3562306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1013),
3662306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1014),
3762306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1015),
3862306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1016),
3962306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1017),
4062306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1018),
4162306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1019),
4262306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x101A),
4362306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x101D),
4462306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x101E),
4562306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1026),
4662306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1027),
4762306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1028),
4862306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1075),
4962306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1076),
5062306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1077),
5162306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1078),
5262306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1079),
5362306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x107A),
5462306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x107B),
5562306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x107C),
5662306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x108A),
5762306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x1099),
5862306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
5962306a36Sopenharmony_ci	INTEL_E1000_ETHERNET_DEVICE(0x2E6E),
6062306a36Sopenharmony_ci	/* required last entry */
6162306a36Sopenharmony_ci	{0,}
6262306a36Sopenharmony_ci};
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ciint e1000_up(struct e1000_adapter *adapter);
6762306a36Sopenharmony_civoid e1000_down(struct e1000_adapter *adapter);
6862306a36Sopenharmony_civoid e1000_reinit_locked(struct e1000_adapter *adapter);
6962306a36Sopenharmony_civoid e1000_reset(struct e1000_adapter *adapter);
7062306a36Sopenharmony_ciint e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
7162306a36Sopenharmony_ciint e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
7262306a36Sopenharmony_civoid e1000_free_all_tx_resources(struct e1000_adapter *adapter);
7362306a36Sopenharmony_civoid e1000_free_all_rx_resources(struct e1000_adapter *adapter);
7462306a36Sopenharmony_cistatic int e1000_setup_tx_resources(struct e1000_adapter *adapter,
7562306a36Sopenharmony_ci				    struct e1000_tx_ring *txdr);
7662306a36Sopenharmony_cistatic int e1000_setup_rx_resources(struct e1000_adapter *adapter,
7762306a36Sopenharmony_ci				    struct e1000_rx_ring *rxdr);
7862306a36Sopenharmony_cistatic void e1000_free_tx_resources(struct e1000_adapter *adapter,
7962306a36Sopenharmony_ci				    struct e1000_tx_ring *tx_ring);
8062306a36Sopenharmony_cistatic void e1000_free_rx_resources(struct e1000_adapter *adapter,
8162306a36Sopenharmony_ci				    struct e1000_rx_ring *rx_ring);
8262306a36Sopenharmony_civoid e1000_update_stats(struct e1000_adapter *adapter);
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_cistatic int e1000_init_module(void);
8562306a36Sopenharmony_cistatic void e1000_exit_module(void);
8662306a36Sopenharmony_cistatic int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
8762306a36Sopenharmony_cistatic void e1000_remove(struct pci_dev *pdev);
8862306a36Sopenharmony_cistatic int e1000_alloc_queues(struct e1000_adapter *adapter);
8962306a36Sopenharmony_cistatic int e1000_sw_init(struct e1000_adapter *adapter);
9062306a36Sopenharmony_ciint e1000_open(struct net_device *netdev);
9162306a36Sopenharmony_ciint e1000_close(struct net_device *netdev);
9262306a36Sopenharmony_cistatic void e1000_configure_tx(struct e1000_adapter *adapter);
9362306a36Sopenharmony_cistatic void e1000_configure_rx(struct e1000_adapter *adapter);
9462306a36Sopenharmony_cistatic void e1000_setup_rctl(struct e1000_adapter *adapter);
9562306a36Sopenharmony_cistatic void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
9662306a36Sopenharmony_cistatic void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
9762306a36Sopenharmony_cistatic void e1000_clean_tx_ring(struct e1000_adapter *adapter,
9862306a36Sopenharmony_ci				struct e1000_tx_ring *tx_ring);
9962306a36Sopenharmony_cistatic void e1000_clean_rx_ring(struct e1000_adapter *adapter,
10062306a36Sopenharmony_ci				struct e1000_rx_ring *rx_ring);
10162306a36Sopenharmony_cistatic void e1000_set_rx_mode(struct net_device *netdev);
10262306a36Sopenharmony_cistatic void e1000_update_phy_info_task(struct work_struct *work);
10362306a36Sopenharmony_cistatic void e1000_watchdog(struct work_struct *work);
10462306a36Sopenharmony_cistatic void e1000_82547_tx_fifo_stall_task(struct work_struct *work);
10562306a36Sopenharmony_cistatic netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
10662306a36Sopenharmony_ci				    struct net_device *netdev);
10762306a36Sopenharmony_cistatic int e1000_change_mtu(struct net_device *netdev, int new_mtu);
10862306a36Sopenharmony_cistatic int e1000_set_mac(struct net_device *netdev, void *p);
10962306a36Sopenharmony_cistatic irqreturn_t e1000_intr(int irq, void *data);
11062306a36Sopenharmony_cistatic bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
11162306a36Sopenharmony_ci			       struct e1000_tx_ring *tx_ring);
11262306a36Sopenharmony_cistatic int e1000_clean(struct napi_struct *napi, int budget);
11362306a36Sopenharmony_cistatic bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
11462306a36Sopenharmony_ci			       struct e1000_rx_ring *rx_ring,
11562306a36Sopenharmony_ci			       int *work_done, int work_to_do);
11662306a36Sopenharmony_cistatic bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
11762306a36Sopenharmony_ci				     struct e1000_rx_ring *rx_ring,
11862306a36Sopenharmony_ci				     int *work_done, int work_to_do);
11962306a36Sopenharmony_cistatic void e1000_alloc_dummy_rx_buffers(struct e1000_adapter *adapter,
12062306a36Sopenharmony_ci					 struct e1000_rx_ring *rx_ring,
12162306a36Sopenharmony_ci					 int cleaned_count)
12262306a36Sopenharmony_ci{
12362306a36Sopenharmony_ci}
12462306a36Sopenharmony_cistatic void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
12562306a36Sopenharmony_ci				   struct e1000_rx_ring *rx_ring,
12662306a36Sopenharmony_ci				   int cleaned_count);
12762306a36Sopenharmony_cistatic void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
12862306a36Sopenharmony_ci					 struct e1000_rx_ring *rx_ring,
12962306a36Sopenharmony_ci					 int cleaned_count);
13062306a36Sopenharmony_cistatic int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
13162306a36Sopenharmony_cistatic int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
13262306a36Sopenharmony_ci			   int cmd);
13362306a36Sopenharmony_cistatic void e1000_enter_82542_rst(struct e1000_adapter *adapter);
13462306a36Sopenharmony_cistatic void e1000_leave_82542_rst(struct e1000_adapter *adapter);
13562306a36Sopenharmony_cistatic void e1000_tx_timeout(struct net_device *dev, unsigned int txqueue);
13662306a36Sopenharmony_cistatic void e1000_reset_task(struct work_struct *work);
13762306a36Sopenharmony_cistatic void e1000_smartspeed(struct e1000_adapter *adapter);
13862306a36Sopenharmony_cistatic int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
13962306a36Sopenharmony_ci				       struct sk_buff *skb);
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cistatic bool e1000_vlan_used(struct e1000_adapter *adapter);
14262306a36Sopenharmony_cistatic void e1000_vlan_mode(struct net_device *netdev,
14362306a36Sopenharmony_ci			    netdev_features_t features);
14462306a36Sopenharmony_cistatic void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
14562306a36Sopenharmony_ci				     bool filter_on);
14662306a36Sopenharmony_cistatic int e1000_vlan_rx_add_vid(struct net_device *netdev,
14762306a36Sopenharmony_ci				 __be16 proto, u16 vid);
14862306a36Sopenharmony_cistatic int e1000_vlan_rx_kill_vid(struct net_device *netdev,
14962306a36Sopenharmony_ci				  __be16 proto, u16 vid);
15062306a36Sopenharmony_cistatic void e1000_restore_vlan(struct e1000_adapter *adapter);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_cistatic int __maybe_unused e1000_suspend(struct device *dev);
15362306a36Sopenharmony_cistatic int __maybe_unused e1000_resume(struct device *dev);
15462306a36Sopenharmony_cistatic void e1000_shutdown(struct pci_dev *pdev);
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci#ifdef CONFIG_NET_POLL_CONTROLLER
15762306a36Sopenharmony_ci/* for netdump / net console */
15862306a36Sopenharmony_cistatic void e1000_netpoll (struct net_device *netdev);
15962306a36Sopenharmony_ci#endif
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci#define COPYBREAK_DEFAULT 256
16262306a36Sopenharmony_cistatic unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
16362306a36Sopenharmony_cimodule_param(copybreak, uint, 0644);
16462306a36Sopenharmony_ciMODULE_PARM_DESC(copybreak,
16562306a36Sopenharmony_ci	"Maximum size of packet that is copied to a new buffer on receive");
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
16862306a36Sopenharmony_ci						pci_channel_state_t state);
16962306a36Sopenharmony_cistatic pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
17062306a36Sopenharmony_cistatic void e1000_io_resume(struct pci_dev *pdev);
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_cistatic const struct pci_error_handlers e1000_err_handler = {
17362306a36Sopenharmony_ci	.error_detected = e1000_io_error_detected,
17462306a36Sopenharmony_ci	.slot_reset = e1000_io_slot_reset,
17562306a36Sopenharmony_ci	.resume = e1000_io_resume,
17662306a36Sopenharmony_ci};
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(e1000_pm_ops, e1000_suspend, e1000_resume);
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_cistatic struct pci_driver e1000_driver = {
18162306a36Sopenharmony_ci	.name     = e1000_driver_name,
18262306a36Sopenharmony_ci	.id_table = e1000_pci_tbl,
18362306a36Sopenharmony_ci	.probe    = e1000_probe,
18462306a36Sopenharmony_ci	.remove   = e1000_remove,
18562306a36Sopenharmony_ci	.driver = {
18662306a36Sopenharmony_ci		.pm = &e1000_pm_ops,
18762306a36Sopenharmony_ci	},
18862306a36Sopenharmony_ci	.shutdown = e1000_shutdown,
18962306a36Sopenharmony_ci	.err_handler = &e1000_err_handler
19062306a36Sopenharmony_ci};
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ciMODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
19362306a36Sopenharmony_ciMODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
19462306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
19762306a36Sopenharmony_cistatic int debug = -1;
19862306a36Sopenharmony_cimodule_param(debug, int, 0);
19962306a36Sopenharmony_ciMODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci/**
20262306a36Sopenharmony_ci * e1000_get_hw_dev - helper function for getting netdev
20362306a36Sopenharmony_ci * @hw: pointer to HW struct
20462306a36Sopenharmony_ci *
20562306a36Sopenharmony_ci * return device used by hardware layer to print debugging information
20662306a36Sopenharmony_ci *
20762306a36Sopenharmony_ci **/
20862306a36Sopenharmony_cistruct net_device *e1000_get_hw_dev(struct e1000_hw *hw)
20962306a36Sopenharmony_ci{
21062306a36Sopenharmony_ci	struct e1000_adapter *adapter = hw->back;
21162306a36Sopenharmony_ci	return adapter->netdev;
21262306a36Sopenharmony_ci}
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci/**
21562306a36Sopenharmony_ci * e1000_init_module - Driver Registration Routine
21662306a36Sopenharmony_ci *
21762306a36Sopenharmony_ci * e1000_init_module is the first routine called when the driver is
21862306a36Sopenharmony_ci * loaded. All it does is register with the PCI subsystem.
21962306a36Sopenharmony_ci **/
22062306a36Sopenharmony_cistatic int __init e1000_init_module(void)
22162306a36Sopenharmony_ci{
22262306a36Sopenharmony_ci	int ret;
22362306a36Sopenharmony_ci	pr_info("%s\n", e1000_driver_string);
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	pr_info("%s\n", e1000_copyright);
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	ret = pci_register_driver(&e1000_driver);
22862306a36Sopenharmony_ci	if (copybreak != COPYBREAK_DEFAULT) {
22962306a36Sopenharmony_ci		if (copybreak == 0)
23062306a36Sopenharmony_ci			pr_info("copybreak disabled\n");
23162306a36Sopenharmony_ci		else
23262306a36Sopenharmony_ci			pr_info("copybreak enabled for "
23362306a36Sopenharmony_ci				   "packets <= %u bytes\n", copybreak);
23462306a36Sopenharmony_ci	}
23562306a36Sopenharmony_ci	return ret;
23662306a36Sopenharmony_ci}
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_cimodule_init(e1000_init_module);
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci/**
24162306a36Sopenharmony_ci * e1000_exit_module - Driver Exit Cleanup Routine
24262306a36Sopenharmony_ci *
24362306a36Sopenharmony_ci * e1000_exit_module is called just before the driver is removed
24462306a36Sopenharmony_ci * from memory.
24562306a36Sopenharmony_ci **/
24662306a36Sopenharmony_cistatic void __exit e1000_exit_module(void)
24762306a36Sopenharmony_ci{
24862306a36Sopenharmony_ci	pci_unregister_driver(&e1000_driver);
24962306a36Sopenharmony_ci}
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cimodule_exit(e1000_exit_module);
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_cistatic int e1000_request_irq(struct e1000_adapter *adapter)
25462306a36Sopenharmony_ci{
25562306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
25662306a36Sopenharmony_ci	irq_handler_t handler = e1000_intr;
25762306a36Sopenharmony_ci	int irq_flags = IRQF_SHARED;
25862306a36Sopenharmony_ci	int err;
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
26162306a36Sopenharmony_ci			  netdev);
26262306a36Sopenharmony_ci	if (err) {
26362306a36Sopenharmony_ci		e_err(probe, "Unable to allocate interrupt Error: %d\n", err);
26462306a36Sopenharmony_ci	}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	return err;
26762306a36Sopenharmony_ci}
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_cistatic void e1000_free_irq(struct e1000_adapter *adapter)
27062306a36Sopenharmony_ci{
27162306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	free_irq(adapter->pdev->irq, netdev);
27462306a36Sopenharmony_ci}
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci/**
27762306a36Sopenharmony_ci * e1000_irq_disable - Mask off interrupt generation on the NIC
27862306a36Sopenharmony_ci * @adapter: board private structure
27962306a36Sopenharmony_ci **/
28062306a36Sopenharmony_cistatic void e1000_irq_disable(struct e1000_adapter *adapter)
28162306a36Sopenharmony_ci{
28262306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	ew32(IMC, ~0);
28562306a36Sopenharmony_ci	E1000_WRITE_FLUSH();
28662306a36Sopenharmony_ci	synchronize_irq(adapter->pdev->irq);
28762306a36Sopenharmony_ci}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci/**
29062306a36Sopenharmony_ci * e1000_irq_enable - Enable default interrupt generation settings
29162306a36Sopenharmony_ci * @adapter: board private structure
29262306a36Sopenharmony_ci **/
29362306a36Sopenharmony_cistatic void e1000_irq_enable(struct e1000_adapter *adapter)
29462306a36Sopenharmony_ci{
29562306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	ew32(IMS, IMS_ENABLE_MASK);
29862306a36Sopenharmony_ci	E1000_WRITE_FLUSH();
29962306a36Sopenharmony_ci}
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_cistatic void e1000_update_mng_vlan(struct e1000_adapter *adapter)
30262306a36Sopenharmony_ci{
30362306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
30462306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
30562306a36Sopenharmony_ci	u16 vid = hw->mng_cookie.vlan_id;
30662306a36Sopenharmony_ci	u16 old_vid = adapter->mng_vlan_id;
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	if (!e1000_vlan_used(adapter))
30962306a36Sopenharmony_ci		return;
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	if (!test_bit(vid, adapter->active_vlans)) {
31262306a36Sopenharmony_ci		if (hw->mng_cookie.status &
31362306a36Sopenharmony_ci		    E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
31462306a36Sopenharmony_ci			e1000_vlan_rx_add_vid(netdev, htons(ETH_P_8021Q), vid);
31562306a36Sopenharmony_ci			adapter->mng_vlan_id = vid;
31662306a36Sopenharmony_ci		} else {
31762306a36Sopenharmony_ci			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
31862306a36Sopenharmony_ci		}
31962306a36Sopenharmony_ci		if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
32062306a36Sopenharmony_ci		    (vid != old_vid) &&
32162306a36Sopenharmony_ci		    !test_bit(old_vid, adapter->active_vlans))
32262306a36Sopenharmony_ci			e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q),
32362306a36Sopenharmony_ci					       old_vid);
32462306a36Sopenharmony_ci	} else {
32562306a36Sopenharmony_ci		adapter->mng_vlan_id = vid;
32662306a36Sopenharmony_ci	}
32762306a36Sopenharmony_ci}
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_cistatic void e1000_init_manageability(struct e1000_adapter *adapter)
33062306a36Sopenharmony_ci{
33162306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	if (adapter->en_mng_pt) {
33462306a36Sopenharmony_ci		u32 manc = er32(MANC);
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci		/* disable hardware interception of ARP */
33762306a36Sopenharmony_ci		manc &= ~(E1000_MANC_ARP_EN);
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci		ew32(MANC, manc);
34062306a36Sopenharmony_ci	}
34162306a36Sopenharmony_ci}
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_cistatic void e1000_release_manageability(struct e1000_adapter *adapter)
34462306a36Sopenharmony_ci{
34562306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	if (adapter->en_mng_pt) {
34862306a36Sopenharmony_ci		u32 manc = er32(MANC);
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci		/* re-enable hardware interception of ARP */
35162306a36Sopenharmony_ci		manc |= E1000_MANC_ARP_EN;
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci		ew32(MANC, manc);
35462306a36Sopenharmony_ci	}
35562306a36Sopenharmony_ci}
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci/**
35862306a36Sopenharmony_ci * e1000_configure - configure the hardware for RX and TX
35962306a36Sopenharmony_ci * @adapter: private board structure
36062306a36Sopenharmony_ci **/
36162306a36Sopenharmony_cistatic void e1000_configure(struct e1000_adapter *adapter)
36262306a36Sopenharmony_ci{
36362306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
36462306a36Sopenharmony_ci	int i;
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	e1000_set_rx_mode(netdev);
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	e1000_restore_vlan(adapter);
36962306a36Sopenharmony_ci	e1000_init_manageability(adapter);
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	e1000_configure_tx(adapter);
37262306a36Sopenharmony_ci	e1000_setup_rctl(adapter);
37362306a36Sopenharmony_ci	e1000_configure_rx(adapter);
37462306a36Sopenharmony_ci	/* call E1000_DESC_UNUSED which always leaves
37562306a36Sopenharmony_ci	 * at least 1 descriptor unused to make sure
37662306a36Sopenharmony_ci	 * next_to_use != next_to_clean
37762306a36Sopenharmony_ci	 */
37862306a36Sopenharmony_ci	for (i = 0; i < adapter->num_rx_queues; i++) {
37962306a36Sopenharmony_ci		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
38062306a36Sopenharmony_ci		adapter->alloc_rx_buf(adapter, ring,
38162306a36Sopenharmony_ci				      E1000_DESC_UNUSED(ring));
38262306a36Sopenharmony_ci	}
38362306a36Sopenharmony_ci}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ciint e1000_up(struct e1000_adapter *adapter)
38662306a36Sopenharmony_ci{
38762306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	/* hardware has been reset, we need to reload some things */
39062306a36Sopenharmony_ci	e1000_configure(adapter);
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	clear_bit(__E1000_DOWN, &adapter->flags);
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	napi_enable(&adapter->napi);
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	e1000_irq_enable(adapter);
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	netif_wake_queue(adapter->netdev);
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	/* fire a link change interrupt to start the watchdog */
40162306a36Sopenharmony_ci	ew32(ICS, E1000_ICS_LSC);
40262306a36Sopenharmony_ci	return 0;
40362306a36Sopenharmony_ci}
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci/**
40662306a36Sopenharmony_ci * e1000_power_up_phy - restore link in case the phy was powered down
40762306a36Sopenharmony_ci * @adapter: address of board private structure
40862306a36Sopenharmony_ci *
40962306a36Sopenharmony_ci * The phy may be powered down to save power and turn off link when the
41062306a36Sopenharmony_ci * driver is unloaded and wake on lan is not enabled (among others)
41162306a36Sopenharmony_ci * *** this routine MUST be followed by a call to e1000_reset ***
41262306a36Sopenharmony_ci **/
41362306a36Sopenharmony_civoid e1000_power_up_phy(struct e1000_adapter *adapter)
41462306a36Sopenharmony_ci{
41562306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
41662306a36Sopenharmony_ci	u16 mii_reg = 0;
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	/* Just clear the power down bit to wake the phy back up */
41962306a36Sopenharmony_ci	if (hw->media_type == e1000_media_type_copper) {
42062306a36Sopenharmony_ci		/* according to the manual, the phy will retain its
42162306a36Sopenharmony_ci		 * settings across a power-down/up cycle
42262306a36Sopenharmony_ci		 */
42362306a36Sopenharmony_ci		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
42462306a36Sopenharmony_ci		mii_reg &= ~MII_CR_POWER_DOWN;
42562306a36Sopenharmony_ci		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
42662306a36Sopenharmony_ci	}
42762306a36Sopenharmony_ci}
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_cistatic void e1000_power_down_phy(struct e1000_adapter *adapter)
43062306a36Sopenharmony_ci{
43162306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	/* Power down the PHY so no link is implied when interface is down *
43462306a36Sopenharmony_ci	 * The PHY cannot be powered down if any of the following is true *
43562306a36Sopenharmony_ci	 * (a) WoL is enabled
43662306a36Sopenharmony_ci	 * (b) AMT is active
43762306a36Sopenharmony_ci	 * (c) SoL/IDER session is active
43862306a36Sopenharmony_ci	 */
43962306a36Sopenharmony_ci	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
44062306a36Sopenharmony_ci	   hw->media_type == e1000_media_type_copper) {
44162306a36Sopenharmony_ci		u16 mii_reg = 0;
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci		switch (hw->mac_type) {
44462306a36Sopenharmony_ci		case e1000_82540:
44562306a36Sopenharmony_ci		case e1000_82545:
44662306a36Sopenharmony_ci		case e1000_82545_rev_3:
44762306a36Sopenharmony_ci		case e1000_82546:
44862306a36Sopenharmony_ci		case e1000_ce4100:
44962306a36Sopenharmony_ci		case e1000_82546_rev_3:
45062306a36Sopenharmony_ci		case e1000_82541:
45162306a36Sopenharmony_ci		case e1000_82541_rev_2:
45262306a36Sopenharmony_ci		case e1000_82547:
45362306a36Sopenharmony_ci		case e1000_82547_rev_2:
45462306a36Sopenharmony_ci			if (er32(MANC) & E1000_MANC_SMBUS_EN)
45562306a36Sopenharmony_ci				goto out;
45662306a36Sopenharmony_ci			break;
45762306a36Sopenharmony_ci		default:
45862306a36Sopenharmony_ci			goto out;
45962306a36Sopenharmony_ci		}
46062306a36Sopenharmony_ci		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
46162306a36Sopenharmony_ci		mii_reg |= MII_CR_POWER_DOWN;
46262306a36Sopenharmony_ci		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
46362306a36Sopenharmony_ci		msleep(1);
46462306a36Sopenharmony_ci	}
46562306a36Sopenharmony_ciout:
46662306a36Sopenharmony_ci	return;
46762306a36Sopenharmony_ci}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_cistatic void e1000_down_and_stop(struct e1000_adapter *adapter)
47062306a36Sopenharmony_ci{
47162306a36Sopenharmony_ci	set_bit(__E1000_DOWN, &adapter->flags);
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci	cancel_delayed_work_sync(&adapter->watchdog_task);
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci	/*
47662306a36Sopenharmony_ci	 * Since the watchdog task can reschedule other tasks, we should cancel
47762306a36Sopenharmony_ci	 * it first, otherwise we can run into the situation when a work is
47862306a36Sopenharmony_ci	 * still running after the adapter has been turned down.
47962306a36Sopenharmony_ci	 */
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci	cancel_delayed_work_sync(&adapter->phy_info_task);
48262306a36Sopenharmony_ci	cancel_delayed_work_sync(&adapter->fifo_stall_task);
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	/* Only kill reset task if adapter is not resetting */
48562306a36Sopenharmony_ci	if (!test_bit(__E1000_RESETTING, &adapter->flags))
48662306a36Sopenharmony_ci		cancel_work_sync(&adapter->reset_task);
48762306a36Sopenharmony_ci}
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_civoid e1000_down(struct e1000_adapter *adapter)
49062306a36Sopenharmony_ci{
49162306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
49262306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
49362306a36Sopenharmony_ci	u32 rctl, tctl;
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	/* disable receives in the hardware */
49662306a36Sopenharmony_ci	rctl = er32(RCTL);
49762306a36Sopenharmony_ci	ew32(RCTL, rctl & ~E1000_RCTL_EN);
49862306a36Sopenharmony_ci	/* flush and sleep below */
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	netif_tx_disable(netdev);
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	/* disable transmits in the hardware */
50362306a36Sopenharmony_ci	tctl = er32(TCTL);
50462306a36Sopenharmony_ci	tctl &= ~E1000_TCTL_EN;
50562306a36Sopenharmony_ci	ew32(TCTL, tctl);
50662306a36Sopenharmony_ci	/* flush both disables and wait for them to finish */
50762306a36Sopenharmony_ci	E1000_WRITE_FLUSH();
50862306a36Sopenharmony_ci	msleep(10);
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci	/* Set the carrier off after transmits have been disabled in the
51162306a36Sopenharmony_ci	 * hardware, to avoid race conditions with e1000_watchdog() (which
51262306a36Sopenharmony_ci	 * may be running concurrently to us, checking for the carrier
51362306a36Sopenharmony_ci	 * bit to decide whether it should enable transmits again). Such
51462306a36Sopenharmony_ci	 * a race condition would result into transmission being disabled
51562306a36Sopenharmony_ci	 * in the hardware until the next IFF_DOWN+IFF_UP cycle.
51662306a36Sopenharmony_ci	 */
51762306a36Sopenharmony_ci	netif_carrier_off(netdev);
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	napi_disable(&adapter->napi);
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci	e1000_irq_disable(adapter);
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci	/* Setting DOWN must be after irq_disable to prevent
52462306a36Sopenharmony_ci	 * a screaming interrupt.  Setting DOWN also prevents
52562306a36Sopenharmony_ci	 * tasks from rescheduling.
52662306a36Sopenharmony_ci	 */
52762306a36Sopenharmony_ci	e1000_down_and_stop(adapter);
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci	adapter->link_speed = 0;
53062306a36Sopenharmony_ci	adapter->link_duplex = 0;
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	e1000_reset(adapter);
53362306a36Sopenharmony_ci	e1000_clean_all_tx_rings(adapter);
53462306a36Sopenharmony_ci	e1000_clean_all_rx_rings(adapter);
53562306a36Sopenharmony_ci}
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_civoid e1000_reinit_locked(struct e1000_adapter *adapter)
53862306a36Sopenharmony_ci{
53962306a36Sopenharmony_ci	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
54062306a36Sopenharmony_ci		msleep(1);
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci	/* only run the task if not already down */
54362306a36Sopenharmony_ci	if (!test_bit(__E1000_DOWN, &adapter->flags)) {
54462306a36Sopenharmony_ci		e1000_down(adapter);
54562306a36Sopenharmony_ci		e1000_up(adapter);
54662306a36Sopenharmony_ci	}
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	clear_bit(__E1000_RESETTING, &adapter->flags);
54962306a36Sopenharmony_ci}
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_civoid e1000_reset(struct e1000_adapter *adapter)
55262306a36Sopenharmony_ci{
55362306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
55462306a36Sopenharmony_ci	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
55562306a36Sopenharmony_ci	bool legacy_pba_adjust = false;
55662306a36Sopenharmony_ci	u16 hwm;
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci	/* Repartition Pba for greater than 9k mtu
55962306a36Sopenharmony_ci	 * To take effect CTRL.RST is required.
56062306a36Sopenharmony_ci	 */
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	switch (hw->mac_type) {
56362306a36Sopenharmony_ci	case e1000_82542_rev2_0:
56462306a36Sopenharmony_ci	case e1000_82542_rev2_1:
56562306a36Sopenharmony_ci	case e1000_82543:
56662306a36Sopenharmony_ci	case e1000_82544:
56762306a36Sopenharmony_ci	case e1000_82540:
56862306a36Sopenharmony_ci	case e1000_82541:
56962306a36Sopenharmony_ci	case e1000_82541_rev_2:
57062306a36Sopenharmony_ci		legacy_pba_adjust = true;
57162306a36Sopenharmony_ci		pba = E1000_PBA_48K;
57262306a36Sopenharmony_ci		break;
57362306a36Sopenharmony_ci	case e1000_82545:
57462306a36Sopenharmony_ci	case e1000_82545_rev_3:
57562306a36Sopenharmony_ci	case e1000_82546:
57662306a36Sopenharmony_ci	case e1000_ce4100:
57762306a36Sopenharmony_ci	case e1000_82546_rev_3:
57862306a36Sopenharmony_ci		pba = E1000_PBA_48K;
57962306a36Sopenharmony_ci		break;
58062306a36Sopenharmony_ci	case e1000_82547:
58162306a36Sopenharmony_ci	case e1000_82547_rev_2:
58262306a36Sopenharmony_ci		legacy_pba_adjust = true;
58362306a36Sopenharmony_ci		pba = E1000_PBA_30K;
58462306a36Sopenharmony_ci		break;
58562306a36Sopenharmony_ci	case e1000_undefined:
58662306a36Sopenharmony_ci	case e1000_num_macs:
58762306a36Sopenharmony_ci		break;
58862306a36Sopenharmony_ci	}
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_ci	if (legacy_pba_adjust) {
59162306a36Sopenharmony_ci		if (hw->max_frame_size > E1000_RXBUFFER_8192)
59262306a36Sopenharmony_ci			pba -= 8; /* allocate more FIFO for Tx */
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci		if (hw->mac_type == e1000_82547) {
59562306a36Sopenharmony_ci			adapter->tx_fifo_head = 0;
59662306a36Sopenharmony_ci			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
59762306a36Sopenharmony_ci			adapter->tx_fifo_size =
59862306a36Sopenharmony_ci				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
59962306a36Sopenharmony_ci			atomic_set(&adapter->tx_fifo_stall, 0);
60062306a36Sopenharmony_ci		}
60162306a36Sopenharmony_ci	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
60262306a36Sopenharmony_ci		/* adjust PBA for jumbo frames */
60362306a36Sopenharmony_ci		ew32(PBA, pba);
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci		/* To maintain wire speed transmits, the Tx FIFO should be
60662306a36Sopenharmony_ci		 * large enough to accommodate two full transmit packets,
60762306a36Sopenharmony_ci		 * rounded up to the next 1KB and expressed in KB.  Likewise,
60862306a36Sopenharmony_ci		 * the Rx FIFO should be large enough to accommodate at least
60962306a36Sopenharmony_ci		 * one full receive packet and is similarly rounded up and
61062306a36Sopenharmony_ci		 * expressed in KB.
61162306a36Sopenharmony_ci		 */
61262306a36Sopenharmony_ci		pba = er32(PBA);
61362306a36Sopenharmony_ci		/* upper 16 bits has Tx packet buffer allocation size in KB */
61462306a36Sopenharmony_ci		tx_space = pba >> 16;
61562306a36Sopenharmony_ci		/* lower 16 bits has Rx packet buffer allocation size in KB */
61662306a36Sopenharmony_ci		pba &= 0xffff;
61762306a36Sopenharmony_ci		/* the Tx fifo also stores 16 bytes of information about the Tx
61862306a36Sopenharmony_ci		 * but don't include ethernet FCS because hardware appends it
61962306a36Sopenharmony_ci		 */
62062306a36Sopenharmony_ci		min_tx_space = (hw->max_frame_size +
62162306a36Sopenharmony_ci				sizeof(struct e1000_tx_desc) -
62262306a36Sopenharmony_ci				ETH_FCS_LEN) * 2;
62362306a36Sopenharmony_ci		min_tx_space = ALIGN(min_tx_space, 1024);
62462306a36Sopenharmony_ci		min_tx_space >>= 10;
62562306a36Sopenharmony_ci		/* software strips receive CRC, so leave room for it */
62662306a36Sopenharmony_ci		min_rx_space = hw->max_frame_size;
62762306a36Sopenharmony_ci		min_rx_space = ALIGN(min_rx_space, 1024);
62862306a36Sopenharmony_ci		min_rx_space >>= 10;
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci		/* If current Tx allocation is less than the min Tx FIFO size,
63162306a36Sopenharmony_ci		 * and the min Tx FIFO size is less than the current Rx FIFO
63262306a36Sopenharmony_ci		 * allocation, take space away from current Rx allocation
63362306a36Sopenharmony_ci		 */
63462306a36Sopenharmony_ci		if (tx_space < min_tx_space &&
63562306a36Sopenharmony_ci		    ((min_tx_space - tx_space) < pba)) {
63662306a36Sopenharmony_ci			pba = pba - (min_tx_space - tx_space);
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci			/* PCI/PCIx hardware has PBA alignment constraints */
63962306a36Sopenharmony_ci			switch (hw->mac_type) {
64062306a36Sopenharmony_ci			case e1000_82545 ... e1000_82546_rev_3:
64162306a36Sopenharmony_ci				pba &= ~(E1000_PBA_8K - 1);
64262306a36Sopenharmony_ci				break;
64362306a36Sopenharmony_ci			default:
64462306a36Sopenharmony_ci				break;
64562306a36Sopenharmony_ci			}
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci			/* if short on Rx space, Rx wins and must trump Tx
64862306a36Sopenharmony_ci			 * adjustment or use Early Receive if available
64962306a36Sopenharmony_ci			 */
65062306a36Sopenharmony_ci			if (pba < min_rx_space)
65162306a36Sopenharmony_ci				pba = min_rx_space;
65262306a36Sopenharmony_ci		}
65362306a36Sopenharmony_ci	}
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci	ew32(PBA, pba);
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci	/* flow control settings:
65862306a36Sopenharmony_ci	 * The high water mark must be low enough to fit one full frame
65962306a36Sopenharmony_ci	 * (or the size used for early receive) above it in the Rx FIFO.
66062306a36Sopenharmony_ci	 * Set it to the lower of:
66162306a36Sopenharmony_ci	 * - 90% of the Rx FIFO size, and
66262306a36Sopenharmony_ci	 * - the full Rx FIFO size minus the early receive size (for parts
66362306a36Sopenharmony_ci	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
66462306a36Sopenharmony_ci	 * - the full Rx FIFO size minus one full frame
66562306a36Sopenharmony_ci	 */
66662306a36Sopenharmony_ci	hwm = min(((pba << 10) * 9 / 10),
66762306a36Sopenharmony_ci		  ((pba << 10) - hw->max_frame_size));
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
67062306a36Sopenharmony_ci	hw->fc_low_water = hw->fc_high_water - 8;
67162306a36Sopenharmony_ci	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
67262306a36Sopenharmony_ci	hw->fc_send_xon = 1;
67362306a36Sopenharmony_ci	hw->fc = hw->original_fc;
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci	/* Allow time for pending master requests to run */
67662306a36Sopenharmony_ci	e1000_reset_hw(hw);
67762306a36Sopenharmony_ci	if (hw->mac_type >= e1000_82544)
67862306a36Sopenharmony_ci		ew32(WUC, 0);
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	if (e1000_init_hw(hw))
68162306a36Sopenharmony_ci		e_dev_err("Hardware Error\n");
68262306a36Sopenharmony_ci	e1000_update_mng_vlan(adapter);
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
68562306a36Sopenharmony_ci	if (hw->mac_type >= e1000_82544 &&
68662306a36Sopenharmony_ci	    hw->autoneg == 1 &&
68762306a36Sopenharmony_ci	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
68862306a36Sopenharmony_ci		u32 ctrl = er32(CTRL);
68962306a36Sopenharmony_ci		/* clear phy power management bit if we are in gig only mode,
69062306a36Sopenharmony_ci		 * which if enabled will attempt negotiation to 100Mb, which
69162306a36Sopenharmony_ci		 * can cause a loss of link at power off or driver unload
69262306a36Sopenharmony_ci		 */
69362306a36Sopenharmony_ci		ctrl &= ~E1000_CTRL_SWDPIN3;
69462306a36Sopenharmony_ci		ew32(CTRL, ctrl);
69562306a36Sopenharmony_ci	}
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
69862306a36Sopenharmony_ci	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	e1000_reset_adaptive(hw);
70162306a36Sopenharmony_ci	e1000_phy_get_info(hw, &adapter->phy_info);
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci	e1000_release_manageability(adapter);
70462306a36Sopenharmony_ci}
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ci/* Dump the eeprom for users having checksum issues */
70762306a36Sopenharmony_cistatic void e1000_dump_eeprom(struct e1000_adapter *adapter)
70862306a36Sopenharmony_ci{
70962306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
71062306a36Sopenharmony_ci	struct ethtool_eeprom eeprom;
71162306a36Sopenharmony_ci	const struct ethtool_ops *ops = netdev->ethtool_ops;
71262306a36Sopenharmony_ci	u8 *data;
71362306a36Sopenharmony_ci	int i;
71462306a36Sopenharmony_ci	u16 csum_old, csum_new = 0;
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	eeprom.len = ops->get_eeprom_len(netdev);
71762306a36Sopenharmony_ci	eeprom.offset = 0;
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci	data = kmalloc(eeprom.len, GFP_KERNEL);
72062306a36Sopenharmony_ci	if (!data)
72162306a36Sopenharmony_ci		return;
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci	ops->get_eeprom(netdev, &eeprom, data);
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_ci	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
72662306a36Sopenharmony_ci		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
72762306a36Sopenharmony_ci	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
72862306a36Sopenharmony_ci		csum_new += data[i] + (data[i + 1] << 8);
72962306a36Sopenharmony_ci	csum_new = EEPROM_SUM - csum_new;
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci	pr_err("/*********************/\n");
73262306a36Sopenharmony_ci	pr_err("Current EEPROM Checksum : 0x%04x\n", csum_old);
73362306a36Sopenharmony_ci	pr_err("Calculated              : 0x%04x\n", csum_new);
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_ci	pr_err("Offset    Values\n");
73662306a36Sopenharmony_ci	pr_err("========  ======\n");
73762306a36Sopenharmony_ci	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci	pr_err("Include this output when contacting your support provider.\n");
74062306a36Sopenharmony_ci	pr_err("This is not a software error! Something bad happened to\n");
74162306a36Sopenharmony_ci	pr_err("your hardware or EEPROM image. Ignoring this problem could\n");
74262306a36Sopenharmony_ci	pr_err("result in further problems, possibly loss of data,\n");
74362306a36Sopenharmony_ci	pr_err("corruption or system hangs!\n");
74462306a36Sopenharmony_ci	pr_err("The MAC Address will be reset to 00:00:00:00:00:00,\n");
74562306a36Sopenharmony_ci	pr_err("which is invalid and requires you to set the proper MAC\n");
74662306a36Sopenharmony_ci	pr_err("address manually before continuing to enable this network\n");
74762306a36Sopenharmony_ci	pr_err("device. Please inspect the EEPROM dump and report the\n");
74862306a36Sopenharmony_ci	pr_err("issue to your hardware vendor or Intel Customer Support.\n");
74962306a36Sopenharmony_ci	pr_err("/*********************/\n");
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	kfree(data);
75262306a36Sopenharmony_ci}
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci/**
75562306a36Sopenharmony_ci * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
75662306a36Sopenharmony_ci * @pdev: PCI device information struct
75762306a36Sopenharmony_ci *
75862306a36Sopenharmony_ci * Return true if an adapter needs ioport resources
75962306a36Sopenharmony_ci **/
76062306a36Sopenharmony_cistatic int e1000_is_need_ioport(struct pci_dev *pdev)
76162306a36Sopenharmony_ci{
76262306a36Sopenharmony_ci	switch (pdev->device) {
76362306a36Sopenharmony_ci	case E1000_DEV_ID_82540EM:
76462306a36Sopenharmony_ci	case E1000_DEV_ID_82540EM_LOM:
76562306a36Sopenharmony_ci	case E1000_DEV_ID_82540EP:
76662306a36Sopenharmony_ci	case E1000_DEV_ID_82540EP_LOM:
76762306a36Sopenharmony_ci	case E1000_DEV_ID_82540EP_LP:
76862306a36Sopenharmony_ci	case E1000_DEV_ID_82541EI:
76962306a36Sopenharmony_ci	case E1000_DEV_ID_82541EI_MOBILE:
77062306a36Sopenharmony_ci	case E1000_DEV_ID_82541ER:
77162306a36Sopenharmony_ci	case E1000_DEV_ID_82541ER_LOM:
77262306a36Sopenharmony_ci	case E1000_DEV_ID_82541GI:
77362306a36Sopenharmony_ci	case E1000_DEV_ID_82541GI_LF:
77462306a36Sopenharmony_ci	case E1000_DEV_ID_82541GI_MOBILE:
77562306a36Sopenharmony_ci	case E1000_DEV_ID_82544EI_COPPER:
77662306a36Sopenharmony_ci	case E1000_DEV_ID_82544EI_FIBER:
77762306a36Sopenharmony_ci	case E1000_DEV_ID_82544GC_COPPER:
77862306a36Sopenharmony_ci	case E1000_DEV_ID_82544GC_LOM:
77962306a36Sopenharmony_ci	case E1000_DEV_ID_82545EM_COPPER:
78062306a36Sopenharmony_ci	case E1000_DEV_ID_82545EM_FIBER:
78162306a36Sopenharmony_ci	case E1000_DEV_ID_82546EB_COPPER:
78262306a36Sopenharmony_ci	case E1000_DEV_ID_82546EB_FIBER:
78362306a36Sopenharmony_ci	case E1000_DEV_ID_82546EB_QUAD_COPPER:
78462306a36Sopenharmony_ci		return true;
78562306a36Sopenharmony_ci	default:
78662306a36Sopenharmony_ci		return false;
78762306a36Sopenharmony_ci	}
78862306a36Sopenharmony_ci}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_cistatic netdev_features_t e1000_fix_features(struct net_device *netdev,
79162306a36Sopenharmony_ci	netdev_features_t features)
79262306a36Sopenharmony_ci{
79362306a36Sopenharmony_ci	/* Since there is no support for separate Rx/Tx vlan accel
79462306a36Sopenharmony_ci	 * enable/disable make sure Tx flag is always in same state as Rx.
79562306a36Sopenharmony_ci	 */
79662306a36Sopenharmony_ci	if (features & NETIF_F_HW_VLAN_CTAG_RX)
79762306a36Sopenharmony_ci		features |= NETIF_F_HW_VLAN_CTAG_TX;
79862306a36Sopenharmony_ci	else
79962306a36Sopenharmony_ci		features &= ~NETIF_F_HW_VLAN_CTAG_TX;
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_ci	return features;
80262306a36Sopenharmony_ci}
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_cistatic int e1000_set_features(struct net_device *netdev,
80562306a36Sopenharmony_ci	netdev_features_t features)
80662306a36Sopenharmony_ci{
80762306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
80862306a36Sopenharmony_ci	netdev_features_t changed = features ^ netdev->features;
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
81162306a36Sopenharmony_ci		e1000_vlan_mode(netdev, features);
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_ci	if (!(changed & (NETIF_F_RXCSUM | NETIF_F_RXALL)))
81462306a36Sopenharmony_ci		return 0;
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci	netdev->features = features;
81762306a36Sopenharmony_ci	adapter->rx_csum = !!(features & NETIF_F_RXCSUM);
81862306a36Sopenharmony_ci
81962306a36Sopenharmony_ci	if (netif_running(netdev))
82062306a36Sopenharmony_ci		e1000_reinit_locked(adapter);
82162306a36Sopenharmony_ci	else
82262306a36Sopenharmony_ci		e1000_reset(adapter);
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_ci	return 1;
82562306a36Sopenharmony_ci}
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_cistatic const struct net_device_ops e1000_netdev_ops = {
82862306a36Sopenharmony_ci	.ndo_open		= e1000_open,
82962306a36Sopenharmony_ci	.ndo_stop		= e1000_close,
83062306a36Sopenharmony_ci	.ndo_start_xmit		= e1000_xmit_frame,
83162306a36Sopenharmony_ci	.ndo_set_rx_mode	= e1000_set_rx_mode,
83262306a36Sopenharmony_ci	.ndo_set_mac_address	= e1000_set_mac,
83362306a36Sopenharmony_ci	.ndo_tx_timeout		= e1000_tx_timeout,
83462306a36Sopenharmony_ci	.ndo_change_mtu		= e1000_change_mtu,
83562306a36Sopenharmony_ci	.ndo_eth_ioctl		= e1000_ioctl,
83662306a36Sopenharmony_ci	.ndo_validate_addr	= eth_validate_addr,
83762306a36Sopenharmony_ci	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
83862306a36Sopenharmony_ci	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
83962306a36Sopenharmony_ci#ifdef CONFIG_NET_POLL_CONTROLLER
84062306a36Sopenharmony_ci	.ndo_poll_controller	= e1000_netpoll,
84162306a36Sopenharmony_ci#endif
84262306a36Sopenharmony_ci	.ndo_fix_features	= e1000_fix_features,
84362306a36Sopenharmony_ci	.ndo_set_features	= e1000_set_features,
84462306a36Sopenharmony_ci};
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_ci/**
84762306a36Sopenharmony_ci * e1000_init_hw_struct - initialize members of hw struct
84862306a36Sopenharmony_ci * @adapter: board private struct
84962306a36Sopenharmony_ci * @hw: structure used by e1000_hw.c
85062306a36Sopenharmony_ci *
85162306a36Sopenharmony_ci * Factors out initialization of the e1000_hw struct to its own function
85262306a36Sopenharmony_ci * that can be called very early at init (just after struct allocation).
85362306a36Sopenharmony_ci * Fields are initialized based on PCI device information and
85462306a36Sopenharmony_ci * OS network device settings (MTU size).
85562306a36Sopenharmony_ci * Returns negative error codes if MAC type setup fails.
85662306a36Sopenharmony_ci */
85762306a36Sopenharmony_cistatic int e1000_init_hw_struct(struct e1000_adapter *adapter,
85862306a36Sopenharmony_ci				struct e1000_hw *hw)
85962306a36Sopenharmony_ci{
86062306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci	/* PCI config space info */
86362306a36Sopenharmony_ci	hw->vendor_id = pdev->vendor;
86462306a36Sopenharmony_ci	hw->device_id = pdev->device;
86562306a36Sopenharmony_ci	hw->subsystem_vendor_id = pdev->subsystem_vendor;
86662306a36Sopenharmony_ci	hw->subsystem_id = pdev->subsystem_device;
86762306a36Sopenharmony_ci	hw->revision_id = pdev->revision;
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_ci	hw->max_frame_size = adapter->netdev->mtu +
87262306a36Sopenharmony_ci			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
87362306a36Sopenharmony_ci	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_ci	/* identify the MAC */
87662306a36Sopenharmony_ci	if (e1000_set_mac_type(hw)) {
87762306a36Sopenharmony_ci		e_err(probe, "Unknown MAC Type\n");
87862306a36Sopenharmony_ci		return -EIO;
87962306a36Sopenharmony_ci	}
88062306a36Sopenharmony_ci
88162306a36Sopenharmony_ci	switch (hw->mac_type) {
88262306a36Sopenharmony_ci	default:
88362306a36Sopenharmony_ci		break;
88462306a36Sopenharmony_ci	case e1000_82541:
88562306a36Sopenharmony_ci	case e1000_82547:
88662306a36Sopenharmony_ci	case e1000_82541_rev_2:
88762306a36Sopenharmony_ci	case e1000_82547_rev_2:
88862306a36Sopenharmony_ci		hw->phy_init_script = 1;
88962306a36Sopenharmony_ci		break;
89062306a36Sopenharmony_ci	}
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_ci	e1000_set_media_type(hw);
89362306a36Sopenharmony_ci	e1000_get_bus_info(hw);
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci	hw->wait_autoneg_complete = false;
89662306a36Sopenharmony_ci	hw->tbi_compatibility_en = true;
89762306a36Sopenharmony_ci	hw->adaptive_ifs = true;
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci	/* Copper options */
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci	if (hw->media_type == e1000_media_type_copper) {
90262306a36Sopenharmony_ci		hw->mdix = AUTO_ALL_MODES;
90362306a36Sopenharmony_ci		hw->disable_polarity_correction = false;
90462306a36Sopenharmony_ci		hw->master_slave = E1000_MASTER_SLAVE;
90562306a36Sopenharmony_ci	}
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_ci	return 0;
90862306a36Sopenharmony_ci}
90962306a36Sopenharmony_ci
91062306a36Sopenharmony_ci/**
91162306a36Sopenharmony_ci * e1000_probe - Device Initialization Routine
91262306a36Sopenharmony_ci * @pdev: PCI device information struct
91362306a36Sopenharmony_ci * @ent: entry in e1000_pci_tbl
91462306a36Sopenharmony_ci *
91562306a36Sopenharmony_ci * Returns 0 on success, negative on failure
91662306a36Sopenharmony_ci *
91762306a36Sopenharmony_ci * e1000_probe initializes an adapter identified by a pci_dev structure.
91862306a36Sopenharmony_ci * The OS initialization, configuring of the adapter private structure,
91962306a36Sopenharmony_ci * and a hardware reset occur.
92062306a36Sopenharmony_ci **/
92162306a36Sopenharmony_cistatic int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
92262306a36Sopenharmony_ci{
92362306a36Sopenharmony_ci	struct net_device *netdev;
92462306a36Sopenharmony_ci	struct e1000_adapter *adapter = NULL;
92562306a36Sopenharmony_ci	struct e1000_hw *hw;
92662306a36Sopenharmony_ci
92762306a36Sopenharmony_ci	static int cards_found;
92862306a36Sopenharmony_ci	static int global_quad_port_a; /* global ksp3 port a indication */
92962306a36Sopenharmony_ci	int i, err, pci_using_dac;
93062306a36Sopenharmony_ci	u16 eeprom_data = 0;
93162306a36Sopenharmony_ci	u16 tmp = 0;
93262306a36Sopenharmony_ci	u16 eeprom_apme_mask = E1000_EEPROM_APME;
93362306a36Sopenharmony_ci	int bars, need_ioport;
93462306a36Sopenharmony_ci	bool disable_dev = false;
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ci	/* do not allocate ioport bars when not needed */
93762306a36Sopenharmony_ci	need_ioport = e1000_is_need_ioport(pdev);
93862306a36Sopenharmony_ci	if (need_ioport) {
93962306a36Sopenharmony_ci		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
94062306a36Sopenharmony_ci		err = pci_enable_device(pdev);
94162306a36Sopenharmony_ci	} else {
94262306a36Sopenharmony_ci		bars = pci_select_bars(pdev, IORESOURCE_MEM);
94362306a36Sopenharmony_ci		err = pci_enable_device_mem(pdev);
94462306a36Sopenharmony_ci	}
94562306a36Sopenharmony_ci	if (err)
94662306a36Sopenharmony_ci		return err;
94762306a36Sopenharmony_ci
94862306a36Sopenharmony_ci	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
94962306a36Sopenharmony_ci	if (err)
95062306a36Sopenharmony_ci		goto err_pci_reg;
95162306a36Sopenharmony_ci
95262306a36Sopenharmony_ci	pci_set_master(pdev);
95362306a36Sopenharmony_ci	err = pci_save_state(pdev);
95462306a36Sopenharmony_ci	if (err)
95562306a36Sopenharmony_ci		goto err_alloc_etherdev;
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_ci	err = -ENOMEM;
95862306a36Sopenharmony_ci	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
95962306a36Sopenharmony_ci	if (!netdev)
96062306a36Sopenharmony_ci		goto err_alloc_etherdev;
96162306a36Sopenharmony_ci
96262306a36Sopenharmony_ci	SET_NETDEV_DEV(netdev, &pdev->dev);
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci	pci_set_drvdata(pdev, netdev);
96562306a36Sopenharmony_ci	adapter = netdev_priv(netdev);
96662306a36Sopenharmony_ci	adapter->netdev = netdev;
96762306a36Sopenharmony_ci	adapter->pdev = pdev;
96862306a36Sopenharmony_ci	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
96962306a36Sopenharmony_ci	adapter->bars = bars;
97062306a36Sopenharmony_ci	adapter->need_ioport = need_ioport;
97162306a36Sopenharmony_ci
97262306a36Sopenharmony_ci	hw = &adapter->hw;
97362306a36Sopenharmony_ci	hw->back = adapter;
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci	err = -EIO;
97662306a36Sopenharmony_ci	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
97762306a36Sopenharmony_ci	if (!hw->hw_addr)
97862306a36Sopenharmony_ci		goto err_ioremap;
97962306a36Sopenharmony_ci
98062306a36Sopenharmony_ci	if (adapter->need_ioport) {
98162306a36Sopenharmony_ci		for (i = BAR_1; i < PCI_STD_NUM_BARS; i++) {
98262306a36Sopenharmony_ci			if (pci_resource_len(pdev, i) == 0)
98362306a36Sopenharmony_ci				continue;
98462306a36Sopenharmony_ci			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
98562306a36Sopenharmony_ci				hw->io_base = pci_resource_start(pdev, i);
98662306a36Sopenharmony_ci				break;
98762306a36Sopenharmony_ci			}
98862306a36Sopenharmony_ci		}
98962306a36Sopenharmony_ci	}
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci	/* make ready for any if (hw->...) below */
99262306a36Sopenharmony_ci	err = e1000_init_hw_struct(adapter, hw);
99362306a36Sopenharmony_ci	if (err)
99462306a36Sopenharmony_ci		goto err_sw_init;
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	/* there is a workaround being applied below that limits
99762306a36Sopenharmony_ci	 * 64-bit DMA addresses to 64-bit hardware.  There are some
99862306a36Sopenharmony_ci	 * 32-bit adapters that Tx hang when given 64-bit DMA addresses
99962306a36Sopenharmony_ci	 */
100062306a36Sopenharmony_ci	pci_using_dac = 0;
100162306a36Sopenharmony_ci	if ((hw->bus_type == e1000_bus_type_pcix) &&
100262306a36Sopenharmony_ci	    !dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
100362306a36Sopenharmony_ci		pci_using_dac = 1;
100462306a36Sopenharmony_ci	} else {
100562306a36Sopenharmony_ci		err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
100662306a36Sopenharmony_ci		if (err) {
100762306a36Sopenharmony_ci			pr_err("No usable DMA config, aborting\n");
100862306a36Sopenharmony_ci			goto err_dma;
100962306a36Sopenharmony_ci		}
101062306a36Sopenharmony_ci	}
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	netdev->netdev_ops = &e1000_netdev_ops;
101362306a36Sopenharmony_ci	e1000_set_ethtool_ops(netdev);
101462306a36Sopenharmony_ci	netdev->watchdog_timeo = 5 * HZ;
101562306a36Sopenharmony_ci	netif_napi_add(netdev, &adapter->napi, e1000_clean);
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
101862306a36Sopenharmony_ci
101962306a36Sopenharmony_ci	adapter->bd_number = cards_found;
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_ci	/* setup the private structure */
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	err = e1000_sw_init(adapter);
102462306a36Sopenharmony_ci	if (err)
102562306a36Sopenharmony_ci		goto err_sw_init;
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_ci	err = -EIO;
102862306a36Sopenharmony_ci	if (hw->mac_type == e1000_ce4100) {
102962306a36Sopenharmony_ci		hw->ce4100_gbe_mdio_base_virt =
103062306a36Sopenharmony_ci					ioremap(pci_resource_start(pdev, BAR_1),
103162306a36Sopenharmony_ci						pci_resource_len(pdev, BAR_1));
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_ci		if (!hw->ce4100_gbe_mdio_base_virt)
103462306a36Sopenharmony_ci			goto err_mdio_ioremap;
103562306a36Sopenharmony_ci	}
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci	if (hw->mac_type >= e1000_82543) {
103862306a36Sopenharmony_ci		netdev->hw_features = NETIF_F_SG |
103962306a36Sopenharmony_ci				   NETIF_F_HW_CSUM |
104062306a36Sopenharmony_ci				   NETIF_F_HW_VLAN_CTAG_RX;
104162306a36Sopenharmony_ci		netdev->features = NETIF_F_HW_VLAN_CTAG_TX |
104262306a36Sopenharmony_ci				   NETIF_F_HW_VLAN_CTAG_FILTER;
104362306a36Sopenharmony_ci	}
104462306a36Sopenharmony_ci
104562306a36Sopenharmony_ci	if ((hw->mac_type >= e1000_82544) &&
104662306a36Sopenharmony_ci	   (hw->mac_type != e1000_82547))
104762306a36Sopenharmony_ci		netdev->hw_features |= NETIF_F_TSO;
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ci	netdev->priv_flags |= IFF_SUPP_NOFCS;
105062306a36Sopenharmony_ci
105162306a36Sopenharmony_ci	netdev->features |= netdev->hw_features;
105262306a36Sopenharmony_ci	netdev->hw_features |= (NETIF_F_RXCSUM |
105362306a36Sopenharmony_ci				NETIF_F_RXALL |
105462306a36Sopenharmony_ci				NETIF_F_RXFCS);
105562306a36Sopenharmony_ci
105662306a36Sopenharmony_ci	if (pci_using_dac) {
105762306a36Sopenharmony_ci		netdev->features |= NETIF_F_HIGHDMA;
105862306a36Sopenharmony_ci		netdev->vlan_features |= NETIF_F_HIGHDMA;
105962306a36Sopenharmony_ci	}
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_ci	netdev->vlan_features |= (NETIF_F_TSO |
106262306a36Sopenharmony_ci				  NETIF_F_HW_CSUM |
106362306a36Sopenharmony_ci				  NETIF_F_SG);
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_ci	/* Do not set IFF_UNICAST_FLT for VMWare's 82545EM */
106662306a36Sopenharmony_ci	if (hw->device_id != E1000_DEV_ID_82545EM_COPPER ||
106762306a36Sopenharmony_ci	    hw->subsystem_vendor_id != PCI_VENDOR_ID_VMWARE)
106862306a36Sopenharmony_ci		netdev->priv_flags |= IFF_UNICAST_FLT;
106962306a36Sopenharmony_ci
107062306a36Sopenharmony_ci	/* MTU range: 46 - 16110 */
107162306a36Sopenharmony_ci	netdev->min_mtu = ETH_ZLEN - ETH_HLEN;
107262306a36Sopenharmony_ci	netdev->max_mtu = MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN);
107362306a36Sopenharmony_ci
107462306a36Sopenharmony_ci	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
107562306a36Sopenharmony_ci
107662306a36Sopenharmony_ci	/* initialize eeprom parameters */
107762306a36Sopenharmony_ci	if (e1000_init_eeprom_params(hw)) {
107862306a36Sopenharmony_ci		e_err(probe, "EEPROM initialization failed\n");
107962306a36Sopenharmony_ci		goto err_eeprom;
108062306a36Sopenharmony_ci	}
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_ci	/* before reading the EEPROM, reset the controller to
108362306a36Sopenharmony_ci	 * put the device in a known good starting state
108462306a36Sopenharmony_ci	 */
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_ci	e1000_reset_hw(hw);
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci	/* make sure the EEPROM is good */
108962306a36Sopenharmony_ci	if (e1000_validate_eeprom_checksum(hw) < 0) {
109062306a36Sopenharmony_ci		e_err(probe, "The EEPROM Checksum Is Not Valid\n");
109162306a36Sopenharmony_ci		e1000_dump_eeprom(adapter);
109262306a36Sopenharmony_ci		/* set MAC address to all zeroes to invalidate and temporary
109362306a36Sopenharmony_ci		 * disable this device for the user. This blocks regular
109462306a36Sopenharmony_ci		 * traffic while still permitting ethtool ioctls from reaching
109562306a36Sopenharmony_ci		 * the hardware as well as allowing the user to run the
109662306a36Sopenharmony_ci		 * interface after manually setting a hw addr using
109762306a36Sopenharmony_ci		 * `ip set address`
109862306a36Sopenharmony_ci		 */
109962306a36Sopenharmony_ci		memset(hw->mac_addr, 0, netdev->addr_len);
110062306a36Sopenharmony_ci	} else {
110162306a36Sopenharmony_ci		/* copy the MAC address out of the EEPROM */
110262306a36Sopenharmony_ci		if (e1000_read_mac_addr(hw))
110362306a36Sopenharmony_ci			e_err(probe, "EEPROM Read Error\n");
110462306a36Sopenharmony_ci	}
110562306a36Sopenharmony_ci	/* don't block initialization here due to bad MAC address */
110662306a36Sopenharmony_ci	eth_hw_addr_set(netdev, hw->mac_addr);
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_ci	if (!is_valid_ether_addr(netdev->dev_addr))
110962306a36Sopenharmony_ci		e_err(probe, "Invalid MAC Address\n");
111062306a36Sopenharmony_ci
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_ci	INIT_DELAYED_WORK(&adapter->watchdog_task, e1000_watchdog);
111362306a36Sopenharmony_ci	INIT_DELAYED_WORK(&adapter->fifo_stall_task,
111462306a36Sopenharmony_ci			  e1000_82547_tx_fifo_stall_task);
111562306a36Sopenharmony_ci	INIT_DELAYED_WORK(&adapter->phy_info_task, e1000_update_phy_info_task);
111662306a36Sopenharmony_ci	INIT_WORK(&adapter->reset_task, e1000_reset_task);
111762306a36Sopenharmony_ci
111862306a36Sopenharmony_ci	e1000_check_options(adapter);
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci	/* Initial Wake on LAN setting
112162306a36Sopenharmony_ci	 * If APM wake is enabled in the EEPROM,
112262306a36Sopenharmony_ci	 * enable the ACPI Magic Packet filter
112362306a36Sopenharmony_ci	 */
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	switch (hw->mac_type) {
112662306a36Sopenharmony_ci	case e1000_82542_rev2_0:
112762306a36Sopenharmony_ci	case e1000_82542_rev2_1:
112862306a36Sopenharmony_ci	case e1000_82543:
112962306a36Sopenharmony_ci		break;
113062306a36Sopenharmony_ci	case e1000_82544:
113162306a36Sopenharmony_ci		e1000_read_eeprom(hw,
113262306a36Sopenharmony_ci			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
113362306a36Sopenharmony_ci		eeprom_apme_mask = E1000_EEPROM_82544_APM;
113462306a36Sopenharmony_ci		break;
113562306a36Sopenharmony_ci	case e1000_82546:
113662306a36Sopenharmony_ci	case e1000_82546_rev_3:
113762306a36Sopenharmony_ci		if (er32(STATUS) & E1000_STATUS_FUNC_1) {
113862306a36Sopenharmony_ci			e1000_read_eeprom(hw,
113962306a36Sopenharmony_ci				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
114062306a36Sopenharmony_ci			break;
114162306a36Sopenharmony_ci		}
114262306a36Sopenharmony_ci		fallthrough;
114362306a36Sopenharmony_ci	default:
114462306a36Sopenharmony_ci		e1000_read_eeprom(hw,
114562306a36Sopenharmony_ci			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
114662306a36Sopenharmony_ci		break;
114762306a36Sopenharmony_ci	}
114862306a36Sopenharmony_ci	if (eeprom_data & eeprom_apme_mask)
114962306a36Sopenharmony_ci		adapter->eeprom_wol |= E1000_WUFC_MAG;
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_ci	/* now that we have the eeprom settings, apply the special cases
115262306a36Sopenharmony_ci	 * where the eeprom may be wrong or the board simply won't support
115362306a36Sopenharmony_ci	 * wake on lan on a particular port
115462306a36Sopenharmony_ci	 */
115562306a36Sopenharmony_ci	switch (pdev->device) {
115662306a36Sopenharmony_ci	case E1000_DEV_ID_82546GB_PCIE:
115762306a36Sopenharmony_ci		adapter->eeprom_wol = 0;
115862306a36Sopenharmony_ci		break;
115962306a36Sopenharmony_ci	case E1000_DEV_ID_82546EB_FIBER:
116062306a36Sopenharmony_ci	case E1000_DEV_ID_82546GB_FIBER:
116162306a36Sopenharmony_ci		/* Wake events only supported on port A for dual fiber
116262306a36Sopenharmony_ci		 * regardless of eeprom setting
116362306a36Sopenharmony_ci		 */
116462306a36Sopenharmony_ci		if (er32(STATUS) & E1000_STATUS_FUNC_1)
116562306a36Sopenharmony_ci			adapter->eeprom_wol = 0;
116662306a36Sopenharmony_ci		break;
116762306a36Sopenharmony_ci	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
116862306a36Sopenharmony_ci		/* if quad port adapter, disable WoL on all but port A */
116962306a36Sopenharmony_ci		if (global_quad_port_a != 0)
117062306a36Sopenharmony_ci			adapter->eeprom_wol = 0;
117162306a36Sopenharmony_ci		else
117262306a36Sopenharmony_ci			adapter->quad_port_a = true;
117362306a36Sopenharmony_ci		/* Reset for multiple quad port adapters */
117462306a36Sopenharmony_ci		if (++global_quad_port_a == 4)
117562306a36Sopenharmony_ci			global_quad_port_a = 0;
117662306a36Sopenharmony_ci		break;
117762306a36Sopenharmony_ci	}
117862306a36Sopenharmony_ci
117962306a36Sopenharmony_ci	/* initialize the wol settings based on the eeprom settings */
118062306a36Sopenharmony_ci	adapter->wol = adapter->eeprom_wol;
118162306a36Sopenharmony_ci	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
118262306a36Sopenharmony_ci
118362306a36Sopenharmony_ci	/* Auto detect PHY address */
118462306a36Sopenharmony_ci	if (hw->mac_type == e1000_ce4100) {
118562306a36Sopenharmony_ci		for (i = 0; i < 32; i++) {
118662306a36Sopenharmony_ci			hw->phy_addr = i;
118762306a36Sopenharmony_ci			e1000_read_phy_reg(hw, PHY_ID2, &tmp);
118862306a36Sopenharmony_ci
118962306a36Sopenharmony_ci			if (tmp != 0 && tmp != 0xFF)
119062306a36Sopenharmony_ci				break;
119162306a36Sopenharmony_ci		}
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_ci		if (i >= 32)
119462306a36Sopenharmony_ci			goto err_eeprom;
119562306a36Sopenharmony_ci	}
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci	/* reset the hardware with the new settings */
119862306a36Sopenharmony_ci	e1000_reset(adapter);
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_ci	strcpy(netdev->name, "eth%d");
120162306a36Sopenharmony_ci	err = register_netdev(netdev);
120262306a36Sopenharmony_ci	if (err)
120362306a36Sopenharmony_ci		goto err_register;
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci	e1000_vlan_filter_on_off(adapter, false);
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_ci	/* print bus type/speed/width info */
120862306a36Sopenharmony_ci	e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n",
120962306a36Sopenharmony_ci	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
121062306a36Sopenharmony_ci	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 :
121162306a36Sopenharmony_ci		(hw->bus_speed == e1000_bus_speed_120) ? 120 :
121262306a36Sopenharmony_ci		(hw->bus_speed == e1000_bus_speed_100) ? 100 :
121362306a36Sopenharmony_ci		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33),
121462306a36Sopenharmony_ci	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
121562306a36Sopenharmony_ci	       netdev->dev_addr);
121662306a36Sopenharmony_ci
121762306a36Sopenharmony_ci	/* carrier off reporting is important to ethtool even BEFORE open */
121862306a36Sopenharmony_ci	netif_carrier_off(netdev);
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_ci	e_info(probe, "Intel(R) PRO/1000 Network Connection\n");
122162306a36Sopenharmony_ci
122262306a36Sopenharmony_ci	cards_found++;
122362306a36Sopenharmony_ci	return 0;
122462306a36Sopenharmony_ci
122562306a36Sopenharmony_cierr_register:
122662306a36Sopenharmony_cierr_eeprom:
122762306a36Sopenharmony_ci	e1000_phy_hw_reset(hw);
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	if (hw->flash_address)
123062306a36Sopenharmony_ci		iounmap(hw->flash_address);
123162306a36Sopenharmony_ci	kfree(adapter->tx_ring);
123262306a36Sopenharmony_ci	kfree(adapter->rx_ring);
123362306a36Sopenharmony_cierr_dma:
123462306a36Sopenharmony_cierr_sw_init:
123562306a36Sopenharmony_cierr_mdio_ioremap:
123662306a36Sopenharmony_ci	iounmap(hw->ce4100_gbe_mdio_base_virt);
123762306a36Sopenharmony_ci	iounmap(hw->hw_addr);
123862306a36Sopenharmony_cierr_ioremap:
123962306a36Sopenharmony_ci	disable_dev = !test_and_set_bit(__E1000_DISABLED, &adapter->flags);
124062306a36Sopenharmony_ci	free_netdev(netdev);
124162306a36Sopenharmony_cierr_alloc_etherdev:
124262306a36Sopenharmony_ci	pci_release_selected_regions(pdev, bars);
124362306a36Sopenharmony_cierr_pci_reg:
124462306a36Sopenharmony_ci	if (!adapter || disable_dev)
124562306a36Sopenharmony_ci		pci_disable_device(pdev);
124662306a36Sopenharmony_ci	return err;
124762306a36Sopenharmony_ci}
124862306a36Sopenharmony_ci
124962306a36Sopenharmony_ci/**
125062306a36Sopenharmony_ci * e1000_remove - Device Removal Routine
125162306a36Sopenharmony_ci * @pdev: PCI device information struct
125262306a36Sopenharmony_ci *
125362306a36Sopenharmony_ci * e1000_remove is called by the PCI subsystem to alert the driver
125462306a36Sopenharmony_ci * that it should release a PCI device. That could be caused by a
125562306a36Sopenharmony_ci * Hot-Plug event, or because the driver is going to be removed from
125662306a36Sopenharmony_ci * memory.
125762306a36Sopenharmony_ci **/
125862306a36Sopenharmony_cistatic void e1000_remove(struct pci_dev *pdev)
125962306a36Sopenharmony_ci{
126062306a36Sopenharmony_ci	struct net_device *netdev = pci_get_drvdata(pdev);
126162306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
126262306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
126362306a36Sopenharmony_ci	bool disable_dev;
126462306a36Sopenharmony_ci
126562306a36Sopenharmony_ci	e1000_down_and_stop(adapter);
126662306a36Sopenharmony_ci	e1000_release_manageability(adapter);
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci	unregister_netdev(netdev);
126962306a36Sopenharmony_ci
127062306a36Sopenharmony_ci	e1000_phy_hw_reset(hw);
127162306a36Sopenharmony_ci
127262306a36Sopenharmony_ci	kfree(adapter->tx_ring);
127362306a36Sopenharmony_ci	kfree(adapter->rx_ring);
127462306a36Sopenharmony_ci
127562306a36Sopenharmony_ci	if (hw->mac_type == e1000_ce4100)
127662306a36Sopenharmony_ci		iounmap(hw->ce4100_gbe_mdio_base_virt);
127762306a36Sopenharmony_ci	iounmap(hw->hw_addr);
127862306a36Sopenharmony_ci	if (hw->flash_address)
127962306a36Sopenharmony_ci		iounmap(hw->flash_address);
128062306a36Sopenharmony_ci	pci_release_selected_regions(pdev, adapter->bars);
128162306a36Sopenharmony_ci
128262306a36Sopenharmony_ci	disable_dev = !test_and_set_bit(__E1000_DISABLED, &adapter->flags);
128362306a36Sopenharmony_ci	free_netdev(netdev);
128462306a36Sopenharmony_ci
128562306a36Sopenharmony_ci	if (disable_dev)
128662306a36Sopenharmony_ci		pci_disable_device(pdev);
128762306a36Sopenharmony_ci}
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_ci/**
129062306a36Sopenharmony_ci * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
129162306a36Sopenharmony_ci * @adapter: board private structure to initialize
129262306a36Sopenharmony_ci *
129362306a36Sopenharmony_ci * e1000_sw_init initializes the Adapter private data structure.
129462306a36Sopenharmony_ci * e1000_init_hw_struct MUST be called before this function
129562306a36Sopenharmony_ci **/
129662306a36Sopenharmony_cistatic int e1000_sw_init(struct e1000_adapter *adapter)
129762306a36Sopenharmony_ci{
129862306a36Sopenharmony_ci	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_ci	adapter->num_tx_queues = 1;
130162306a36Sopenharmony_ci	adapter->num_rx_queues = 1;
130262306a36Sopenharmony_ci
130362306a36Sopenharmony_ci	if (e1000_alloc_queues(adapter)) {
130462306a36Sopenharmony_ci		e_err(probe, "Unable to allocate memory for queues\n");
130562306a36Sopenharmony_ci		return -ENOMEM;
130662306a36Sopenharmony_ci	}
130762306a36Sopenharmony_ci
130862306a36Sopenharmony_ci	/* Explicitly disable IRQ since the NIC can be in any state. */
130962306a36Sopenharmony_ci	e1000_irq_disable(adapter);
131062306a36Sopenharmony_ci
131162306a36Sopenharmony_ci	spin_lock_init(&adapter->stats_lock);
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci	set_bit(__E1000_DOWN, &adapter->flags);
131462306a36Sopenharmony_ci
131562306a36Sopenharmony_ci	return 0;
131662306a36Sopenharmony_ci}
131762306a36Sopenharmony_ci
131862306a36Sopenharmony_ci/**
131962306a36Sopenharmony_ci * e1000_alloc_queues - Allocate memory for all rings
132062306a36Sopenharmony_ci * @adapter: board private structure to initialize
132162306a36Sopenharmony_ci *
132262306a36Sopenharmony_ci * We allocate one ring per queue at run-time since we don't know the
132362306a36Sopenharmony_ci * number of queues at compile-time.
132462306a36Sopenharmony_ci **/
132562306a36Sopenharmony_cistatic int e1000_alloc_queues(struct e1000_adapter *adapter)
132662306a36Sopenharmony_ci{
132762306a36Sopenharmony_ci	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
132862306a36Sopenharmony_ci				   sizeof(struct e1000_tx_ring), GFP_KERNEL);
132962306a36Sopenharmony_ci	if (!adapter->tx_ring)
133062306a36Sopenharmony_ci		return -ENOMEM;
133162306a36Sopenharmony_ci
133262306a36Sopenharmony_ci	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
133362306a36Sopenharmony_ci				   sizeof(struct e1000_rx_ring), GFP_KERNEL);
133462306a36Sopenharmony_ci	if (!adapter->rx_ring) {
133562306a36Sopenharmony_ci		kfree(adapter->tx_ring);
133662306a36Sopenharmony_ci		return -ENOMEM;
133762306a36Sopenharmony_ci	}
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_ci	return E1000_SUCCESS;
134062306a36Sopenharmony_ci}
134162306a36Sopenharmony_ci
134262306a36Sopenharmony_ci/**
134362306a36Sopenharmony_ci * e1000_open - Called when a network interface is made active
134462306a36Sopenharmony_ci * @netdev: network interface device structure
134562306a36Sopenharmony_ci *
134662306a36Sopenharmony_ci * Returns 0 on success, negative value on failure
134762306a36Sopenharmony_ci *
134862306a36Sopenharmony_ci * The open entry point is called when a network interface is made
134962306a36Sopenharmony_ci * active by the system (IFF_UP).  At this point all resources needed
135062306a36Sopenharmony_ci * for transmit and receive operations are allocated, the interrupt
135162306a36Sopenharmony_ci * handler is registered with the OS, the watchdog task is started,
135262306a36Sopenharmony_ci * and the stack is notified that the interface is ready.
135362306a36Sopenharmony_ci **/
135462306a36Sopenharmony_ciint e1000_open(struct net_device *netdev)
135562306a36Sopenharmony_ci{
135662306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
135762306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
135862306a36Sopenharmony_ci	int err;
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ci	/* disallow open during test */
136162306a36Sopenharmony_ci	if (test_bit(__E1000_TESTING, &adapter->flags))
136262306a36Sopenharmony_ci		return -EBUSY;
136362306a36Sopenharmony_ci
136462306a36Sopenharmony_ci	netif_carrier_off(netdev);
136562306a36Sopenharmony_ci
136662306a36Sopenharmony_ci	/* allocate transmit descriptors */
136762306a36Sopenharmony_ci	err = e1000_setup_all_tx_resources(adapter);
136862306a36Sopenharmony_ci	if (err)
136962306a36Sopenharmony_ci		goto err_setup_tx;
137062306a36Sopenharmony_ci
137162306a36Sopenharmony_ci	/* allocate receive descriptors */
137262306a36Sopenharmony_ci	err = e1000_setup_all_rx_resources(adapter);
137362306a36Sopenharmony_ci	if (err)
137462306a36Sopenharmony_ci		goto err_setup_rx;
137562306a36Sopenharmony_ci
137662306a36Sopenharmony_ci	e1000_power_up_phy(adapter);
137762306a36Sopenharmony_ci
137862306a36Sopenharmony_ci	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
137962306a36Sopenharmony_ci	if ((hw->mng_cookie.status &
138062306a36Sopenharmony_ci			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
138162306a36Sopenharmony_ci		e1000_update_mng_vlan(adapter);
138262306a36Sopenharmony_ci	}
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_ci	/* before we allocate an interrupt, we must be ready to handle it.
138562306a36Sopenharmony_ci	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
138662306a36Sopenharmony_ci	 * as soon as we call pci_request_irq, so we have to setup our
138762306a36Sopenharmony_ci	 * clean_rx handler before we do so.
138862306a36Sopenharmony_ci	 */
138962306a36Sopenharmony_ci	e1000_configure(adapter);
139062306a36Sopenharmony_ci
139162306a36Sopenharmony_ci	err = e1000_request_irq(adapter);
139262306a36Sopenharmony_ci	if (err)
139362306a36Sopenharmony_ci		goto err_req_irq;
139462306a36Sopenharmony_ci
139562306a36Sopenharmony_ci	/* From here on the code is the same as e1000_up() */
139662306a36Sopenharmony_ci	clear_bit(__E1000_DOWN, &adapter->flags);
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci	napi_enable(&adapter->napi);
139962306a36Sopenharmony_ci
140062306a36Sopenharmony_ci	e1000_irq_enable(adapter);
140162306a36Sopenharmony_ci
140262306a36Sopenharmony_ci	netif_start_queue(netdev);
140362306a36Sopenharmony_ci
140462306a36Sopenharmony_ci	/* fire a link status change interrupt to start the watchdog */
140562306a36Sopenharmony_ci	ew32(ICS, E1000_ICS_LSC);
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_ci	return E1000_SUCCESS;
140862306a36Sopenharmony_ci
140962306a36Sopenharmony_cierr_req_irq:
141062306a36Sopenharmony_ci	e1000_power_down_phy(adapter);
141162306a36Sopenharmony_ci	e1000_free_all_rx_resources(adapter);
141262306a36Sopenharmony_cierr_setup_rx:
141362306a36Sopenharmony_ci	e1000_free_all_tx_resources(adapter);
141462306a36Sopenharmony_cierr_setup_tx:
141562306a36Sopenharmony_ci	e1000_reset(adapter);
141662306a36Sopenharmony_ci
141762306a36Sopenharmony_ci	return err;
141862306a36Sopenharmony_ci}
141962306a36Sopenharmony_ci
142062306a36Sopenharmony_ci/**
142162306a36Sopenharmony_ci * e1000_close - Disables a network interface
142262306a36Sopenharmony_ci * @netdev: network interface device structure
142362306a36Sopenharmony_ci *
142462306a36Sopenharmony_ci * Returns 0, this is not allowed to fail
142562306a36Sopenharmony_ci *
142662306a36Sopenharmony_ci * The close entry point is called when an interface is de-activated
142762306a36Sopenharmony_ci * by the OS.  The hardware is still under the drivers control, but
142862306a36Sopenharmony_ci * needs to be disabled.  A global MAC reset is issued to stop the
142962306a36Sopenharmony_ci * hardware, and all transmit and receive resources are freed.
143062306a36Sopenharmony_ci **/
143162306a36Sopenharmony_ciint e1000_close(struct net_device *netdev)
143262306a36Sopenharmony_ci{
143362306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
143462306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
143562306a36Sopenharmony_ci	int count = E1000_CHECK_RESET_COUNT;
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags) && count--)
143862306a36Sopenharmony_ci		usleep_range(10000, 20000);
143962306a36Sopenharmony_ci
144062306a36Sopenharmony_ci	WARN_ON(count < 0);
144162306a36Sopenharmony_ci
144262306a36Sopenharmony_ci	/* signal that we're down so that the reset task will no longer run */
144362306a36Sopenharmony_ci	set_bit(__E1000_DOWN, &adapter->flags);
144462306a36Sopenharmony_ci	clear_bit(__E1000_RESETTING, &adapter->flags);
144562306a36Sopenharmony_ci
144662306a36Sopenharmony_ci	e1000_down(adapter);
144762306a36Sopenharmony_ci	e1000_power_down_phy(adapter);
144862306a36Sopenharmony_ci	e1000_free_irq(adapter);
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci	e1000_free_all_tx_resources(adapter);
145162306a36Sopenharmony_ci	e1000_free_all_rx_resources(adapter);
145262306a36Sopenharmony_ci
145362306a36Sopenharmony_ci	/* kill manageability vlan ID if supported, but not if a vlan with
145462306a36Sopenharmony_ci	 * the same ID is registered on the host OS (let 8021q kill it)
145562306a36Sopenharmony_ci	 */
145662306a36Sopenharmony_ci	if ((hw->mng_cookie.status &
145762306a36Sopenharmony_ci	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
145862306a36Sopenharmony_ci	    !test_bit(adapter->mng_vlan_id, adapter->active_vlans)) {
145962306a36Sopenharmony_ci		e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q),
146062306a36Sopenharmony_ci				       adapter->mng_vlan_id);
146162306a36Sopenharmony_ci	}
146262306a36Sopenharmony_ci
146362306a36Sopenharmony_ci	return 0;
146462306a36Sopenharmony_ci}
146562306a36Sopenharmony_ci
146662306a36Sopenharmony_ci/**
146762306a36Sopenharmony_ci * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
146862306a36Sopenharmony_ci * @adapter: address of board private structure
146962306a36Sopenharmony_ci * @start: address of beginning of memory
147062306a36Sopenharmony_ci * @len: length of memory
147162306a36Sopenharmony_ci **/
147262306a36Sopenharmony_cistatic bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
147362306a36Sopenharmony_ci				  unsigned long len)
147462306a36Sopenharmony_ci{
147562306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
147662306a36Sopenharmony_ci	unsigned long begin = (unsigned long)start;
147762306a36Sopenharmony_ci	unsigned long end = begin + len;
147862306a36Sopenharmony_ci
147962306a36Sopenharmony_ci	/* First rev 82545 and 82546 need to not allow any memory
148062306a36Sopenharmony_ci	 * write location to cross 64k boundary due to errata 23
148162306a36Sopenharmony_ci	 */
148262306a36Sopenharmony_ci	if (hw->mac_type == e1000_82545 ||
148362306a36Sopenharmony_ci	    hw->mac_type == e1000_ce4100 ||
148462306a36Sopenharmony_ci	    hw->mac_type == e1000_82546) {
148562306a36Sopenharmony_ci		return ((begin ^ (end - 1)) >> 16) == 0;
148662306a36Sopenharmony_ci	}
148762306a36Sopenharmony_ci
148862306a36Sopenharmony_ci	return true;
148962306a36Sopenharmony_ci}
149062306a36Sopenharmony_ci
149162306a36Sopenharmony_ci/**
149262306a36Sopenharmony_ci * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
149362306a36Sopenharmony_ci * @adapter: board private structure
149462306a36Sopenharmony_ci * @txdr:    tx descriptor ring (for a specific queue) to setup
149562306a36Sopenharmony_ci *
149662306a36Sopenharmony_ci * Return 0 on success, negative on failure
149762306a36Sopenharmony_ci **/
149862306a36Sopenharmony_cistatic int e1000_setup_tx_resources(struct e1000_adapter *adapter,
149962306a36Sopenharmony_ci				    struct e1000_tx_ring *txdr)
150062306a36Sopenharmony_ci{
150162306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
150262306a36Sopenharmony_ci	int size;
150362306a36Sopenharmony_ci
150462306a36Sopenharmony_ci	size = sizeof(struct e1000_tx_buffer) * txdr->count;
150562306a36Sopenharmony_ci	txdr->buffer_info = vzalloc(size);
150662306a36Sopenharmony_ci	if (!txdr->buffer_info)
150762306a36Sopenharmony_ci		return -ENOMEM;
150862306a36Sopenharmony_ci
150962306a36Sopenharmony_ci	/* round up to nearest 4K */
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ci	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
151262306a36Sopenharmony_ci	txdr->size = ALIGN(txdr->size, 4096);
151362306a36Sopenharmony_ci
151462306a36Sopenharmony_ci	txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma,
151562306a36Sopenharmony_ci					GFP_KERNEL);
151662306a36Sopenharmony_ci	if (!txdr->desc) {
151762306a36Sopenharmony_cisetup_tx_desc_die:
151862306a36Sopenharmony_ci		vfree(txdr->buffer_info);
151962306a36Sopenharmony_ci		return -ENOMEM;
152062306a36Sopenharmony_ci	}
152162306a36Sopenharmony_ci
152262306a36Sopenharmony_ci	/* Fix for errata 23, can't cross 64kB boundary */
152362306a36Sopenharmony_ci	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
152462306a36Sopenharmony_ci		void *olddesc = txdr->desc;
152562306a36Sopenharmony_ci		dma_addr_t olddma = txdr->dma;
152662306a36Sopenharmony_ci		e_err(tx_err, "txdr align check failed: %u bytes at %p\n",
152762306a36Sopenharmony_ci		      txdr->size, txdr->desc);
152862306a36Sopenharmony_ci		/* Try again, without freeing the previous */
152962306a36Sopenharmony_ci		txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size,
153062306a36Sopenharmony_ci						&txdr->dma, GFP_KERNEL);
153162306a36Sopenharmony_ci		/* Failed allocation, critical failure */
153262306a36Sopenharmony_ci		if (!txdr->desc) {
153362306a36Sopenharmony_ci			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
153462306a36Sopenharmony_ci					  olddma);
153562306a36Sopenharmony_ci			goto setup_tx_desc_die;
153662306a36Sopenharmony_ci		}
153762306a36Sopenharmony_ci
153862306a36Sopenharmony_ci		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
153962306a36Sopenharmony_ci			/* give up */
154062306a36Sopenharmony_ci			dma_free_coherent(&pdev->dev, txdr->size, txdr->desc,
154162306a36Sopenharmony_ci					  txdr->dma);
154262306a36Sopenharmony_ci			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
154362306a36Sopenharmony_ci					  olddma);
154462306a36Sopenharmony_ci			e_err(probe, "Unable to allocate aligned memory "
154562306a36Sopenharmony_ci			      "for the transmit descriptor ring\n");
154662306a36Sopenharmony_ci			vfree(txdr->buffer_info);
154762306a36Sopenharmony_ci			return -ENOMEM;
154862306a36Sopenharmony_ci		} else {
154962306a36Sopenharmony_ci			/* Free old allocation, new allocation was successful */
155062306a36Sopenharmony_ci			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
155162306a36Sopenharmony_ci					  olddma);
155262306a36Sopenharmony_ci		}
155362306a36Sopenharmony_ci	}
155462306a36Sopenharmony_ci	memset(txdr->desc, 0, txdr->size);
155562306a36Sopenharmony_ci
155662306a36Sopenharmony_ci	txdr->next_to_use = 0;
155762306a36Sopenharmony_ci	txdr->next_to_clean = 0;
155862306a36Sopenharmony_ci
155962306a36Sopenharmony_ci	return 0;
156062306a36Sopenharmony_ci}
156162306a36Sopenharmony_ci
156262306a36Sopenharmony_ci/**
156362306a36Sopenharmony_ci * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
156462306a36Sopenharmony_ci * 				  (Descriptors) for all queues
156562306a36Sopenharmony_ci * @adapter: board private structure
156662306a36Sopenharmony_ci *
156762306a36Sopenharmony_ci * Return 0 on success, negative on failure
156862306a36Sopenharmony_ci **/
156962306a36Sopenharmony_ciint e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
157062306a36Sopenharmony_ci{
157162306a36Sopenharmony_ci	int i, err = 0;
157262306a36Sopenharmony_ci
157362306a36Sopenharmony_ci	for (i = 0; i < adapter->num_tx_queues; i++) {
157462306a36Sopenharmony_ci		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
157562306a36Sopenharmony_ci		if (err) {
157662306a36Sopenharmony_ci			e_err(probe, "Allocation for Tx Queue %u failed\n", i);
157762306a36Sopenharmony_ci			for (i-- ; i >= 0; i--)
157862306a36Sopenharmony_ci				e1000_free_tx_resources(adapter,
157962306a36Sopenharmony_ci							&adapter->tx_ring[i]);
158062306a36Sopenharmony_ci			break;
158162306a36Sopenharmony_ci		}
158262306a36Sopenharmony_ci	}
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci	return err;
158562306a36Sopenharmony_ci}
158662306a36Sopenharmony_ci
158762306a36Sopenharmony_ci/**
158862306a36Sopenharmony_ci * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
158962306a36Sopenharmony_ci * @adapter: board private structure
159062306a36Sopenharmony_ci *
159162306a36Sopenharmony_ci * Configure the Tx unit of the MAC after a reset.
159262306a36Sopenharmony_ci **/
159362306a36Sopenharmony_cistatic void e1000_configure_tx(struct e1000_adapter *adapter)
159462306a36Sopenharmony_ci{
159562306a36Sopenharmony_ci	u64 tdba;
159662306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
159762306a36Sopenharmony_ci	u32 tdlen, tctl, tipg;
159862306a36Sopenharmony_ci	u32 ipgr1, ipgr2;
159962306a36Sopenharmony_ci
160062306a36Sopenharmony_ci	/* Setup the HW Tx Head and Tail descriptor pointers */
160162306a36Sopenharmony_ci
160262306a36Sopenharmony_ci	switch (adapter->num_tx_queues) {
160362306a36Sopenharmony_ci	case 1:
160462306a36Sopenharmony_ci	default:
160562306a36Sopenharmony_ci		tdba = adapter->tx_ring[0].dma;
160662306a36Sopenharmony_ci		tdlen = adapter->tx_ring[0].count *
160762306a36Sopenharmony_ci			sizeof(struct e1000_tx_desc);
160862306a36Sopenharmony_ci		ew32(TDLEN, tdlen);
160962306a36Sopenharmony_ci		ew32(TDBAH, (tdba >> 32));
161062306a36Sopenharmony_ci		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
161162306a36Sopenharmony_ci		ew32(TDT, 0);
161262306a36Sopenharmony_ci		ew32(TDH, 0);
161362306a36Sopenharmony_ci		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ?
161462306a36Sopenharmony_ci					   E1000_TDH : E1000_82542_TDH);
161562306a36Sopenharmony_ci		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ?
161662306a36Sopenharmony_ci					   E1000_TDT : E1000_82542_TDT);
161762306a36Sopenharmony_ci		break;
161862306a36Sopenharmony_ci	}
161962306a36Sopenharmony_ci
162062306a36Sopenharmony_ci	/* Set the default values for the Tx Inter Packet Gap timer */
162162306a36Sopenharmony_ci	if ((hw->media_type == e1000_media_type_fiber ||
162262306a36Sopenharmony_ci	     hw->media_type == e1000_media_type_internal_serdes))
162362306a36Sopenharmony_ci		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
162462306a36Sopenharmony_ci	else
162562306a36Sopenharmony_ci		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
162662306a36Sopenharmony_ci
162762306a36Sopenharmony_ci	switch (hw->mac_type) {
162862306a36Sopenharmony_ci	case e1000_82542_rev2_0:
162962306a36Sopenharmony_ci	case e1000_82542_rev2_1:
163062306a36Sopenharmony_ci		tipg = DEFAULT_82542_TIPG_IPGT;
163162306a36Sopenharmony_ci		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
163262306a36Sopenharmony_ci		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
163362306a36Sopenharmony_ci		break;
163462306a36Sopenharmony_ci	default:
163562306a36Sopenharmony_ci		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
163662306a36Sopenharmony_ci		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
163762306a36Sopenharmony_ci		break;
163862306a36Sopenharmony_ci	}
163962306a36Sopenharmony_ci	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
164062306a36Sopenharmony_ci	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
164162306a36Sopenharmony_ci	ew32(TIPG, tipg);
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_ci	/* Set the Tx Interrupt Delay register */
164462306a36Sopenharmony_ci
164562306a36Sopenharmony_ci	ew32(TIDV, adapter->tx_int_delay);
164662306a36Sopenharmony_ci	if (hw->mac_type >= e1000_82540)
164762306a36Sopenharmony_ci		ew32(TADV, adapter->tx_abs_int_delay);
164862306a36Sopenharmony_ci
164962306a36Sopenharmony_ci	/* Program the Transmit Control Register */
165062306a36Sopenharmony_ci
165162306a36Sopenharmony_ci	tctl = er32(TCTL);
165262306a36Sopenharmony_ci	tctl &= ~E1000_TCTL_CT;
165362306a36Sopenharmony_ci	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
165462306a36Sopenharmony_ci		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
165562306a36Sopenharmony_ci
165662306a36Sopenharmony_ci	e1000_config_collision_dist(hw);
165762306a36Sopenharmony_ci
165862306a36Sopenharmony_ci	/* Setup Transmit Descriptor Settings for eop descriptor */
165962306a36Sopenharmony_ci	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
166062306a36Sopenharmony_ci
166162306a36Sopenharmony_ci	/* only set IDE if we are delaying interrupts using the timers */
166262306a36Sopenharmony_ci	if (adapter->tx_int_delay)
166362306a36Sopenharmony_ci		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
166462306a36Sopenharmony_ci
166562306a36Sopenharmony_ci	if (hw->mac_type < e1000_82543)
166662306a36Sopenharmony_ci		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
166762306a36Sopenharmony_ci	else
166862306a36Sopenharmony_ci		adapter->txd_cmd |= E1000_TXD_CMD_RS;
166962306a36Sopenharmony_ci
167062306a36Sopenharmony_ci	/* Cache if we're 82544 running in PCI-X because we'll
167162306a36Sopenharmony_ci	 * need this to apply a workaround later in the send path.
167262306a36Sopenharmony_ci	 */
167362306a36Sopenharmony_ci	if (hw->mac_type == e1000_82544 &&
167462306a36Sopenharmony_ci	    hw->bus_type == e1000_bus_type_pcix)
167562306a36Sopenharmony_ci		adapter->pcix_82544 = true;
167662306a36Sopenharmony_ci
167762306a36Sopenharmony_ci	ew32(TCTL, tctl);
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_ci}
168062306a36Sopenharmony_ci
168162306a36Sopenharmony_ci/**
168262306a36Sopenharmony_ci * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
168362306a36Sopenharmony_ci * @adapter: board private structure
168462306a36Sopenharmony_ci * @rxdr:    rx descriptor ring (for a specific queue) to setup
168562306a36Sopenharmony_ci *
168662306a36Sopenharmony_ci * Returns 0 on success, negative on failure
168762306a36Sopenharmony_ci **/
168862306a36Sopenharmony_cistatic int e1000_setup_rx_resources(struct e1000_adapter *adapter,
168962306a36Sopenharmony_ci				    struct e1000_rx_ring *rxdr)
169062306a36Sopenharmony_ci{
169162306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
169262306a36Sopenharmony_ci	int size, desc_len;
169362306a36Sopenharmony_ci
169462306a36Sopenharmony_ci	size = sizeof(struct e1000_rx_buffer) * rxdr->count;
169562306a36Sopenharmony_ci	rxdr->buffer_info = vzalloc(size);
169662306a36Sopenharmony_ci	if (!rxdr->buffer_info)
169762306a36Sopenharmony_ci		return -ENOMEM;
169862306a36Sopenharmony_ci
169962306a36Sopenharmony_ci	desc_len = sizeof(struct e1000_rx_desc);
170062306a36Sopenharmony_ci
170162306a36Sopenharmony_ci	/* Round up to nearest 4K */
170262306a36Sopenharmony_ci
170362306a36Sopenharmony_ci	rxdr->size = rxdr->count * desc_len;
170462306a36Sopenharmony_ci	rxdr->size = ALIGN(rxdr->size, 4096);
170562306a36Sopenharmony_ci
170662306a36Sopenharmony_ci	rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
170762306a36Sopenharmony_ci					GFP_KERNEL);
170862306a36Sopenharmony_ci	if (!rxdr->desc) {
170962306a36Sopenharmony_cisetup_rx_desc_die:
171062306a36Sopenharmony_ci		vfree(rxdr->buffer_info);
171162306a36Sopenharmony_ci		return -ENOMEM;
171262306a36Sopenharmony_ci	}
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ci	/* Fix for errata 23, can't cross 64kB boundary */
171562306a36Sopenharmony_ci	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
171662306a36Sopenharmony_ci		void *olddesc = rxdr->desc;
171762306a36Sopenharmony_ci		dma_addr_t olddma = rxdr->dma;
171862306a36Sopenharmony_ci		e_err(rx_err, "rxdr align check failed: %u bytes at %p\n",
171962306a36Sopenharmony_ci		      rxdr->size, rxdr->desc);
172062306a36Sopenharmony_ci		/* Try again, without freeing the previous */
172162306a36Sopenharmony_ci		rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size,
172262306a36Sopenharmony_ci						&rxdr->dma, GFP_KERNEL);
172362306a36Sopenharmony_ci		/* Failed allocation, critical failure */
172462306a36Sopenharmony_ci		if (!rxdr->desc) {
172562306a36Sopenharmony_ci			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
172662306a36Sopenharmony_ci					  olddma);
172762306a36Sopenharmony_ci			goto setup_rx_desc_die;
172862306a36Sopenharmony_ci		}
172962306a36Sopenharmony_ci
173062306a36Sopenharmony_ci		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
173162306a36Sopenharmony_ci			/* give up */
173262306a36Sopenharmony_ci			dma_free_coherent(&pdev->dev, rxdr->size, rxdr->desc,
173362306a36Sopenharmony_ci					  rxdr->dma);
173462306a36Sopenharmony_ci			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
173562306a36Sopenharmony_ci					  olddma);
173662306a36Sopenharmony_ci			e_err(probe, "Unable to allocate aligned memory for "
173762306a36Sopenharmony_ci			      "the Rx descriptor ring\n");
173862306a36Sopenharmony_ci			goto setup_rx_desc_die;
173962306a36Sopenharmony_ci		} else {
174062306a36Sopenharmony_ci			/* Free old allocation, new allocation was successful */
174162306a36Sopenharmony_ci			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
174262306a36Sopenharmony_ci					  olddma);
174362306a36Sopenharmony_ci		}
174462306a36Sopenharmony_ci	}
174562306a36Sopenharmony_ci	memset(rxdr->desc, 0, rxdr->size);
174662306a36Sopenharmony_ci
174762306a36Sopenharmony_ci	rxdr->next_to_clean = 0;
174862306a36Sopenharmony_ci	rxdr->next_to_use = 0;
174962306a36Sopenharmony_ci	rxdr->rx_skb_top = NULL;
175062306a36Sopenharmony_ci
175162306a36Sopenharmony_ci	return 0;
175262306a36Sopenharmony_ci}
175362306a36Sopenharmony_ci
175462306a36Sopenharmony_ci/**
175562306a36Sopenharmony_ci * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
175662306a36Sopenharmony_ci * 				  (Descriptors) for all queues
175762306a36Sopenharmony_ci * @adapter: board private structure
175862306a36Sopenharmony_ci *
175962306a36Sopenharmony_ci * Return 0 on success, negative on failure
176062306a36Sopenharmony_ci **/
176162306a36Sopenharmony_ciint e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
176262306a36Sopenharmony_ci{
176362306a36Sopenharmony_ci	int i, err = 0;
176462306a36Sopenharmony_ci
176562306a36Sopenharmony_ci	for (i = 0; i < adapter->num_rx_queues; i++) {
176662306a36Sopenharmony_ci		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
176762306a36Sopenharmony_ci		if (err) {
176862306a36Sopenharmony_ci			e_err(probe, "Allocation for Rx Queue %u failed\n", i);
176962306a36Sopenharmony_ci			for (i-- ; i >= 0; i--)
177062306a36Sopenharmony_ci				e1000_free_rx_resources(adapter,
177162306a36Sopenharmony_ci							&adapter->rx_ring[i]);
177262306a36Sopenharmony_ci			break;
177362306a36Sopenharmony_ci		}
177462306a36Sopenharmony_ci	}
177562306a36Sopenharmony_ci
177662306a36Sopenharmony_ci	return err;
177762306a36Sopenharmony_ci}
177862306a36Sopenharmony_ci
177962306a36Sopenharmony_ci/**
178062306a36Sopenharmony_ci * e1000_setup_rctl - configure the receive control registers
178162306a36Sopenharmony_ci * @adapter: Board private structure
178262306a36Sopenharmony_ci **/
178362306a36Sopenharmony_cistatic void e1000_setup_rctl(struct e1000_adapter *adapter)
178462306a36Sopenharmony_ci{
178562306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
178662306a36Sopenharmony_ci	u32 rctl;
178762306a36Sopenharmony_ci
178862306a36Sopenharmony_ci	rctl = er32(RCTL);
178962306a36Sopenharmony_ci
179062306a36Sopenharmony_ci	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
179162306a36Sopenharmony_ci
179262306a36Sopenharmony_ci	rctl |= E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
179362306a36Sopenharmony_ci		E1000_RCTL_RDMTS_HALF |
179462306a36Sopenharmony_ci		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
179562306a36Sopenharmony_ci
179662306a36Sopenharmony_ci	if (hw->tbi_compatibility_on == 1)
179762306a36Sopenharmony_ci		rctl |= E1000_RCTL_SBP;
179862306a36Sopenharmony_ci	else
179962306a36Sopenharmony_ci		rctl &= ~E1000_RCTL_SBP;
180062306a36Sopenharmony_ci
180162306a36Sopenharmony_ci	if (adapter->netdev->mtu <= ETH_DATA_LEN)
180262306a36Sopenharmony_ci		rctl &= ~E1000_RCTL_LPE;
180362306a36Sopenharmony_ci	else
180462306a36Sopenharmony_ci		rctl |= E1000_RCTL_LPE;
180562306a36Sopenharmony_ci
180662306a36Sopenharmony_ci	/* Setup buffer sizes */
180762306a36Sopenharmony_ci	rctl &= ~E1000_RCTL_SZ_4096;
180862306a36Sopenharmony_ci	rctl |= E1000_RCTL_BSEX;
180962306a36Sopenharmony_ci	switch (adapter->rx_buffer_len) {
181062306a36Sopenharmony_ci	case E1000_RXBUFFER_2048:
181162306a36Sopenharmony_ci	default:
181262306a36Sopenharmony_ci		rctl |= E1000_RCTL_SZ_2048;
181362306a36Sopenharmony_ci		rctl &= ~E1000_RCTL_BSEX;
181462306a36Sopenharmony_ci		break;
181562306a36Sopenharmony_ci	case E1000_RXBUFFER_4096:
181662306a36Sopenharmony_ci		rctl |= E1000_RCTL_SZ_4096;
181762306a36Sopenharmony_ci		break;
181862306a36Sopenharmony_ci	case E1000_RXBUFFER_8192:
181962306a36Sopenharmony_ci		rctl |= E1000_RCTL_SZ_8192;
182062306a36Sopenharmony_ci		break;
182162306a36Sopenharmony_ci	case E1000_RXBUFFER_16384:
182262306a36Sopenharmony_ci		rctl |= E1000_RCTL_SZ_16384;
182362306a36Sopenharmony_ci		break;
182462306a36Sopenharmony_ci	}
182562306a36Sopenharmony_ci
182662306a36Sopenharmony_ci	/* This is useful for sniffing bad packets. */
182762306a36Sopenharmony_ci	if (adapter->netdev->features & NETIF_F_RXALL) {
182862306a36Sopenharmony_ci		/* UPE and MPE will be handled by normal PROMISC logic
182962306a36Sopenharmony_ci		 * in e1000e_set_rx_mode
183062306a36Sopenharmony_ci		 */
183162306a36Sopenharmony_ci		rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
183262306a36Sopenharmony_ci			 E1000_RCTL_BAM | /* RX All Bcast Pkts */
183362306a36Sopenharmony_ci			 E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
183462306a36Sopenharmony_ci
183562306a36Sopenharmony_ci		rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */
183662306a36Sopenharmony_ci			  E1000_RCTL_DPF | /* Allow filtered pause */
183762306a36Sopenharmony_ci			  E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */
183862306a36Sopenharmony_ci		/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
183962306a36Sopenharmony_ci		 * and that breaks VLANs.
184062306a36Sopenharmony_ci		 */
184162306a36Sopenharmony_ci	}
184262306a36Sopenharmony_ci
184362306a36Sopenharmony_ci	ew32(RCTL, rctl);
184462306a36Sopenharmony_ci}
184562306a36Sopenharmony_ci
184662306a36Sopenharmony_ci/**
184762306a36Sopenharmony_ci * e1000_configure_rx - Configure 8254x Receive Unit after Reset
184862306a36Sopenharmony_ci * @adapter: board private structure
184962306a36Sopenharmony_ci *
185062306a36Sopenharmony_ci * Configure the Rx unit of the MAC after a reset.
185162306a36Sopenharmony_ci **/
185262306a36Sopenharmony_cistatic void e1000_configure_rx(struct e1000_adapter *adapter)
185362306a36Sopenharmony_ci{
185462306a36Sopenharmony_ci	u64 rdba;
185562306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
185662306a36Sopenharmony_ci	u32 rdlen, rctl, rxcsum;
185762306a36Sopenharmony_ci
185862306a36Sopenharmony_ci	if (adapter->netdev->mtu > ETH_DATA_LEN) {
185962306a36Sopenharmony_ci		rdlen = adapter->rx_ring[0].count *
186062306a36Sopenharmony_ci			sizeof(struct e1000_rx_desc);
186162306a36Sopenharmony_ci		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
186262306a36Sopenharmony_ci		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
186362306a36Sopenharmony_ci	} else {
186462306a36Sopenharmony_ci		rdlen = adapter->rx_ring[0].count *
186562306a36Sopenharmony_ci			sizeof(struct e1000_rx_desc);
186662306a36Sopenharmony_ci		adapter->clean_rx = e1000_clean_rx_irq;
186762306a36Sopenharmony_ci		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
186862306a36Sopenharmony_ci	}
186962306a36Sopenharmony_ci
187062306a36Sopenharmony_ci	/* disable receives while setting up the descriptors */
187162306a36Sopenharmony_ci	rctl = er32(RCTL);
187262306a36Sopenharmony_ci	ew32(RCTL, rctl & ~E1000_RCTL_EN);
187362306a36Sopenharmony_ci
187462306a36Sopenharmony_ci	/* set the Receive Delay Timer Register */
187562306a36Sopenharmony_ci	ew32(RDTR, adapter->rx_int_delay);
187662306a36Sopenharmony_ci
187762306a36Sopenharmony_ci	if (hw->mac_type >= e1000_82540) {
187862306a36Sopenharmony_ci		ew32(RADV, adapter->rx_abs_int_delay);
187962306a36Sopenharmony_ci		if (adapter->itr_setting != 0)
188062306a36Sopenharmony_ci			ew32(ITR, 1000000000 / (adapter->itr * 256));
188162306a36Sopenharmony_ci	}
188262306a36Sopenharmony_ci
188362306a36Sopenharmony_ci	/* Setup the HW Rx Head and Tail Descriptor Pointers and
188462306a36Sopenharmony_ci	 * the Base and Length of the Rx Descriptor Ring
188562306a36Sopenharmony_ci	 */
188662306a36Sopenharmony_ci	switch (adapter->num_rx_queues) {
188762306a36Sopenharmony_ci	case 1:
188862306a36Sopenharmony_ci	default:
188962306a36Sopenharmony_ci		rdba = adapter->rx_ring[0].dma;
189062306a36Sopenharmony_ci		ew32(RDLEN, rdlen);
189162306a36Sopenharmony_ci		ew32(RDBAH, (rdba >> 32));
189262306a36Sopenharmony_ci		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
189362306a36Sopenharmony_ci		ew32(RDT, 0);
189462306a36Sopenharmony_ci		ew32(RDH, 0);
189562306a36Sopenharmony_ci		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ?
189662306a36Sopenharmony_ci					   E1000_RDH : E1000_82542_RDH);
189762306a36Sopenharmony_ci		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ?
189862306a36Sopenharmony_ci					   E1000_RDT : E1000_82542_RDT);
189962306a36Sopenharmony_ci		break;
190062306a36Sopenharmony_ci	}
190162306a36Sopenharmony_ci
190262306a36Sopenharmony_ci	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
190362306a36Sopenharmony_ci	if (hw->mac_type >= e1000_82543) {
190462306a36Sopenharmony_ci		rxcsum = er32(RXCSUM);
190562306a36Sopenharmony_ci		if (adapter->rx_csum)
190662306a36Sopenharmony_ci			rxcsum |= E1000_RXCSUM_TUOFL;
190762306a36Sopenharmony_ci		else
190862306a36Sopenharmony_ci			/* don't need to clear IPPCSE as it defaults to 0 */
190962306a36Sopenharmony_ci			rxcsum &= ~E1000_RXCSUM_TUOFL;
191062306a36Sopenharmony_ci		ew32(RXCSUM, rxcsum);
191162306a36Sopenharmony_ci	}
191262306a36Sopenharmony_ci
191362306a36Sopenharmony_ci	/* Enable Receives */
191462306a36Sopenharmony_ci	ew32(RCTL, rctl | E1000_RCTL_EN);
191562306a36Sopenharmony_ci}
191662306a36Sopenharmony_ci
191762306a36Sopenharmony_ci/**
191862306a36Sopenharmony_ci * e1000_free_tx_resources - Free Tx Resources per Queue
191962306a36Sopenharmony_ci * @adapter: board private structure
192062306a36Sopenharmony_ci * @tx_ring: Tx descriptor ring for a specific queue
192162306a36Sopenharmony_ci *
192262306a36Sopenharmony_ci * Free all transmit software resources
192362306a36Sopenharmony_ci **/
192462306a36Sopenharmony_cistatic void e1000_free_tx_resources(struct e1000_adapter *adapter,
192562306a36Sopenharmony_ci				    struct e1000_tx_ring *tx_ring)
192662306a36Sopenharmony_ci{
192762306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
192862306a36Sopenharmony_ci
192962306a36Sopenharmony_ci	e1000_clean_tx_ring(adapter, tx_ring);
193062306a36Sopenharmony_ci
193162306a36Sopenharmony_ci	vfree(tx_ring->buffer_info);
193262306a36Sopenharmony_ci	tx_ring->buffer_info = NULL;
193362306a36Sopenharmony_ci
193462306a36Sopenharmony_ci	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
193562306a36Sopenharmony_ci			  tx_ring->dma);
193662306a36Sopenharmony_ci
193762306a36Sopenharmony_ci	tx_ring->desc = NULL;
193862306a36Sopenharmony_ci}
193962306a36Sopenharmony_ci
194062306a36Sopenharmony_ci/**
194162306a36Sopenharmony_ci * e1000_free_all_tx_resources - Free Tx Resources for All Queues
194262306a36Sopenharmony_ci * @adapter: board private structure
194362306a36Sopenharmony_ci *
194462306a36Sopenharmony_ci * Free all transmit software resources
194562306a36Sopenharmony_ci **/
194662306a36Sopenharmony_civoid e1000_free_all_tx_resources(struct e1000_adapter *adapter)
194762306a36Sopenharmony_ci{
194862306a36Sopenharmony_ci	int i;
194962306a36Sopenharmony_ci
195062306a36Sopenharmony_ci	for (i = 0; i < adapter->num_tx_queues; i++)
195162306a36Sopenharmony_ci		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
195262306a36Sopenharmony_ci}
195362306a36Sopenharmony_ci
195462306a36Sopenharmony_cistatic void
195562306a36Sopenharmony_cie1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
195662306a36Sopenharmony_ci				 struct e1000_tx_buffer *buffer_info,
195762306a36Sopenharmony_ci				 int budget)
195862306a36Sopenharmony_ci{
195962306a36Sopenharmony_ci	if (buffer_info->dma) {
196062306a36Sopenharmony_ci		if (buffer_info->mapped_as_page)
196162306a36Sopenharmony_ci			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
196262306a36Sopenharmony_ci				       buffer_info->length, DMA_TO_DEVICE);
196362306a36Sopenharmony_ci		else
196462306a36Sopenharmony_ci			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
196562306a36Sopenharmony_ci					 buffer_info->length,
196662306a36Sopenharmony_ci					 DMA_TO_DEVICE);
196762306a36Sopenharmony_ci		buffer_info->dma = 0;
196862306a36Sopenharmony_ci	}
196962306a36Sopenharmony_ci	if (buffer_info->skb) {
197062306a36Sopenharmony_ci		napi_consume_skb(buffer_info->skb, budget);
197162306a36Sopenharmony_ci		buffer_info->skb = NULL;
197262306a36Sopenharmony_ci	}
197362306a36Sopenharmony_ci	buffer_info->time_stamp = 0;
197462306a36Sopenharmony_ci	/* buffer_info must be completely set up in the transmit path */
197562306a36Sopenharmony_ci}
197662306a36Sopenharmony_ci
197762306a36Sopenharmony_ci/**
197862306a36Sopenharmony_ci * e1000_clean_tx_ring - Free Tx Buffers
197962306a36Sopenharmony_ci * @adapter: board private structure
198062306a36Sopenharmony_ci * @tx_ring: ring to be cleaned
198162306a36Sopenharmony_ci **/
198262306a36Sopenharmony_cistatic void e1000_clean_tx_ring(struct e1000_adapter *adapter,
198362306a36Sopenharmony_ci				struct e1000_tx_ring *tx_ring)
198462306a36Sopenharmony_ci{
198562306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
198662306a36Sopenharmony_ci	struct e1000_tx_buffer *buffer_info;
198762306a36Sopenharmony_ci	unsigned long size;
198862306a36Sopenharmony_ci	unsigned int i;
198962306a36Sopenharmony_ci
199062306a36Sopenharmony_ci	/* Free all the Tx ring sk_buffs */
199162306a36Sopenharmony_ci
199262306a36Sopenharmony_ci	for (i = 0; i < tx_ring->count; i++) {
199362306a36Sopenharmony_ci		buffer_info = &tx_ring->buffer_info[i];
199462306a36Sopenharmony_ci		e1000_unmap_and_free_tx_resource(adapter, buffer_info, 0);
199562306a36Sopenharmony_ci	}
199662306a36Sopenharmony_ci
199762306a36Sopenharmony_ci	netdev_reset_queue(adapter->netdev);
199862306a36Sopenharmony_ci	size = sizeof(struct e1000_tx_buffer) * tx_ring->count;
199962306a36Sopenharmony_ci	memset(tx_ring->buffer_info, 0, size);
200062306a36Sopenharmony_ci
200162306a36Sopenharmony_ci	/* Zero out the descriptor ring */
200262306a36Sopenharmony_ci
200362306a36Sopenharmony_ci	memset(tx_ring->desc, 0, tx_ring->size);
200462306a36Sopenharmony_ci
200562306a36Sopenharmony_ci	tx_ring->next_to_use = 0;
200662306a36Sopenharmony_ci	tx_ring->next_to_clean = 0;
200762306a36Sopenharmony_ci	tx_ring->last_tx_tso = false;
200862306a36Sopenharmony_ci
200962306a36Sopenharmony_ci	writel(0, hw->hw_addr + tx_ring->tdh);
201062306a36Sopenharmony_ci	writel(0, hw->hw_addr + tx_ring->tdt);
201162306a36Sopenharmony_ci}
201262306a36Sopenharmony_ci
201362306a36Sopenharmony_ci/**
201462306a36Sopenharmony_ci * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
201562306a36Sopenharmony_ci * @adapter: board private structure
201662306a36Sopenharmony_ci **/
201762306a36Sopenharmony_cistatic void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
201862306a36Sopenharmony_ci{
201962306a36Sopenharmony_ci	int i;
202062306a36Sopenharmony_ci
202162306a36Sopenharmony_ci	for (i = 0; i < adapter->num_tx_queues; i++)
202262306a36Sopenharmony_ci		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
202362306a36Sopenharmony_ci}
202462306a36Sopenharmony_ci
202562306a36Sopenharmony_ci/**
202662306a36Sopenharmony_ci * e1000_free_rx_resources - Free Rx Resources
202762306a36Sopenharmony_ci * @adapter: board private structure
202862306a36Sopenharmony_ci * @rx_ring: ring to clean the resources from
202962306a36Sopenharmony_ci *
203062306a36Sopenharmony_ci * Free all receive software resources
203162306a36Sopenharmony_ci **/
203262306a36Sopenharmony_cistatic void e1000_free_rx_resources(struct e1000_adapter *adapter,
203362306a36Sopenharmony_ci				    struct e1000_rx_ring *rx_ring)
203462306a36Sopenharmony_ci{
203562306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
203662306a36Sopenharmony_ci
203762306a36Sopenharmony_ci	e1000_clean_rx_ring(adapter, rx_ring);
203862306a36Sopenharmony_ci
203962306a36Sopenharmony_ci	vfree(rx_ring->buffer_info);
204062306a36Sopenharmony_ci	rx_ring->buffer_info = NULL;
204162306a36Sopenharmony_ci
204262306a36Sopenharmony_ci	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
204362306a36Sopenharmony_ci			  rx_ring->dma);
204462306a36Sopenharmony_ci
204562306a36Sopenharmony_ci	rx_ring->desc = NULL;
204662306a36Sopenharmony_ci}
204762306a36Sopenharmony_ci
204862306a36Sopenharmony_ci/**
204962306a36Sopenharmony_ci * e1000_free_all_rx_resources - Free Rx Resources for All Queues
205062306a36Sopenharmony_ci * @adapter: board private structure
205162306a36Sopenharmony_ci *
205262306a36Sopenharmony_ci * Free all receive software resources
205362306a36Sopenharmony_ci **/
205462306a36Sopenharmony_civoid e1000_free_all_rx_resources(struct e1000_adapter *adapter)
205562306a36Sopenharmony_ci{
205662306a36Sopenharmony_ci	int i;
205762306a36Sopenharmony_ci
205862306a36Sopenharmony_ci	for (i = 0; i < adapter->num_rx_queues; i++)
205962306a36Sopenharmony_ci		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
206062306a36Sopenharmony_ci}
206162306a36Sopenharmony_ci
206262306a36Sopenharmony_ci#define E1000_HEADROOM (NET_SKB_PAD + NET_IP_ALIGN)
206362306a36Sopenharmony_cistatic unsigned int e1000_frag_len(const struct e1000_adapter *a)
206462306a36Sopenharmony_ci{
206562306a36Sopenharmony_ci	return SKB_DATA_ALIGN(a->rx_buffer_len + E1000_HEADROOM) +
206662306a36Sopenharmony_ci		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
206762306a36Sopenharmony_ci}
206862306a36Sopenharmony_ci
206962306a36Sopenharmony_cistatic void *e1000_alloc_frag(const struct e1000_adapter *a)
207062306a36Sopenharmony_ci{
207162306a36Sopenharmony_ci	unsigned int len = e1000_frag_len(a);
207262306a36Sopenharmony_ci	u8 *data = netdev_alloc_frag(len);
207362306a36Sopenharmony_ci
207462306a36Sopenharmony_ci	if (likely(data))
207562306a36Sopenharmony_ci		data += E1000_HEADROOM;
207662306a36Sopenharmony_ci	return data;
207762306a36Sopenharmony_ci}
207862306a36Sopenharmony_ci
207962306a36Sopenharmony_ci/**
208062306a36Sopenharmony_ci * e1000_clean_rx_ring - Free Rx Buffers per Queue
208162306a36Sopenharmony_ci * @adapter: board private structure
208262306a36Sopenharmony_ci * @rx_ring: ring to free buffers from
208362306a36Sopenharmony_ci **/
208462306a36Sopenharmony_cistatic void e1000_clean_rx_ring(struct e1000_adapter *adapter,
208562306a36Sopenharmony_ci				struct e1000_rx_ring *rx_ring)
208662306a36Sopenharmony_ci{
208762306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
208862306a36Sopenharmony_ci	struct e1000_rx_buffer *buffer_info;
208962306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
209062306a36Sopenharmony_ci	unsigned long size;
209162306a36Sopenharmony_ci	unsigned int i;
209262306a36Sopenharmony_ci
209362306a36Sopenharmony_ci	/* Free all the Rx netfrags */
209462306a36Sopenharmony_ci	for (i = 0; i < rx_ring->count; i++) {
209562306a36Sopenharmony_ci		buffer_info = &rx_ring->buffer_info[i];
209662306a36Sopenharmony_ci		if (adapter->clean_rx == e1000_clean_rx_irq) {
209762306a36Sopenharmony_ci			if (buffer_info->dma)
209862306a36Sopenharmony_ci				dma_unmap_single(&pdev->dev, buffer_info->dma,
209962306a36Sopenharmony_ci						 adapter->rx_buffer_len,
210062306a36Sopenharmony_ci						 DMA_FROM_DEVICE);
210162306a36Sopenharmony_ci			if (buffer_info->rxbuf.data) {
210262306a36Sopenharmony_ci				skb_free_frag(buffer_info->rxbuf.data);
210362306a36Sopenharmony_ci				buffer_info->rxbuf.data = NULL;
210462306a36Sopenharmony_ci			}
210562306a36Sopenharmony_ci		} else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
210662306a36Sopenharmony_ci			if (buffer_info->dma)
210762306a36Sopenharmony_ci				dma_unmap_page(&pdev->dev, buffer_info->dma,
210862306a36Sopenharmony_ci					       adapter->rx_buffer_len,
210962306a36Sopenharmony_ci					       DMA_FROM_DEVICE);
211062306a36Sopenharmony_ci			if (buffer_info->rxbuf.page) {
211162306a36Sopenharmony_ci				put_page(buffer_info->rxbuf.page);
211262306a36Sopenharmony_ci				buffer_info->rxbuf.page = NULL;
211362306a36Sopenharmony_ci			}
211462306a36Sopenharmony_ci		}
211562306a36Sopenharmony_ci
211662306a36Sopenharmony_ci		buffer_info->dma = 0;
211762306a36Sopenharmony_ci	}
211862306a36Sopenharmony_ci
211962306a36Sopenharmony_ci	/* there also may be some cached data from a chained receive */
212062306a36Sopenharmony_ci	napi_free_frags(&adapter->napi);
212162306a36Sopenharmony_ci	rx_ring->rx_skb_top = NULL;
212262306a36Sopenharmony_ci
212362306a36Sopenharmony_ci	size = sizeof(struct e1000_rx_buffer) * rx_ring->count;
212462306a36Sopenharmony_ci	memset(rx_ring->buffer_info, 0, size);
212562306a36Sopenharmony_ci
212662306a36Sopenharmony_ci	/* Zero out the descriptor ring */
212762306a36Sopenharmony_ci	memset(rx_ring->desc, 0, rx_ring->size);
212862306a36Sopenharmony_ci
212962306a36Sopenharmony_ci	rx_ring->next_to_clean = 0;
213062306a36Sopenharmony_ci	rx_ring->next_to_use = 0;
213162306a36Sopenharmony_ci
213262306a36Sopenharmony_ci	writel(0, hw->hw_addr + rx_ring->rdh);
213362306a36Sopenharmony_ci	writel(0, hw->hw_addr + rx_ring->rdt);
213462306a36Sopenharmony_ci}
213562306a36Sopenharmony_ci
213662306a36Sopenharmony_ci/**
213762306a36Sopenharmony_ci * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
213862306a36Sopenharmony_ci * @adapter: board private structure
213962306a36Sopenharmony_ci **/
214062306a36Sopenharmony_cistatic void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
214162306a36Sopenharmony_ci{
214262306a36Sopenharmony_ci	int i;
214362306a36Sopenharmony_ci
214462306a36Sopenharmony_ci	for (i = 0; i < adapter->num_rx_queues; i++)
214562306a36Sopenharmony_ci		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
214662306a36Sopenharmony_ci}
214762306a36Sopenharmony_ci
214862306a36Sopenharmony_ci/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
214962306a36Sopenharmony_ci * and memory write and invalidate disabled for certain operations
215062306a36Sopenharmony_ci */
215162306a36Sopenharmony_cistatic void e1000_enter_82542_rst(struct e1000_adapter *adapter)
215262306a36Sopenharmony_ci{
215362306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
215462306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
215562306a36Sopenharmony_ci	u32 rctl;
215662306a36Sopenharmony_ci
215762306a36Sopenharmony_ci	e1000_pci_clear_mwi(hw);
215862306a36Sopenharmony_ci
215962306a36Sopenharmony_ci	rctl = er32(RCTL);
216062306a36Sopenharmony_ci	rctl |= E1000_RCTL_RST;
216162306a36Sopenharmony_ci	ew32(RCTL, rctl);
216262306a36Sopenharmony_ci	E1000_WRITE_FLUSH();
216362306a36Sopenharmony_ci	mdelay(5);
216462306a36Sopenharmony_ci
216562306a36Sopenharmony_ci	if (netif_running(netdev))
216662306a36Sopenharmony_ci		e1000_clean_all_rx_rings(adapter);
216762306a36Sopenharmony_ci}
216862306a36Sopenharmony_ci
216962306a36Sopenharmony_cistatic void e1000_leave_82542_rst(struct e1000_adapter *adapter)
217062306a36Sopenharmony_ci{
217162306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
217262306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
217362306a36Sopenharmony_ci	u32 rctl;
217462306a36Sopenharmony_ci
217562306a36Sopenharmony_ci	rctl = er32(RCTL);
217662306a36Sopenharmony_ci	rctl &= ~E1000_RCTL_RST;
217762306a36Sopenharmony_ci	ew32(RCTL, rctl);
217862306a36Sopenharmony_ci	E1000_WRITE_FLUSH();
217962306a36Sopenharmony_ci	mdelay(5);
218062306a36Sopenharmony_ci
218162306a36Sopenharmony_ci	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
218262306a36Sopenharmony_ci		e1000_pci_set_mwi(hw);
218362306a36Sopenharmony_ci
218462306a36Sopenharmony_ci	if (netif_running(netdev)) {
218562306a36Sopenharmony_ci		/* No need to loop, because 82542 supports only 1 queue */
218662306a36Sopenharmony_ci		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
218762306a36Sopenharmony_ci		e1000_configure_rx(adapter);
218862306a36Sopenharmony_ci		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
218962306a36Sopenharmony_ci	}
219062306a36Sopenharmony_ci}
219162306a36Sopenharmony_ci
219262306a36Sopenharmony_ci/**
219362306a36Sopenharmony_ci * e1000_set_mac - Change the Ethernet Address of the NIC
219462306a36Sopenharmony_ci * @netdev: network interface device structure
219562306a36Sopenharmony_ci * @p: pointer to an address structure
219662306a36Sopenharmony_ci *
219762306a36Sopenharmony_ci * Returns 0 on success, negative on failure
219862306a36Sopenharmony_ci **/
219962306a36Sopenharmony_cistatic int e1000_set_mac(struct net_device *netdev, void *p)
220062306a36Sopenharmony_ci{
220162306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
220262306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
220362306a36Sopenharmony_ci	struct sockaddr *addr = p;
220462306a36Sopenharmony_ci
220562306a36Sopenharmony_ci	if (!is_valid_ether_addr(addr->sa_data))
220662306a36Sopenharmony_ci		return -EADDRNOTAVAIL;
220762306a36Sopenharmony_ci
220862306a36Sopenharmony_ci	/* 82542 2.0 needs to be in reset to write receive address registers */
220962306a36Sopenharmony_ci
221062306a36Sopenharmony_ci	if (hw->mac_type == e1000_82542_rev2_0)
221162306a36Sopenharmony_ci		e1000_enter_82542_rst(adapter);
221262306a36Sopenharmony_ci
221362306a36Sopenharmony_ci	eth_hw_addr_set(netdev, addr->sa_data);
221462306a36Sopenharmony_ci	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
221562306a36Sopenharmony_ci
221662306a36Sopenharmony_ci	e1000_rar_set(hw, hw->mac_addr, 0);
221762306a36Sopenharmony_ci
221862306a36Sopenharmony_ci	if (hw->mac_type == e1000_82542_rev2_0)
221962306a36Sopenharmony_ci		e1000_leave_82542_rst(adapter);
222062306a36Sopenharmony_ci
222162306a36Sopenharmony_ci	return 0;
222262306a36Sopenharmony_ci}
222362306a36Sopenharmony_ci
222462306a36Sopenharmony_ci/**
222562306a36Sopenharmony_ci * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
222662306a36Sopenharmony_ci * @netdev: network interface device structure
222762306a36Sopenharmony_ci *
222862306a36Sopenharmony_ci * The set_rx_mode entry point is called whenever the unicast or multicast
222962306a36Sopenharmony_ci * address lists or the network interface flags are updated. This routine is
223062306a36Sopenharmony_ci * responsible for configuring the hardware for proper unicast, multicast,
223162306a36Sopenharmony_ci * promiscuous mode, and all-multi behavior.
223262306a36Sopenharmony_ci **/
223362306a36Sopenharmony_cistatic void e1000_set_rx_mode(struct net_device *netdev)
223462306a36Sopenharmony_ci{
223562306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
223662306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
223762306a36Sopenharmony_ci	struct netdev_hw_addr *ha;
223862306a36Sopenharmony_ci	bool use_uc = false;
223962306a36Sopenharmony_ci	u32 rctl;
224062306a36Sopenharmony_ci	u32 hash_value;
224162306a36Sopenharmony_ci	int i, rar_entries = E1000_RAR_ENTRIES;
224262306a36Sopenharmony_ci	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
224362306a36Sopenharmony_ci	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
224462306a36Sopenharmony_ci
224562306a36Sopenharmony_ci	if (!mcarray)
224662306a36Sopenharmony_ci		return;
224762306a36Sopenharmony_ci
224862306a36Sopenharmony_ci	/* Check for Promiscuous and All Multicast modes */
224962306a36Sopenharmony_ci
225062306a36Sopenharmony_ci	rctl = er32(RCTL);
225162306a36Sopenharmony_ci
225262306a36Sopenharmony_ci	if (netdev->flags & IFF_PROMISC) {
225362306a36Sopenharmony_ci		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
225462306a36Sopenharmony_ci		rctl &= ~E1000_RCTL_VFE;
225562306a36Sopenharmony_ci	} else {
225662306a36Sopenharmony_ci		if (netdev->flags & IFF_ALLMULTI)
225762306a36Sopenharmony_ci			rctl |= E1000_RCTL_MPE;
225862306a36Sopenharmony_ci		else
225962306a36Sopenharmony_ci			rctl &= ~E1000_RCTL_MPE;
226062306a36Sopenharmony_ci		/* Enable VLAN filter if there is a VLAN */
226162306a36Sopenharmony_ci		if (e1000_vlan_used(adapter))
226262306a36Sopenharmony_ci			rctl |= E1000_RCTL_VFE;
226362306a36Sopenharmony_ci	}
226462306a36Sopenharmony_ci
226562306a36Sopenharmony_ci	if (netdev_uc_count(netdev) > rar_entries - 1) {
226662306a36Sopenharmony_ci		rctl |= E1000_RCTL_UPE;
226762306a36Sopenharmony_ci	} else if (!(netdev->flags & IFF_PROMISC)) {
226862306a36Sopenharmony_ci		rctl &= ~E1000_RCTL_UPE;
226962306a36Sopenharmony_ci		use_uc = true;
227062306a36Sopenharmony_ci	}
227162306a36Sopenharmony_ci
227262306a36Sopenharmony_ci	ew32(RCTL, rctl);
227362306a36Sopenharmony_ci
227462306a36Sopenharmony_ci	/* 82542 2.0 needs to be in reset to write receive address registers */
227562306a36Sopenharmony_ci
227662306a36Sopenharmony_ci	if (hw->mac_type == e1000_82542_rev2_0)
227762306a36Sopenharmony_ci		e1000_enter_82542_rst(adapter);
227862306a36Sopenharmony_ci
227962306a36Sopenharmony_ci	/* load the first 14 addresses into the exact filters 1-14. Unicast
228062306a36Sopenharmony_ci	 * addresses take precedence to avoid disabling unicast filtering
228162306a36Sopenharmony_ci	 * when possible.
228262306a36Sopenharmony_ci	 *
228362306a36Sopenharmony_ci	 * RAR 0 is used for the station MAC address
228462306a36Sopenharmony_ci	 * if there are not 14 addresses, go ahead and clear the filters
228562306a36Sopenharmony_ci	 */
228662306a36Sopenharmony_ci	i = 1;
228762306a36Sopenharmony_ci	if (use_uc)
228862306a36Sopenharmony_ci		netdev_for_each_uc_addr(ha, netdev) {
228962306a36Sopenharmony_ci			if (i == rar_entries)
229062306a36Sopenharmony_ci				break;
229162306a36Sopenharmony_ci			e1000_rar_set(hw, ha->addr, i++);
229262306a36Sopenharmony_ci		}
229362306a36Sopenharmony_ci
229462306a36Sopenharmony_ci	netdev_for_each_mc_addr(ha, netdev) {
229562306a36Sopenharmony_ci		if (i == rar_entries) {
229662306a36Sopenharmony_ci			/* load any remaining addresses into the hash table */
229762306a36Sopenharmony_ci			u32 hash_reg, hash_bit, mta;
229862306a36Sopenharmony_ci			hash_value = e1000_hash_mc_addr(hw, ha->addr);
229962306a36Sopenharmony_ci			hash_reg = (hash_value >> 5) & 0x7F;
230062306a36Sopenharmony_ci			hash_bit = hash_value & 0x1F;
230162306a36Sopenharmony_ci			mta = (1 << hash_bit);
230262306a36Sopenharmony_ci			mcarray[hash_reg] |= mta;
230362306a36Sopenharmony_ci		} else {
230462306a36Sopenharmony_ci			e1000_rar_set(hw, ha->addr, i++);
230562306a36Sopenharmony_ci		}
230662306a36Sopenharmony_ci	}
230762306a36Sopenharmony_ci
230862306a36Sopenharmony_ci	for (; i < rar_entries; i++) {
230962306a36Sopenharmony_ci		E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
231062306a36Sopenharmony_ci		E1000_WRITE_FLUSH();
231162306a36Sopenharmony_ci		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
231262306a36Sopenharmony_ci		E1000_WRITE_FLUSH();
231362306a36Sopenharmony_ci	}
231462306a36Sopenharmony_ci
231562306a36Sopenharmony_ci	/* write the hash table completely, write from bottom to avoid
231662306a36Sopenharmony_ci	 * both stupid write combining chipsets, and flushing each write
231762306a36Sopenharmony_ci	 */
231862306a36Sopenharmony_ci	for (i = mta_reg_count - 1; i >= 0 ; i--) {
231962306a36Sopenharmony_ci		/* If we are on an 82544 has an errata where writing odd
232062306a36Sopenharmony_ci		 * offsets overwrites the previous even offset, but writing
232162306a36Sopenharmony_ci		 * backwards over the range solves the issue by always
232262306a36Sopenharmony_ci		 * writing the odd offset first
232362306a36Sopenharmony_ci		 */
232462306a36Sopenharmony_ci		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
232562306a36Sopenharmony_ci	}
232662306a36Sopenharmony_ci	E1000_WRITE_FLUSH();
232762306a36Sopenharmony_ci
232862306a36Sopenharmony_ci	if (hw->mac_type == e1000_82542_rev2_0)
232962306a36Sopenharmony_ci		e1000_leave_82542_rst(adapter);
233062306a36Sopenharmony_ci
233162306a36Sopenharmony_ci	kfree(mcarray);
233262306a36Sopenharmony_ci}
233362306a36Sopenharmony_ci
233462306a36Sopenharmony_ci/**
233562306a36Sopenharmony_ci * e1000_update_phy_info_task - get phy info
233662306a36Sopenharmony_ci * @work: work struct contained inside adapter struct
233762306a36Sopenharmony_ci *
233862306a36Sopenharmony_ci * Need to wait a few seconds after link up to get diagnostic information from
233962306a36Sopenharmony_ci * the phy
234062306a36Sopenharmony_ci */
234162306a36Sopenharmony_cistatic void e1000_update_phy_info_task(struct work_struct *work)
234262306a36Sopenharmony_ci{
234362306a36Sopenharmony_ci	struct e1000_adapter *adapter = container_of(work,
234462306a36Sopenharmony_ci						     struct e1000_adapter,
234562306a36Sopenharmony_ci						     phy_info_task.work);
234662306a36Sopenharmony_ci
234762306a36Sopenharmony_ci	e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
234862306a36Sopenharmony_ci}
234962306a36Sopenharmony_ci
235062306a36Sopenharmony_ci/**
235162306a36Sopenharmony_ci * e1000_82547_tx_fifo_stall_task - task to complete work
235262306a36Sopenharmony_ci * @work: work struct contained inside adapter struct
235362306a36Sopenharmony_ci **/
235462306a36Sopenharmony_cistatic void e1000_82547_tx_fifo_stall_task(struct work_struct *work)
235562306a36Sopenharmony_ci{
235662306a36Sopenharmony_ci	struct e1000_adapter *adapter = container_of(work,
235762306a36Sopenharmony_ci						     struct e1000_adapter,
235862306a36Sopenharmony_ci						     fifo_stall_task.work);
235962306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
236062306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
236162306a36Sopenharmony_ci	u32 tctl;
236262306a36Sopenharmony_ci
236362306a36Sopenharmony_ci	if (atomic_read(&adapter->tx_fifo_stall)) {
236462306a36Sopenharmony_ci		if ((er32(TDT) == er32(TDH)) &&
236562306a36Sopenharmony_ci		   (er32(TDFT) == er32(TDFH)) &&
236662306a36Sopenharmony_ci		   (er32(TDFTS) == er32(TDFHS))) {
236762306a36Sopenharmony_ci			tctl = er32(TCTL);
236862306a36Sopenharmony_ci			ew32(TCTL, tctl & ~E1000_TCTL_EN);
236962306a36Sopenharmony_ci			ew32(TDFT, adapter->tx_head_addr);
237062306a36Sopenharmony_ci			ew32(TDFH, adapter->tx_head_addr);
237162306a36Sopenharmony_ci			ew32(TDFTS, adapter->tx_head_addr);
237262306a36Sopenharmony_ci			ew32(TDFHS, adapter->tx_head_addr);
237362306a36Sopenharmony_ci			ew32(TCTL, tctl);
237462306a36Sopenharmony_ci			E1000_WRITE_FLUSH();
237562306a36Sopenharmony_ci
237662306a36Sopenharmony_ci			adapter->tx_fifo_head = 0;
237762306a36Sopenharmony_ci			atomic_set(&adapter->tx_fifo_stall, 0);
237862306a36Sopenharmony_ci			netif_wake_queue(netdev);
237962306a36Sopenharmony_ci		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
238062306a36Sopenharmony_ci			schedule_delayed_work(&adapter->fifo_stall_task, 1);
238162306a36Sopenharmony_ci		}
238262306a36Sopenharmony_ci	}
238362306a36Sopenharmony_ci}
238462306a36Sopenharmony_ci
238562306a36Sopenharmony_cibool e1000_has_link(struct e1000_adapter *adapter)
238662306a36Sopenharmony_ci{
238762306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
238862306a36Sopenharmony_ci	bool link_active = false;
238962306a36Sopenharmony_ci
239062306a36Sopenharmony_ci	/* get_link_status is set on LSC (link status) interrupt or rx
239162306a36Sopenharmony_ci	 * sequence error interrupt (except on intel ce4100).
239262306a36Sopenharmony_ci	 * get_link_status will stay false until the
239362306a36Sopenharmony_ci	 * e1000_check_for_link establishes link for copper adapters
239462306a36Sopenharmony_ci	 * ONLY
239562306a36Sopenharmony_ci	 */
239662306a36Sopenharmony_ci	switch (hw->media_type) {
239762306a36Sopenharmony_ci	case e1000_media_type_copper:
239862306a36Sopenharmony_ci		if (hw->mac_type == e1000_ce4100)
239962306a36Sopenharmony_ci			hw->get_link_status = 1;
240062306a36Sopenharmony_ci		if (hw->get_link_status) {
240162306a36Sopenharmony_ci			e1000_check_for_link(hw);
240262306a36Sopenharmony_ci			link_active = !hw->get_link_status;
240362306a36Sopenharmony_ci		} else {
240462306a36Sopenharmony_ci			link_active = true;
240562306a36Sopenharmony_ci		}
240662306a36Sopenharmony_ci		break;
240762306a36Sopenharmony_ci	case e1000_media_type_fiber:
240862306a36Sopenharmony_ci		e1000_check_for_link(hw);
240962306a36Sopenharmony_ci		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
241062306a36Sopenharmony_ci		break;
241162306a36Sopenharmony_ci	case e1000_media_type_internal_serdes:
241262306a36Sopenharmony_ci		e1000_check_for_link(hw);
241362306a36Sopenharmony_ci		link_active = hw->serdes_has_link;
241462306a36Sopenharmony_ci		break;
241562306a36Sopenharmony_ci	default:
241662306a36Sopenharmony_ci		break;
241762306a36Sopenharmony_ci	}
241862306a36Sopenharmony_ci
241962306a36Sopenharmony_ci	return link_active;
242062306a36Sopenharmony_ci}
242162306a36Sopenharmony_ci
242262306a36Sopenharmony_ci/**
242362306a36Sopenharmony_ci * e1000_watchdog - work function
242462306a36Sopenharmony_ci * @work: work struct contained inside adapter struct
242562306a36Sopenharmony_ci **/
242662306a36Sopenharmony_cistatic void e1000_watchdog(struct work_struct *work)
242762306a36Sopenharmony_ci{
242862306a36Sopenharmony_ci	struct e1000_adapter *adapter = container_of(work,
242962306a36Sopenharmony_ci						     struct e1000_adapter,
243062306a36Sopenharmony_ci						     watchdog_task.work);
243162306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
243262306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
243362306a36Sopenharmony_ci	struct e1000_tx_ring *txdr = adapter->tx_ring;
243462306a36Sopenharmony_ci	u32 link, tctl;
243562306a36Sopenharmony_ci
243662306a36Sopenharmony_ci	link = e1000_has_link(adapter);
243762306a36Sopenharmony_ci	if ((netif_carrier_ok(netdev)) && link)
243862306a36Sopenharmony_ci		goto link_up;
243962306a36Sopenharmony_ci
244062306a36Sopenharmony_ci	if (link) {
244162306a36Sopenharmony_ci		if (!netif_carrier_ok(netdev)) {
244262306a36Sopenharmony_ci			u32 ctrl;
244362306a36Sopenharmony_ci			/* update snapshot of PHY registers on LSC */
244462306a36Sopenharmony_ci			e1000_get_speed_and_duplex(hw,
244562306a36Sopenharmony_ci						   &adapter->link_speed,
244662306a36Sopenharmony_ci						   &adapter->link_duplex);
244762306a36Sopenharmony_ci
244862306a36Sopenharmony_ci			ctrl = er32(CTRL);
244962306a36Sopenharmony_ci			pr_info("%s NIC Link is Up %d Mbps %s, "
245062306a36Sopenharmony_ci				"Flow Control: %s\n",
245162306a36Sopenharmony_ci				netdev->name,
245262306a36Sopenharmony_ci				adapter->link_speed,
245362306a36Sopenharmony_ci				adapter->link_duplex == FULL_DUPLEX ?
245462306a36Sopenharmony_ci				"Full Duplex" : "Half Duplex",
245562306a36Sopenharmony_ci				((ctrl & E1000_CTRL_TFCE) && (ctrl &
245662306a36Sopenharmony_ci				E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
245762306a36Sopenharmony_ci				E1000_CTRL_RFCE) ? "RX" : ((ctrl &
245862306a36Sopenharmony_ci				E1000_CTRL_TFCE) ? "TX" : "None")));
245962306a36Sopenharmony_ci
246062306a36Sopenharmony_ci			/* adjust timeout factor according to speed/duplex */
246162306a36Sopenharmony_ci			adapter->tx_timeout_factor = 1;
246262306a36Sopenharmony_ci			switch (adapter->link_speed) {
246362306a36Sopenharmony_ci			case SPEED_10:
246462306a36Sopenharmony_ci				adapter->tx_timeout_factor = 16;
246562306a36Sopenharmony_ci				break;
246662306a36Sopenharmony_ci			case SPEED_100:
246762306a36Sopenharmony_ci				/* maybe add some timeout factor ? */
246862306a36Sopenharmony_ci				break;
246962306a36Sopenharmony_ci			}
247062306a36Sopenharmony_ci
247162306a36Sopenharmony_ci			/* enable transmits in the hardware */
247262306a36Sopenharmony_ci			tctl = er32(TCTL);
247362306a36Sopenharmony_ci			tctl |= E1000_TCTL_EN;
247462306a36Sopenharmony_ci			ew32(TCTL, tctl);
247562306a36Sopenharmony_ci
247662306a36Sopenharmony_ci			netif_carrier_on(netdev);
247762306a36Sopenharmony_ci			if (!test_bit(__E1000_DOWN, &adapter->flags))
247862306a36Sopenharmony_ci				schedule_delayed_work(&adapter->phy_info_task,
247962306a36Sopenharmony_ci						      2 * HZ);
248062306a36Sopenharmony_ci			adapter->smartspeed = 0;
248162306a36Sopenharmony_ci		}
248262306a36Sopenharmony_ci	} else {
248362306a36Sopenharmony_ci		if (netif_carrier_ok(netdev)) {
248462306a36Sopenharmony_ci			adapter->link_speed = 0;
248562306a36Sopenharmony_ci			adapter->link_duplex = 0;
248662306a36Sopenharmony_ci			pr_info("%s NIC Link is Down\n",
248762306a36Sopenharmony_ci				netdev->name);
248862306a36Sopenharmony_ci			netif_carrier_off(netdev);
248962306a36Sopenharmony_ci
249062306a36Sopenharmony_ci			if (!test_bit(__E1000_DOWN, &adapter->flags))
249162306a36Sopenharmony_ci				schedule_delayed_work(&adapter->phy_info_task,
249262306a36Sopenharmony_ci						      2 * HZ);
249362306a36Sopenharmony_ci		}
249462306a36Sopenharmony_ci
249562306a36Sopenharmony_ci		e1000_smartspeed(adapter);
249662306a36Sopenharmony_ci	}
249762306a36Sopenharmony_ci
249862306a36Sopenharmony_cilink_up:
249962306a36Sopenharmony_ci	e1000_update_stats(adapter);
250062306a36Sopenharmony_ci
250162306a36Sopenharmony_ci	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
250262306a36Sopenharmony_ci	adapter->tpt_old = adapter->stats.tpt;
250362306a36Sopenharmony_ci	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
250462306a36Sopenharmony_ci	adapter->colc_old = adapter->stats.colc;
250562306a36Sopenharmony_ci
250662306a36Sopenharmony_ci	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
250762306a36Sopenharmony_ci	adapter->gorcl_old = adapter->stats.gorcl;
250862306a36Sopenharmony_ci	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
250962306a36Sopenharmony_ci	adapter->gotcl_old = adapter->stats.gotcl;
251062306a36Sopenharmony_ci
251162306a36Sopenharmony_ci	e1000_update_adaptive(hw);
251262306a36Sopenharmony_ci
251362306a36Sopenharmony_ci	if (!netif_carrier_ok(netdev)) {
251462306a36Sopenharmony_ci		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
251562306a36Sopenharmony_ci			/* We've lost link, so the controller stops DMA,
251662306a36Sopenharmony_ci			 * but we've got queued Tx work that's never going
251762306a36Sopenharmony_ci			 * to get done, so reset controller to flush Tx.
251862306a36Sopenharmony_ci			 * (Do the reset outside of interrupt context).
251962306a36Sopenharmony_ci			 */
252062306a36Sopenharmony_ci			adapter->tx_timeout_count++;
252162306a36Sopenharmony_ci			schedule_work(&adapter->reset_task);
252262306a36Sopenharmony_ci			/* exit immediately since reset is imminent */
252362306a36Sopenharmony_ci			return;
252462306a36Sopenharmony_ci		}
252562306a36Sopenharmony_ci	}
252662306a36Sopenharmony_ci
252762306a36Sopenharmony_ci	/* Simple mode for Interrupt Throttle Rate (ITR) */
252862306a36Sopenharmony_ci	if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) {
252962306a36Sopenharmony_ci		/* Symmetric Tx/Rx gets a reduced ITR=2000;
253062306a36Sopenharmony_ci		 * Total asymmetrical Tx or Rx gets ITR=8000;
253162306a36Sopenharmony_ci		 * everyone else is between 2000-8000.
253262306a36Sopenharmony_ci		 */
253362306a36Sopenharmony_ci		u32 goc = (adapter->gotcl + adapter->gorcl) / 10000;
253462306a36Sopenharmony_ci		u32 dif = (adapter->gotcl > adapter->gorcl ?
253562306a36Sopenharmony_ci			    adapter->gotcl - adapter->gorcl :
253662306a36Sopenharmony_ci			    adapter->gorcl - adapter->gotcl) / 10000;
253762306a36Sopenharmony_ci		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
253862306a36Sopenharmony_ci
253962306a36Sopenharmony_ci		ew32(ITR, 1000000000 / (itr * 256));
254062306a36Sopenharmony_ci	}
254162306a36Sopenharmony_ci
254262306a36Sopenharmony_ci	/* Cause software interrupt to ensure rx ring is cleaned */
254362306a36Sopenharmony_ci	ew32(ICS, E1000_ICS_RXDMT0);
254462306a36Sopenharmony_ci
254562306a36Sopenharmony_ci	/* Force detection of hung controller every watchdog period */
254662306a36Sopenharmony_ci	adapter->detect_tx_hung = true;
254762306a36Sopenharmony_ci
254862306a36Sopenharmony_ci	/* Reschedule the task */
254962306a36Sopenharmony_ci	if (!test_bit(__E1000_DOWN, &adapter->flags))
255062306a36Sopenharmony_ci		schedule_delayed_work(&adapter->watchdog_task, 2 * HZ);
255162306a36Sopenharmony_ci}
255262306a36Sopenharmony_ci
255362306a36Sopenharmony_cienum latency_range {
255462306a36Sopenharmony_ci	lowest_latency = 0,
255562306a36Sopenharmony_ci	low_latency = 1,
255662306a36Sopenharmony_ci	bulk_latency = 2,
255762306a36Sopenharmony_ci	latency_invalid = 255
255862306a36Sopenharmony_ci};
255962306a36Sopenharmony_ci
256062306a36Sopenharmony_ci/**
256162306a36Sopenharmony_ci * e1000_update_itr - update the dynamic ITR value based on statistics
256262306a36Sopenharmony_ci * @adapter: pointer to adapter
256362306a36Sopenharmony_ci * @itr_setting: current adapter->itr
256462306a36Sopenharmony_ci * @packets: the number of packets during this measurement interval
256562306a36Sopenharmony_ci * @bytes: the number of bytes during this measurement interval
256662306a36Sopenharmony_ci *
256762306a36Sopenharmony_ci *      Stores a new ITR value based on packets and byte
256862306a36Sopenharmony_ci *      counts during the last interrupt.  The advantage of per interrupt
256962306a36Sopenharmony_ci *      computation is faster updates and more accurate ITR for the current
257062306a36Sopenharmony_ci *      traffic pattern.  Constants in this function were computed
257162306a36Sopenharmony_ci *      based on theoretical maximum wire speed and thresholds were set based
257262306a36Sopenharmony_ci *      on testing data as well as attempting to minimize response time
257362306a36Sopenharmony_ci *      while increasing bulk throughput.
257462306a36Sopenharmony_ci *      this functionality is controlled by the InterruptThrottleRate module
257562306a36Sopenharmony_ci *      parameter (see e1000_param.c)
257662306a36Sopenharmony_ci **/
257762306a36Sopenharmony_cistatic unsigned int e1000_update_itr(struct e1000_adapter *adapter,
257862306a36Sopenharmony_ci				     u16 itr_setting, int packets, int bytes)
257962306a36Sopenharmony_ci{
258062306a36Sopenharmony_ci	unsigned int retval = itr_setting;
258162306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
258262306a36Sopenharmony_ci
258362306a36Sopenharmony_ci	if (unlikely(hw->mac_type < e1000_82540))
258462306a36Sopenharmony_ci		goto update_itr_done;
258562306a36Sopenharmony_ci
258662306a36Sopenharmony_ci	if (packets == 0)
258762306a36Sopenharmony_ci		goto update_itr_done;
258862306a36Sopenharmony_ci
258962306a36Sopenharmony_ci	switch (itr_setting) {
259062306a36Sopenharmony_ci	case lowest_latency:
259162306a36Sopenharmony_ci		/* jumbo frames get bulk treatment*/
259262306a36Sopenharmony_ci		if (bytes/packets > 8000)
259362306a36Sopenharmony_ci			retval = bulk_latency;
259462306a36Sopenharmony_ci		else if ((packets < 5) && (bytes > 512))
259562306a36Sopenharmony_ci			retval = low_latency;
259662306a36Sopenharmony_ci		break;
259762306a36Sopenharmony_ci	case low_latency:  /* 50 usec aka 20000 ints/s */
259862306a36Sopenharmony_ci		if (bytes > 10000) {
259962306a36Sopenharmony_ci			/* jumbo frames need bulk latency setting */
260062306a36Sopenharmony_ci			if (bytes/packets > 8000)
260162306a36Sopenharmony_ci				retval = bulk_latency;
260262306a36Sopenharmony_ci			else if ((packets < 10) || ((bytes/packets) > 1200))
260362306a36Sopenharmony_ci				retval = bulk_latency;
260462306a36Sopenharmony_ci			else if ((packets > 35))
260562306a36Sopenharmony_ci				retval = lowest_latency;
260662306a36Sopenharmony_ci		} else if (bytes/packets > 2000)
260762306a36Sopenharmony_ci			retval = bulk_latency;
260862306a36Sopenharmony_ci		else if (packets <= 2 && bytes < 512)
260962306a36Sopenharmony_ci			retval = lowest_latency;
261062306a36Sopenharmony_ci		break;
261162306a36Sopenharmony_ci	case bulk_latency: /* 250 usec aka 4000 ints/s */
261262306a36Sopenharmony_ci		if (bytes > 25000) {
261362306a36Sopenharmony_ci			if (packets > 35)
261462306a36Sopenharmony_ci				retval = low_latency;
261562306a36Sopenharmony_ci		} else if (bytes < 6000) {
261662306a36Sopenharmony_ci			retval = low_latency;
261762306a36Sopenharmony_ci		}
261862306a36Sopenharmony_ci		break;
261962306a36Sopenharmony_ci	}
262062306a36Sopenharmony_ci
262162306a36Sopenharmony_ciupdate_itr_done:
262262306a36Sopenharmony_ci	return retval;
262362306a36Sopenharmony_ci}
262462306a36Sopenharmony_ci
262562306a36Sopenharmony_cistatic void e1000_set_itr(struct e1000_adapter *adapter)
262662306a36Sopenharmony_ci{
262762306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
262862306a36Sopenharmony_ci	u16 current_itr;
262962306a36Sopenharmony_ci	u32 new_itr = adapter->itr;
263062306a36Sopenharmony_ci
263162306a36Sopenharmony_ci	if (unlikely(hw->mac_type < e1000_82540))
263262306a36Sopenharmony_ci		return;
263362306a36Sopenharmony_ci
263462306a36Sopenharmony_ci	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
263562306a36Sopenharmony_ci	if (unlikely(adapter->link_speed != SPEED_1000)) {
263662306a36Sopenharmony_ci		new_itr = 4000;
263762306a36Sopenharmony_ci		goto set_itr_now;
263862306a36Sopenharmony_ci	}
263962306a36Sopenharmony_ci
264062306a36Sopenharmony_ci	adapter->tx_itr = e1000_update_itr(adapter, adapter->tx_itr,
264162306a36Sopenharmony_ci					   adapter->total_tx_packets,
264262306a36Sopenharmony_ci					   adapter->total_tx_bytes);
264362306a36Sopenharmony_ci	/* conservative mode (itr 3) eliminates the lowest_latency setting */
264462306a36Sopenharmony_ci	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
264562306a36Sopenharmony_ci		adapter->tx_itr = low_latency;
264662306a36Sopenharmony_ci
264762306a36Sopenharmony_ci	adapter->rx_itr = e1000_update_itr(adapter, adapter->rx_itr,
264862306a36Sopenharmony_ci					   adapter->total_rx_packets,
264962306a36Sopenharmony_ci					   adapter->total_rx_bytes);
265062306a36Sopenharmony_ci	/* conservative mode (itr 3) eliminates the lowest_latency setting */
265162306a36Sopenharmony_ci	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
265262306a36Sopenharmony_ci		adapter->rx_itr = low_latency;
265362306a36Sopenharmony_ci
265462306a36Sopenharmony_ci	current_itr = max(adapter->rx_itr, adapter->tx_itr);
265562306a36Sopenharmony_ci
265662306a36Sopenharmony_ci	switch (current_itr) {
265762306a36Sopenharmony_ci	/* counts and packets in update_itr are dependent on these numbers */
265862306a36Sopenharmony_ci	case lowest_latency:
265962306a36Sopenharmony_ci		new_itr = 70000;
266062306a36Sopenharmony_ci		break;
266162306a36Sopenharmony_ci	case low_latency:
266262306a36Sopenharmony_ci		new_itr = 20000; /* aka hwitr = ~200 */
266362306a36Sopenharmony_ci		break;
266462306a36Sopenharmony_ci	case bulk_latency:
266562306a36Sopenharmony_ci		new_itr = 4000;
266662306a36Sopenharmony_ci		break;
266762306a36Sopenharmony_ci	default:
266862306a36Sopenharmony_ci		break;
266962306a36Sopenharmony_ci	}
267062306a36Sopenharmony_ci
267162306a36Sopenharmony_ciset_itr_now:
267262306a36Sopenharmony_ci	if (new_itr != adapter->itr) {
267362306a36Sopenharmony_ci		/* this attempts to bias the interrupt rate towards Bulk
267462306a36Sopenharmony_ci		 * by adding intermediate steps when interrupt rate is
267562306a36Sopenharmony_ci		 * increasing
267662306a36Sopenharmony_ci		 */
267762306a36Sopenharmony_ci		new_itr = new_itr > adapter->itr ?
267862306a36Sopenharmony_ci			  min(adapter->itr + (new_itr >> 2), new_itr) :
267962306a36Sopenharmony_ci			  new_itr;
268062306a36Sopenharmony_ci		adapter->itr = new_itr;
268162306a36Sopenharmony_ci		ew32(ITR, 1000000000 / (new_itr * 256));
268262306a36Sopenharmony_ci	}
268362306a36Sopenharmony_ci}
268462306a36Sopenharmony_ci
268562306a36Sopenharmony_ci#define E1000_TX_FLAGS_CSUM		0x00000001
268662306a36Sopenharmony_ci#define E1000_TX_FLAGS_VLAN		0x00000002
268762306a36Sopenharmony_ci#define E1000_TX_FLAGS_TSO		0x00000004
268862306a36Sopenharmony_ci#define E1000_TX_FLAGS_IPV4		0x00000008
268962306a36Sopenharmony_ci#define E1000_TX_FLAGS_NO_FCS		0x00000010
269062306a36Sopenharmony_ci#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
269162306a36Sopenharmony_ci#define E1000_TX_FLAGS_VLAN_SHIFT	16
269262306a36Sopenharmony_ci
269362306a36Sopenharmony_cistatic int e1000_tso(struct e1000_adapter *adapter,
269462306a36Sopenharmony_ci		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb,
269562306a36Sopenharmony_ci		     __be16 protocol)
269662306a36Sopenharmony_ci{
269762306a36Sopenharmony_ci	struct e1000_context_desc *context_desc;
269862306a36Sopenharmony_ci	struct e1000_tx_buffer *buffer_info;
269962306a36Sopenharmony_ci	unsigned int i;
270062306a36Sopenharmony_ci	u32 cmd_length = 0;
270162306a36Sopenharmony_ci	u16 ipcse = 0, tucse, mss;
270262306a36Sopenharmony_ci	u8 ipcss, ipcso, tucss, tucso, hdr_len;
270362306a36Sopenharmony_ci
270462306a36Sopenharmony_ci	if (skb_is_gso(skb)) {
270562306a36Sopenharmony_ci		int err;
270662306a36Sopenharmony_ci
270762306a36Sopenharmony_ci		err = skb_cow_head(skb, 0);
270862306a36Sopenharmony_ci		if (err < 0)
270962306a36Sopenharmony_ci			return err;
271062306a36Sopenharmony_ci
271162306a36Sopenharmony_ci		hdr_len = skb_tcp_all_headers(skb);
271262306a36Sopenharmony_ci		mss = skb_shinfo(skb)->gso_size;
271362306a36Sopenharmony_ci		if (protocol == htons(ETH_P_IP)) {
271462306a36Sopenharmony_ci			struct iphdr *iph = ip_hdr(skb);
271562306a36Sopenharmony_ci			iph->tot_len = 0;
271662306a36Sopenharmony_ci			iph->check = 0;
271762306a36Sopenharmony_ci			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
271862306a36Sopenharmony_ci								 iph->daddr, 0,
271962306a36Sopenharmony_ci								 IPPROTO_TCP,
272062306a36Sopenharmony_ci								 0);
272162306a36Sopenharmony_ci			cmd_length = E1000_TXD_CMD_IP;
272262306a36Sopenharmony_ci			ipcse = skb_transport_offset(skb) - 1;
272362306a36Sopenharmony_ci		} else if (skb_is_gso_v6(skb)) {
272462306a36Sopenharmony_ci			tcp_v6_gso_csum_prep(skb);
272562306a36Sopenharmony_ci			ipcse = 0;
272662306a36Sopenharmony_ci		}
272762306a36Sopenharmony_ci		ipcss = skb_network_offset(skb);
272862306a36Sopenharmony_ci		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
272962306a36Sopenharmony_ci		tucss = skb_transport_offset(skb);
273062306a36Sopenharmony_ci		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
273162306a36Sopenharmony_ci		tucse = 0;
273262306a36Sopenharmony_ci
273362306a36Sopenharmony_ci		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
273462306a36Sopenharmony_ci			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
273562306a36Sopenharmony_ci
273662306a36Sopenharmony_ci		i = tx_ring->next_to_use;
273762306a36Sopenharmony_ci		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
273862306a36Sopenharmony_ci		buffer_info = &tx_ring->buffer_info[i];
273962306a36Sopenharmony_ci
274062306a36Sopenharmony_ci		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
274162306a36Sopenharmony_ci		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
274262306a36Sopenharmony_ci		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
274362306a36Sopenharmony_ci		context_desc->upper_setup.tcp_fields.tucss = tucss;
274462306a36Sopenharmony_ci		context_desc->upper_setup.tcp_fields.tucso = tucso;
274562306a36Sopenharmony_ci		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
274662306a36Sopenharmony_ci		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
274762306a36Sopenharmony_ci		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
274862306a36Sopenharmony_ci		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
274962306a36Sopenharmony_ci
275062306a36Sopenharmony_ci		buffer_info->time_stamp = jiffies;
275162306a36Sopenharmony_ci		buffer_info->next_to_watch = i;
275262306a36Sopenharmony_ci
275362306a36Sopenharmony_ci		if (++i == tx_ring->count)
275462306a36Sopenharmony_ci			i = 0;
275562306a36Sopenharmony_ci
275662306a36Sopenharmony_ci		tx_ring->next_to_use = i;
275762306a36Sopenharmony_ci
275862306a36Sopenharmony_ci		return true;
275962306a36Sopenharmony_ci	}
276062306a36Sopenharmony_ci	return false;
276162306a36Sopenharmony_ci}
276262306a36Sopenharmony_ci
276362306a36Sopenharmony_cistatic bool e1000_tx_csum(struct e1000_adapter *adapter,
276462306a36Sopenharmony_ci			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb,
276562306a36Sopenharmony_ci			  __be16 protocol)
276662306a36Sopenharmony_ci{
276762306a36Sopenharmony_ci	struct e1000_context_desc *context_desc;
276862306a36Sopenharmony_ci	struct e1000_tx_buffer *buffer_info;
276962306a36Sopenharmony_ci	unsigned int i;
277062306a36Sopenharmony_ci	u8 css;
277162306a36Sopenharmony_ci	u32 cmd_len = E1000_TXD_CMD_DEXT;
277262306a36Sopenharmony_ci
277362306a36Sopenharmony_ci	if (skb->ip_summed != CHECKSUM_PARTIAL)
277462306a36Sopenharmony_ci		return false;
277562306a36Sopenharmony_ci
277662306a36Sopenharmony_ci	switch (protocol) {
277762306a36Sopenharmony_ci	case cpu_to_be16(ETH_P_IP):
277862306a36Sopenharmony_ci		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
277962306a36Sopenharmony_ci			cmd_len |= E1000_TXD_CMD_TCP;
278062306a36Sopenharmony_ci		break;
278162306a36Sopenharmony_ci	case cpu_to_be16(ETH_P_IPV6):
278262306a36Sopenharmony_ci		/* XXX not handling all IPV6 headers */
278362306a36Sopenharmony_ci		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
278462306a36Sopenharmony_ci			cmd_len |= E1000_TXD_CMD_TCP;
278562306a36Sopenharmony_ci		break;
278662306a36Sopenharmony_ci	default:
278762306a36Sopenharmony_ci		if (unlikely(net_ratelimit()))
278862306a36Sopenharmony_ci			e_warn(drv, "checksum_partial proto=%x!\n",
278962306a36Sopenharmony_ci			       skb->protocol);
279062306a36Sopenharmony_ci		break;
279162306a36Sopenharmony_ci	}
279262306a36Sopenharmony_ci
279362306a36Sopenharmony_ci	css = skb_checksum_start_offset(skb);
279462306a36Sopenharmony_ci
279562306a36Sopenharmony_ci	i = tx_ring->next_to_use;
279662306a36Sopenharmony_ci	buffer_info = &tx_ring->buffer_info[i];
279762306a36Sopenharmony_ci	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
279862306a36Sopenharmony_ci
279962306a36Sopenharmony_ci	context_desc->lower_setup.ip_config = 0;
280062306a36Sopenharmony_ci	context_desc->upper_setup.tcp_fields.tucss = css;
280162306a36Sopenharmony_ci	context_desc->upper_setup.tcp_fields.tucso =
280262306a36Sopenharmony_ci		css + skb->csum_offset;
280362306a36Sopenharmony_ci	context_desc->upper_setup.tcp_fields.tucse = 0;
280462306a36Sopenharmony_ci	context_desc->tcp_seg_setup.data = 0;
280562306a36Sopenharmony_ci	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
280662306a36Sopenharmony_ci
280762306a36Sopenharmony_ci	buffer_info->time_stamp = jiffies;
280862306a36Sopenharmony_ci	buffer_info->next_to_watch = i;
280962306a36Sopenharmony_ci
281062306a36Sopenharmony_ci	if (unlikely(++i == tx_ring->count))
281162306a36Sopenharmony_ci		i = 0;
281262306a36Sopenharmony_ci
281362306a36Sopenharmony_ci	tx_ring->next_to_use = i;
281462306a36Sopenharmony_ci
281562306a36Sopenharmony_ci	return true;
281662306a36Sopenharmony_ci}
281762306a36Sopenharmony_ci
281862306a36Sopenharmony_ci#define E1000_MAX_TXD_PWR	12
281962306a36Sopenharmony_ci#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
282062306a36Sopenharmony_ci
282162306a36Sopenharmony_cistatic int e1000_tx_map(struct e1000_adapter *adapter,
282262306a36Sopenharmony_ci			struct e1000_tx_ring *tx_ring,
282362306a36Sopenharmony_ci			struct sk_buff *skb, unsigned int first,
282462306a36Sopenharmony_ci			unsigned int max_per_txd, unsigned int nr_frags,
282562306a36Sopenharmony_ci			unsigned int mss)
282662306a36Sopenharmony_ci{
282762306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
282862306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
282962306a36Sopenharmony_ci	struct e1000_tx_buffer *buffer_info;
283062306a36Sopenharmony_ci	unsigned int len = skb_headlen(skb);
283162306a36Sopenharmony_ci	unsigned int offset = 0, size, count = 0, i;
283262306a36Sopenharmony_ci	unsigned int f, bytecount, segs;
283362306a36Sopenharmony_ci
283462306a36Sopenharmony_ci	i = tx_ring->next_to_use;
283562306a36Sopenharmony_ci
283662306a36Sopenharmony_ci	while (len) {
283762306a36Sopenharmony_ci		buffer_info = &tx_ring->buffer_info[i];
283862306a36Sopenharmony_ci		size = min(len, max_per_txd);
283962306a36Sopenharmony_ci		/* Workaround for Controller erratum --
284062306a36Sopenharmony_ci		 * descriptor for non-tso packet in a linear SKB that follows a
284162306a36Sopenharmony_ci		 * tso gets written back prematurely before the data is fully
284262306a36Sopenharmony_ci		 * DMA'd to the controller
284362306a36Sopenharmony_ci		 */
284462306a36Sopenharmony_ci		if (!skb->data_len && tx_ring->last_tx_tso &&
284562306a36Sopenharmony_ci		    !skb_is_gso(skb)) {
284662306a36Sopenharmony_ci			tx_ring->last_tx_tso = false;
284762306a36Sopenharmony_ci			size -= 4;
284862306a36Sopenharmony_ci		}
284962306a36Sopenharmony_ci
285062306a36Sopenharmony_ci		/* Workaround for premature desc write-backs
285162306a36Sopenharmony_ci		 * in TSO mode.  Append 4-byte sentinel desc
285262306a36Sopenharmony_ci		 */
285362306a36Sopenharmony_ci		if (unlikely(mss && !nr_frags && size == len && size > 8))
285462306a36Sopenharmony_ci			size -= 4;
285562306a36Sopenharmony_ci		/* work-around for errata 10 and it applies
285662306a36Sopenharmony_ci		 * to all controllers in PCI-X mode
285762306a36Sopenharmony_ci		 * The fix is to make sure that the first descriptor of a
285862306a36Sopenharmony_ci		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
285962306a36Sopenharmony_ci		 */
286062306a36Sopenharmony_ci		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
286162306a36Sopenharmony_ci			     (size > 2015) && count == 0))
286262306a36Sopenharmony_ci			size = 2015;
286362306a36Sopenharmony_ci
286462306a36Sopenharmony_ci		/* Workaround for potential 82544 hang in PCI-X.  Avoid
286562306a36Sopenharmony_ci		 * terminating buffers within evenly-aligned dwords.
286662306a36Sopenharmony_ci		 */
286762306a36Sopenharmony_ci		if (unlikely(adapter->pcix_82544 &&
286862306a36Sopenharmony_ci		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
286962306a36Sopenharmony_ci		   size > 4))
287062306a36Sopenharmony_ci			size -= 4;
287162306a36Sopenharmony_ci
287262306a36Sopenharmony_ci		buffer_info->length = size;
287362306a36Sopenharmony_ci		/* set time_stamp *before* dma to help avoid a possible race */
287462306a36Sopenharmony_ci		buffer_info->time_stamp = jiffies;
287562306a36Sopenharmony_ci		buffer_info->mapped_as_page = false;
287662306a36Sopenharmony_ci		buffer_info->dma = dma_map_single(&pdev->dev,
287762306a36Sopenharmony_ci						  skb->data + offset,
287862306a36Sopenharmony_ci						  size, DMA_TO_DEVICE);
287962306a36Sopenharmony_ci		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
288062306a36Sopenharmony_ci			goto dma_error;
288162306a36Sopenharmony_ci		buffer_info->next_to_watch = i;
288262306a36Sopenharmony_ci
288362306a36Sopenharmony_ci		len -= size;
288462306a36Sopenharmony_ci		offset += size;
288562306a36Sopenharmony_ci		count++;
288662306a36Sopenharmony_ci		if (len) {
288762306a36Sopenharmony_ci			i++;
288862306a36Sopenharmony_ci			if (unlikely(i == tx_ring->count))
288962306a36Sopenharmony_ci				i = 0;
289062306a36Sopenharmony_ci		}
289162306a36Sopenharmony_ci	}
289262306a36Sopenharmony_ci
289362306a36Sopenharmony_ci	for (f = 0; f < nr_frags; f++) {
289462306a36Sopenharmony_ci		const skb_frag_t *frag = &skb_shinfo(skb)->frags[f];
289562306a36Sopenharmony_ci
289662306a36Sopenharmony_ci		len = skb_frag_size(frag);
289762306a36Sopenharmony_ci		offset = 0;
289862306a36Sopenharmony_ci
289962306a36Sopenharmony_ci		while (len) {
290062306a36Sopenharmony_ci			unsigned long bufend;
290162306a36Sopenharmony_ci			i++;
290262306a36Sopenharmony_ci			if (unlikely(i == tx_ring->count))
290362306a36Sopenharmony_ci				i = 0;
290462306a36Sopenharmony_ci
290562306a36Sopenharmony_ci			buffer_info = &tx_ring->buffer_info[i];
290662306a36Sopenharmony_ci			size = min(len, max_per_txd);
290762306a36Sopenharmony_ci			/* Workaround for premature desc write-backs
290862306a36Sopenharmony_ci			 * in TSO mode.  Append 4-byte sentinel desc
290962306a36Sopenharmony_ci			 */
291062306a36Sopenharmony_ci			if (unlikely(mss && f == (nr_frags-1) &&
291162306a36Sopenharmony_ci			    size == len && size > 8))
291262306a36Sopenharmony_ci				size -= 4;
291362306a36Sopenharmony_ci			/* Workaround for potential 82544 hang in PCI-X.
291462306a36Sopenharmony_ci			 * Avoid terminating buffers within evenly-aligned
291562306a36Sopenharmony_ci			 * dwords.
291662306a36Sopenharmony_ci			 */
291762306a36Sopenharmony_ci			bufend = (unsigned long)
291862306a36Sopenharmony_ci				page_to_phys(skb_frag_page(frag));
291962306a36Sopenharmony_ci			bufend += offset + size - 1;
292062306a36Sopenharmony_ci			if (unlikely(adapter->pcix_82544 &&
292162306a36Sopenharmony_ci				     !(bufend & 4) &&
292262306a36Sopenharmony_ci				     size > 4))
292362306a36Sopenharmony_ci				size -= 4;
292462306a36Sopenharmony_ci
292562306a36Sopenharmony_ci			buffer_info->length = size;
292662306a36Sopenharmony_ci			buffer_info->time_stamp = jiffies;
292762306a36Sopenharmony_ci			buffer_info->mapped_as_page = true;
292862306a36Sopenharmony_ci			buffer_info->dma = skb_frag_dma_map(&pdev->dev, frag,
292962306a36Sopenharmony_ci						offset, size, DMA_TO_DEVICE);
293062306a36Sopenharmony_ci			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
293162306a36Sopenharmony_ci				goto dma_error;
293262306a36Sopenharmony_ci			buffer_info->next_to_watch = i;
293362306a36Sopenharmony_ci
293462306a36Sopenharmony_ci			len -= size;
293562306a36Sopenharmony_ci			offset += size;
293662306a36Sopenharmony_ci			count++;
293762306a36Sopenharmony_ci		}
293862306a36Sopenharmony_ci	}
293962306a36Sopenharmony_ci
294062306a36Sopenharmony_ci	segs = skb_shinfo(skb)->gso_segs ?: 1;
294162306a36Sopenharmony_ci	/* multiply data chunks by size of headers */
294262306a36Sopenharmony_ci	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
294362306a36Sopenharmony_ci
294462306a36Sopenharmony_ci	tx_ring->buffer_info[i].skb = skb;
294562306a36Sopenharmony_ci	tx_ring->buffer_info[i].segs = segs;
294662306a36Sopenharmony_ci	tx_ring->buffer_info[i].bytecount = bytecount;
294762306a36Sopenharmony_ci	tx_ring->buffer_info[first].next_to_watch = i;
294862306a36Sopenharmony_ci
294962306a36Sopenharmony_ci	return count;
295062306a36Sopenharmony_ci
295162306a36Sopenharmony_cidma_error:
295262306a36Sopenharmony_ci	dev_err(&pdev->dev, "TX DMA map failed\n");
295362306a36Sopenharmony_ci	buffer_info->dma = 0;
295462306a36Sopenharmony_ci	if (count)
295562306a36Sopenharmony_ci		count--;
295662306a36Sopenharmony_ci
295762306a36Sopenharmony_ci	while (count--) {
295862306a36Sopenharmony_ci		if (i == 0)
295962306a36Sopenharmony_ci			i += tx_ring->count;
296062306a36Sopenharmony_ci		i--;
296162306a36Sopenharmony_ci		buffer_info = &tx_ring->buffer_info[i];
296262306a36Sopenharmony_ci		e1000_unmap_and_free_tx_resource(adapter, buffer_info, 0);
296362306a36Sopenharmony_ci	}
296462306a36Sopenharmony_ci
296562306a36Sopenharmony_ci	return 0;
296662306a36Sopenharmony_ci}
296762306a36Sopenharmony_ci
296862306a36Sopenharmony_cistatic void e1000_tx_queue(struct e1000_adapter *adapter,
296962306a36Sopenharmony_ci			   struct e1000_tx_ring *tx_ring, int tx_flags,
297062306a36Sopenharmony_ci			   int count)
297162306a36Sopenharmony_ci{
297262306a36Sopenharmony_ci	struct e1000_tx_desc *tx_desc = NULL;
297362306a36Sopenharmony_ci	struct e1000_tx_buffer *buffer_info;
297462306a36Sopenharmony_ci	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
297562306a36Sopenharmony_ci	unsigned int i;
297662306a36Sopenharmony_ci
297762306a36Sopenharmony_ci	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
297862306a36Sopenharmony_ci		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
297962306a36Sopenharmony_ci			     E1000_TXD_CMD_TSE;
298062306a36Sopenharmony_ci		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
298162306a36Sopenharmony_ci
298262306a36Sopenharmony_ci		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
298362306a36Sopenharmony_ci			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
298462306a36Sopenharmony_ci	}
298562306a36Sopenharmony_ci
298662306a36Sopenharmony_ci	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
298762306a36Sopenharmony_ci		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
298862306a36Sopenharmony_ci		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
298962306a36Sopenharmony_ci	}
299062306a36Sopenharmony_ci
299162306a36Sopenharmony_ci	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
299262306a36Sopenharmony_ci		txd_lower |= E1000_TXD_CMD_VLE;
299362306a36Sopenharmony_ci		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
299462306a36Sopenharmony_ci	}
299562306a36Sopenharmony_ci
299662306a36Sopenharmony_ci	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
299762306a36Sopenharmony_ci		txd_lower &= ~(E1000_TXD_CMD_IFCS);
299862306a36Sopenharmony_ci
299962306a36Sopenharmony_ci	i = tx_ring->next_to_use;
300062306a36Sopenharmony_ci
300162306a36Sopenharmony_ci	while (count--) {
300262306a36Sopenharmony_ci		buffer_info = &tx_ring->buffer_info[i];
300362306a36Sopenharmony_ci		tx_desc = E1000_TX_DESC(*tx_ring, i);
300462306a36Sopenharmony_ci		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
300562306a36Sopenharmony_ci		tx_desc->lower.data =
300662306a36Sopenharmony_ci			cpu_to_le32(txd_lower | buffer_info->length);
300762306a36Sopenharmony_ci		tx_desc->upper.data = cpu_to_le32(txd_upper);
300862306a36Sopenharmony_ci		if (unlikely(++i == tx_ring->count))
300962306a36Sopenharmony_ci			i = 0;
301062306a36Sopenharmony_ci	}
301162306a36Sopenharmony_ci
301262306a36Sopenharmony_ci	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
301362306a36Sopenharmony_ci
301462306a36Sopenharmony_ci	/* txd_cmd re-enables FCS, so we'll re-disable it here as desired. */
301562306a36Sopenharmony_ci	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
301662306a36Sopenharmony_ci		tx_desc->lower.data &= ~(cpu_to_le32(E1000_TXD_CMD_IFCS));
301762306a36Sopenharmony_ci
301862306a36Sopenharmony_ci	/* Force memory writes to complete before letting h/w
301962306a36Sopenharmony_ci	 * know there are new descriptors to fetch.  (Only
302062306a36Sopenharmony_ci	 * applicable for weak-ordered memory model archs,
302162306a36Sopenharmony_ci	 * such as IA-64).
302262306a36Sopenharmony_ci	 */
302362306a36Sopenharmony_ci	dma_wmb();
302462306a36Sopenharmony_ci
302562306a36Sopenharmony_ci	tx_ring->next_to_use = i;
302662306a36Sopenharmony_ci}
302762306a36Sopenharmony_ci
302862306a36Sopenharmony_ci/* 82547 workaround to avoid controller hang in half-duplex environment.
302962306a36Sopenharmony_ci * The workaround is to avoid queuing a large packet that would span
303062306a36Sopenharmony_ci * the internal Tx FIFO ring boundary by notifying the stack to resend
303162306a36Sopenharmony_ci * the packet at a later time.  This gives the Tx FIFO an opportunity to
303262306a36Sopenharmony_ci * flush all packets.  When that occurs, we reset the Tx FIFO pointers
303362306a36Sopenharmony_ci * to the beginning of the Tx FIFO.
303462306a36Sopenharmony_ci */
303562306a36Sopenharmony_ci
303662306a36Sopenharmony_ci#define E1000_FIFO_HDR			0x10
303762306a36Sopenharmony_ci#define E1000_82547_PAD_LEN		0x3E0
303862306a36Sopenharmony_ci
303962306a36Sopenharmony_cistatic int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
304062306a36Sopenharmony_ci				       struct sk_buff *skb)
304162306a36Sopenharmony_ci{
304262306a36Sopenharmony_ci	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
304362306a36Sopenharmony_ci	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
304462306a36Sopenharmony_ci
304562306a36Sopenharmony_ci	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
304662306a36Sopenharmony_ci
304762306a36Sopenharmony_ci	if (adapter->link_duplex != HALF_DUPLEX)
304862306a36Sopenharmony_ci		goto no_fifo_stall_required;
304962306a36Sopenharmony_ci
305062306a36Sopenharmony_ci	if (atomic_read(&adapter->tx_fifo_stall))
305162306a36Sopenharmony_ci		return 1;
305262306a36Sopenharmony_ci
305362306a36Sopenharmony_ci	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
305462306a36Sopenharmony_ci		atomic_set(&adapter->tx_fifo_stall, 1);
305562306a36Sopenharmony_ci		return 1;
305662306a36Sopenharmony_ci	}
305762306a36Sopenharmony_ci
305862306a36Sopenharmony_cino_fifo_stall_required:
305962306a36Sopenharmony_ci	adapter->tx_fifo_head += skb_fifo_len;
306062306a36Sopenharmony_ci	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
306162306a36Sopenharmony_ci		adapter->tx_fifo_head -= adapter->tx_fifo_size;
306262306a36Sopenharmony_ci	return 0;
306362306a36Sopenharmony_ci}
306462306a36Sopenharmony_ci
306562306a36Sopenharmony_cistatic int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
306662306a36Sopenharmony_ci{
306762306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
306862306a36Sopenharmony_ci	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
306962306a36Sopenharmony_ci
307062306a36Sopenharmony_ci	netif_stop_queue(netdev);
307162306a36Sopenharmony_ci	/* Herbert's original patch had:
307262306a36Sopenharmony_ci	 *  smp_mb__after_netif_stop_queue();
307362306a36Sopenharmony_ci	 * but since that doesn't exist yet, just open code it.
307462306a36Sopenharmony_ci	 */
307562306a36Sopenharmony_ci	smp_mb();
307662306a36Sopenharmony_ci
307762306a36Sopenharmony_ci	/* We need to check again in a case another CPU has just
307862306a36Sopenharmony_ci	 * made room available.
307962306a36Sopenharmony_ci	 */
308062306a36Sopenharmony_ci	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
308162306a36Sopenharmony_ci		return -EBUSY;
308262306a36Sopenharmony_ci
308362306a36Sopenharmony_ci	/* A reprieve! */
308462306a36Sopenharmony_ci	netif_start_queue(netdev);
308562306a36Sopenharmony_ci	++adapter->restart_queue;
308662306a36Sopenharmony_ci	return 0;
308762306a36Sopenharmony_ci}
308862306a36Sopenharmony_ci
308962306a36Sopenharmony_cistatic int e1000_maybe_stop_tx(struct net_device *netdev,
309062306a36Sopenharmony_ci			       struct e1000_tx_ring *tx_ring, int size)
309162306a36Sopenharmony_ci{
309262306a36Sopenharmony_ci	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
309362306a36Sopenharmony_ci		return 0;
309462306a36Sopenharmony_ci	return __e1000_maybe_stop_tx(netdev, size);
309562306a36Sopenharmony_ci}
309662306a36Sopenharmony_ci
309762306a36Sopenharmony_ci#define TXD_USE_COUNT(S, X) (((S) + ((1 << (X)) - 1)) >> (X))
309862306a36Sopenharmony_cistatic netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
309962306a36Sopenharmony_ci				    struct net_device *netdev)
310062306a36Sopenharmony_ci{
310162306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
310262306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
310362306a36Sopenharmony_ci	struct e1000_tx_ring *tx_ring;
310462306a36Sopenharmony_ci	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
310562306a36Sopenharmony_ci	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
310662306a36Sopenharmony_ci	unsigned int tx_flags = 0;
310762306a36Sopenharmony_ci	unsigned int len = skb_headlen(skb);
310862306a36Sopenharmony_ci	unsigned int nr_frags;
310962306a36Sopenharmony_ci	unsigned int mss;
311062306a36Sopenharmony_ci	int count = 0;
311162306a36Sopenharmony_ci	int tso;
311262306a36Sopenharmony_ci	unsigned int f;
311362306a36Sopenharmony_ci	__be16 protocol = vlan_get_protocol(skb);
311462306a36Sopenharmony_ci
311562306a36Sopenharmony_ci	/* This goes back to the question of how to logically map a Tx queue
311662306a36Sopenharmony_ci	 * to a flow.  Right now, performance is impacted slightly negatively
311762306a36Sopenharmony_ci	 * if using multiple Tx queues.  If the stack breaks away from a
311862306a36Sopenharmony_ci	 * single qdisc implementation, we can look at this again.
311962306a36Sopenharmony_ci	 */
312062306a36Sopenharmony_ci	tx_ring = adapter->tx_ring;
312162306a36Sopenharmony_ci
312262306a36Sopenharmony_ci	/* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
312362306a36Sopenharmony_ci	 * packets may get corrupted during padding by HW.
312462306a36Sopenharmony_ci	 * To WA this issue, pad all small packets manually.
312562306a36Sopenharmony_ci	 */
312662306a36Sopenharmony_ci	if (eth_skb_pad(skb))
312762306a36Sopenharmony_ci		return NETDEV_TX_OK;
312862306a36Sopenharmony_ci
312962306a36Sopenharmony_ci	mss = skb_shinfo(skb)->gso_size;
313062306a36Sopenharmony_ci	/* The controller does a simple calculation to
313162306a36Sopenharmony_ci	 * make sure there is enough room in the FIFO before
313262306a36Sopenharmony_ci	 * initiating the DMA for each buffer.  The calc is:
313362306a36Sopenharmony_ci	 * 4 = ceil(buffer len/mss).  To make sure we don't
313462306a36Sopenharmony_ci	 * overrun the FIFO, adjust the max buffer len if mss
313562306a36Sopenharmony_ci	 * drops.
313662306a36Sopenharmony_ci	 */
313762306a36Sopenharmony_ci	if (mss) {
313862306a36Sopenharmony_ci		u8 hdr_len;
313962306a36Sopenharmony_ci		max_per_txd = min(mss << 2, max_per_txd);
314062306a36Sopenharmony_ci		max_txd_pwr = fls(max_per_txd) - 1;
314162306a36Sopenharmony_ci
314262306a36Sopenharmony_ci		hdr_len = skb_tcp_all_headers(skb);
314362306a36Sopenharmony_ci		if (skb->data_len && hdr_len == len) {
314462306a36Sopenharmony_ci			switch (hw->mac_type) {
314562306a36Sopenharmony_ci			case e1000_82544: {
314662306a36Sopenharmony_ci				unsigned int pull_size;
314762306a36Sopenharmony_ci
314862306a36Sopenharmony_ci				/* Make sure we have room to chop off 4 bytes,
314962306a36Sopenharmony_ci				 * and that the end alignment will work out to
315062306a36Sopenharmony_ci				 * this hardware's requirements
315162306a36Sopenharmony_ci				 * NOTE: this is a TSO only workaround
315262306a36Sopenharmony_ci				 * if end byte alignment not correct move us
315362306a36Sopenharmony_ci				 * into the next dword
315462306a36Sopenharmony_ci				 */
315562306a36Sopenharmony_ci				if ((unsigned long)(skb_tail_pointer(skb) - 1)
315662306a36Sopenharmony_ci				    & 4)
315762306a36Sopenharmony_ci					break;
315862306a36Sopenharmony_ci				pull_size = min((unsigned int)4, skb->data_len);
315962306a36Sopenharmony_ci				if (!__pskb_pull_tail(skb, pull_size)) {
316062306a36Sopenharmony_ci					e_err(drv, "__pskb_pull_tail "
316162306a36Sopenharmony_ci					      "failed.\n");
316262306a36Sopenharmony_ci					dev_kfree_skb_any(skb);
316362306a36Sopenharmony_ci					return NETDEV_TX_OK;
316462306a36Sopenharmony_ci				}
316562306a36Sopenharmony_ci				len = skb_headlen(skb);
316662306a36Sopenharmony_ci				break;
316762306a36Sopenharmony_ci			}
316862306a36Sopenharmony_ci			default:
316962306a36Sopenharmony_ci				/* do nothing */
317062306a36Sopenharmony_ci				break;
317162306a36Sopenharmony_ci			}
317262306a36Sopenharmony_ci		}
317362306a36Sopenharmony_ci	}
317462306a36Sopenharmony_ci
317562306a36Sopenharmony_ci	/* reserve a descriptor for the offload context */
317662306a36Sopenharmony_ci	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
317762306a36Sopenharmony_ci		count++;
317862306a36Sopenharmony_ci	count++;
317962306a36Sopenharmony_ci
318062306a36Sopenharmony_ci	/* Controller Erratum workaround */
318162306a36Sopenharmony_ci	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
318262306a36Sopenharmony_ci		count++;
318362306a36Sopenharmony_ci
318462306a36Sopenharmony_ci	count += TXD_USE_COUNT(len, max_txd_pwr);
318562306a36Sopenharmony_ci
318662306a36Sopenharmony_ci	if (adapter->pcix_82544)
318762306a36Sopenharmony_ci		count++;
318862306a36Sopenharmony_ci
318962306a36Sopenharmony_ci	/* work-around for errata 10 and it applies to all controllers
319062306a36Sopenharmony_ci	 * in PCI-X mode, so add one more descriptor to the count
319162306a36Sopenharmony_ci	 */
319262306a36Sopenharmony_ci	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
319362306a36Sopenharmony_ci			(len > 2015)))
319462306a36Sopenharmony_ci		count++;
319562306a36Sopenharmony_ci
319662306a36Sopenharmony_ci	nr_frags = skb_shinfo(skb)->nr_frags;
319762306a36Sopenharmony_ci	for (f = 0; f < nr_frags; f++)
319862306a36Sopenharmony_ci		count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]),
319962306a36Sopenharmony_ci				       max_txd_pwr);
320062306a36Sopenharmony_ci	if (adapter->pcix_82544)
320162306a36Sopenharmony_ci		count += nr_frags;
320262306a36Sopenharmony_ci
320362306a36Sopenharmony_ci	/* need: count + 2 desc gap to keep tail from touching
320462306a36Sopenharmony_ci	 * head, otherwise try next time
320562306a36Sopenharmony_ci	 */
320662306a36Sopenharmony_ci	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
320762306a36Sopenharmony_ci		return NETDEV_TX_BUSY;
320862306a36Sopenharmony_ci
320962306a36Sopenharmony_ci	if (unlikely((hw->mac_type == e1000_82547) &&
321062306a36Sopenharmony_ci		     (e1000_82547_fifo_workaround(adapter, skb)))) {
321162306a36Sopenharmony_ci		netif_stop_queue(netdev);
321262306a36Sopenharmony_ci		if (!test_bit(__E1000_DOWN, &adapter->flags))
321362306a36Sopenharmony_ci			schedule_delayed_work(&adapter->fifo_stall_task, 1);
321462306a36Sopenharmony_ci		return NETDEV_TX_BUSY;
321562306a36Sopenharmony_ci	}
321662306a36Sopenharmony_ci
321762306a36Sopenharmony_ci	if (skb_vlan_tag_present(skb)) {
321862306a36Sopenharmony_ci		tx_flags |= E1000_TX_FLAGS_VLAN;
321962306a36Sopenharmony_ci		tx_flags |= (skb_vlan_tag_get(skb) <<
322062306a36Sopenharmony_ci			     E1000_TX_FLAGS_VLAN_SHIFT);
322162306a36Sopenharmony_ci	}
322262306a36Sopenharmony_ci
322362306a36Sopenharmony_ci	first = tx_ring->next_to_use;
322462306a36Sopenharmony_ci
322562306a36Sopenharmony_ci	tso = e1000_tso(adapter, tx_ring, skb, protocol);
322662306a36Sopenharmony_ci	if (tso < 0) {
322762306a36Sopenharmony_ci		dev_kfree_skb_any(skb);
322862306a36Sopenharmony_ci		return NETDEV_TX_OK;
322962306a36Sopenharmony_ci	}
323062306a36Sopenharmony_ci
323162306a36Sopenharmony_ci	if (likely(tso)) {
323262306a36Sopenharmony_ci		if (likely(hw->mac_type != e1000_82544))
323362306a36Sopenharmony_ci			tx_ring->last_tx_tso = true;
323462306a36Sopenharmony_ci		tx_flags |= E1000_TX_FLAGS_TSO;
323562306a36Sopenharmony_ci	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb, protocol)))
323662306a36Sopenharmony_ci		tx_flags |= E1000_TX_FLAGS_CSUM;
323762306a36Sopenharmony_ci
323862306a36Sopenharmony_ci	if (protocol == htons(ETH_P_IP))
323962306a36Sopenharmony_ci		tx_flags |= E1000_TX_FLAGS_IPV4;
324062306a36Sopenharmony_ci
324162306a36Sopenharmony_ci	if (unlikely(skb->no_fcs))
324262306a36Sopenharmony_ci		tx_flags |= E1000_TX_FLAGS_NO_FCS;
324362306a36Sopenharmony_ci
324462306a36Sopenharmony_ci	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
324562306a36Sopenharmony_ci			     nr_frags, mss);
324662306a36Sopenharmony_ci
324762306a36Sopenharmony_ci	if (count) {
324862306a36Sopenharmony_ci		/* The descriptors needed is higher than other Intel drivers
324962306a36Sopenharmony_ci		 * due to a number of workarounds.  The breakdown is below:
325062306a36Sopenharmony_ci		 * Data descriptors: MAX_SKB_FRAGS + 1
325162306a36Sopenharmony_ci		 * Context Descriptor: 1
325262306a36Sopenharmony_ci		 * Keep head from touching tail: 2
325362306a36Sopenharmony_ci		 * Workarounds: 3
325462306a36Sopenharmony_ci		 */
325562306a36Sopenharmony_ci		int desc_needed = MAX_SKB_FRAGS + 7;
325662306a36Sopenharmony_ci
325762306a36Sopenharmony_ci		netdev_sent_queue(netdev, skb->len);
325862306a36Sopenharmony_ci		skb_tx_timestamp(skb);
325962306a36Sopenharmony_ci
326062306a36Sopenharmony_ci		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
326162306a36Sopenharmony_ci
326262306a36Sopenharmony_ci		/* 82544 potentially requires twice as many data descriptors
326362306a36Sopenharmony_ci		 * in order to guarantee buffers don't end on evenly-aligned
326462306a36Sopenharmony_ci		 * dwords
326562306a36Sopenharmony_ci		 */
326662306a36Sopenharmony_ci		if (adapter->pcix_82544)
326762306a36Sopenharmony_ci			desc_needed += MAX_SKB_FRAGS + 1;
326862306a36Sopenharmony_ci
326962306a36Sopenharmony_ci		/* Make sure there is space in the ring for the next send. */
327062306a36Sopenharmony_ci		e1000_maybe_stop_tx(netdev, tx_ring, desc_needed);
327162306a36Sopenharmony_ci
327262306a36Sopenharmony_ci		if (!netdev_xmit_more() ||
327362306a36Sopenharmony_ci		    netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) {
327462306a36Sopenharmony_ci			writel(tx_ring->next_to_use, hw->hw_addr + tx_ring->tdt);
327562306a36Sopenharmony_ci		}
327662306a36Sopenharmony_ci	} else {
327762306a36Sopenharmony_ci		dev_kfree_skb_any(skb);
327862306a36Sopenharmony_ci		tx_ring->buffer_info[first].time_stamp = 0;
327962306a36Sopenharmony_ci		tx_ring->next_to_use = first;
328062306a36Sopenharmony_ci	}
328162306a36Sopenharmony_ci
328262306a36Sopenharmony_ci	return NETDEV_TX_OK;
328362306a36Sopenharmony_ci}
328462306a36Sopenharmony_ci
328562306a36Sopenharmony_ci#define NUM_REGS 38 /* 1 based count */
328662306a36Sopenharmony_cistatic void e1000_regdump(struct e1000_adapter *adapter)
328762306a36Sopenharmony_ci{
328862306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
328962306a36Sopenharmony_ci	u32 regs[NUM_REGS];
329062306a36Sopenharmony_ci	u32 *regs_buff = regs;
329162306a36Sopenharmony_ci	int i = 0;
329262306a36Sopenharmony_ci
329362306a36Sopenharmony_ci	static const char * const reg_name[] = {
329462306a36Sopenharmony_ci		"CTRL",  "STATUS",
329562306a36Sopenharmony_ci		"RCTL", "RDLEN", "RDH", "RDT", "RDTR",
329662306a36Sopenharmony_ci		"TCTL", "TDBAL", "TDBAH", "TDLEN", "TDH", "TDT",
329762306a36Sopenharmony_ci		"TIDV", "TXDCTL", "TADV", "TARC0",
329862306a36Sopenharmony_ci		"TDBAL1", "TDBAH1", "TDLEN1", "TDH1", "TDT1",
329962306a36Sopenharmony_ci		"TXDCTL1", "TARC1",
330062306a36Sopenharmony_ci		"CTRL_EXT", "ERT", "RDBAL", "RDBAH",
330162306a36Sopenharmony_ci		"TDFH", "TDFT", "TDFHS", "TDFTS", "TDFPC",
330262306a36Sopenharmony_ci		"RDFH", "RDFT", "RDFHS", "RDFTS", "RDFPC"
330362306a36Sopenharmony_ci	};
330462306a36Sopenharmony_ci
330562306a36Sopenharmony_ci	regs_buff[0]  = er32(CTRL);
330662306a36Sopenharmony_ci	regs_buff[1]  = er32(STATUS);
330762306a36Sopenharmony_ci
330862306a36Sopenharmony_ci	regs_buff[2]  = er32(RCTL);
330962306a36Sopenharmony_ci	regs_buff[3]  = er32(RDLEN);
331062306a36Sopenharmony_ci	regs_buff[4]  = er32(RDH);
331162306a36Sopenharmony_ci	regs_buff[5]  = er32(RDT);
331262306a36Sopenharmony_ci	regs_buff[6]  = er32(RDTR);
331362306a36Sopenharmony_ci
331462306a36Sopenharmony_ci	regs_buff[7]  = er32(TCTL);
331562306a36Sopenharmony_ci	regs_buff[8]  = er32(TDBAL);
331662306a36Sopenharmony_ci	regs_buff[9]  = er32(TDBAH);
331762306a36Sopenharmony_ci	regs_buff[10] = er32(TDLEN);
331862306a36Sopenharmony_ci	regs_buff[11] = er32(TDH);
331962306a36Sopenharmony_ci	regs_buff[12] = er32(TDT);
332062306a36Sopenharmony_ci	regs_buff[13] = er32(TIDV);
332162306a36Sopenharmony_ci	regs_buff[14] = er32(TXDCTL);
332262306a36Sopenharmony_ci	regs_buff[15] = er32(TADV);
332362306a36Sopenharmony_ci	regs_buff[16] = er32(TARC0);
332462306a36Sopenharmony_ci
332562306a36Sopenharmony_ci	regs_buff[17] = er32(TDBAL1);
332662306a36Sopenharmony_ci	regs_buff[18] = er32(TDBAH1);
332762306a36Sopenharmony_ci	regs_buff[19] = er32(TDLEN1);
332862306a36Sopenharmony_ci	regs_buff[20] = er32(TDH1);
332962306a36Sopenharmony_ci	regs_buff[21] = er32(TDT1);
333062306a36Sopenharmony_ci	regs_buff[22] = er32(TXDCTL1);
333162306a36Sopenharmony_ci	regs_buff[23] = er32(TARC1);
333262306a36Sopenharmony_ci	regs_buff[24] = er32(CTRL_EXT);
333362306a36Sopenharmony_ci	regs_buff[25] = er32(ERT);
333462306a36Sopenharmony_ci	regs_buff[26] = er32(RDBAL0);
333562306a36Sopenharmony_ci	regs_buff[27] = er32(RDBAH0);
333662306a36Sopenharmony_ci	regs_buff[28] = er32(TDFH);
333762306a36Sopenharmony_ci	regs_buff[29] = er32(TDFT);
333862306a36Sopenharmony_ci	regs_buff[30] = er32(TDFHS);
333962306a36Sopenharmony_ci	regs_buff[31] = er32(TDFTS);
334062306a36Sopenharmony_ci	regs_buff[32] = er32(TDFPC);
334162306a36Sopenharmony_ci	regs_buff[33] = er32(RDFH);
334262306a36Sopenharmony_ci	regs_buff[34] = er32(RDFT);
334362306a36Sopenharmony_ci	regs_buff[35] = er32(RDFHS);
334462306a36Sopenharmony_ci	regs_buff[36] = er32(RDFTS);
334562306a36Sopenharmony_ci	regs_buff[37] = er32(RDFPC);
334662306a36Sopenharmony_ci
334762306a36Sopenharmony_ci	pr_info("Register dump\n");
334862306a36Sopenharmony_ci	for (i = 0; i < NUM_REGS; i++)
334962306a36Sopenharmony_ci		pr_info("%-15s  %08x\n", reg_name[i], regs_buff[i]);
335062306a36Sopenharmony_ci}
335162306a36Sopenharmony_ci
335262306a36Sopenharmony_ci/*
335362306a36Sopenharmony_ci * e1000_dump: Print registers, tx ring and rx ring
335462306a36Sopenharmony_ci */
335562306a36Sopenharmony_cistatic void e1000_dump(struct e1000_adapter *adapter)
335662306a36Sopenharmony_ci{
335762306a36Sopenharmony_ci	/* this code doesn't handle multiple rings */
335862306a36Sopenharmony_ci	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
335962306a36Sopenharmony_ci	struct e1000_rx_ring *rx_ring = adapter->rx_ring;
336062306a36Sopenharmony_ci	int i;
336162306a36Sopenharmony_ci
336262306a36Sopenharmony_ci	if (!netif_msg_hw(adapter))
336362306a36Sopenharmony_ci		return;
336462306a36Sopenharmony_ci
336562306a36Sopenharmony_ci	/* Print Registers */
336662306a36Sopenharmony_ci	e1000_regdump(adapter);
336762306a36Sopenharmony_ci
336862306a36Sopenharmony_ci	/* transmit dump */
336962306a36Sopenharmony_ci	pr_info("TX Desc ring0 dump\n");
337062306a36Sopenharmony_ci
337162306a36Sopenharmony_ci	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
337262306a36Sopenharmony_ci	 *
337362306a36Sopenharmony_ci	 * Legacy Transmit Descriptor
337462306a36Sopenharmony_ci	 *   +--------------------------------------------------------------+
337562306a36Sopenharmony_ci	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
337662306a36Sopenharmony_ci	 *   +--------------------------------------------------------------+
337762306a36Sopenharmony_ci	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
337862306a36Sopenharmony_ci	 *   +--------------------------------------------------------------+
337962306a36Sopenharmony_ci	 *   63       48 47        36 35    32 31     24 23    16 15        0
338062306a36Sopenharmony_ci	 *
338162306a36Sopenharmony_ci	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
338262306a36Sopenharmony_ci	 *   63      48 47    40 39       32 31             16 15    8 7      0
338362306a36Sopenharmony_ci	 *   +----------------------------------------------------------------+
338462306a36Sopenharmony_ci	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
338562306a36Sopenharmony_ci	 *   +----------------------------------------------------------------+
338662306a36Sopenharmony_ci	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
338762306a36Sopenharmony_ci	 *   +----------------------------------------------------------------+
338862306a36Sopenharmony_ci	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
338962306a36Sopenharmony_ci	 *
339062306a36Sopenharmony_ci	 * Extended Data Descriptor (DTYP=0x1)
339162306a36Sopenharmony_ci	 *   +----------------------------------------------------------------+
339262306a36Sopenharmony_ci	 * 0 |                     Buffer Address [63:0]                      |
339362306a36Sopenharmony_ci	 *   +----------------------------------------------------------------+
339462306a36Sopenharmony_ci	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
339562306a36Sopenharmony_ci	 *   +----------------------------------------------------------------+
339662306a36Sopenharmony_ci	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
339762306a36Sopenharmony_ci	 */
339862306a36Sopenharmony_ci	pr_info("Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma       ] leng  ntw timestmp         bi->skb\n");
339962306a36Sopenharmony_ci	pr_info("Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen] [bi->dma       ] leng  ntw timestmp         bi->skb\n");
340062306a36Sopenharmony_ci
340162306a36Sopenharmony_ci	if (!netif_msg_tx_done(adapter))
340262306a36Sopenharmony_ci		goto rx_ring_summary;
340362306a36Sopenharmony_ci
340462306a36Sopenharmony_ci	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
340562306a36Sopenharmony_ci		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
340662306a36Sopenharmony_ci		struct e1000_tx_buffer *buffer_info = &tx_ring->buffer_info[i];
340762306a36Sopenharmony_ci		struct my_u { __le64 a; __le64 b; };
340862306a36Sopenharmony_ci		struct my_u *u = (struct my_u *)tx_desc;
340962306a36Sopenharmony_ci		const char *type;
341062306a36Sopenharmony_ci
341162306a36Sopenharmony_ci		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
341262306a36Sopenharmony_ci			type = "NTC/U";
341362306a36Sopenharmony_ci		else if (i == tx_ring->next_to_use)
341462306a36Sopenharmony_ci			type = "NTU";
341562306a36Sopenharmony_ci		else if (i == tx_ring->next_to_clean)
341662306a36Sopenharmony_ci			type = "NTC";
341762306a36Sopenharmony_ci		else
341862306a36Sopenharmony_ci			type = "";
341962306a36Sopenharmony_ci
342062306a36Sopenharmony_ci		pr_info("T%c[0x%03X]    %016llX %016llX %016llX %04X  %3X %016llX %p %s\n",
342162306a36Sopenharmony_ci			((le64_to_cpu(u->b) & (1<<20)) ? 'd' : 'c'), i,
342262306a36Sopenharmony_ci			le64_to_cpu(u->a), le64_to_cpu(u->b),
342362306a36Sopenharmony_ci			(u64)buffer_info->dma, buffer_info->length,
342462306a36Sopenharmony_ci			buffer_info->next_to_watch,
342562306a36Sopenharmony_ci			(u64)buffer_info->time_stamp, buffer_info->skb, type);
342662306a36Sopenharmony_ci	}
342762306a36Sopenharmony_ci
342862306a36Sopenharmony_cirx_ring_summary:
342962306a36Sopenharmony_ci	/* receive dump */
343062306a36Sopenharmony_ci	pr_info("\nRX Desc ring dump\n");
343162306a36Sopenharmony_ci
343262306a36Sopenharmony_ci	/* Legacy Receive Descriptor Format
343362306a36Sopenharmony_ci	 *
343462306a36Sopenharmony_ci	 * +-----------------------------------------------------+
343562306a36Sopenharmony_ci	 * |                Buffer Address [63:0]                |
343662306a36Sopenharmony_ci	 * +-----------------------------------------------------+
343762306a36Sopenharmony_ci	 * | VLAN Tag | Errors | Status 0 | Packet csum | Length |
343862306a36Sopenharmony_ci	 * +-----------------------------------------------------+
343962306a36Sopenharmony_ci	 * 63       48 47    40 39      32 31         16 15      0
344062306a36Sopenharmony_ci	 */
344162306a36Sopenharmony_ci	pr_info("R[desc]      [address 63:0  ] [vl er S cks ln] [bi->dma       ] [bi->skb]\n");
344262306a36Sopenharmony_ci
344362306a36Sopenharmony_ci	if (!netif_msg_rx_status(adapter))
344462306a36Sopenharmony_ci		goto exit;
344562306a36Sopenharmony_ci
344662306a36Sopenharmony_ci	for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
344762306a36Sopenharmony_ci		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
344862306a36Sopenharmony_ci		struct e1000_rx_buffer *buffer_info = &rx_ring->buffer_info[i];
344962306a36Sopenharmony_ci		struct my_u { __le64 a; __le64 b; };
345062306a36Sopenharmony_ci		struct my_u *u = (struct my_u *)rx_desc;
345162306a36Sopenharmony_ci		const char *type;
345262306a36Sopenharmony_ci
345362306a36Sopenharmony_ci		if (i == rx_ring->next_to_use)
345462306a36Sopenharmony_ci			type = "NTU";
345562306a36Sopenharmony_ci		else if (i == rx_ring->next_to_clean)
345662306a36Sopenharmony_ci			type = "NTC";
345762306a36Sopenharmony_ci		else
345862306a36Sopenharmony_ci			type = "";
345962306a36Sopenharmony_ci
346062306a36Sopenharmony_ci		pr_info("R[0x%03X]     %016llX %016llX %016llX %p %s\n",
346162306a36Sopenharmony_ci			i, le64_to_cpu(u->a), le64_to_cpu(u->b),
346262306a36Sopenharmony_ci			(u64)buffer_info->dma, buffer_info->rxbuf.data, type);
346362306a36Sopenharmony_ci	} /* for */
346462306a36Sopenharmony_ci
346562306a36Sopenharmony_ci	/* dump the descriptor caches */
346662306a36Sopenharmony_ci	/* rx */
346762306a36Sopenharmony_ci	pr_info("Rx descriptor cache in 64bit format\n");
346862306a36Sopenharmony_ci	for (i = 0x6000; i <= 0x63FF ; i += 0x10) {
346962306a36Sopenharmony_ci		pr_info("R%04X: %08X|%08X %08X|%08X\n",
347062306a36Sopenharmony_ci			i,
347162306a36Sopenharmony_ci			readl(adapter->hw.hw_addr + i+4),
347262306a36Sopenharmony_ci			readl(adapter->hw.hw_addr + i),
347362306a36Sopenharmony_ci			readl(adapter->hw.hw_addr + i+12),
347462306a36Sopenharmony_ci			readl(adapter->hw.hw_addr + i+8));
347562306a36Sopenharmony_ci	}
347662306a36Sopenharmony_ci	/* tx */
347762306a36Sopenharmony_ci	pr_info("Tx descriptor cache in 64bit format\n");
347862306a36Sopenharmony_ci	for (i = 0x7000; i <= 0x73FF ; i += 0x10) {
347962306a36Sopenharmony_ci		pr_info("T%04X: %08X|%08X %08X|%08X\n",
348062306a36Sopenharmony_ci			i,
348162306a36Sopenharmony_ci			readl(adapter->hw.hw_addr + i+4),
348262306a36Sopenharmony_ci			readl(adapter->hw.hw_addr + i),
348362306a36Sopenharmony_ci			readl(adapter->hw.hw_addr + i+12),
348462306a36Sopenharmony_ci			readl(adapter->hw.hw_addr + i+8));
348562306a36Sopenharmony_ci	}
348662306a36Sopenharmony_ciexit:
348762306a36Sopenharmony_ci	return;
348862306a36Sopenharmony_ci}
348962306a36Sopenharmony_ci
349062306a36Sopenharmony_ci/**
349162306a36Sopenharmony_ci * e1000_tx_timeout - Respond to a Tx Hang
349262306a36Sopenharmony_ci * @netdev: network interface device structure
349362306a36Sopenharmony_ci * @txqueue: number of the Tx queue that hung (unused)
349462306a36Sopenharmony_ci **/
349562306a36Sopenharmony_cistatic void e1000_tx_timeout(struct net_device *netdev, unsigned int __always_unused txqueue)
349662306a36Sopenharmony_ci{
349762306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
349862306a36Sopenharmony_ci
349962306a36Sopenharmony_ci	/* Do the reset outside of interrupt context */
350062306a36Sopenharmony_ci	adapter->tx_timeout_count++;
350162306a36Sopenharmony_ci	schedule_work(&adapter->reset_task);
350262306a36Sopenharmony_ci}
350362306a36Sopenharmony_ci
350462306a36Sopenharmony_cistatic void e1000_reset_task(struct work_struct *work)
350562306a36Sopenharmony_ci{
350662306a36Sopenharmony_ci	struct e1000_adapter *adapter =
350762306a36Sopenharmony_ci		container_of(work, struct e1000_adapter, reset_task);
350862306a36Sopenharmony_ci
350962306a36Sopenharmony_ci	e_err(drv, "Reset adapter\n");
351062306a36Sopenharmony_ci	e1000_reinit_locked(adapter);
351162306a36Sopenharmony_ci}
351262306a36Sopenharmony_ci
351362306a36Sopenharmony_ci/**
351462306a36Sopenharmony_ci * e1000_change_mtu - Change the Maximum Transfer Unit
351562306a36Sopenharmony_ci * @netdev: network interface device structure
351662306a36Sopenharmony_ci * @new_mtu: new value for maximum frame size
351762306a36Sopenharmony_ci *
351862306a36Sopenharmony_ci * Returns 0 on success, negative on failure
351962306a36Sopenharmony_ci **/
352062306a36Sopenharmony_cistatic int e1000_change_mtu(struct net_device *netdev, int new_mtu)
352162306a36Sopenharmony_ci{
352262306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
352362306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
352462306a36Sopenharmony_ci	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
352562306a36Sopenharmony_ci
352662306a36Sopenharmony_ci	/* Adapter-specific max frame size limits. */
352762306a36Sopenharmony_ci	switch (hw->mac_type) {
352862306a36Sopenharmony_ci	case e1000_undefined ... e1000_82542_rev2_1:
352962306a36Sopenharmony_ci		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
353062306a36Sopenharmony_ci			e_err(probe, "Jumbo Frames not supported.\n");
353162306a36Sopenharmony_ci			return -EINVAL;
353262306a36Sopenharmony_ci		}
353362306a36Sopenharmony_ci		break;
353462306a36Sopenharmony_ci	default:
353562306a36Sopenharmony_ci		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
353662306a36Sopenharmony_ci		break;
353762306a36Sopenharmony_ci	}
353862306a36Sopenharmony_ci
353962306a36Sopenharmony_ci	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
354062306a36Sopenharmony_ci		msleep(1);
354162306a36Sopenharmony_ci	/* e1000_down has a dependency on max_frame_size */
354262306a36Sopenharmony_ci	hw->max_frame_size = max_frame;
354362306a36Sopenharmony_ci	if (netif_running(netdev)) {
354462306a36Sopenharmony_ci		/* prevent buffers from being reallocated */
354562306a36Sopenharmony_ci		adapter->alloc_rx_buf = e1000_alloc_dummy_rx_buffers;
354662306a36Sopenharmony_ci		e1000_down(adapter);
354762306a36Sopenharmony_ci	}
354862306a36Sopenharmony_ci
354962306a36Sopenharmony_ci	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
355062306a36Sopenharmony_ci	 * means we reserve 2 more, this pushes us to allocate from the next
355162306a36Sopenharmony_ci	 * larger slab size.
355262306a36Sopenharmony_ci	 * i.e. RXBUFFER_2048 --> size-4096 slab
355362306a36Sopenharmony_ci	 * however with the new *_jumbo_rx* routines, jumbo receives will use
355462306a36Sopenharmony_ci	 * fragmented skbs
355562306a36Sopenharmony_ci	 */
355662306a36Sopenharmony_ci
355762306a36Sopenharmony_ci	if (max_frame <= E1000_RXBUFFER_2048)
355862306a36Sopenharmony_ci		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
355962306a36Sopenharmony_ci	else
356062306a36Sopenharmony_ci#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
356162306a36Sopenharmony_ci		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
356262306a36Sopenharmony_ci#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
356362306a36Sopenharmony_ci		adapter->rx_buffer_len = PAGE_SIZE;
356462306a36Sopenharmony_ci#endif
356562306a36Sopenharmony_ci
356662306a36Sopenharmony_ci	/* adjust allocation if LPE protects us, and we aren't using SBP */
356762306a36Sopenharmony_ci	if (!hw->tbi_compatibility_on &&
356862306a36Sopenharmony_ci	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
356962306a36Sopenharmony_ci	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
357062306a36Sopenharmony_ci		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
357162306a36Sopenharmony_ci
357262306a36Sopenharmony_ci	netdev_dbg(netdev, "changing MTU from %d to %d\n",
357362306a36Sopenharmony_ci		   netdev->mtu, new_mtu);
357462306a36Sopenharmony_ci	netdev->mtu = new_mtu;
357562306a36Sopenharmony_ci
357662306a36Sopenharmony_ci	if (netif_running(netdev))
357762306a36Sopenharmony_ci		e1000_up(adapter);
357862306a36Sopenharmony_ci	else
357962306a36Sopenharmony_ci		e1000_reset(adapter);
358062306a36Sopenharmony_ci
358162306a36Sopenharmony_ci	clear_bit(__E1000_RESETTING, &adapter->flags);
358262306a36Sopenharmony_ci
358362306a36Sopenharmony_ci	return 0;
358462306a36Sopenharmony_ci}
358562306a36Sopenharmony_ci
358662306a36Sopenharmony_ci/**
358762306a36Sopenharmony_ci * e1000_update_stats - Update the board statistics counters
358862306a36Sopenharmony_ci * @adapter: board private structure
358962306a36Sopenharmony_ci **/
359062306a36Sopenharmony_civoid e1000_update_stats(struct e1000_adapter *adapter)
359162306a36Sopenharmony_ci{
359262306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
359362306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
359462306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
359562306a36Sopenharmony_ci	unsigned long flags;
359662306a36Sopenharmony_ci	u16 phy_tmp;
359762306a36Sopenharmony_ci
359862306a36Sopenharmony_ci#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
359962306a36Sopenharmony_ci
360062306a36Sopenharmony_ci	/* Prevent stats update while adapter is being reset, or if the pci
360162306a36Sopenharmony_ci	 * connection is down.
360262306a36Sopenharmony_ci	 */
360362306a36Sopenharmony_ci	if (adapter->link_speed == 0)
360462306a36Sopenharmony_ci		return;
360562306a36Sopenharmony_ci	if (pci_channel_offline(pdev))
360662306a36Sopenharmony_ci		return;
360762306a36Sopenharmony_ci
360862306a36Sopenharmony_ci	spin_lock_irqsave(&adapter->stats_lock, flags);
360962306a36Sopenharmony_ci
361062306a36Sopenharmony_ci	/* these counters are modified from e1000_tbi_adjust_stats,
361162306a36Sopenharmony_ci	 * called from the interrupt context, so they must only
361262306a36Sopenharmony_ci	 * be written while holding adapter->stats_lock
361362306a36Sopenharmony_ci	 */
361462306a36Sopenharmony_ci
361562306a36Sopenharmony_ci	adapter->stats.crcerrs += er32(CRCERRS);
361662306a36Sopenharmony_ci	adapter->stats.gprc += er32(GPRC);
361762306a36Sopenharmony_ci	adapter->stats.gorcl += er32(GORCL);
361862306a36Sopenharmony_ci	adapter->stats.gorch += er32(GORCH);
361962306a36Sopenharmony_ci	adapter->stats.bprc += er32(BPRC);
362062306a36Sopenharmony_ci	adapter->stats.mprc += er32(MPRC);
362162306a36Sopenharmony_ci	adapter->stats.roc += er32(ROC);
362262306a36Sopenharmony_ci
362362306a36Sopenharmony_ci	adapter->stats.prc64 += er32(PRC64);
362462306a36Sopenharmony_ci	adapter->stats.prc127 += er32(PRC127);
362562306a36Sopenharmony_ci	adapter->stats.prc255 += er32(PRC255);
362662306a36Sopenharmony_ci	adapter->stats.prc511 += er32(PRC511);
362762306a36Sopenharmony_ci	adapter->stats.prc1023 += er32(PRC1023);
362862306a36Sopenharmony_ci	adapter->stats.prc1522 += er32(PRC1522);
362962306a36Sopenharmony_ci
363062306a36Sopenharmony_ci	adapter->stats.symerrs += er32(SYMERRS);
363162306a36Sopenharmony_ci	adapter->stats.mpc += er32(MPC);
363262306a36Sopenharmony_ci	adapter->stats.scc += er32(SCC);
363362306a36Sopenharmony_ci	adapter->stats.ecol += er32(ECOL);
363462306a36Sopenharmony_ci	adapter->stats.mcc += er32(MCC);
363562306a36Sopenharmony_ci	adapter->stats.latecol += er32(LATECOL);
363662306a36Sopenharmony_ci	adapter->stats.dc += er32(DC);
363762306a36Sopenharmony_ci	adapter->stats.sec += er32(SEC);
363862306a36Sopenharmony_ci	adapter->stats.rlec += er32(RLEC);
363962306a36Sopenharmony_ci	adapter->stats.xonrxc += er32(XONRXC);
364062306a36Sopenharmony_ci	adapter->stats.xontxc += er32(XONTXC);
364162306a36Sopenharmony_ci	adapter->stats.xoffrxc += er32(XOFFRXC);
364262306a36Sopenharmony_ci	adapter->stats.xofftxc += er32(XOFFTXC);
364362306a36Sopenharmony_ci	adapter->stats.fcruc += er32(FCRUC);
364462306a36Sopenharmony_ci	adapter->stats.gptc += er32(GPTC);
364562306a36Sopenharmony_ci	adapter->stats.gotcl += er32(GOTCL);
364662306a36Sopenharmony_ci	adapter->stats.gotch += er32(GOTCH);
364762306a36Sopenharmony_ci	adapter->stats.rnbc += er32(RNBC);
364862306a36Sopenharmony_ci	adapter->stats.ruc += er32(RUC);
364962306a36Sopenharmony_ci	adapter->stats.rfc += er32(RFC);
365062306a36Sopenharmony_ci	adapter->stats.rjc += er32(RJC);
365162306a36Sopenharmony_ci	adapter->stats.torl += er32(TORL);
365262306a36Sopenharmony_ci	adapter->stats.torh += er32(TORH);
365362306a36Sopenharmony_ci	adapter->stats.totl += er32(TOTL);
365462306a36Sopenharmony_ci	adapter->stats.toth += er32(TOTH);
365562306a36Sopenharmony_ci	adapter->stats.tpr += er32(TPR);
365662306a36Sopenharmony_ci
365762306a36Sopenharmony_ci	adapter->stats.ptc64 += er32(PTC64);
365862306a36Sopenharmony_ci	adapter->stats.ptc127 += er32(PTC127);
365962306a36Sopenharmony_ci	adapter->stats.ptc255 += er32(PTC255);
366062306a36Sopenharmony_ci	adapter->stats.ptc511 += er32(PTC511);
366162306a36Sopenharmony_ci	adapter->stats.ptc1023 += er32(PTC1023);
366262306a36Sopenharmony_ci	adapter->stats.ptc1522 += er32(PTC1522);
366362306a36Sopenharmony_ci
366462306a36Sopenharmony_ci	adapter->stats.mptc += er32(MPTC);
366562306a36Sopenharmony_ci	adapter->stats.bptc += er32(BPTC);
366662306a36Sopenharmony_ci
366762306a36Sopenharmony_ci	/* used for adaptive IFS */
366862306a36Sopenharmony_ci
366962306a36Sopenharmony_ci	hw->tx_packet_delta = er32(TPT);
367062306a36Sopenharmony_ci	adapter->stats.tpt += hw->tx_packet_delta;
367162306a36Sopenharmony_ci	hw->collision_delta = er32(COLC);
367262306a36Sopenharmony_ci	adapter->stats.colc += hw->collision_delta;
367362306a36Sopenharmony_ci
367462306a36Sopenharmony_ci	if (hw->mac_type >= e1000_82543) {
367562306a36Sopenharmony_ci		adapter->stats.algnerrc += er32(ALGNERRC);
367662306a36Sopenharmony_ci		adapter->stats.rxerrc += er32(RXERRC);
367762306a36Sopenharmony_ci		adapter->stats.tncrs += er32(TNCRS);
367862306a36Sopenharmony_ci		adapter->stats.cexterr += er32(CEXTERR);
367962306a36Sopenharmony_ci		adapter->stats.tsctc += er32(TSCTC);
368062306a36Sopenharmony_ci		adapter->stats.tsctfc += er32(TSCTFC);
368162306a36Sopenharmony_ci	}
368262306a36Sopenharmony_ci
368362306a36Sopenharmony_ci	/* Fill out the OS statistics structure */
368462306a36Sopenharmony_ci	netdev->stats.multicast = adapter->stats.mprc;
368562306a36Sopenharmony_ci	netdev->stats.collisions = adapter->stats.colc;
368662306a36Sopenharmony_ci
368762306a36Sopenharmony_ci	/* Rx Errors */
368862306a36Sopenharmony_ci
368962306a36Sopenharmony_ci	/* RLEC on some newer hardware can be incorrect so build
369062306a36Sopenharmony_ci	 * our own version based on RUC and ROC
369162306a36Sopenharmony_ci	 */
369262306a36Sopenharmony_ci	netdev->stats.rx_errors = adapter->stats.rxerrc +
369362306a36Sopenharmony_ci		adapter->stats.crcerrs + adapter->stats.algnerrc +
369462306a36Sopenharmony_ci		adapter->stats.ruc + adapter->stats.roc +
369562306a36Sopenharmony_ci		adapter->stats.cexterr;
369662306a36Sopenharmony_ci	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
369762306a36Sopenharmony_ci	netdev->stats.rx_length_errors = adapter->stats.rlerrc;
369862306a36Sopenharmony_ci	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
369962306a36Sopenharmony_ci	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
370062306a36Sopenharmony_ci	netdev->stats.rx_missed_errors = adapter->stats.mpc;
370162306a36Sopenharmony_ci
370262306a36Sopenharmony_ci	/* Tx Errors */
370362306a36Sopenharmony_ci	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
370462306a36Sopenharmony_ci	netdev->stats.tx_errors = adapter->stats.txerrc;
370562306a36Sopenharmony_ci	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
370662306a36Sopenharmony_ci	netdev->stats.tx_window_errors = adapter->stats.latecol;
370762306a36Sopenharmony_ci	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
370862306a36Sopenharmony_ci	if (hw->bad_tx_carr_stats_fd &&
370962306a36Sopenharmony_ci	    adapter->link_duplex == FULL_DUPLEX) {
371062306a36Sopenharmony_ci		netdev->stats.tx_carrier_errors = 0;
371162306a36Sopenharmony_ci		adapter->stats.tncrs = 0;
371262306a36Sopenharmony_ci	}
371362306a36Sopenharmony_ci
371462306a36Sopenharmony_ci	/* Tx Dropped needs to be maintained elsewhere */
371562306a36Sopenharmony_ci
371662306a36Sopenharmony_ci	/* Phy Stats */
371762306a36Sopenharmony_ci	if (hw->media_type == e1000_media_type_copper) {
371862306a36Sopenharmony_ci		if ((adapter->link_speed == SPEED_1000) &&
371962306a36Sopenharmony_ci		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
372062306a36Sopenharmony_ci			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
372162306a36Sopenharmony_ci			adapter->phy_stats.idle_errors += phy_tmp;
372262306a36Sopenharmony_ci		}
372362306a36Sopenharmony_ci
372462306a36Sopenharmony_ci		if ((hw->mac_type <= e1000_82546) &&
372562306a36Sopenharmony_ci		   (hw->phy_type == e1000_phy_m88) &&
372662306a36Sopenharmony_ci		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
372762306a36Sopenharmony_ci			adapter->phy_stats.receive_errors += phy_tmp;
372862306a36Sopenharmony_ci	}
372962306a36Sopenharmony_ci
373062306a36Sopenharmony_ci	/* Management Stats */
373162306a36Sopenharmony_ci	if (hw->has_smbus) {
373262306a36Sopenharmony_ci		adapter->stats.mgptc += er32(MGTPTC);
373362306a36Sopenharmony_ci		adapter->stats.mgprc += er32(MGTPRC);
373462306a36Sopenharmony_ci		adapter->stats.mgpdc += er32(MGTPDC);
373562306a36Sopenharmony_ci	}
373662306a36Sopenharmony_ci
373762306a36Sopenharmony_ci	spin_unlock_irqrestore(&adapter->stats_lock, flags);
373862306a36Sopenharmony_ci}
373962306a36Sopenharmony_ci
374062306a36Sopenharmony_ci/**
374162306a36Sopenharmony_ci * e1000_intr - Interrupt Handler
374262306a36Sopenharmony_ci * @irq: interrupt number
374362306a36Sopenharmony_ci * @data: pointer to a network interface device structure
374462306a36Sopenharmony_ci **/
374562306a36Sopenharmony_cistatic irqreturn_t e1000_intr(int irq, void *data)
374662306a36Sopenharmony_ci{
374762306a36Sopenharmony_ci	struct net_device *netdev = data;
374862306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
374962306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
375062306a36Sopenharmony_ci	u32 icr = er32(ICR);
375162306a36Sopenharmony_ci
375262306a36Sopenharmony_ci	if (unlikely((!icr)))
375362306a36Sopenharmony_ci		return IRQ_NONE;  /* Not our interrupt */
375462306a36Sopenharmony_ci
375562306a36Sopenharmony_ci	/* we might have caused the interrupt, but the above
375662306a36Sopenharmony_ci	 * read cleared it, and just in case the driver is
375762306a36Sopenharmony_ci	 * down there is nothing to do so return handled
375862306a36Sopenharmony_ci	 */
375962306a36Sopenharmony_ci	if (unlikely(test_bit(__E1000_DOWN, &adapter->flags)))
376062306a36Sopenharmony_ci		return IRQ_HANDLED;
376162306a36Sopenharmony_ci
376262306a36Sopenharmony_ci	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
376362306a36Sopenharmony_ci		hw->get_link_status = 1;
376462306a36Sopenharmony_ci		/* guard against interrupt when we're going down */
376562306a36Sopenharmony_ci		if (!test_bit(__E1000_DOWN, &adapter->flags))
376662306a36Sopenharmony_ci			schedule_delayed_work(&adapter->watchdog_task, 1);
376762306a36Sopenharmony_ci	}
376862306a36Sopenharmony_ci
376962306a36Sopenharmony_ci	/* disable interrupts, without the synchronize_irq bit */
377062306a36Sopenharmony_ci	ew32(IMC, ~0);
377162306a36Sopenharmony_ci	E1000_WRITE_FLUSH();
377262306a36Sopenharmony_ci
377362306a36Sopenharmony_ci	if (likely(napi_schedule_prep(&adapter->napi))) {
377462306a36Sopenharmony_ci		adapter->total_tx_bytes = 0;
377562306a36Sopenharmony_ci		adapter->total_tx_packets = 0;
377662306a36Sopenharmony_ci		adapter->total_rx_bytes = 0;
377762306a36Sopenharmony_ci		adapter->total_rx_packets = 0;
377862306a36Sopenharmony_ci		__napi_schedule(&adapter->napi);
377962306a36Sopenharmony_ci	} else {
378062306a36Sopenharmony_ci		/* this really should not happen! if it does it is basically a
378162306a36Sopenharmony_ci		 * bug, but not a hard error, so enable ints and continue
378262306a36Sopenharmony_ci		 */
378362306a36Sopenharmony_ci		if (!test_bit(__E1000_DOWN, &adapter->flags))
378462306a36Sopenharmony_ci			e1000_irq_enable(adapter);
378562306a36Sopenharmony_ci	}
378662306a36Sopenharmony_ci
378762306a36Sopenharmony_ci	return IRQ_HANDLED;
378862306a36Sopenharmony_ci}
378962306a36Sopenharmony_ci
379062306a36Sopenharmony_ci/**
379162306a36Sopenharmony_ci * e1000_clean - NAPI Rx polling callback
379262306a36Sopenharmony_ci * @napi: napi struct containing references to driver info
379362306a36Sopenharmony_ci * @budget: budget given to driver for receive packets
379462306a36Sopenharmony_ci **/
379562306a36Sopenharmony_cistatic int e1000_clean(struct napi_struct *napi, int budget)
379662306a36Sopenharmony_ci{
379762306a36Sopenharmony_ci	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter,
379862306a36Sopenharmony_ci						     napi);
379962306a36Sopenharmony_ci	int tx_clean_complete = 0, work_done = 0;
380062306a36Sopenharmony_ci
380162306a36Sopenharmony_ci	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
380262306a36Sopenharmony_ci
380362306a36Sopenharmony_ci	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
380462306a36Sopenharmony_ci
380562306a36Sopenharmony_ci	if (!tx_clean_complete || work_done == budget)
380662306a36Sopenharmony_ci		return budget;
380762306a36Sopenharmony_ci
380862306a36Sopenharmony_ci	/* Exit the polling mode, but don't re-enable interrupts if stack might
380962306a36Sopenharmony_ci	 * poll us due to busy-polling
381062306a36Sopenharmony_ci	 */
381162306a36Sopenharmony_ci	if (likely(napi_complete_done(napi, work_done))) {
381262306a36Sopenharmony_ci		if (likely(adapter->itr_setting & 3))
381362306a36Sopenharmony_ci			e1000_set_itr(adapter);
381462306a36Sopenharmony_ci		if (!test_bit(__E1000_DOWN, &adapter->flags))
381562306a36Sopenharmony_ci			e1000_irq_enable(adapter);
381662306a36Sopenharmony_ci	}
381762306a36Sopenharmony_ci
381862306a36Sopenharmony_ci	return work_done;
381962306a36Sopenharmony_ci}
382062306a36Sopenharmony_ci
382162306a36Sopenharmony_ci/**
382262306a36Sopenharmony_ci * e1000_clean_tx_irq - Reclaim resources after transmit completes
382362306a36Sopenharmony_ci * @adapter: board private structure
382462306a36Sopenharmony_ci * @tx_ring: ring to clean
382562306a36Sopenharmony_ci **/
382662306a36Sopenharmony_cistatic bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
382762306a36Sopenharmony_ci			       struct e1000_tx_ring *tx_ring)
382862306a36Sopenharmony_ci{
382962306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
383062306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
383162306a36Sopenharmony_ci	struct e1000_tx_desc *tx_desc, *eop_desc;
383262306a36Sopenharmony_ci	struct e1000_tx_buffer *buffer_info;
383362306a36Sopenharmony_ci	unsigned int i, eop;
383462306a36Sopenharmony_ci	unsigned int count = 0;
383562306a36Sopenharmony_ci	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
383662306a36Sopenharmony_ci	unsigned int bytes_compl = 0, pkts_compl = 0;
383762306a36Sopenharmony_ci
383862306a36Sopenharmony_ci	i = tx_ring->next_to_clean;
383962306a36Sopenharmony_ci	eop = tx_ring->buffer_info[i].next_to_watch;
384062306a36Sopenharmony_ci	eop_desc = E1000_TX_DESC(*tx_ring, eop);
384162306a36Sopenharmony_ci
384262306a36Sopenharmony_ci	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
384362306a36Sopenharmony_ci	       (count < tx_ring->count)) {
384462306a36Sopenharmony_ci		bool cleaned = false;
384562306a36Sopenharmony_ci		dma_rmb();	/* read buffer_info after eop_desc */
384662306a36Sopenharmony_ci		for ( ; !cleaned; count++) {
384762306a36Sopenharmony_ci			tx_desc = E1000_TX_DESC(*tx_ring, i);
384862306a36Sopenharmony_ci			buffer_info = &tx_ring->buffer_info[i];
384962306a36Sopenharmony_ci			cleaned = (i == eop);
385062306a36Sopenharmony_ci
385162306a36Sopenharmony_ci			if (cleaned) {
385262306a36Sopenharmony_ci				total_tx_packets += buffer_info->segs;
385362306a36Sopenharmony_ci				total_tx_bytes += buffer_info->bytecount;
385462306a36Sopenharmony_ci				if (buffer_info->skb) {
385562306a36Sopenharmony_ci					bytes_compl += buffer_info->skb->len;
385662306a36Sopenharmony_ci					pkts_compl++;
385762306a36Sopenharmony_ci				}
385862306a36Sopenharmony_ci
385962306a36Sopenharmony_ci			}
386062306a36Sopenharmony_ci			e1000_unmap_and_free_tx_resource(adapter, buffer_info,
386162306a36Sopenharmony_ci							 64);
386262306a36Sopenharmony_ci			tx_desc->upper.data = 0;
386362306a36Sopenharmony_ci
386462306a36Sopenharmony_ci			if (unlikely(++i == tx_ring->count))
386562306a36Sopenharmony_ci				i = 0;
386662306a36Sopenharmony_ci		}
386762306a36Sopenharmony_ci
386862306a36Sopenharmony_ci		eop = tx_ring->buffer_info[i].next_to_watch;
386962306a36Sopenharmony_ci		eop_desc = E1000_TX_DESC(*tx_ring, eop);
387062306a36Sopenharmony_ci	}
387162306a36Sopenharmony_ci
387262306a36Sopenharmony_ci	/* Synchronize with E1000_DESC_UNUSED called from e1000_xmit_frame,
387362306a36Sopenharmony_ci	 * which will reuse the cleaned buffers.
387462306a36Sopenharmony_ci	 */
387562306a36Sopenharmony_ci	smp_store_release(&tx_ring->next_to_clean, i);
387662306a36Sopenharmony_ci
387762306a36Sopenharmony_ci	netdev_completed_queue(netdev, pkts_compl, bytes_compl);
387862306a36Sopenharmony_ci
387962306a36Sopenharmony_ci#define TX_WAKE_THRESHOLD 32
388062306a36Sopenharmony_ci	if (unlikely(count && netif_carrier_ok(netdev) &&
388162306a36Sopenharmony_ci		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
388262306a36Sopenharmony_ci		/* Make sure that anybody stopping the queue after this
388362306a36Sopenharmony_ci		 * sees the new next_to_clean.
388462306a36Sopenharmony_ci		 */
388562306a36Sopenharmony_ci		smp_mb();
388662306a36Sopenharmony_ci
388762306a36Sopenharmony_ci		if (netif_queue_stopped(netdev) &&
388862306a36Sopenharmony_ci		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
388962306a36Sopenharmony_ci			netif_wake_queue(netdev);
389062306a36Sopenharmony_ci			++adapter->restart_queue;
389162306a36Sopenharmony_ci		}
389262306a36Sopenharmony_ci	}
389362306a36Sopenharmony_ci
389462306a36Sopenharmony_ci	if (adapter->detect_tx_hung) {
389562306a36Sopenharmony_ci		/* Detect a transmit hang in hardware, this serializes the
389662306a36Sopenharmony_ci		 * check with the clearing of time_stamp and movement of i
389762306a36Sopenharmony_ci		 */
389862306a36Sopenharmony_ci		adapter->detect_tx_hung = false;
389962306a36Sopenharmony_ci		if (tx_ring->buffer_info[eop].time_stamp &&
390062306a36Sopenharmony_ci		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
390162306a36Sopenharmony_ci			       (adapter->tx_timeout_factor * HZ)) &&
390262306a36Sopenharmony_ci		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
390362306a36Sopenharmony_ci
390462306a36Sopenharmony_ci			/* detected Tx unit hang */
390562306a36Sopenharmony_ci			e_err(drv, "Detected Tx Unit Hang\n"
390662306a36Sopenharmony_ci			      "  Tx Queue             <%lu>\n"
390762306a36Sopenharmony_ci			      "  TDH                  <%x>\n"
390862306a36Sopenharmony_ci			      "  TDT                  <%x>\n"
390962306a36Sopenharmony_ci			      "  next_to_use          <%x>\n"
391062306a36Sopenharmony_ci			      "  next_to_clean        <%x>\n"
391162306a36Sopenharmony_ci			      "buffer_info[next_to_clean]\n"
391262306a36Sopenharmony_ci			      "  time_stamp           <%lx>\n"
391362306a36Sopenharmony_ci			      "  next_to_watch        <%x>\n"
391462306a36Sopenharmony_ci			      "  jiffies              <%lx>\n"
391562306a36Sopenharmony_ci			      "  next_to_watch.status <%x>\n",
391662306a36Sopenharmony_ci				(unsigned long)(tx_ring - adapter->tx_ring),
391762306a36Sopenharmony_ci				readl(hw->hw_addr + tx_ring->tdh),
391862306a36Sopenharmony_ci				readl(hw->hw_addr + tx_ring->tdt),
391962306a36Sopenharmony_ci				tx_ring->next_to_use,
392062306a36Sopenharmony_ci				tx_ring->next_to_clean,
392162306a36Sopenharmony_ci				tx_ring->buffer_info[eop].time_stamp,
392262306a36Sopenharmony_ci				eop,
392362306a36Sopenharmony_ci				jiffies,
392462306a36Sopenharmony_ci				eop_desc->upper.fields.status);
392562306a36Sopenharmony_ci			e1000_dump(adapter);
392662306a36Sopenharmony_ci			netif_stop_queue(netdev);
392762306a36Sopenharmony_ci		}
392862306a36Sopenharmony_ci	}
392962306a36Sopenharmony_ci	adapter->total_tx_bytes += total_tx_bytes;
393062306a36Sopenharmony_ci	adapter->total_tx_packets += total_tx_packets;
393162306a36Sopenharmony_ci	netdev->stats.tx_bytes += total_tx_bytes;
393262306a36Sopenharmony_ci	netdev->stats.tx_packets += total_tx_packets;
393362306a36Sopenharmony_ci	return count < tx_ring->count;
393462306a36Sopenharmony_ci}
393562306a36Sopenharmony_ci
393662306a36Sopenharmony_ci/**
393762306a36Sopenharmony_ci * e1000_rx_checksum - Receive Checksum Offload for 82543
393862306a36Sopenharmony_ci * @adapter:     board private structure
393962306a36Sopenharmony_ci * @status_err:  receive descriptor status and error fields
394062306a36Sopenharmony_ci * @csum:        receive descriptor csum field
394162306a36Sopenharmony_ci * @skb:         socket buffer with received data
394262306a36Sopenharmony_ci **/
394362306a36Sopenharmony_cistatic void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
394462306a36Sopenharmony_ci			      u32 csum, struct sk_buff *skb)
394562306a36Sopenharmony_ci{
394662306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
394762306a36Sopenharmony_ci	u16 status = (u16)status_err;
394862306a36Sopenharmony_ci	u8 errors = (u8)(status_err >> 24);
394962306a36Sopenharmony_ci
395062306a36Sopenharmony_ci	skb_checksum_none_assert(skb);
395162306a36Sopenharmony_ci
395262306a36Sopenharmony_ci	/* 82543 or newer only */
395362306a36Sopenharmony_ci	if (unlikely(hw->mac_type < e1000_82543))
395462306a36Sopenharmony_ci		return;
395562306a36Sopenharmony_ci	/* Ignore Checksum bit is set */
395662306a36Sopenharmony_ci	if (unlikely(status & E1000_RXD_STAT_IXSM))
395762306a36Sopenharmony_ci		return;
395862306a36Sopenharmony_ci	/* TCP/UDP checksum error bit is set */
395962306a36Sopenharmony_ci	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
396062306a36Sopenharmony_ci		/* let the stack verify checksum errors */
396162306a36Sopenharmony_ci		adapter->hw_csum_err++;
396262306a36Sopenharmony_ci		return;
396362306a36Sopenharmony_ci	}
396462306a36Sopenharmony_ci	/* TCP/UDP Checksum has not been calculated */
396562306a36Sopenharmony_ci	if (!(status & E1000_RXD_STAT_TCPCS))
396662306a36Sopenharmony_ci		return;
396762306a36Sopenharmony_ci
396862306a36Sopenharmony_ci	/* It must be a TCP or UDP packet with a valid checksum */
396962306a36Sopenharmony_ci	if (likely(status & E1000_RXD_STAT_TCPCS)) {
397062306a36Sopenharmony_ci		/* TCP checksum is good */
397162306a36Sopenharmony_ci		skb->ip_summed = CHECKSUM_UNNECESSARY;
397262306a36Sopenharmony_ci	}
397362306a36Sopenharmony_ci	adapter->hw_csum_good++;
397462306a36Sopenharmony_ci}
397562306a36Sopenharmony_ci
397662306a36Sopenharmony_ci/**
397762306a36Sopenharmony_ci * e1000_consume_page - helper function for jumbo Rx path
397862306a36Sopenharmony_ci * @bi: software descriptor shadow data
397962306a36Sopenharmony_ci * @skb: skb being modified
398062306a36Sopenharmony_ci * @length: length of data being added
398162306a36Sopenharmony_ci **/
398262306a36Sopenharmony_cistatic void e1000_consume_page(struct e1000_rx_buffer *bi, struct sk_buff *skb,
398362306a36Sopenharmony_ci			       u16 length)
398462306a36Sopenharmony_ci{
398562306a36Sopenharmony_ci	bi->rxbuf.page = NULL;
398662306a36Sopenharmony_ci	skb->len += length;
398762306a36Sopenharmony_ci	skb->data_len += length;
398862306a36Sopenharmony_ci	skb->truesize += PAGE_SIZE;
398962306a36Sopenharmony_ci}
399062306a36Sopenharmony_ci
399162306a36Sopenharmony_ci/**
399262306a36Sopenharmony_ci * e1000_receive_skb - helper function to handle rx indications
399362306a36Sopenharmony_ci * @adapter: board private structure
399462306a36Sopenharmony_ci * @status: descriptor status field as written by hardware
399562306a36Sopenharmony_ci * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
399662306a36Sopenharmony_ci * @skb: pointer to sk_buff to be indicated to stack
399762306a36Sopenharmony_ci */
399862306a36Sopenharmony_cistatic void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
399962306a36Sopenharmony_ci			      __le16 vlan, struct sk_buff *skb)
400062306a36Sopenharmony_ci{
400162306a36Sopenharmony_ci	skb->protocol = eth_type_trans(skb, adapter->netdev);
400262306a36Sopenharmony_ci
400362306a36Sopenharmony_ci	if (status & E1000_RXD_STAT_VP) {
400462306a36Sopenharmony_ci		u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK;
400562306a36Sopenharmony_ci
400662306a36Sopenharmony_ci		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
400762306a36Sopenharmony_ci	}
400862306a36Sopenharmony_ci	napi_gro_receive(&adapter->napi, skb);
400962306a36Sopenharmony_ci}
401062306a36Sopenharmony_ci
401162306a36Sopenharmony_ci/**
401262306a36Sopenharmony_ci * e1000_tbi_adjust_stats
401362306a36Sopenharmony_ci * @hw: Struct containing variables accessed by shared code
401462306a36Sopenharmony_ci * @stats: point to stats struct
401562306a36Sopenharmony_ci * @frame_len: The length of the frame in question
401662306a36Sopenharmony_ci * @mac_addr: The Ethernet destination address of the frame in question
401762306a36Sopenharmony_ci *
401862306a36Sopenharmony_ci * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
401962306a36Sopenharmony_ci */
402062306a36Sopenharmony_cistatic void e1000_tbi_adjust_stats(struct e1000_hw *hw,
402162306a36Sopenharmony_ci				   struct e1000_hw_stats *stats,
402262306a36Sopenharmony_ci				   u32 frame_len, const u8 *mac_addr)
402362306a36Sopenharmony_ci{
402462306a36Sopenharmony_ci	u64 carry_bit;
402562306a36Sopenharmony_ci
402662306a36Sopenharmony_ci	/* First adjust the frame length. */
402762306a36Sopenharmony_ci	frame_len--;
402862306a36Sopenharmony_ci	/* We need to adjust the statistics counters, since the hardware
402962306a36Sopenharmony_ci	 * counters overcount this packet as a CRC error and undercount
403062306a36Sopenharmony_ci	 * the packet as a good packet
403162306a36Sopenharmony_ci	 */
403262306a36Sopenharmony_ci	/* This packet should not be counted as a CRC error. */
403362306a36Sopenharmony_ci	stats->crcerrs--;
403462306a36Sopenharmony_ci	/* This packet does count as a Good Packet Received. */
403562306a36Sopenharmony_ci	stats->gprc++;
403662306a36Sopenharmony_ci
403762306a36Sopenharmony_ci	/* Adjust the Good Octets received counters */
403862306a36Sopenharmony_ci	carry_bit = 0x80000000 & stats->gorcl;
403962306a36Sopenharmony_ci	stats->gorcl += frame_len;
404062306a36Sopenharmony_ci	/* If the high bit of Gorcl (the low 32 bits of the Good Octets
404162306a36Sopenharmony_ci	 * Received Count) was one before the addition,
404262306a36Sopenharmony_ci	 * AND it is zero after, then we lost the carry out,
404362306a36Sopenharmony_ci	 * need to add one to Gorch (Good Octets Received Count High).
404462306a36Sopenharmony_ci	 * This could be simplified if all environments supported
404562306a36Sopenharmony_ci	 * 64-bit integers.
404662306a36Sopenharmony_ci	 */
404762306a36Sopenharmony_ci	if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
404862306a36Sopenharmony_ci		stats->gorch++;
404962306a36Sopenharmony_ci	/* Is this a broadcast or multicast?  Check broadcast first,
405062306a36Sopenharmony_ci	 * since the test for a multicast frame will test positive on
405162306a36Sopenharmony_ci	 * a broadcast frame.
405262306a36Sopenharmony_ci	 */
405362306a36Sopenharmony_ci	if (is_broadcast_ether_addr(mac_addr))
405462306a36Sopenharmony_ci		stats->bprc++;
405562306a36Sopenharmony_ci	else if (is_multicast_ether_addr(mac_addr))
405662306a36Sopenharmony_ci		stats->mprc++;
405762306a36Sopenharmony_ci
405862306a36Sopenharmony_ci	if (frame_len == hw->max_frame_size) {
405962306a36Sopenharmony_ci		/* In this case, the hardware has overcounted the number of
406062306a36Sopenharmony_ci		 * oversize frames.
406162306a36Sopenharmony_ci		 */
406262306a36Sopenharmony_ci		if (stats->roc > 0)
406362306a36Sopenharmony_ci			stats->roc--;
406462306a36Sopenharmony_ci	}
406562306a36Sopenharmony_ci
406662306a36Sopenharmony_ci	/* Adjust the bin counters when the extra byte put the frame in the
406762306a36Sopenharmony_ci	 * wrong bin. Remember that the frame_len was adjusted above.
406862306a36Sopenharmony_ci	 */
406962306a36Sopenharmony_ci	if (frame_len == 64) {
407062306a36Sopenharmony_ci		stats->prc64++;
407162306a36Sopenharmony_ci		stats->prc127--;
407262306a36Sopenharmony_ci	} else if (frame_len == 127) {
407362306a36Sopenharmony_ci		stats->prc127++;
407462306a36Sopenharmony_ci		stats->prc255--;
407562306a36Sopenharmony_ci	} else if (frame_len == 255) {
407662306a36Sopenharmony_ci		stats->prc255++;
407762306a36Sopenharmony_ci		stats->prc511--;
407862306a36Sopenharmony_ci	} else if (frame_len == 511) {
407962306a36Sopenharmony_ci		stats->prc511++;
408062306a36Sopenharmony_ci		stats->prc1023--;
408162306a36Sopenharmony_ci	} else if (frame_len == 1023) {
408262306a36Sopenharmony_ci		stats->prc1023++;
408362306a36Sopenharmony_ci		stats->prc1522--;
408462306a36Sopenharmony_ci	} else if (frame_len == 1522) {
408562306a36Sopenharmony_ci		stats->prc1522++;
408662306a36Sopenharmony_ci	}
408762306a36Sopenharmony_ci}
408862306a36Sopenharmony_ci
408962306a36Sopenharmony_cistatic bool e1000_tbi_should_accept(struct e1000_adapter *adapter,
409062306a36Sopenharmony_ci				    u8 status, u8 errors,
409162306a36Sopenharmony_ci				    u32 length, const u8 *data)
409262306a36Sopenharmony_ci{
409362306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
409462306a36Sopenharmony_ci	u8 last_byte = *(data + length - 1);
409562306a36Sopenharmony_ci
409662306a36Sopenharmony_ci	if (TBI_ACCEPT(hw, status, errors, length, last_byte)) {
409762306a36Sopenharmony_ci		unsigned long irq_flags;
409862306a36Sopenharmony_ci
409962306a36Sopenharmony_ci		spin_lock_irqsave(&adapter->stats_lock, irq_flags);
410062306a36Sopenharmony_ci		e1000_tbi_adjust_stats(hw, &adapter->stats, length, data);
410162306a36Sopenharmony_ci		spin_unlock_irqrestore(&adapter->stats_lock, irq_flags);
410262306a36Sopenharmony_ci
410362306a36Sopenharmony_ci		return true;
410462306a36Sopenharmony_ci	}
410562306a36Sopenharmony_ci
410662306a36Sopenharmony_ci	return false;
410762306a36Sopenharmony_ci}
410862306a36Sopenharmony_ci
410962306a36Sopenharmony_cistatic struct sk_buff *e1000_alloc_rx_skb(struct e1000_adapter *adapter,
411062306a36Sopenharmony_ci					  unsigned int bufsz)
411162306a36Sopenharmony_ci{
411262306a36Sopenharmony_ci	struct sk_buff *skb = napi_alloc_skb(&adapter->napi, bufsz);
411362306a36Sopenharmony_ci
411462306a36Sopenharmony_ci	if (unlikely(!skb))
411562306a36Sopenharmony_ci		adapter->alloc_rx_buff_failed++;
411662306a36Sopenharmony_ci	return skb;
411762306a36Sopenharmony_ci}
411862306a36Sopenharmony_ci
411962306a36Sopenharmony_ci/**
412062306a36Sopenharmony_ci * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
412162306a36Sopenharmony_ci * @adapter: board private structure
412262306a36Sopenharmony_ci * @rx_ring: ring to clean
412362306a36Sopenharmony_ci * @work_done: amount of napi work completed this call
412462306a36Sopenharmony_ci * @work_to_do: max amount of work allowed for this call to do
412562306a36Sopenharmony_ci *
412662306a36Sopenharmony_ci * the return value indicates whether actual cleaning was done, there
412762306a36Sopenharmony_ci * is no guarantee that everything was cleaned
412862306a36Sopenharmony_ci */
412962306a36Sopenharmony_cistatic bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
413062306a36Sopenharmony_ci				     struct e1000_rx_ring *rx_ring,
413162306a36Sopenharmony_ci				     int *work_done, int work_to_do)
413262306a36Sopenharmony_ci{
413362306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
413462306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
413562306a36Sopenharmony_ci	struct e1000_rx_desc *rx_desc, *next_rxd;
413662306a36Sopenharmony_ci	struct e1000_rx_buffer *buffer_info, *next_buffer;
413762306a36Sopenharmony_ci	u32 length;
413862306a36Sopenharmony_ci	unsigned int i;
413962306a36Sopenharmony_ci	int cleaned_count = 0;
414062306a36Sopenharmony_ci	bool cleaned = false;
414162306a36Sopenharmony_ci	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
414262306a36Sopenharmony_ci
414362306a36Sopenharmony_ci	i = rx_ring->next_to_clean;
414462306a36Sopenharmony_ci	rx_desc = E1000_RX_DESC(*rx_ring, i);
414562306a36Sopenharmony_ci	buffer_info = &rx_ring->buffer_info[i];
414662306a36Sopenharmony_ci
414762306a36Sopenharmony_ci	while (rx_desc->status & E1000_RXD_STAT_DD) {
414862306a36Sopenharmony_ci		struct sk_buff *skb;
414962306a36Sopenharmony_ci		u8 status;
415062306a36Sopenharmony_ci
415162306a36Sopenharmony_ci		if (*work_done >= work_to_do)
415262306a36Sopenharmony_ci			break;
415362306a36Sopenharmony_ci		(*work_done)++;
415462306a36Sopenharmony_ci		dma_rmb(); /* read descriptor and rx_buffer_info after status DD */
415562306a36Sopenharmony_ci
415662306a36Sopenharmony_ci		status = rx_desc->status;
415762306a36Sopenharmony_ci
415862306a36Sopenharmony_ci		if (++i == rx_ring->count)
415962306a36Sopenharmony_ci			i = 0;
416062306a36Sopenharmony_ci
416162306a36Sopenharmony_ci		next_rxd = E1000_RX_DESC(*rx_ring, i);
416262306a36Sopenharmony_ci		prefetch(next_rxd);
416362306a36Sopenharmony_ci
416462306a36Sopenharmony_ci		next_buffer = &rx_ring->buffer_info[i];
416562306a36Sopenharmony_ci
416662306a36Sopenharmony_ci		cleaned = true;
416762306a36Sopenharmony_ci		cleaned_count++;
416862306a36Sopenharmony_ci		dma_unmap_page(&pdev->dev, buffer_info->dma,
416962306a36Sopenharmony_ci			       adapter->rx_buffer_len, DMA_FROM_DEVICE);
417062306a36Sopenharmony_ci		buffer_info->dma = 0;
417162306a36Sopenharmony_ci
417262306a36Sopenharmony_ci		length = le16_to_cpu(rx_desc->length);
417362306a36Sopenharmony_ci
417462306a36Sopenharmony_ci		/* errors is only valid for DD + EOP descriptors */
417562306a36Sopenharmony_ci		if (unlikely((status & E1000_RXD_STAT_EOP) &&
417662306a36Sopenharmony_ci		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
417762306a36Sopenharmony_ci			u8 *mapped = page_address(buffer_info->rxbuf.page);
417862306a36Sopenharmony_ci
417962306a36Sopenharmony_ci			if (e1000_tbi_should_accept(adapter, status,
418062306a36Sopenharmony_ci						    rx_desc->errors,
418162306a36Sopenharmony_ci						    length, mapped)) {
418262306a36Sopenharmony_ci				length--;
418362306a36Sopenharmony_ci			} else if (netdev->features & NETIF_F_RXALL) {
418462306a36Sopenharmony_ci				goto process_skb;
418562306a36Sopenharmony_ci			} else {
418662306a36Sopenharmony_ci				/* an error means any chain goes out the window
418762306a36Sopenharmony_ci				 * too
418862306a36Sopenharmony_ci				 */
418962306a36Sopenharmony_ci				dev_kfree_skb(rx_ring->rx_skb_top);
419062306a36Sopenharmony_ci				rx_ring->rx_skb_top = NULL;
419162306a36Sopenharmony_ci				goto next_desc;
419262306a36Sopenharmony_ci			}
419362306a36Sopenharmony_ci		}
419462306a36Sopenharmony_ci
419562306a36Sopenharmony_ci#define rxtop rx_ring->rx_skb_top
419662306a36Sopenharmony_ciprocess_skb:
419762306a36Sopenharmony_ci		if (!(status & E1000_RXD_STAT_EOP)) {
419862306a36Sopenharmony_ci			/* this descriptor is only the beginning (or middle) */
419962306a36Sopenharmony_ci			if (!rxtop) {
420062306a36Sopenharmony_ci				/* this is the beginning of a chain */
420162306a36Sopenharmony_ci				rxtop = napi_get_frags(&adapter->napi);
420262306a36Sopenharmony_ci				if (!rxtop)
420362306a36Sopenharmony_ci					break;
420462306a36Sopenharmony_ci
420562306a36Sopenharmony_ci				skb_fill_page_desc(rxtop, 0,
420662306a36Sopenharmony_ci						   buffer_info->rxbuf.page,
420762306a36Sopenharmony_ci						   0, length);
420862306a36Sopenharmony_ci			} else {
420962306a36Sopenharmony_ci				/* this is the middle of a chain */
421062306a36Sopenharmony_ci				skb_fill_page_desc(rxtop,
421162306a36Sopenharmony_ci				    skb_shinfo(rxtop)->nr_frags,
421262306a36Sopenharmony_ci				    buffer_info->rxbuf.page, 0, length);
421362306a36Sopenharmony_ci			}
421462306a36Sopenharmony_ci			e1000_consume_page(buffer_info, rxtop, length);
421562306a36Sopenharmony_ci			goto next_desc;
421662306a36Sopenharmony_ci		} else {
421762306a36Sopenharmony_ci			if (rxtop) {
421862306a36Sopenharmony_ci				/* end of the chain */
421962306a36Sopenharmony_ci				skb_fill_page_desc(rxtop,
422062306a36Sopenharmony_ci				    skb_shinfo(rxtop)->nr_frags,
422162306a36Sopenharmony_ci				    buffer_info->rxbuf.page, 0, length);
422262306a36Sopenharmony_ci				skb = rxtop;
422362306a36Sopenharmony_ci				rxtop = NULL;
422462306a36Sopenharmony_ci				e1000_consume_page(buffer_info, skb, length);
422562306a36Sopenharmony_ci			} else {
422662306a36Sopenharmony_ci				struct page *p;
422762306a36Sopenharmony_ci				/* no chain, got EOP, this buf is the packet
422862306a36Sopenharmony_ci				 * copybreak to save the put_page/alloc_page
422962306a36Sopenharmony_ci				 */
423062306a36Sopenharmony_ci				p = buffer_info->rxbuf.page;
423162306a36Sopenharmony_ci				if (length <= copybreak) {
423262306a36Sopenharmony_ci					if (likely(!(netdev->features & NETIF_F_RXFCS)))
423362306a36Sopenharmony_ci						length -= 4;
423462306a36Sopenharmony_ci					skb = e1000_alloc_rx_skb(adapter,
423562306a36Sopenharmony_ci								 length);
423662306a36Sopenharmony_ci					if (!skb)
423762306a36Sopenharmony_ci						break;
423862306a36Sopenharmony_ci
423962306a36Sopenharmony_ci					memcpy(skb_tail_pointer(skb),
424062306a36Sopenharmony_ci					       page_address(p), length);
424162306a36Sopenharmony_ci
424262306a36Sopenharmony_ci					/* re-use the page, so don't erase
424362306a36Sopenharmony_ci					 * buffer_info->rxbuf.page
424462306a36Sopenharmony_ci					 */
424562306a36Sopenharmony_ci					skb_put(skb, length);
424662306a36Sopenharmony_ci					e1000_rx_checksum(adapter,
424762306a36Sopenharmony_ci							  status | rx_desc->errors << 24,
424862306a36Sopenharmony_ci							  le16_to_cpu(rx_desc->csum), skb);
424962306a36Sopenharmony_ci
425062306a36Sopenharmony_ci					total_rx_bytes += skb->len;
425162306a36Sopenharmony_ci					total_rx_packets++;
425262306a36Sopenharmony_ci
425362306a36Sopenharmony_ci					e1000_receive_skb(adapter, status,
425462306a36Sopenharmony_ci							  rx_desc->special, skb);
425562306a36Sopenharmony_ci					goto next_desc;
425662306a36Sopenharmony_ci				} else {
425762306a36Sopenharmony_ci					skb = napi_get_frags(&adapter->napi);
425862306a36Sopenharmony_ci					if (!skb) {
425962306a36Sopenharmony_ci						adapter->alloc_rx_buff_failed++;
426062306a36Sopenharmony_ci						break;
426162306a36Sopenharmony_ci					}
426262306a36Sopenharmony_ci					skb_fill_page_desc(skb, 0, p, 0,
426362306a36Sopenharmony_ci							   length);
426462306a36Sopenharmony_ci					e1000_consume_page(buffer_info, skb,
426562306a36Sopenharmony_ci							   length);
426662306a36Sopenharmony_ci				}
426762306a36Sopenharmony_ci			}
426862306a36Sopenharmony_ci		}
426962306a36Sopenharmony_ci
427062306a36Sopenharmony_ci		/* Receive Checksum Offload XXX recompute due to CRC strip? */
427162306a36Sopenharmony_ci		e1000_rx_checksum(adapter,
427262306a36Sopenharmony_ci				  (u32)(status) |
427362306a36Sopenharmony_ci				  ((u32)(rx_desc->errors) << 24),
427462306a36Sopenharmony_ci				  le16_to_cpu(rx_desc->csum), skb);
427562306a36Sopenharmony_ci
427662306a36Sopenharmony_ci		total_rx_bytes += (skb->len - 4); /* don't count FCS */
427762306a36Sopenharmony_ci		if (likely(!(netdev->features & NETIF_F_RXFCS)))
427862306a36Sopenharmony_ci			pskb_trim(skb, skb->len - 4);
427962306a36Sopenharmony_ci		total_rx_packets++;
428062306a36Sopenharmony_ci
428162306a36Sopenharmony_ci		if (status & E1000_RXD_STAT_VP) {
428262306a36Sopenharmony_ci			__le16 vlan = rx_desc->special;
428362306a36Sopenharmony_ci			u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK;
428462306a36Sopenharmony_ci
428562306a36Sopenharmony_ci			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
428662306a36Sopenharmony_ci		}
428762306a36Sopenharmony_ci
428862306a36Sopenharmony_ci		napi_gro_frags(&adapter->napi);
428962306a36Sopenharmony_ci
429062306a36Sopenharmony_cinext_desc:
429162306a36Sopenharmony_ci		rx_desc->status = 0;
429262306a36Sopenharmony_ci
429362306a36Sopenharmony_ci		/* return some buffers to hardware, one at a time is too slow */
429462306a36Sopenharmony_ci		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
429562306a36Sopenharmony_ci			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
429662306a36Sopenharmony_ci			cleaned_count = 0;
429762306a36Sopenharmony_ci		}
429862306a36Sopenharmony_ci
429962306a36Sopenharmony_ci		/* use prefetched values */
430062306a36Sopenharmony_ci		rx_desc = next_rxd;
430162306a36Sopenharmony_ci		buffer_info = next_buffer;
430262306a36Sopenharmony_ci	}
430362306a36Sopenharmony_ci	rx_ring->next_to_clean = i;
430462306a36Sopenharmony_ci
430562306a36Sopenharmony_ci	cleaned_count = E1000_DESC_UNUSED(rx_ring);
430662306a36Sopenharmony_ci	if (cleaned_count)
430762306a36Sopenharmony_ci		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
430862306a36Sopenharmony_ci
430962306a36Sopenharmony_ci	adapter->total_rx_packets += total_rx_packets;
431062306a36Sopenharmony_ci	adapter->total_rx_bytes += total_rx_bytes;
431162306a36Sopenharmony_ci	netdev->stats.rx_bytes += total_rx_bytes;
431262306a36Sopenharmony_ci	netdev->stats.rx_packets += total_rx_packets;
431362306a36Sopenharmony_ci	return cleaned;
431462306a36Sopenharmony_ci}
431562306a36Sopenharmony_ci
431662306a36Sopenharmony_ci/* this should improve performance for small packets with large amounts
431762306a36Sopenharmony_ci * of reassembly being done in the stack
431862306a36Sopenharmony_ci */
431962306a36Sopenharmony_cistatic struct sk_buff *e1000_copybreak(struct e1000_adapter *adapter,
432062306a36Sopenharmony_ci				       struct e1000_rx_buffer *buffer_info,
432162306a36Sopenharmony_ci				       u32 length, const void *data)
432262306a36Sopenharmony_ci{
432362306a36Sopenharmony_ci	struct sk_buff *skb;
432462306a36Sopenharmony_ci
432562306a36Sopenharmony_ci	if (length > copybreak)
432662306a36Sopenharmony_ci		return NULL;
432762306a36Sopenharmony_ci
432862306a36Sopenharmony_ci	skb = e1000_alloc_rx_skb(adapter, length);
432962306a36Sopenharmony_ci	if (!skb)
433062306a36Sopenharmony_ci		return NULL;
433162306a36Sopenharmony_ci
433262306a36Sopenharmony_ci	dma_sync_single_for_cpu(&adapter->pdev->dev, buffer_info->dma,
433362306a36Sopenharmony_ci				length, DMA_FROM_DEVICE);
433462306a36Sopenharmony_ci
433562306a36Sopenharmony_ci	skb_put_data(skb, data, length);
433662306a36Sopenharmony_ci
433762306a36Sopenharmony_ci	return skb;
433862306a36Sopenharmony_ci}
433962306a36Sopenharmony_ci
434062306a36Sopenharmony_ci/**
434162306a36Sopenharmony_ci * e1000_clean_rx_irq - Send received data up the network stack; legacy
434262306a36Sopenharmony_ci * @adapter: board private structure
434362306a36Sopenharmony_ci * @rx_ring: ring to clean
434462306a36Sopenharmony_ci * @work_done: amount of napi work completed this call
434562306a36Sopenharmony_ci * @work_to_do: max amount of work allowed for this call to do
434662306a36Sopenharmony_ci */
434762306a36Sopenharmony_cistatic bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
434862306a36Sopenharmony_ci			       struct e1000_rx_ring *rx_ring,
434962306a36Sopenharmony_ci			       int *work_done, int work_to_do)
435062306a36Sopenharmony_ci{
435162306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
435262306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
435362306a36Sopenharmony_ci	struct e1000_rx_desc *rx_desc, *next_rxd;
435462306a36Sopenharmony_ci	struct e1000_rx_buffer *buffer_info, *next_buffer;
435562306a36Sopenharmony_ci	u32 length;
435662306a36Sopenharmony_ci	unsigned int i;
435762306a36Sopenharmony_ci	int cleaned_count = 0;
435862306a36Sopenharmony_ci	bool cleaned = false;
435962306a36Sopenharmony_ci	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
436062306a36Sopenharmony_ci
436162306a36Sopenharmony_ci	i = rx_ring->next_to_clean;
436262306a36Sopenharmony_ci	rx_desc = E1000_RX_DESC(*rx_ring, i);
436362306a36Sopenharmony_ci	buffer_info = &rx_ring->buffer_info[i];
436462306a36Sopenharmony_ci
436562306a36Sopenharmony_ci	while (rx_desc->status & E1000_RXD_STAT_DD) {
436662306a36Sopenharmony_ci		struct sk_buff *skb;
436762306a36Sopenharmony_ci		u8 *data;
436862306a36Sopenharmony_ci		u8 status;
436962306a36Sopenharmony_ci
437062306a36Sopenharmony_ci		if (*work_done >= work_to_do)
437162306a36Sopenharmony_ci			break;
437262306a36Sopenharmony_ci		(*work_done)++;
437362306a36Sopenharmony_ci		dma_rmb(); /* read descriptor and rx_buffer_info after status DD */
437462306a36Sopenharmony_ci
437562306a36Sopenharmony_ci		status = rx_desc->status;
437662306a36Sopenharmony_ci		length = le16_to_cpu(rx_desc->length);
437762306a36Sopenharmony_ci
437862306a36Sopenharmony_ci		data = buffer_info->rxbuf.data;
437962306a36Sopenharmony_ci		prefetch(data);
438062306a36Sopenharmony_ci		skb = e1000_copybreak(adapter, buffer_info, length, data);
438162306a36Sopenharmony_ci		if (!skb) {
438262306a36Sopenharmony_ci			unsigned int frag_len = e1000_frag_len(adapter);
438362306a36Sopenharmony_ci
438462306a36Sopenharmony_ci			skb = napi_build_skb(data - E1000_HEADROOM, frag_len);
438562306a36Sopenharmony_ci			if (!skb) {
438662306a36Sopenharmony_ci				adapter->alloc_rx_buff_failed++;
438762306a36Sopenharmony_ci				break;
438862306a36Sopenharmony_ci			}
438962306a36Sopenharmony_ci
439062306a36Sopenharmony_ci			skb_reserve(skb, E1000_HEADROOM);
439162306a36Sopenharmony_ci			dma_unmap_single(&pdev->dev, buffer_info->dma,
439262306a36Sopenharmony_ci					 adapter->rx_buffer_len,
439362306a36Sopenharmony_ci					 DMA_FROM_DEVICE);
439462306a36Sopenharmony_ci			buffer_info->dma = 0;
439562306a36Sopenharmony_ci			buffer_info->rxbuf.data = NULL;
439662306a36Sopenharmony_ci		}
439762306a36Sopenharmony_ci
439862306a36Sopenharmony_ci		if (++i == rx_ring->count)
439962306a36Sopenharmony_ci			i = 0;
440062306a36Sopenharmony_ci
440162306a36Sopenharmony_ci		next_rxd = E1000_RX_DESC(*rx_ring, i);
440262306a36Sopenharmony_ci		prefetch(next_rxd);
440362306a36Sopenharmony_ci
440462306a36Sopenharmony_ci		next_buffer = &rx_ring->buffer_info[i];
440562306a36Sopenharmony_ci
440662306a36Sopenharmony_ci		cleaned = true;
440762306a36Sopenharmony_ci		cleaned_count++;
440862306a36Sopenharmony_ci
440962306a36Sopenharmony_ci		/* !EOP means multiple descriptors were used to store a single
441062306a36Sopenharmony_ci		 * packet, if thats the case we need to toss it.  In fact, we
441162306a36Sopenharmony_ci		 * to toss every packet with the EOP bit clear and the next
441262306a36Sopenharmony_ci		 * frame that _does_ have the EOP bit set, as it is by
441362306a36Sopenharmony_ci		 * definition only a frame fragment
441462306a36Sopenharmony_ci		 */
441562306a36Sopenharmony_ci		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
441662306a36Sopenharmony_ci			adapter->discarding = true;
441762306a36Sopenharmony_ci
441862306a36Sopenharmony_ci		if (adapter->discarding) {
441962306a36Sopenharmony_ci			/* All receives must fit into a single buffer */
442062306a36Sopenharmony_ci			netdev_dbg(netdev, "Receive packet consumed multiple buffers\n");
442162306a36Sopenharmony_ci			dev_kfree_skb(skb);
442262306a36Sopenharmony_ci			if (status & E1000_RXD_STAT_EOP)
442362306a36Sopenharmony_ci				adapter->discarding = false;
442462306a36Sopenharmony_ci			goto next_desc;
442562306a36Sopenharmony_ci		}
442662306a36Sopenharmony_ci
442762306a36Sopenharmony_ci		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
442862306a36Sopenharmony_ci			if (e1000_tbi_should_accept(adapter, status,
442962306a36Sopenharmony_ci						    rx_desc->errors,
443062306a36Sopenharmony_ci						    length, data)) {
443162306a36Sopenharmony_ci				length--;
443262306a36Sopenharmony_ci			} else if (netdev->features & NETIF_F_RXALL) {
443362306a36Sopenharmony_ci				goto process_skb;
443462306a36Sopenharmony_ci			} else {
443562306a36Sopenharmony_ci				dev_kfree_skb(skb);
443662306a36Sopenharmony_ci				goto next_desc;
443762306a36Sopenharmony_ci			}
443862306a36Sopenharmony_ci		}
443962306a36Sopenharmony_ci
444062306a36Sopenharmony_ciprocess_skb:
444162306a36Sopenharmony_ci		total_rx_bytes += (length - 4); /* don't count FCS */
444262306a36Sopenharmony_ci		total_rx_packets++;
444362306a36Sopenharmony_ci
444462306a36Sopenharmony_ci		if (likely(!(netdev->features & NETIF_F_RXFCS)))
444562306a36Sopenharmony_ci			/* adjust length to remove Ethernet CRC, this must be
444662306a36Sopenharmony_ci			 * done after the TBI_ACCEPT workaround above
444762306a36Sopenharmony_ci			 */
444862306a36Sopenharmony_ci			length -= 4;
444962306a36Sopenharmony_ci
445062306a36Sopenharmony_ci		if (buffer_info->rxbuf.data == NULL)
445162306a36Sopenharmony_ci			skb_put(skb, length);
445262306a36Sopenharmony_ci		else /* copybreak skb */
445362306a36Sopenharmony_ci			skb_trim(skb, length);
445462306a36Sopenharmony_ci
445562306a36Sopenharmony_ci		/* Receive Checksum Offload */
445662306a36Sopenharmony_ci		e1000_rx_checksum(adapter,
445762306a36Sopenharmony_ci				  (u32)(status) |
445862306a36Sopenharmony_ci				  ((u32)(rx_desc->errors) << 24),
445962306a36Sopenharmony_ci				  le16_to_cpu(rx_desc->csum), skb);
446062306a36Sopenharmony_ci
446162306a36Sopenharmony_ci		e1000_receive_skb(adapter, status, rx_desc->special, skb);
446262306a36Sopenharmony_ci
446362306a36Sopenharmony_cinext_desc:
446462306a36Sopenharmony_ci		rx_desc->status = 0;
446562306a36Sopenharmony_ci
446662306a36Sopenharmony_ci		/* return some buffers to hardware, one at a time is too slow */
446762306a36Sopenharmony_ci		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
446862306a36Sopenharmony_ci			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
446962306a36Sopenharmony_ci			cleaned_count = 0;
447062306a36Sopenharmony_ci		}
447162306a36Sopenharmony_ci
447262306a36Sopenharmony_ci		/* use prefetched values */
447362306a36Sopenharmony_ci		rx_desc = next_rxd;
447462306a36Sopenharmony_ci		buffer_info = next_buffer;
447562306a36Sopenharmony_ci	}
447662306a36Sopenharmony_ci	rx_ring->next_to_clean = i;
447762306a36Sopenharmony_ci
447862306a36Sopenharmony_ci	cleaned_count = E1000_DESC_UNUSED(rx_ring);
447962306a36Sopenharmony_ci	if (cleaned_count)
448062306a36Sopenharmony_ci		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
448162306a36Sopenharmony_ci
448262306a36Sopenharmony_ci	adapter->total_rx_packets += total_rx_packets;
448362306a36Sopenharmony_ci	adapter->total_rx_bytes += total_rx_bytes;
448462306a36Sopenharmony_ci	netdev->stats.rx_bytes += total_rx_bytes;
448562306a36Sopenharmony_ci	netdev->stats.rx_packets += total_rx_packets;
448662306a36Sopenharmony_ci	return cleaned;
448762306a36Sopenharmony_ci}
448862306a36Sopenharmony_ci
448962306a36Sopenharmony_ci/**
449062306a36Sopenharmony_ci * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
449162306a36Sopenharmony_ci * @adapter: address of board private structure
449262306a36Sopenharmony_ci * @rx_ring: pointer to receive ring structure
449362306a36Sopenharmony_ci * @cleaned_count: number of buffers to allocate this pass
449462306a36Sopenharmony_ci **/
449562306a36Sopenharmony_cistatic void
449662306a36Sopenharmony_cie1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
449762306a36Sopenharmony_ci			     struct e1000_rx_ring *rx_ring, int cleaned_count)
449862306a36Sopenharmony_ci{
449962306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
450062306a36Sopenharmony_ci	struct e1000_rx_desc *rx_desc;
450162306a36Sopenharmony_ci	struct e1000_rx_buffer *buffer_info;
450262306a36Sopenharmony_ci	unsigned int i;
450362306a36Sopenharmony_ci
450462306a36Sopenharmony_ci	i = rx_ring->next_to_use;
450562306a36Sopenharmony_ci	buffer_info = &rx_ring->buffer_info[i];
450662306a36Sopenharmony_ci
450762306a36Sopenharmony_ci	while (cleaned_count--) {
450862306a36Sopenharmony_ci		/* allocate a new page if necessary */
450962306a36Sopenharmony_ci		if (!buffer_info->rxbuf.page) {
451062306a36Sopenharmony_ci			buffer_info->rxbuf.page = alloc_page(GFP_ATOMIC);
451162306a36Sopenharmony_ci			if (unlikely(!buffer_info->rxbuf.page)) {
451262306a36Sopenharmony_ci				adapter->alloc_rx_buff_failed++;
451362306a36Sopenharmony_ci				break;
451462306a36Sopenharmony_ci			}
451562306a36Sopenharmony_ci		}
451662306a36Sopenharmony_ci
451762306a36Sopenharmony_ci		if (!buffer_info->dma) {
451862306a36Sopenharmony_ci			buffer_info->dma = dma_map_page(&pdev->dev,
451962306a36Sopenharmony_ci							buffer_info->rxbuf.page, 0,
452062306a36Sopenharmony_ci							adapter->rx_buffer_len,
452162306a36Sopenharmony_ci							DMA_FROM_DEVICE);
452262306a36Sopenharmony_ci			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
452362306a36Sopenharmony_ci				put_page(buffer_info->rxbuf.page);
452462306a36Sopenharmony_ci				buffer_info->rxbuf.page = NULL;
452562306a36Sopenharmony_ci				buffer_info->dma = 0;
452662306a36Sopenharmony_ci				adapter->alloc_rx_buff_failed++;
452762306a36Sopenharmony_ci				break;
452862306a36Sopenharmony_ci			}
452962306a36Sopenharmony_ci		}
453062306a36Sopenharmony_ci
453162306a36Sopenharmony_ci		rx_desc = E1000_RX_DESC(*rx_ring, i);
453262306a36Sopenharmony_ci		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
453362306a36Sopenharmony_ci
453462306a36Sopenharmony_ci		if (unlikely(++i == rx_ring->count))
453562306a36Sopenharmony_ci			i = 0;
453662306a36Sopenharmony_ci		buffer_info = &rx_ring->buffer_info[i];
453762306a36Sopenharmony_ci	}
453862306a36Sopenharmony_ci
453962306a36Sopenharmony_ci	if (likely(rx_ring->next_to_use != i)) {
454062306a36Sopenharmony_ci		rx_ring->next_to_use = i;
454162306a36Sopenharmony_ci		if (unlikely(i-- == 0))
454262306a36Sopenharmony_ci			i = (rx_ring->count - 1);
454362306a36Sopenharmony_ci
454462306a36Sopenharmony_ci		/* Force memory writes to complete before letting h/w
454562306a36Sopenharmony_ci		 * know there are new descriptors to fetch.  (Only
454662306a36Sopenharmony_ci		 * applicable for weak-ordered memory model archs,
454762306a36Sopenharmony_ci		 * such as IA-64).
454862306a36Sopenharmony_ci		 */
454962306a36Sopenharmony_ci		dma_wmb();
455062306a36Sopenharmony_ci		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
455162306a36Sopenharmony_ci	}
455262306a36Sopenharmony_ci}
455362306a36Sopenharmony_ci
455462306a36Sopenharmony_ci/**
455562306a36Sopenharmony_ci * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
455662306a36Sopenharmony_ci * @adapter: address of board private structure
455762306a36Sopenharmony_ci * @rx_ring: pointer to ring struct
455862306a36Sopenharmony_ci * @cleaned_count: number of new Rx buffers to try to allocate
455962306a36Sopenharmony_ci **/
456062306a36Sopenharmony_cistatic void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
456162306a36Sopenharmony_ci				   struct e1000_rx_ring *rx_ring,
456262306a36Sopenharmony_ci				   int cleaned_count)
456362306a36Sopenharmony_ci{
456462306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
456562306a36Sopenharmony_ci	struct pci_dev *pdev = adapter->pdev;
456662306a36Sopenharmony_ci	struct e1000_rx_desc *rx_desc;
456762306a36Sopenharmony_ci	struct e1000_rx_buffer *buffer_info;
456862306a36Sopenharmony_ci	unsigned int i;
456962306a36Sopenharmony_ci	unsigned int bufsz = adapter->rx_buffer_len;
457062306a36Sopenharmony_ci
457162306a36Sopenharmony_ci	i = rx_ring->next_to_use;
457262306a36Sopenharmony_ci	buffer_info = &rx_ring->buffer_info[i];
457362306a36Sopenharmony_ci
457462306a36Sopenharmony_ci	while (cleaned_count--) {
457562306a36Sopenharmony_ci		void *data;
457662306a36Sopenharmony_ci
457762306a36Sopenharmony_ci		if (buffer_info->rxbuf.data)
457862306a36Sopenharmony_ci			goto skip;
457962306a36Sopenharmony_ci
458062306a36Sopenharmony_ci		data = e1000_alloc_frag(adapter);
458162306a36Sopenharmony_ci		if (!data) {
458262306a36Sopenharmony_ci			/* Better luck next round */
458362306a36Sopenharmony_ci			adapter->alloc_rx_buff_failed++;
458462306a36Sopenharmony_ci			break;
458562306a36Sopenharmony_ci		}
458662306a36Sopenharmony_ci
458762306a36Sopenharmony_ci		/* Fix for errata 23, can't cross 64kB boundary */
458862306a36Sopenharmony_ci		if (!e1000_check_64k_bound(adapter, data, bufsz)) {
458962306a36Sopenharmony_ci			void *olddata = data;
459062306a36Sopenharmony_ci			e_err(rx_err, "skb align check failed: %u bytes at "
459162306a36Sopenharmony_ci			      "%p\n", bufsz, data);
459262306a36Sopenharmony_ci			/* Try again, without freeing the previous */
459362306a36Sopenharmony_ci			data = e1000_alloc_frag(adapter);
459462306a36Sopenharmony_ci			/* Failed allocation, critical failure */
459562306a36Sopenharmony_ci			if (!data) {
459662306a36Sopenharmony_ci				skb_free_frag(olddata);
459762306a36Sopenharmony_ci				adapter->alloc_rx_buff_failed++;
459862306a36Sopenharmony_ci				break;
459962306a36Sopenharmony_ci			}
460062306a36Sopenharmony_ci
460162306a36Sopenharmony_ci			if (!e1000_check_64k_bound(adapter, data, bufsz)) {
460262306a36Sopenharmony_ci				/* give up */
460362306a36Sopenharmony_ci				skb_free_frag(data);
460462306a36Sopenharmony_ci				skb_free_frag(olddata);
460562306a36Sopenharmony_ci				adapter->alloc_rx_buff_failed++;
460662306a36Sopenharmony_ci				break;
460762306a36Sopenharmony_ci			}
460862306a36Sopenharmony_ci
460962306a36Sopenharmony_ci			/* Use new allocation */
461062306a36Sopenharmony_ci			skb_free_frag(olddata);
461162306a36Sopenharmony_ci		}
461262306a36Sopenharmony_ci		buffer_info->dma = dma_map_single(&pdev->dev,
461362306a36Sopenharmony_ci						  data,
461462306a36Sopenharmony_ci						  adapter->rx_buffer_len,
461562306a36Sopenharmony_ci						  DMA_FROM_DEVICE);
461662306a36Sopenharmony_ci		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
461762306a36Sopenharmony_ci			skb_free_frag(data);
461862306a36Sopenharmony_ci			buffer_info->dma = 0;
461962306a36Sopenharmony_ci			adapter->alloc_rx_buff_failed++;
462062306a36Sopenharmony_ci			break;
462162306a36Sopenharmony_ci		}
462262306a36Sopenharmony_ci
462362306a36Sopenharmony_ci		/* XXX if it was allocated cleanly it will never map to a
462462306a36Sopenharmony_ci		 * boundary crossing
462562306a36Sopenharmony_ci		 */
462662306a36Sopenharmony_ci
462762306a36Sopenharmony_ci		/* Fix for errata 23, can't cross 64kB boundary */
462862306a36Sopenharmony_ci		if (!e1000_check_64k_bound(adapter,
462962306a36Sopenharmony_ci					(void *)(unsigned long)buffer_info->dma,
463062306a36Sopenharmony_ci					adapter->rx_buffer_len)) {
463162306a36Sopenharmony_ci			e_err(rx_err, "dma align check failed: %u bytes at "
463262306a36Sopenharmony_ci			      "%p\n", adapter->rx_buffer_len,
463362306a36Sopenharmony_ci			      (void *)(unsigned long)buffer_info->dma);
463462306a36Sopenharmony_ci
463562306a36Sopenharmony_ci			dma_unmap_single(&pdev->dev, buffer_info->dma,
463662306a36Sopenharmony_ci					 adapter->rx_buffer_len,
463762306a36Sopenharmony_ci					 DMA_FROM_DEVICE);
463862306a36Sopenharmony_ci
463962306a36Sopenharmony_ci			skb_free_frag(data);
464062306a36Sopenharmony_ci			buffer_info->rxbuf.data = NULL;
464162306a36Sopenharmony_ci			buffer_info->dma = 0;
464262306a36Sopenharmony_ci
464362306a36Sopenharmony_ci			adapter->alloc_rx_buff_failed++;
464462306a36Sopenharmony_ci			break;
464562306a36Sopenharmony_ci		}
464662306a36Sopenharmony_ci		buffer_info->rxbuf.data = data;
464762306a36Sopenharmony_ci skip:
464862306a36Sopenharmony_ci		rx_desc = E1000_RX_DESC(*rx_ring, i);
464962306a36Sopenharmony_ci		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
465062306a36Sopenharmony_ci
465162306a36Sopenharmony_ci		if (unlikely(++i == rx_ring->count))
465262306a36Sopenharmony_ci			i = 0;
465362306a36Sopenharmony_ci		buffer_info = &rx_ring->buffer_info[i];
465462306a36Sopenharmony_ci	}
465562306a36Sopenharmony_ci
465662306a36Sopenharmony_ci	if (likely(rx_ring->next_to_use != i)) {
465762306a36Sopenharmony_ci		rx_ring->next_to_use = i;
465862306a36Sopenharmony_ci		if (unlikely(i-- == 0))
465962306a36Sopenharmony_ci			i = (rx_ring->count - 1);
466062306a36Sopenharmony_ci
466162306a36Sopenharmony_ci		/* Force memory writes to complete before letting h/w
466262306a36Sopenharmony_ci		 * know there are new descriptors to fetch.  (Only
466362306a36Sopenharmony_ci		 * applicable for weak-ordered memory model archs,
466462306a36Sopenharmony_ci		 * such as IA-64).
466562306a36Sopenharmony_ci		 */
466662306a36Sopenharmony_ci		dma_wmb();
466762306a36Sopenharmony_ci		writel(i, hw->hw_addr + rx_ring->rdt);
466862306a36Sopenharmony_ci	}
466962306a36Sopenharmony_ci}
467062306a36Sopenharmony_ci
467162306a36Sopenharmony_ci/**
467262306a36Sopenharmony_ci * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
467362306a36Sopenharmony_ci * @adapter: address of board private structure
467462306a36Sopenharmony_ci **/
467562306a36Sopenharmony_cistatic void e1000_smartspeed(struct e1000_adapter *adapter)
467662306a36Sopenharmony_ci{
467762306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
467862306a36Sopenharmony_ci	u16 phy_status;
467962306a36Sopenharmony_ci	u16 phy_ctrl;
468062306a36Sopenharmony_ci
468162306a36Sopenharmony_ci	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
468262306a36Sopenharmony_ci	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
468362306a36Sopenharmony_ci		return;
468462306a36Sopenharmony_ci
468562306a36Sopenharmony_ci	if (adapter->smartspeed == 0) {
468662306a36Sopenharmony_ci		/* If Master/Slave config fault is asserted twice,
468762306a36Sopenharmony_ci		 * we assume back-to-back
468862306a36Sopenharmony_ci		 */
468962306a36Sopenharmony_ci		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
469062306a36Sopenharmony_ci		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT))
469162306a36Sopenharmony_ci			return;
469262306a36Sopenharmony_ci		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
469362306a36Sopenharmony_ci		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT))
469462306a36Sopenharmony_ci			return;
469562306a36Sopenharmony_ci		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
469662306a36Sopenharmony_ci		if (phy_ctrl & CR_1000T_MS_ENABLE) {
469762306a36Sopenharmony_ci			phy_ctrl &= ~CR_1000T_MS_ENABLE;
469862306a36Sopenharmony_ci			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
469962306a36Sopenharmony_ci					    phy_ctrl);
470062306a36Sopenharmony_ci			adapter->smartspeed++;
470162306a36Sopenharmony_ci			if (!e1000_phy_setup_autoneg(hw) &&
470262306a36Sopenharmony_ci			   !e1000_read_phy_reg(hw, PHY_CTRL,
470362306a36Sopenharmony_ci					       &phy_ctrl)) {
470462306a36Sopenharmony_ci				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
470562306a36Sopenharmony_ci					     MII_CR_RESTART_AUTO_NEG);
470662306a36Sopenharmony_ci				e1000_write_phy_reg(hw, PHY_CTRL,
470762306a36Sopenharmony_ci						    phy_ctrl);
470862306a36Sopenharmony_ci			}
470962306a36Sopenharmony_ci		}
471062306a36Sopenharmony_ci		return;
471162306a36Sopenharmony_ci	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
471262306a36Sopenharmony_ci		/* If still no link, perhaps using 2/3 pair cable */
471362306a36Sopenharmony_ci		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
471462306a36Sopenharmony_ci		phy_ctrl |= CR_1000T_MS_ENABLE;
471562306a36Sopenharmony_ci		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
471662306a36Sopenharmony_ci		if (!e1000_phy_setup_autoneg(hw) &&
471762306a36Sopenharmony_ci		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
471862306a36Sopenharmony_ci			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
471962306a36Sopenharmony_ci				     MII_CR_RESTART_AUTO_NEG);
472062306a36Sopenharmony_ci			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
472162306a36Sopenharmony_ci		}
472262306a36Sopenharmony_ci	}
472362306a36Sopenharmony_ci	/* Restart process after E1000_SMARTSPEED_MAX iterations */
472462306a36Sopenharmony_ci	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
472562306a36Sopenharmony_ci		adapter->smartspeed = 0;
472662306a36Sopenharmony_ci}
472762306a36Sopenharmony_ci
472862306a36Sopenharmony_ci/**
472962306a36Sopenharmony_ci * e1000_ioctl - handle ioctl calls
473062306a36Sopenharmony_ci * @netdev: pointer to our netdev
473162306a36Sopenharmony_ci * @ifr: pointer to interface request structure
473262306a36Sopenharmony_ci * @cmd: ioctl data
473362306a36Sopenharmony_ci **/
473462306a36Sopenharmony_cistatic int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
473562306a36Sopenharmony_ci{
473662306a36Sopenharmony_ci	switch (cmd) {
473762306a36Sopenharmony_ci	case SIOCGMIIPHY:
473862306a36Sopenharmony_ci	case SIOCGMIIREG:
473962306a36Sopenharmony_ci	case SIOCSMIIREG:
474062306a36Sopenharmony_ci		return e1000_mii_ioctl(netdev, ifr, cmd);
474162306a36Sopenharmony_ci	default:
474262306a36Sopenharmony_ci		return -EOPNOTSUPP;
474362306a36Sopenharmony_ci	}
474462306a36Sopenharmony_ci}
474562306a36Sopenharmony_ci
474662306a36Sopenharmony_ci/**
474762306a36Sopenharmony_ci * e1000_mii_ioctl -
474862306a36Sopenharmony_ci * @netdev: pointer to our netdev
474962306a36Sopenharmony_ci * @ifr: pointer to interface request structure
475062306a36Sopenharmony_ci * @cmd: ioctl data
475162306a36Sopenharmony_ci **/
475262306a36Sopenharmony_cistatic int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
475362306a36Sopenharmony_ci			   int cmd)
475462306a36Sopenharmony_ci{
475562306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
475662306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
475762306a36Sopenharmony_ci	struct mii_ioctl_data *data = if_mii(ifr);
475862306a36Sopenharmony_ci	int retval;
475962306a36Sopenharmony_ci	u16 mii_reg;
476062306a36Sopenharmony_ci	unsigned long flags;
476162306a36Sopenharmony_ci
476262306a36Sopenharmony_ci	if (hw->media_type != e1000_media_type_copper)
476362306a36Sopenharmony_ci		return -EOPNOTSUPP;
476462306a36Sopenharmony_ci
476562306a36Sopenharmony_ci	switch (cmd) {
476662306a36Sopenharmony_ci	case SIOCGMIIPHY:
476762306a36Sopenharmony_ci		data->phy_id = hw->phy_addr;
476862306a36Sopenharmony_ci		break;
476962306a36Sopenharmony_ci	case SIOCGMIIREG:
477062306a36Sopenharmony_ci		spin_lock_irqsave(&adapter->stats_lock, flags);
477162306a36Sopenharmony_ci		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
477262306a36Sopenharmony_ci				   &data->val_out)) {
477362306a36Sopenharmony_ci			spin_unlock_irqrestore(&adapter->stats_lock, flags);
477462306a36Sopenharmony_ci			return -EIO;
477562306a36Sopenharmony_ci		}
477662306a36Sopenharmony_ci		spin_unlock_irqrestore(&adapter->stats_lock, flags);
477762306a36Sopenharmony_ci		break;
477862306a36Sopenharmony_ci	case SIOCSMIIREG:
477962306a36Sopenharmony_ci		if (data->reg_num & ~(0x1F))
478062306a36Sopenharmony_ci			return -EFAULT;
478162306a36Sopenharmony_ci		mii_reg = data->val_in;
478262306a36Sopenharmony_ci		spin_lock_irqsave(&adapter->stats_lock, flags);
478362306a36Sopenharmony_ci		if (e1000_write_phy_reg(hw, data->reg_num,
478462306a36Sopenharmony_ci					mii_reg)) {
478562306a36Sopenharmony_ci			spin_unlock_irqrestore(&adapter->stats_lock, flags);
478662306a36Sopenharmony_ci			return -EIO;
478762306a36Sopenharmony_ci		}
478862306a36Sopenharmony_ci		spin_unlock_irqrestore(&adapter->stats_lock, flags);
478962306a36Sopenharmony_ci		if (hw->media_type == e1000_media_type_copper) {
479062306a36Sopenharmony_ci			switch (data->reg_num) {
479162306a36Sopenharmony_ci			case PHY_CTRL:
479262306a36Sopenharmony_ci				if (mii_reg & MII_CR_POWER_DOWN)
479362306a36Sopenharmony_ci					break;
479462306a36Sopenharmony_ci				if (mii_reg & MII_CR_AUTO_NEG_EN) {
479562306a36Sopenharmony_ci					hw->autoneg = 1;
479662306a36Sopenharmony_ci					hw->autoneg_advertised = 0x2F;
479762306a36Sopenharmony_ci				} else {
479862306a36Sopenharmony_ci					u32 speed;
479962306a36Sopenharmony_ci					if (mii_reg & 0x40)
480062306a36Sopenharmony_ci						speed = SPEED_1000;
480162306a36Sopenharmony_ci					else if (mii_reg & 0x2000)
480262306a36Sopenharmony_ci						speed = SPEED_100;
480362306a36Sopenharmony_ci					else
480462306a36Sopenharmony_ci						speed = SPEED_10;
480562306a36Sopenharmony_ci					retval = e1000_set_spd_dplx(
480662306a36Sopenharmony_ci						adapter, speed,
480762306a36Sopenharmony_ci						((mii_reg & 0x100)
480862306a36Sopenharmony_ci						 ? DUPLEX_FULL :
480962306a36Sopenharmony_ci						 DUPLEX_HALF));
481062306a36Sopenharmony_ci					if (retval)
481162306a36Sopenharmony_ci						return retval;
481262306a36Sopenharmony_ci				}
481362306a36Sopenharmony_ci				if (netif_running(adapter->netdev))
481462306a36Sopenharmony_ci					e1000_reinit_locked(adapter);
481562306a36Sopenharmony_ci				else
481662306a36Sopenharmony_ci					e1000_reset(adapter);
481762306a36Sopenharmony_ci				break;
481862306a36Sopenharmony_ci			case M88E1000_PHY_SPEC_CTRL:
481962306a36Sopenharmony_ci			case M88E1000_EXT_PHY_SPEC_CTRL:
482062306a36Sopenharmony_ci				if (e1000_phy_reset(hw))
482162306a36Sopenharmony_ci					return -EIO;
482262306a36Sopenharmony_ci				break;
482362306a36Sopenharmony_ci			}
482462306a36Sopenharmony_ci		} else {
482562306a36Sopenharmony_ci			switch (data->reg_num) {
482662306a36Sopenharmony_ci			case PHY_CTRL:
482762306a36Sopenharmony_ci				if (mii_reg & MII_CR_POWER_DOWN)
482862306a36Sopenharmony_ci					break;
482962306a36Sopenharmony_ci				if (netif_running(adapter->netdev))
483062306a36Sopenharmony_ci					e1000_reinit_locked(adapter);
483162306a36Sopenharmony_ci				else
483262306a36Sopenharmony_ci					e1000_reset(adapter);
483362306a36Sopenharmony_ci				break;
483462306a36Sopenharmony_ci			}
483562306a36Sopenharmony_ci		}
483662306a36Sopenharmony_ci		break;
483762306a36Sopenharmony_ci	default:
483862306a36Sopenharmony_ci		return -EOPNOTSUPP;
483962306a36Sopenharmony_ci	}
484062306a36Sopenharmony_ci	return E1000_SUCCESS;
484162306a36Sopenharmony_ci}
484262306a36Sopenharmony_ci
484362306a36Sopenharmony_civoid e1000_pci_set_mwi(struct e1000_hw *hw)
484462306a36Sopenharmony_ci{
484562306a36Sopenharmony_ci	struct e1000_adapter *adapter = hw->back;
484662306a36Sopenharmony_ci	int ret_val = pci_set_mwi(adapter->pdev);
484762306a36Sopenharmony_ci
484862306a36Sopenharmony_ci	if (ret_val)
484962306a36Sopenharmony_ci		e_err(probe, "Error in setting MWI\n");
485062306a36Sopenharmony_ci}
485162306a36Sopenharmony_ci
485262306a36Sopenharmony_civoid e1000_pci_clear_mwi(struct e1000_hw *hw)
485362306a36Sopenharmony_ci{
485462306a36Sopenharmony_ci	struct e1000_adapter *adapter = hw->back;
485562306a36Sopenharmony_ci
485662306a36Sopenharmony_ci	pci_clear_mwi(adapter->pdev);
485762306a36Sopenharmony_ci}
485862306a36Sopenharmony_ci
485962306a36Sopenharmony_ciint e1000_pcix_get_mmrbc(struct e1000_hw *hw)
486062306a36Sopenharmony_ci{
486162306a36Sopenharmony_ci	struct e1000_adapter *adapter = hw->back;
486262306a36Sopenharmony_ci	return pcix_get_mmrbc(adapter->pdev);
486362306a36Sopenharmony_ci}
486462306a36Sopenharmony_ci
486562306a36Sopenharmony_civoid e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
486662306a36Sopenharmony_ci{
486762306a36Sopenharmony_ci	struct e1000_adapter *adapter = hw->back;
486862306a36Sopenharmony_ci	pcix_set_mmrbc(adapter->pdev, mmrbc);
486962306a36Sopenharmony_ci}
487062306a36Sopenharmony_ci
487162306a36Sopenharmony_civoid e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
487262306a36Sopenharmony_ci{
487362306a36Sopenharmony_ci	outl(value, port);
487462306a36Sopenharmony_ci}
487562306a36Sopenharmony_ci
487662306a36Sopenharmony_cistatic bool e1000_vlan_used(struct e1000_adapter *adapter)
487762306a36Sopenharmony_ci{
487862306a36Sopenharmony_ci	u16 vid;
487962306a36Sopenharmony_ci
488062306a36Sopenharmony_ci	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
488162306a36Sopenharmony_ci		return true;
488262306a36Sopenharmony_ci	return false;
488362306a36Sopenharmony_ci}
488462306a36Sopenharmony_ci
488562306a36Sopenharmony_cistatic void __e1000_vlan_mode(struct e1000_adapter *adapter,
488662306a36Sopenharmony_ci			      netdev_features_t features)
488762306a36Sopenharmony_ci{
488862306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
488962306a36Sopenharmony_ci	u32 ctrl;
489062306a36Sopenharmony_ci
489162306a36Sopenharmony_ci	ctrl = er32(CTRL);
489262306a36Sopenharmony_ci	if (features & NETIF_F_HW_VLAN_CTAG_RX) {
489362306a36Sopenharmony_ci		/* enable VLAN tag insert/strip */
489462306a36Sopenharmony_ci		ctrl |= E1000_CTRL_VME;
489562306a36Sopenharmony_ci	} else {
489662306a36Sopenharmony_ci		/* disable VLAN tag insert/strip */
489762306a36Sopenharmony_ci		ctrl &= ~E1000_CTRL_VME;
489862306a36Sopenharmony_ci	}
489962306a36Sopenharmony_ci	ew32(CTRL, ctrl);
490062306a36Sopenharmony_ci}
490162306a36Sopenharmony_cistatic void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
490262306a36Sopenharmony_ci				     bool filter_on)
490362306a36Sopenharmony_ci{
490462306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
490562306a36Sopenharmony_ci	u32 rctl;
490662306a36Sopenharmony_ci
490762306a36Sopenharmony_ci	if (!test_bit(__E1000_DOWN, &adapter->flags))
490862306a36Sopenharmony_ci		e1000_irq_disable(adapter);
490962306a36Sopenharmony_ci
491062306a36Sopenharmony_ci	__e1000_vlan_mode(adapter, adapter->netdev->features);
491162306a36Sopenharmony_ci	if (filter_on) {
491262306a36Sopenharmony_ci		/* enable VLAN receive filtering */
491362306a36Sopenharmony_ci		rctl = er32(RCTL);
491462306a36Sopenharmony_ci		rctl &= ~E1000_RCTL_CFIEN;
491562306a36Sopenharmony_ci		if (!(adapter->netdev->flags & IFF_PROMISC))
491662306a36Sopenharmony_ci			rctl |= E1000_RCTL_VFE;
491762306a36Sopenharmony_ci		ew32(RCTL, rctl);
491862306a36Sopenharmony_ci		e1000_update_mng_vlan(adapter);
491962306a36Sopenharmony_ci	} else {
492062306a36Sopenharmony_ci		/* disable VLAN receive filtering */
492162306a36Sopenharmony_ci		rctl = er32(RCTL);
492262306a36Sopenharmony_ci		rctl &= ~E1000_RCTL_VFE;
492362306a36Sopenharmony_ci		ew32(RCTL, rctl);
492462306a36Sopenharmony_ci	}
492562306a36Sopenharmony_ci
492662306a36Sopenharmony_ci	if (!test_bit(__E1000_DOWN, &adapter->flags))
492762306a36Sopenharmony_ci		e1000_irq_enable(adapter);
492862306a36Sopenharmony_ci}
492962306a36Sopenharmony_ci
493062306a36Sopenharmony_cistatic void e1000_vlan_mode(struct net_device *netdev,
493162306a36Sopenharmony_ci			    netdev_features_t features)
493262306a36Sopenharmony_ci{
493362306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
493462306a36Sopenharmony_ci
493562306a36Sopenharmony_ci	if (!test_bit(__E1000_DOWN, &adapter->flags))
493662306a36Sopenharmony_ci		e1000_irq_disable(adapter);
493762306a36Sopenharmony_ci
493862306a36Sopenharmony_ci	__e1000_vlan_mode(adapter, features);
493962306a36Sopenharmony_ci
494062306a36Sopenharmony_ci	if (!test_bit(__E1000_DOWN, &adapter->flags))
494162306a36Sopenharmony_ci		e1000_irq_enable(adapter);
494262306a36Sopenharmony_ci}
494362306a36Sopenharmony_ci
494462306a36Sopenharmony_cistatic int e1000_vlan_rx_add_vid(struct net_device *netdev,
494562306a36Sopenharmony_ci				 __be16 proto, u16 vid)
494662306a36Sopenharmony_ci{
494762306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
494862306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
494962306a36Sopenharmony_ci	u32 vfta, index;
495062306a36Sopenharmony_ci
495162306a36Sopenharmony_ci	if ((hw->mng_cookie.status &
495262306a36Sopenharmony_ci	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
495362306a36Sopenharmony_ci	    (vid == adapter->mng_vlan_id))
495462306a36Sopenharmony_ci		return 0;
495562306a36Sopenharmony_ci
495662306a36Sopenharmony_ci	if (!e1000_vlan_used(adapter))
495762306a36Sopenharmony_ci		e1000_vlan_filter_on_off(adapter, true);
495862306a36Sopenharmony_ci
495962306a36Sopenharmony_ci	/* add VID to filter table */
496062306a36Sopenharmony_ci	index = (vid >> 5) & 0x7F;
496162306a36Sopenharmony_ci	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
496262306a36Sopenharmony_ci	vfta |= (1 << (vid & 0x1F));
496362306a36Sopenharmony_ci	e1000_write_vfta(hw, index, vfta);
496462306a36Sopenharmony_ci
496562306a36Sopenharmony_ci	set_bit(vid, adapter->active_vlans);
496662306a36Sopenharmony_ci
496762306a36Sopenharmony_ci	return 0;
496862306a36Sopenharmony_ci}
496962306a36Sopenharmony_ci
497062306a36Sopenharmony_cistatic int e1000_vlan_rx_kill_vid(struct net_device *netdev,
497162306a36Sopenharmony_ci				  __be16 proto, u16 vid)
497262306a36Sopenharmony_ci{
497362306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
497462306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
497562306a36Sopenharmony_ci	u32 vfta, index;
497662306a36Sopenharmony_ci
497762306a36Sopenharmony_ci	if (!test_bit(__E1000_DOWN, &adapter->flags))
497862306a36Sopenharmony_ci		e1000_irq_disable(adapter);
497962306a36Sopenharmony_ci	if (!test_bit(__E1000_DOWN, &adapter->flags))
498062306a36Sopenharmony_ci		e1000_irq_enable(adapter);
498162306a36Sopenharmony_ci
498262306a36Sopenharmony_ci	/* remove VID from filter table */
498362306a36Sopenharmony_ci	index = (vid >> 5) & 0x7F;
498462306a36Sopenharmony_ci	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
498562306a36Sopenharmony_ci	vfta &= ~(1 << (vid & 0x1F));
498662306a36Sopenharmony_ci	e1000_write_vfta(hw, index, vfta);
498762306a36Sopenharmony_ci
498862306a36Sopenharmony_ci	clear_bit(vid, adapter->active_vlans);
498962306a36Sopenharmony_ci
499062306a36Sopenharmony_ci	if (!e1000_vlan_used(adapter))
499162306a36Sopenharmony_ci		e1000_vlan_filter_on_off(adapter, false);
499262306a36Sopenharmony_ci
499362306a36Sopenharmony_ci	return 0;
499462306a36Sopenharmony_ci}
499562306a36Sopenharmony_ci
499662306a36Sopenharmony_cistatic void e1000_restore_vlan(struct e1000_adapter *adapter)
499762306a36Sopenharmony_ci{
499862306a36Sopenharmony_ci	u16 vid;
499962306a36Sopenharmony_ci
500062306a36Sopenharmony_ci	if (!e1000_vlan_used(adapter))
500162306a36Sopenharmony_ci		return;
500262306a36Sopenharmony_ci
500362306a36Sopenharmony_ci	e1000_vlan_filter_on_off(adapter, true);
500462306a36Sopenharmony_ci	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
500562306a36Sopenharmony_ci		e1000_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);
500662306a36Sopenharmony_ci}
500762306a36Sopenharmony_ci
500862306a36Sopenharmony_ciint e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
500962306a36Sopenharmony_ci{
501062306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
501162306a36Sopenharmony_ci
501262306a36Sopenharmony_ci	hw->autoneg = 0;
501362306a36Sopenharmony_ci
501462306a36Sopenharmony_ci	/* Make sure dplx is at most 1 bit and lsb of speed is not set
501562306a36Sopenharmony_ci	 * for the switch() below to work
501662306a36Sopenharmony_ci	 */
501762306a36Sopenharmony_ci	if ((spd & 1) || (dplx & ~1))
501862306a36Sopenharmony_ci		goto err_inval;
501962306a36Sopenharmony_ci
502062306a36Sopenharmony_ci	/* Fiber NICs only allow 1000 gbps Full duplex */
502162306a36Sopenharmony_ci	if ((hw->media_type == e1000_media_type_fiber) &&
502262306a36Sopenharmony_ci	    spd != SPEED_1000 &&
502362306a36Sopenharmony_ci	    dplx != DUPLEX_FULL)
502462306a36Sopenharmony_ci		goto err_inval;
502562306a36Sopenharmony_ci
502662306a36Sopenharmony_ci	switch (spd + dplx) {
502762306a36Sopenharmony_ci	case SPEED_10 + DUPLEX_HALF:
502862306a36Sopenharmony_ci		hw->forced_speed_duplex = e1000_10_half;
502962306a36Sopenharmony_ci		break;
503062306a36Sopenharmony_ci	case SPEED_10 + DUPLEX_FULL:
503162306a36Sopenharmony_ci		hw->forced_speed_duplex = e1000_10_full;
503262306a36Sopenharmony_ci		break;
503362306a36Sopenharmony_ci	case SPEED_100 + DUPLEX_HALF:
503462306a36Sopenharmony_ci		hw->forced_speed_duplex = e1000_100_half;
503562306a36Sopenharmony_ci		break;
503662306a36Sopenharmony_ci	case SPEED_100 + DUPLEX_FULL:
503762306a36Sopenharmony_ci		hw->forced_speed_duplex = e1000_100_full;
503862306a36Sopenharmony_ci		break;
503962306a36Sopenharmony_ci	case SPEED_1000 + DUPLEX_FULL:
504062306a36Sopenharmony_ci		hw->autoneg = 1;
504162306a36Sopenharmony_ci		hw->autoneg_advertised = ADVERTISE_1000_FULL;
504262306a36Sopenharmony_ci		break;
504362306a36Sopenharmony_ci	case SPEED_1000 + DUPLEX_HALF: /* not supported */
504462306a36Sopenharmony_ci	default:
504562306a36Sopenharmony_ci		goto err_inval;
504662306a36Sopenharmony_ci	}
504762306a36Sopenharmony_ci
504862306a36Sopenharmony_ci	/* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
504962306a36Sopenharmony_ci	hw->mdix = AUTO_ALL_MODES;
505062306a36Sopenharmony_ci
505162306a36Sopenharmony_ci	return 0;
505262306a36Sopenharmony_ci
505362306a36Sopenharmony_cierr_inval:
505462306a36Sopenharmony_ci	e_err(probe, "Unsupported Speed/Duplex configuration\n");
505562306a36Sopenharmony_ci	return -EINVAL;
505662306a36Sopenharmony_ci}
505762306a36Sopenharmony_ci
505862306a36Sopenharmony_cistatic int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
505962306a36Sopenharmony_ci{
506062306a36Sopenharmony_ci	struct net_device *netdev = pci_get_drvdata(pdev);
506162306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
506262306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
506362306a36Sopenharmony_ci	u32 ctrl, ctrl_ext, rctl, status;
506462306a36Sopenharmony_ci	u32 wufc = adapter->wol;
506562306a36Sopenharmony_ci
506662306a36Sopenharmony_ci	netif_device_detach(netdev);
506762306a36Sopenharmony_ci
506862306a36Sopenharmony_ci	if (netif_running(netdev)) {
506962306a36Sopenharmony_ci		int count = E1000_CHECK_RESET_COUNT;
507062306a36Sopenharmony_ci
507162306a36Sopenharmony_ci		while (test_bit(__E1000_RESETTING, &adapter->flags) && count--)
507262306a36Sopenharmony_ci			usleep_range(10000, 20000);
507362306a36Sopenharmony_ci
507462306a36Sopenharmony_ci		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
507562306a36Sopenharmony_ci		e1000_down(adapter);
507662306a36Sopenharmony_ci	}
507762306a36Sopenharmony_ci
507862306a36Sopenharmony_ci	status = er32(STATUS);
507962306a36Sopenharmony_ci	if (status & E1000_STATUS_LU)
508062306a36Sopenharmony_ci		wufc &= ~E1000_WUFC_LNKC;
508162306a36Sopenharmony_ci
508262306a36Sopenharmony_ci	if (wufc) {
508362306a36Sopenharmony_ci		e1000_setup_rctl(adapter);
508462306a36Sopenharmony_ci		e1000_set_rx_mode(netdev);
508562306a36Sopenharmony_ci
508662306a36Sopenharmony_ci		rctl = er32(RCTL);
508762306a36Sopenharmony_ci
508862306a36Sopenharmony_ci		/* turn on all-multi mode if wake on multicast is enabled */
508962306a36Sopenharmony_ci		if (wufc & E1000_WUFC_MC)
509062306a36Sopenharmony_ci			rctl |= E1000_RCTL_MPE;
509162306a36Sopenharmony_ci
509262306a36Sopenharmony_ci		/* enable receives in the hardware */
509362306a36Sopenharmony_ci		ew32(RCTL, rctl | E1000_RCTL_EN);
509462306a36Sopenharmony_ci
509562306a36Sopenharmony_ci		if (hw->mac_type >= e1000_82540) {
509662306a36Sopenharmony_ci			ctrl = er32(CTRL);
509762306a36Sopenharmony_ci			/* advertise wake from D3Cold */
509862306a36Sopenharmony_ci			#define E1000_CTRL_ADVD3WUC 0x00100000
509962306a36Sopenharmony_ci			/* phy power management enable */
510062306a36Sopenharmony_ci			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
510162306a36Sopenharmony_ci			ctrl |= E1000_CTRL_ADVD3WUC |
510262306a36Sopenharmony_ci				E1000_CTRL_EN_PHY_PWR_MGMT;
510362306a36Sopenharmony_ci			ew32(CTRL, ctrl);
510462306a36Sopenharmony_ci		}
510562306a36Sopenharmony_ci
510662306a36Sopenharmony_ci		if (hw->media_type == e1000_media_type_fiber ||
510762306a36Sopenharmony_ci		    hw->media_type == e1000_media_type_internal_serdes) {
510862306a36Sopenharmony_ci			/* keep the laser running in D3 */
510962306a36Sopenharmony_ci			ctrl_ext = er32(CTRL_EXT);
511062306a36Sopenharmony_ci			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
511162306a36Sopenharmony_ci			ew32(CTRL_EXT, ctrl_ext);
511262306a36Sopenharmony_ci		}
511362306a36Sopenharmony_ci
511462306a36Sopenharmony_ci		ew32(WUC, E1000_WUC_PME_EN);
511562306a36Sopenharmony_ci		ew32(WUFC, wufc);
511662306a36Sopenharmony_ci	} else {
511762306a36Sopenharmony_ci		ew32(WUC, 0);
511862306a36Sopenharmony_ci		ew32(WUFC, 0);
511962306a36Sopenharmony_ci	}
512062306a36Sopenharmony_ci
512162306a36Sopenharmony_ci	e1000_release_manageability(adapter);
512262306a36Sopenharmony_ci
512362306a36Sopenharmony_ci	*enable_wake = !!wufc;
512462306a36Sopenharmony_ci
512562306a36Sopenharmony_ci	/* make sure adapter isn't asleep if manageability is enabled */
512662306a36Sopenharmony_ci	if (adapter->en_mng_pt)
512762306a36Sopenharmony_ci		*enable_wake = true;
512862306a36Sopenharmony_ci
512962306a36Sopenharmony_ci	if (netif_running(netdev))
513062306a36Sopenharmony_ci		e1000_free_irq(adapter);
513162306a36Sopenharmony_ci
513262306a36Sopenharmony_ci	if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags))
513362306a36Sopenharmony_ci		pci_disable_device(pdev);
513462306a36Sopenharmony_ci
513562306a36Sopenharmony_ci	return 0;
513662306a36Sopenharmony_ci}
513762306a36Sopenharmony_ci
513862306a36Sopenharmony_cistatic int __maybe_unused e1000_suspend(struct device *dev)
513962306a36Sopenharmony_ci{
514062306a36Sopenharmony_ci	int retval;
514162306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(dev);
514262306a36Sopenharmony_ci	bool wake;
514362306a36Sopenharmony_ci
514462306a36Sopenharmony_ci	retval = __e1000_shutdown(pdev, &wake);
514562306a36Sopenharmony_ci	device_set_wakeup_enable(dev, wake);
514662306a36Sopenharmony_ci
514762306a36Sopenharmony_ci	return retval;
514862306a36Sopenharmony_ci}
514962306a36Sopenharmony_ci
515062306a36Sopenharmony_cistatic int __maybe_unused e1000_resume(struct device *dev)
515162306a36Sopenharmony_ci{
515262306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(dev);
515362306a36Sopenharmony_ci	struct net_device *netdev = pci_get_drvdata(pdev);
515462306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
515562306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
515662306a36Sopenharmony_ci	u32 err;
515762306a36Sopenharmony_ci
515862306a36Sopenharmony_ci	if (adapter->need_ioport)
515962306a36Sopenharmony_ci		err = pci_enable_device(pdev);
516062306a36Sopenharmony_ci	else
516162306a36Sopenharmony_ci		err = pci_enable_device_mem(pdev);
516262306a36Sopenharmony_ci	if (err) {
516362306a36Sopenharmony_ci		pr_err("Cannot enable PCI device from suspend\n");
516462306a36Sopenharmony_ci		return err;
516562306a36Sopenharmony_ci	}
516662306a36Sopenharmony_ci
516762306a36Sopenharmony_ci	/* flush memory to make sure state is correct */
516862306a36Sopenharmony_ci	smp_mb__before_atomic();
516962306a36Sopenharmony_ci	clear_bit(__E1000_DISABLED, &adapter->flags);
517062306a36Sopenharmony_ci	pci_set_master(pdev);
517162306a36Sopenharmony_ci
517262306a36Sopenharmony_ci	pci_enable_wake(pdev, PCI_D3hot, 0);
517362306a36Sopenharmony_ci	pci_enable_wake(pdev, PCI_D3cold, 0);
517462306a36Sopenharmony_ci
517562306a36Sopenharmony_ci	if (netif_running(netdev)) {
517662306a36Sopenharmony_ci		err = e1000_request_irq(adapter);
517762306a36Sopenharmony_ci		if (err)
517862306a36Sopenharmony_ci			return err;
517962306a36Sopenharmony_ci	}
518062306a36Sopenharmony_ci
518162306a36Sopenharmony_ci	e1000_power_up_phy(adapter);
518262306a36Sopenharmony_ci	e1000_reset(adapter);
518362306a36Sopenharmony_ci	ew32(WUS, ~0);
518462306a36Sopenharmony_ci
518562306a36Sopenharmony_ci	e1000_init_manageability(adapter);
518662306a36Sopenharmony_ci
518762306a36Sopenharmony_ci	if (netif_running(netdev))
518862306a36Sopenharmony_ci		e1000_up(adapter);
518962306a36Sopenharmony_ci
519062306a36Sopenharmony_ci	netif_device_attach(netdev);
519162306a36Sopenharmony_ci
519262306a36Sopenharmony_ci	return 0;
519362306a36Sopenharmony_ci}
519462306a36Sopenharmony_ci
519562306a36Sopenharmony_cistatic void e1000_shutdown(struct pci_dev *pdev)
519662306a36Sopenharmony_ci{
519762306a36Sopenharmony_ci	bool wake;
519862306a36Sopenharmony_ci
519962306a36Sopenharmony_ci	__e1000_shutdown(pdev, &wake);
520062306a36Sopenharmony_ci
520162306a36Sopenharmony_ci	if (system_state == SYSTEM_POWER_OFF) {
520262306a36Sopenharmony_ci		pci_wake_from_d3(pdev, wake);
520362306a36Sopenharmony_ci		pci_set_power_state(pdev, PCI_D3hot);
520462306a36Sopenharmony_ci	}
520562306a36Sopenharmony_ci}
520662306a36Sopenharmony_ci
520762306a36Sopenharmony_ci#ifdef CONFIG_NET_POLL_CONTROLLER
520862306a36Sopenharmony_ci/* Polling 'interrupt' - used by things like netconsole to send skbs
520962306a36Sopenharmony_ci * without having to re-enable interrupts. It's not called while
521062306a36Sopenharmony_ci * the interrupt routine is executing.
521162306a36Sopenharmony_ci */
521262306a36Sopenharmony_cistatic void e1000_netpoll(struct net_device *netdev)
521362306a36Sopenharmony_ci{
521462306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
521562306a36Sopenharmony_ci
521662306a36Sopenharmony_ci	if (disable_hardirq(adapter->pdev->irq))
521762306a36Sopenharmony_ci		e1000_intr(adapter->pdev->irq, netdev);
521862306a36Sopenharmony_ci	enable_irq(adapter->pdev->irq);
521962306a36Sopenharmony_ci}
522062306a36Sopenharmony_ci#endif
522162306a36Sopenharmony_ci
522262306a36Sopenharmony_ci/**
522362306a36Sopenharmony_ci * e1000_io_error_detected - called when PCI error is detected
522462306a36Sopenharmony_ci * @pdev: Pointer to PCI device
522562306a36Sopenharmony_ci * @state: The current pci connection state
522662306a36Sopenharmony_ci *
522762306a36Sopenharmony_ci * This function is called after a PCI bus error affecting
522862306a36Sopenharmony_ci * this device has been detected.
522962306a36Sopenharmony_ci */
523062306a36Sopenharmony_cistatic pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
523162306a36Sopenharmony_ci						pci_channel_state_t state)
523262306a36Sopenharmony_ci{
523362306a36Sopenharmony_ci	struct net_device *netdev = pci_get_drvdata(pdev);
523462306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
523562306a36Sopenharmony_ci
523662306a36Sopenharmony_ci	netif_device_detach(netdev);
523762306a36Sopenharmony_ci
523862306a36Sopenharmony_ci	if (state == pci_channel_io_perm_failure)
523962306a36Sopenharmony_ci		return PCI_ERS_RESULT_DISCONNECT;
524062306a36Sopenharmony_ci
524162306a36Sopenharmony_ci	if (netif_running(netdev))
524262306a36Sopenharmony_ci		e1000_down(adapter);
524362306a36Sopenharmony_ci
524462306a36Sopenharmony_ci	if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags))
524562306a36Sopenharmony_ci		pci_disable_device(pdev);
524662306a36Sopenharmony_ci
524762306a36Sopenharmony_ci	/* Request a slot reset. */
524862306a36Sopenharmony_ci	return PCI_ERS_RESULT_NEED_RESET;
524962306a36Sopenharmony_ci}
525062306a36Sopenharmony_ci
525162306a36Sopenharmony_ci/**
525262306a36Sopenharmony_ci * e1000_io_slot_reset - called after the pci bus has been reset.
525362306a36Sopenharmony_ci * @pdev: Pointer to PCI device
525462306a36Sopenharmony_ci *
525562306a36Sopenharmony_ci * Restart the card from scratch, as if from a cold-boot. Implementation
525662306a36Sopenharmony_ci * resembles the first-half of the e1000_resume routine.
525762306a36Sopenharmony_ci */
525862306a36Sopenharmony_cistatic pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
525962306a36Sopenharmony_ci{
526062306a36Sopenharmony_ci	struct net_device *netdev = pci_get_drvdata(pdev);
526162306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
526262306a36Sopenharmony_ci	struct e1000_hw *hw = &adapter->hw;
526362306a36Sopenharmony_ci	int err;
526462306a36Sopenharmony_ci
526562306a36Sopenharmony_ci	if (adapter->need_ioport)
526662306a36Sopenharmony_ci		err = pci_enable_device(pdev);
526762306a36Sopenharmony_ci	else
526862306a36Sopenharmony_ci		err = pci_enable_device_mem(pdev);
526962306a36Sopenharmony_ci	if (err) {
527062306a36Sopenharmony_ci		pr_err("Cannot re-enable PCI device after reset.\n");
527162306a36Sopenharmony_ci		return PCI_ERS_RESULT_DISCONNECT;
527262306a36Sopenharmony_ci	}
527362306a36Sopenharmony_ci
527462306a36Sopenharmony_ci	/* flush memory to make sure state is correct */
527562306a36Sopenharmony_ci	smp_mb__before_atomic();
527662306a36Sopenharmony_ci	clear_bit(__E1000_DISABLED, &adapter->flags);
527762306a36Sopenharmony_ci	pci_set_master(pdev);
527862306a36Sopenharmony_ci
527962306a36Sopenharmony_ci	pci_enable_wake(pdev, PCI_D3hot, 0);
528062306a36Sopenharmony_ci	pci_enable_wake(pdev, PCI_D3cold, 0);
528162306a36Sopenharmony_ci
528262306a36Sopenharmony_ci	e1000_reset(adapter);
528362306a36Sopenharmony_ci	ew32(WUS, ~0);
528462306a36Sopenharmony_ci
528562306a36Sopenharmony_ci	return PCI_ERS_RESULT_RECOVERED;
528662306a36Sopenharmony_ci}
528762306a36Sopenharmony_ci
528862306a36Sopenharmony_ci/**
528962306a36Sopenharmony_ci * e1000_io_resume - called when traffic can start flowing again.
529062306a36Sopenharmony_ci * @pdev: Pointer to PCI device
529162306a36Sopenharmony_ci *
529262306a36Sopenharmony_ci * This callback is called when the error recovery driver tells us that
529362306a36Sopenharmony_ci * its OK to resume normal operation. Implementation resembles the
529462306a36Sopenharmony_ci * second-half of the e1000_resume routine.
529562306a36Sopenharmony_ci */
529662306a36Sopenharmony_cistatic void e1000_io_resume(struct pci_dev *pdev)
529762306a36Sopenharmony_ci{
529862306a36Sopenharmony_ci	struct net_device *netdev = pci_get_drvdata(pdev);
529962306a36Sopenharmony_ci	struct e1000_adapter *adapter = netdev_priv(netdev);
530062306a36Sopenharmony_ci
530162306a36Sopenharmony_ci	e1000_init_manageability(adapter);
530262306a36Sopenharmony_ci
530362306a36Sopenharmony_ci	if (netif_running(netdev)) {
530462306a36Sopenharmony_ci		if (e1000_up(adapter)) {
530562306a36Sopenharmony_ci			pr_info("can't bring device back up after reset\n");
530662306a36Sopenharmony_ci			return;
530762306a36Sopenharmony_ci		}
530862306a36Sopenharmony_ci	}
530962306a36Sopenharmony_ci
531062306a36Sopenharmony_ci	netif_device_attach(netdev);
531162306a36Sopenharmony_ci}
531262306a36Sopenharmony_ci
531362306a36Sopenharmony_ci/* e1000_main.c */
5314