diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 359 | 
1 files changed, 238 insertions, 121 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index ced544499f1..01e5e89ef95 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -25,6 +25,8 @@  *******************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/module.h>  #include <linux/types.h>  #include <linux/init.h> @@ -51,6 +53,7 @@  #include <linux/if_ether.h>  #include <linux/aer.h>  #include <linux/prefetch.h> +#include <linux/pm_runtime.h>  #ifdef CONFIG_IGB_DCA  #include <linux/dca.h>  #endif @@ -145,9 +148,9 @@ static bool igb_clean_rx_irq(struct igb_q_vector *, int);  static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);  static void igb_tx_timeout(struct net_device *);  static void igb_reset_task(struct work_struct *); -static void igb_vlan_mode(struct net_device *netdev, u32 features); -static void igb_vlan_rx_add_vid(struct net_device *, u16); -static void igb_vlan_rx_kill_vid(struct net_device *, u16); +static void igb_vlan_mode(struct net_device *netdev, netdev_features_t features); +static int igb_vlan_rx_add_vid(struct net_device *, u16); +static int igb_vlan_rx_kill_vid(struct net_device *, u16);  static void igb_restore_vlan(struct igb_adapter *);  static void igb_rar_set_qsel(struct igb_adapter *, u8 *, u32 , u8);  static void igb_ping_all_vfs(struct igb_adapter *); @@ -170,8 +173,18 @@ static int igb_check_vf_assignment(struct igb_adapter *adapter);  #endif  #ifdef CONFIG_PM -static int igb_suspend(struct pci_dev *, pm_message_t); -static int igb_resume(struct pci_dev *); +static int igb_suspend(struct device *); +static int igb_resume(struct device *); +#ifdef CONFIG_PM_RUNTIME +static int igb_runtime_suspend(struct device *dev); +static int igb_runtime_resume(struct device *dev); +static int igb_runtime_idle(struct device *dev); +#endif +static const struct dev_pm_ops igb_pm_ops = { +	SET_SYSTEM_SLEEP_PM_OPS(igb_suspend, igb_resume) +	SET_RUNTIME_PM_OPS(igb_runtime_suspend, igb_runtime_resume, +			igb_runtime_idle) +};  #endif  static void igb_shutdown(struct pci_dev *);  #ifdef CONFIG_IGB_DCA @@ -212,9 +225,7 @@ static struct pci_driver igb_driver = {  	.probe    = igb_probe,  	.remove   = __devexit_p(igb_remove),  #ifdef CONFIG_PM -	/* Power Management Hooks */ -	.suspend  = igb_suspend, -	.resume   = igb_resume, +	.driver.pm = &igb_pm_ops,  #endif  	.shutdown = igb_shutdown,  	.err_handler = &igb_err_handler @@ -325,16 +336,13 @@ static void igb_regdump(struct e1000_hw *hw, struct igb_reg_info *reginfo)  			regs[n] = rd32(E1000_TXDCTL(n));  		break;  	default: -		printk(KERN_INFO "%-15s %08x\n", -			reginfo->name, rd32(reginfo->ofs)); +		pr_info("%-15s %08x\n", reginfo->name, rd32(reginfo->ofs));  		return;  	}  	snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]"); -	printk(KERN_INFO "%-15s ", rname); -	for (n = 0; n < 4; n++) -		printk(KERN_CONT "%08x ", regs[n]); -	printk(KERN_CONT "\n"); +	pr_info("%-15s %08x %08x %08x %08x\n", rname, regs[0], regs[1], +		regs[2], regs[3]);  }  /* @@ -359,18 +367,15 @@ static void igb_dump(struct igb_adapter *adapter)  	/* Print netdevice Info */  	if (netdev) {  		dev_info(&adapter->pdev->dev, "Net device Info\n"); -		printk(KERN_INFO "Device Name     state            " -			"trans_start      last_rx\n"); -		printk(KERN_INFO "%-15s %016lX %016lX %016lX\n", -		netdev->name, -		netdev->state, -		netdev->trans_start, -		netdev->last_rx); +		pr_info("Device Name     state            trans_start      " +			"last_rx\n"); +		pr_info("%-15s %016lX %016lX %016lX\n", netdev->name, +			netdev->state, netdev->trans_start, netdev->last_rx);  	}  	/* Print Registers */  	dev_info(&adapter->pdev->dev, "Register Dump\n"); -	printk(KERN_INFO " Register Name   Value\n"); +	pr_info(" Register Name   Value\n");  	for (reginfo = (struct igb_reg_info *)igb_reg_info_tbl;  	     reginfo->name; reginfo++) {  		igb_regdump(hw, reginfo); @@ -381,18 +386,17 @@ static void igb_dump(struct igb_adapter *adapter)  		goto exit;  	dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); -	printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma  ]" -		" leng ntw timestamp\n"); +	pr_info("Queue [NTU] [NTC] [bi(ntc)->dma  ] leng ntw timestamp\n");  	for (n = 0; n < adapter->num_tx_queues; n++) {  		struct igb_tx_buffer *buffer_info;  		tx_ring = adapter->tx_ring[n];  		buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean]; -		printk(KERN_INFO " %5d %5X %5X %016llX %04X %p %016llX\n", -			   n, tx_ring->next_to_use, tx_ring->next_to_clean, -			   (u64)buffer_info->dma, -			   buffer_info->length, -			   buffer_info->next_to_watch, -			   (u64)buffer_info->time_stamp); +		pr_info(" %5d %5X %5X %016llX %04X %p %016llX\n", +			n, tx_ring->next_to_use, tx_ring->next_to_clean, +			(u64)buffer_info->dma, +			buffer_info->length, +			buffer_info->next_to_watch, +			(u64)buffer_info->time_stamp);  	}  	/* Print TX Rings */ @@ -414,36 +418,38 @@ static void igb_dump(struct igb_adapter *adapter)  	for (n = 0; n < adapter->num_tx_queues; n++) {  		tx_ring = adapter->tx_ring[n]; -		printk(KERN_INFO "------------------------------------\n"); -		printk(KERN_INFO "TX QUEUE INDEX = %d\n", tx_ring->queue_index); -		printk(KERN_INFO "------------------------------------\n"); -		printk(KERN_INFO "T [desc]     [address 63:0  ] " -			"[PlPOCIStDDM Ln] [bi->dma       ] " -			"leng  ntw timestamp        bi->skb\n"); +		pr_info("------------------------------------\n"); +		pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index); +		pr_info("------------------------------------\n"); +		pr_info("T [desc]     [address 63:0  ] [PlPOCIStDDM Ln] " +			"[bi->dma       ] leng  ntw timestamp        " +			"bi->skb\n");  		for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { +			const char *next_desc;  			struct igb_tx_buffer *buffer_info;  			tx_desc = IGB_TX_DESC(tx_ring, i);  			buffer_info = &tx_ring->tx_buffer_info[i];  			u0 = (struct my_u0 *)tx_desc; -			printk(KERN_INFO "T [0x%03X]    %016llX %016llX %016llX" -				" %04X  %p %016llX %p", i, +			if (i == tx_ring->next_to_use && +			    i == tx_ring->next_to_clean) +				next_desc = " NTC/U"; +			else if (i == tx_ring->next_to_use) +				next_desc = " NTU"; +			else if (i == tx_ring->next_to_clean) +				next_desc = " NTC"; +			else +				next_desc = ""; + +			pr_info("T [0x%03X]    %016llX %016llX %016llX" +				" %04X  %p %016llX %p%s\n", i,  				le64_to_cpu(u0->a),  				le64_to_cpu(u0->b),  				(u64)buffer_info->dma,  				buffer_info->length,  				buffer_info->next_to_watch,  				(u64)buffer_info->time_stamp, -				buffer_info->skb); -			if (i == tx_ring->next_to_use && -				i == tx_ring->next_to_clean) -				printk(KERN_CONT " NTC/U\n"); -			else if (i == tx_ring->next_to_use) -				printk(KERN_CONT " NTU\n"); -			else if (i == tx_ring->next_to_clean) -				printk(KERN_CONT " NTC\n"); -			else -				printk(KERN_CONT "\n"); +				buffer_info->skb, next_desc);  			if (netif_msg_pktdata(adapter) && buffer_info->dma != 0)  				print_hex_dump(KERN_INFO, "", @@ -456,11 +462,11 @@ static void igb_dump(struct igb_adapter *adapter)  	/* Print RX Rings Summary */  rx_ring_summary:  	dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); -	printk(KERN_INFO "Queue [NTU] [NTC]\n"); +	pr_info("Queue [NTU] [NTC]\n");  	for (n = 0; n < adapter->num_rx_queues; n++) {  		rx_ring = adapter->rx_ring[n]; -		printk(KERN_INFO " %5d %5X %5X\n", n, -			   rx_ring->next_to_use, rx_ring->next_to_clean); +		pr_info(" %5d %5X %5X\n", +			n, rx_ring->next_to_use, rx_ring->next_to_clean);  	}  	/* Print RX Rings */ @@ -492,36 +498,43 @@ rx_ring_summary:  	for (n = 0; n < adapter->num_rx_queues; n++) {  		rx_ring = adapter->rx_ring[n]; -		printk(KERN_INFO "------------------------------------\n"); -		printk(KERN_INFO "RX QUEUE INDEX = %d\n", rx_ring->queue_index); -		printk(KERN_INFO "------------------------------------\n"); -		printk(KERN_INFO "R  [desc]      [ PktBuf     A0] " -			"[  HeadBuf   DD] [bi->dma       ] [bi->skb] " -			"<-- Adv Rx Read format\n"); -		printk(KERN_INFO "RWB[desc]      [PcsmIpSHl PtRs] " -			"[vl er S cks ln] ---------------- [bi->skb] " -			"<-- Adv Rx Write-Back format\n"); +		pr_info("------------------------------------\n"); +		pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index); +		pr_info("------------------------------------\n"); +		pr_info("R  [desc]      [ PktBuf     A0] [  HeadBuf   DD] " +			"[bi->dma       ] [bi->skb] <-- Adv Rx Read format\n"); +		pr_info("RWB[desc]      [PcsmIpSHl PtRs] [vl er S cks ln] -----" +			"----------- [bi->skb] <-- Adv Rx Write-Back format\n");  		for (i = 0; i < rx_ring->count; i++) { +			const char *next_desc;  			struct igb_rx_buffer *buffer_info;  			buffer_info = &rx_ring->rx_buffer_info[i];  			rx_desc = IGB_RX_DESC(rx_ring, i);  			u0 = (struct my_u0 *)rx_desc;  			staterr = le32_to_cpu(rx_desc->wb.upper.status_error); + +			if (i == rx_ring->next_to_use) +				next_desc = " NTU"; +			else if (i == rx_ring->next_to_clean) +				next_desc = " NTC"; +			else +				next_desc = ""; +  			if (staterr & E1000_RXD_STAT_DD) {  				/* Descriptor Done */ -				printk(KERN_INFO "RWB[0x%03X]     %016llX " -					"%016llX ---------------- %p", i, +				pr_info("%s[0x%03X]     %016llX %016llX -------" +					"--------- %p%s\n", "RWB", i,  					le64_to_cpu(u0->a),  					le64_to_cpu(u0->b), -					buffer_info->skb); +					buffer_info->skb, next_desc);  			} else { -				printk(KERN_INFO "R  [0x%03X]     %016llX " -					"%016llX %016llX %p", i, +				pr_info("%s[0x%03X]     %016llX %016llX %016llX" +					" %p%s\n", "R  ", i,  					le64_to_cpu(u0->a),  					le64_to_cpu(u0->b),  					(u64)buffer_info->dma, -					buffer_info->skb); +					buffer_info->skb, next_desc);  				if (netif_msg_pktdata(adapter)) {  					print_hex_dump(KERN_INFO, "", @@ -538,14 +551,6 @@ rx_ring_summary:  					  PAGE_SIZE/2, true);  				}  			} - -			if (i == rx_ring->next_to_use) -				printk(KERN_CONT " NTU\n"); -			else if (i == rx_ring->next_to_clean) -				printk(KERN_CONT " NTC\n"); -			else -				printk(KERN_CONT "\n"); -  		}  	} @@ -599,10 +604,10 @@ struct net_device *igb_get_hw_dev(struct e1000_hw *hw)  static int __init igb_init_module(void)  {  	int ret; -	printk(KERN_INFO "%s - version %s\n", +	pr_info("%s - version %s\n",  	       igb_driver_string, igb_driver_version); -	printk(KERN_INFO "%s\n", igb_copyright); +	pr_info("%s\n", igb_copyright);  #ifdef CONFIG_IGB_DCA  	dca_register_notify(&dca_notifier); @@ -1502,6 +1507,7 @@ void igb_power_up_link(struct igb_adapter *adapter)  		igb_power_up_phy_copper(&adapter->hw);  	else  		igb_power_up_serdes_link_82575(&adapter->hw); +	igb_reset_phy(&adapter->hw);  }  /** @@ -1742,7 +1748,8 @@ void igb_reset(struct igb_adapter *adapter)  	igb_get_phy_info(hw);  } -static u32 igb_fix_features(struct net_device *netdev, u32 features) +static netdev_features_t igb_fix_features(struct net_device *netdev, +	netdev_features_t features)  {  	/*  	 * Since there is no support for separate rx/tx vlan accel @@ -1756,9 +1763,10 @@ static u32 igb_fix_features(struct net_device *netdev, u32 features)  	return features;  } -static int igb_set_features(struct net_device *netdev, u32 features) +static int igb_set_features(struct net_device *netdev, +	netdev_features_t features)  { -	u32 changed = netdev->features ^ features; +	netdev_features_t changed = netdev->features ^ features;  	if (changed & NETIF_F_HW_VLAN_RX)  		igb_vlan_mode(netdev, features); @@ -2113,6 +2121,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,  	default:  		break;  	} + +	pm_runtime_put_noidle(&pdev->dev);  	return 0;  err_register: @@ -2152,6 +2162,8 @@ static void __devexit igb_remove(struct pci_dev *pdev)  	struct igb_adapter *adapter = netdev_priv(netdev);  	struct e1000_hw *hw = &adapter->hw; +	pm_runtime_get_noresume(&pdev->dev); +  	/*  	 * The watchdog timer may be rescheduled, so explicitly  	 * disable watchdog from being rescheduled. @@ -2474,16 +2486,22 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)   * handler is registered with the OS, the watchdog timer is started,   * and the stack is notified that the interface is ready.   **/ -static int igb_open(struct net_device *netdev) +static int __igb_open(struct net_device *netdev, bool resuming)  {  	struct igb_adapter *adapter = netdev_priv(netdev);  	struct e1000_hw *hw = &adapter->hw; +	struct pci_dev *pdev = adapter->pdev;  	int err;  	int i;  	/* disallow open during test */ -	if (test_bit(__IGB_TESTING, &adapter->state)) +	if (test_bit(__IGB_TESTING, &adapter->state)) { +		WARN_ON(resuming);  		return -EBUSY; +	} + +	if (!resuming) +		pm_runtime_get_sync(&pdev->dev);  	netif_carrier_off(netdev); @@ -2529,6 +2547,9 @@ static int igb_open(struct net_device *netdev)  	netif_tx_start_all_queues(netdev); +	if (!resuming) +		pm_runtime_put(&pdev->dev); +  	/* start the watchdog. */  	hw->mac.get_link_status = 1;  	schedule_work(&adapter->watchdog_task); @@ -2543,10 +2564,17 @@ err_setup_rx:  	igb_free_all_tx_resources(adapter);  err_setup_tx:  	igb_reset(adapter); +	if (!resuming) +		pm_runtime_put(&pdev->dev);  	return err;  } +static int igb_open(struct net_device *netdev) +{ +	return __igb_open(netdev, false); +} +  /**   * igb_close - Disables a network interface   * @netdev: network interface device structure @@ -2558,21 +2586,32 @@ err_setup_tx:   * needs to be disabled.  A global MAC reset is issued to stop the   * hardware, and all transmit and receive resources are freed.   **/ -static int igb_close(struct net_device *netdev) +static int __igb_close(struct net_device *netdev, bool suspending)  {  	struct igb_adapter *adapter = netdev_priv(netdev); +	struct pci_dev *pdev = adapter->pdev;  	WARN_ON(test_bit(__IGB_RESETTING, &adapter->state)); -	igb_down(adapter); +	if (!suspending) +		pm_runtime_get_sync(&pdev->dev); + +	igb_down(adapter);  	igb_free_irq(adapter);  	igb_free_all_tx_resources(adapter);  	igb_free_all_rx_resources(adapter); +	if (!suspending) +		pm_runtime_put_sync(&pdev->dev);  	return 0;  } +static int igb_close(struct net_device *netdev) +{ +	return __igb_close(netdev, false); +} +  /**   * igb_setup_tx_resources - allocate Tx resources (Descriptors)   * @tx_ring: tx descriptor ring (for a specific queue) to setup @@ -3203,6 +3242,7 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring)  		buffer_info = &tx_ring->tx_buffer_info[i];  		igb_unmap_and_free_tx_resource(tx_ring, buffer_info);  	} +	netdev_tx_reset_queue(txring_txq(tx_ring));  	size = sizeof(struct igb_tx_buffer) * tx_ring->count;  	memset(tx_ring->tx_buffer_info, 0, size); @@ -3632,6 +3672,9 @@ static void igb_watchdog_task(struct work_struct *work)  	link = igb_has_link(adapter);  	if (link) { +		/* Cancel scheduled suspend requests. */ +		pm_runtime_resume(netdev->dev.parent); +  		if (!netif_carrier_ok(netdev)) {  			u32 ctrl;  			hw->mac.ops.get_speed_and_duplex(hw, @@ -3640,23 +3683,23 @@ static void igb_watchdog_task(struct work_struct *work)  			ctrl = rd32(E1000_CTRL);  			/* Links status message must follow this format */ -			printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s, " -				 "Flow Control: %s\n", +			printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s " +			       "Duplex, Flow Control: %s\n",  			       netdev->name,  			       adapter->link_speed,  			       adapter->link_duplex == FULL_DUPLEX ? -				 "Full Duplex" : "Half Duplex", -			       ((ctrl & E1000_CTRL_TFCE) && -			        (ctrl & E1000_CTRL_RFCE)) ? "RX/TX" : -			       ((ctrl & E1000_CTRL_RFCE) ?  "RX" : -			       ((ctrl & E1000_CTRL_TFCE) ?  "TX" : "None"))); +			       "Full" : "Half", +			       (ctrl & E1000_CTRL_TFCE) && +			       (ctrl & E1000_CTRL_RFCE) ? "RX/TX" : +			       (ctrl & E1000_CTRL_RFCE) ?  "RX" : +			       (ctrl & E1000_CTRL_TFCE) ?  "TX" : "None");  			/* check for thermal sensor event */ -			if (igb_thermal_sensor_event(hw, E1000_THSTAT_LINK_THROTTLE)) { -				printk(KERN_INFO "igb: %s The network adapter " -						 "link speed was downshifted " -						 "because it overheated.\n", -						 netdev->name); +			if (igb_thermal_sensor_event(hw, +			    E1000_THSTAT_LINK_THROTTLE)) { +				netdev_info(netdev, "The network adapter link " +					    "speed was downshifted because it " +					    "overheated\n");  			}  			/* adjust timeout factor according to speed/duplex */ @@ -3686,11 +3729,10 @@ static void igb_watchdog_task(struct work_struct *work)  			adapter->link_duplex = 0;  			/* check for thermal sensor event */ -			if (igb_thermal_sensor_event(hw, E1000_THSTAT_PWR_DOWN)) { -				printk(KERN_ERR "igb: %s The network adapter " -						"was stopped because it " -						"overheated.\n", -						netdev->name); +			if (igb_thermal_sensor_event(hw, +			    E1000_THSTAT_PWR_DOWN)) { +				netdev_err(netdev, "The network adapter was " +					   "stopped because it overheated\n");  			}  			/* Links status message must follow this format */ @@ -3704,6 +3746,9 @@ static void igb_watchdog_task(struct work_struct *work)  			if (!test_bit(__IGB_DOWN, &adapter->state))  				mod_timer(&adapter->phy_info_timer,  					  round_jiffies(jiffies + 2 * HZ)); + +			pm_schedule_suspend(netdev->dev.parent, +					    MSEC_PER_SEC * 5);  		}  	} @@ -4241,6 +4286,8 @@ static void igb_tx_map(struct igb_ring *tx_ring,  		frag++;  	} +	netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount); +  	/* write last descriptor with RS and EOP bits */  	cmd_type |= cpu_to_le32(size) | cpu_to_le32(IGB_TXD_DCMD);  	tx_desc->read.cmd_type_len = cmd_type; @@ -5780,6 +5827,8 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)  		}  	} +	netdev_tx_completed_queue(txring_txq(tx_ring), +				  total_packets, total_bytes);  	i += tx_ring->count;  	tx_ring->next_to_clean = i;  	u64_stats_update_begin(&tx_ring->tx_syncp); @@ -6138,7 +6187,7 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,  		return true;  	if (!page) { -		page = netdev_alloc_page(rx_ring->netdev); +		page = alloc_page(GFP_ATOMIC | __GFP_COLD);  		bi->page = page;  		if (unlikely(!page)) {  			rx_ring->rx_stats.alloc_failed++; @@ -6467,7 +6516,7 @@ s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)  	return 0;  } -static void igb_vlan_mode(struct net_device *netdev, u32 features) +static void igb_vlan_mode(struct net_device *netdev, netdev_features_t features)  {  	struct igb_adapter *adapter = netdev_priv(netdev);  	struct e1000_hw *hw = &adapter->hw; @@ -6494,7 +6543,7 @@ static void igb_vlan_mode(struct net_device *netdev, u32 features)  	igb_rlpml_set(adapter);  } -static void igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid) +static int igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid)  {  	struct igb_adapter *adapter = netdev_priv(netdev);  	struct e1000_hw *hw = &adapter->hw; @@ -6507,9 +6556,11 @@ static void igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid)  	igb_vfta_set(hw, vid, true);  	set_bit(vid, adapter->active_vlans); + +	return 0;  } -static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) +static int igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)  {  	struct igb_adapter *adapter = netdev_priv(netdev);  	struct e1000_hw *hw = &adapter->hw; @@ -6524,6 +6575,8 @@ static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)  		igb_vfta_set(hw, vid, false);  	clear_bit(vid, adapter->active_vlans); + +	return 0;  }  static void igb_restore_vlan(struct igb_adapter *adapter) @@ -6582,13 +6635,14 @@ err_inval:  	return -EINVAL;  } -static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake) +static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake, +			  bool runtime)  {  	struct net_device *netdev = pci_get_drvdata(pdev);  	struct igb_adapter *adapter = netdev_priv(netdev);  	struct e1000_hw *hw = &adapter->hw;  	u32 ctrl, rctl, status; -	u32 wufc = adapter->wol; +	u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;  #ifdef CONFIG_PM  	int retval = 0;  #endif @@ -6596,7 +6650,7 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)  	netif_device_detach(netdev);  	if (netif_running(netdev)) -		igb_close(netdev); +		__igb_close(netdev, true);  	igb_clear_interrupt_scheme(adapter); @@ -6655,12 +6709,13 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)  }  #ifdef CONFIG_PM -static int igb_suspend(struct pci_dev *pdev, pm_message_t state) +static int igb_suspend(struct device *dev)  {  	int retval;  	bool wake; +	struct pci_dev *pdev = to_pci_dev(dev); -	retval = __igb_shutdown(pdev, &wake); +	retval = __igb_shutdown(pdev, &wake, 0);  	if (retval)  		return retval; @@ -6674,8 +6729,9 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)  	return 0;  } -static int igb_resume(struct pci_dev *pdev) +static int igb_resume(struct device *dev)  { +	struct pci_dev *pdev = to_pci_dev(dev);  	struct net_device *netdev = pci_get_drvdata(pdev);  	struct igb_adapter *adapter = netdev_priv(netdev);  	struct e1000_hw *hw = &adapter->hw; @@ -6696,7 +6752,18 @@ static int igb_resume(struct pci_dev *pdev)  	pci_enable_wake(pdev, PCI_D3hot, 0);  	pci_enable_wake(pdev, PCI_D3cold, 0); -	if (igb_init_interrupt_scheme(adapter)) { +	if (!rtnl_is_locked()) { +		/* +		 * shut up ASSERT_RTNL() warning in +		 * netif_set_real_num_tx/rx_queues. +		 */ +		rtnl_lock(); +		err = igb_init_interrupt_scheme(adapter); +		rtnl_unlock(); +	} else { +		err = igb_init_interrupt_scheme(adapter); +	} +	if (err) {  		dev_err(&pdev->dev, "Unable to allocate memory for queues\n");  		return -ENOMEM;  	} @@ -6709,23 +6776,61 @@ static int igb_resume(struct pci_dev *pdev)  	wr32(E1000_WUS, ~0); -	if (netif_running(netdev)) { -		err = igb_open(netdev); +	if (netdev->flags & IFF_UP) { +		err = __igb_open(netdev, true);  		if (err)  			return err;  	}  	netif_device_attach(netdev); +	return 0; +} + +#ifdef CONFIG_PM_RUNTIME +static int igb_runtime_idle(struct device *dev) +{ +	struct pci_dev *pdev = to_pci_dev(dev); +	struct net_device *netdev = pci_get_drvdata(pdev); +	struct igb_adapter *adapter = netdev_priv(netdev); + +	if (!igb_has_link(adapter)) +		pm_schedule_suspend(dev, MSEC_PER_SEC * 5); + +	return -EBUSY; +} + +static int igb_runtime_suspend(struct device *dev) +{ +	struct pci_dev *pdev = to_pci_dev(dev); +	int retval; +	bool wake; + +	retval = __igb_shutdown(pdev, &wake, 1); +	if (retval) +		return retval; + +	if (wake) { +		pci_prepare_to_sleep(pdev); +	} else { +		pci_wake_from_d3(pdev, false); +		pci_set_power_state(pdev, PCI_D3hot); +	}  	return 0;  } + +static int igb_runtime_resume(struct device *dev) +{ +	return igb_resume(dev); +} +#endif /* CONFIG_PM_RUNTIME */  #endif  static void igb_shutdown(struct pci_dev *pdev)  {  	bool wake; -	__igb_shutdown(pdev, &wake); +	__igb_shutdown(pdev, &wake, 0);  	if (system_state == SYSTEM_POWER_OFF) {  		pci_wake_from_d3(pdev, wake); @@ -7064,15 +7169,28 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)  			wr32(E1000_DMCTXTH, 0);  			/* -			 * DMA Coalescing high water mark needs to be higher -			 * than the RX threshold. set hwm to PBA -  2 * max -			 * frame size +			 * DMA Coalescing high water mark needs to be greater +			 * than the Rx threshold. Set hwm to PBA - max frame +			 * size in 16B units, capping it at PBA - 6KB.  			 */ -			hwm = pba - (2 * adapter->max_frame_size); +			hwm = 64 * pba - adapter->max_frame_size / 16; +			if (hwm < 64 * (pba - 6)) +				hwm = 64 * (pba - 6); +			reg = rd32(E1000_FCRTC); +			reg &= ~E1000_FCRTC_RTH_COAL_MASK; +			reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT) +				& E1000_FCRTC_RTH_COAL_MASK); +			wr32(E1000_FCRTC, reg); + +			/* +			 * Set the DMA Coalescing Rx threshold to PBA - 2 * max +			 * frame size, capping it at PBA - 10KB. +			 */ +			dmac_thr = pba - adapter->max_frame_size / 512; +			if (dmac_thr < pba - 10) +				dmac_thr = pba - 10;  			reg = rd32(E1000_DMACR);  			reg &= ~E1000_DMACR_DMACTHR_MASK; -			dmac_thr = pba - 4; -  			reg |= ((dmac_thr << E1000_DMACR_DMACTHR_SHIFT)  				& E1000_DMACR_DMACTHR_MASK); @@ -7088,7 +7206,6 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)  			 * coalescing(smart fifb)-UTRESH=0  			 */  			wr32(E1000_DMCRTRH, 0); -			wr32(E1000_FCRTC, hwm);  			reg = (IGB_DMCTLX_DCFLUSH_DIS | 0x4);  |