diff options
Diffstat (limited to 'drivers/net/r8169.c')
| -rw-r--r-- | drivers/net/r8169.c | 91 | 
1 files changed, 63 insertions, 28 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index bde7d61f1930..7ffdb80adf40 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -25,6 +25,7 @@  #include <linux/dma-mapping.h>  #include <linux/pm_runtime.h>  #include <linux/firmware.h> +#include <linux/pci-aspm.h>  #include <asm/system.h>  #include <asm/io.h> @@ -617,8 +618,9 @@ static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data)  	}  } -static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd) +static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)  { +	void __iomem *ioaddr = tp->mmio_addr;  	int i;  	RTL_W8(ERIDR, cmd); @@ -630,7 +632,7 @@ static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd)  			break;  	} -	ocp_write(ioaddr, 0x1, 0x30, 0x00000001); +	ocp_write(tp, 0x1, 0x30, 0x00000001);  }  #define OOB_CMD_RESET		0x00 @@ -973,7 +975,8 @@ static void __rtl8169_check_link_status(struct net_device *dev,  		if (pm)  			pm_request_resume(&tp->pci_dev->dev);  		netif_carrier_on(dev); -		netif_info(tp, ifup, dev, "link up\n"); +		if (net_ratelimit()) +			netif_info(tp, ifup, dev, "link up\n");  	} else {  		netif_carrier_off(dev);  		netif_info(tp, ifdown, dev, "link down\n"); @@ -2867,8 +2870,11 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)  {  	void __iomem *ioaddr = tp->mmio_addr; -	if (tp->mac_version == RTL_GIGA_MAC_VER_27) +	if (((tp->mac_version == RTL_GIGA_MAC_VER_27) || +	     (tp->mac_version == RTL_GIGA_MAC_VER_28)) && +	    (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) {  		return; +	}  	if (((tp->mac_version == RTL_GIGA_MAC_VER_23) ||  	     (tp->mac_version == RTL_GIGA_MAC_VER_24)) && @@ -2890,6 +2896,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)  	switch (tp->mac_version) {  	case RTL_GIGA_MAC_VER_25:  	case RTL_GIGA_MAC_VER_26: +	case RTL_GIGA_MAC_VER_27: +	case RTL_GIGA_MAC_VER_28:  		RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80);  		break;  	} @@ -2899,12 +2907,17 @@ static void r8168_pll_power_up(struct rtl8169_private *tp)  {  	void __iomem *ioaddr = tp->mmio_addr; -	if (tp->mac_version == RTL_GIGA_MAC_VER_27) +	if (((tp->mac_version == RTL_GIGA_MAC_VER_27) || +	     (tp->mac_version == RTL_GIGA_MAC_VER_28)) && +	    (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) {  		return; +	}  	switch (tp->mac_version) {  	case RTL_GIGA_MAC_VER_25:  	case RTL_GIGA_MAC_VER_26: +	case RTL_GIGA_MAC_VER_27: +	case RTL_GIGA_MAC_VER_28:  		RTL_W8(PMCH, RTL_R8(PMCH) | 0x80);  		break;  	} @@ -3008,6 +3021,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)  	mii->reg_num_mask = 0x1f;  	mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII); +	/* disable ASPM completely as that cause random device stop working +	 * problems as well as full system hangs for some PCIe devices users */ +	pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | +				     PCIE_LINK_STATE_CLKPM); +  	/* enable device (incl. PCI PM wakeup and hotplug setup) */  	rc = pci_enable_device(pdev);  	if (rc < 0) { @@ -3041,7 +3059,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)  		goto err_out_mwi_2;  	} -	tp->cp_cmd = PCIMulRW | RxChkSum; +	tp->cp_cmd = RxChkSum;  	if ((sizeof(dma_addr_t) > 4) &&  	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) { @@ -3189,6 +3207,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)  	if (pci_dev_run_wake(pdev))  		pm_runtime_put_noidle(&pdev->dev); +	netif_carrier_off(dev); +  out:  	return rc; @@ -3315,7 +3335,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)  	/* Disable interrupts */  	rtl8169_irq_mask_and_ack(ioaddr); -	if (tp->mac_version == RTL_GIGA_MAC_VER_28) { +	if (tp->mac_version == RTL_GIGA_MAC_VER_27 || +	    tp->mac_version == RTL_GIGA_MAC_VER_28) {  		while (RTL_R8(TxPoll) & NPQ)  			udelay(20); @@ -3757,7 +3778,8 @@ static void rtl_hw_start_8168(struct net_device *dev)  	RTL_W16(IntrMitigate, 0x5151);  	/* Work around for RxFIFO overflow. */ -	if (tp->mac_version == RTL_GIGA_MAC_VER_11) { +	if (tp->mac_version == RTL_GIGA_MAC_VER_11 || +	    tp->mac_version == RTL_GIGA_MAC_VER_22) {  		tp->intr_event |= RxFIFOOver | PCSTimeout;  		tp->intr_event &= ~RxOverflow;  	} @@ -3843,8 +3865,7 @@ static void rtl_hw_start_8168(struct net_device *dev)  	Cxpl_dbg_sel | \  	ASF | \  	PktCntrDisable | \ -	PCIDAC | \ -	PCIMulRW) +	Mac_dbgo_sel)  static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)  { @@ -3874,8 +3895,6 @@ static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)  	if ((cfg1 & LEDS0) && (cfg1 & LEDS1))  		RTL_W8(Config1, cfg1 & ~LEDS0); -	RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); -  	rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));  } @@ -3887,8 +3906,6 @@ static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev)  	RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable);  	RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); - -	RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);  }  static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev) @@ -3914,6 +3931,8 @@ static void rtl_hw_start_8101(struct net_device *dev)  		}  	} +	RTL_W8(Cfg9346, Cfg9346_Unlock); +  	switch (tp->mac_version) {  	case RTL_GIGA_MAC_VER_07:  		rtl_hw_start_8102e_1(ioaddr, pdev); @@ -3928,14 +3947,13 @@ static void rtl_hw_start_8101(struct net_device *dev)  		break;  	} -	RTL_W8(Cfg9346, Cfg9346_Unlock); +	RTL_W8(Cfg9346, Cfg9346_Lock);  	RTL_W8(MaxTxPacketSize, TxPacketMax);  	rtl_set_rx_max_size(ioaddr, rx_buf_sz); -	tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; - +	tp->cp_cmd &= ~R810X_CPCMD_QUIRK_MASK;  	RTL_W16(CPlusCmd, tp->cp_cmd);  	RTL_W16(IntrMitigate, 0x0000); @@ -3945,14 +3963,10 @@ static void rtl_hw_start_8101(struct net_device *dev)  	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);  	rtl_set_rx_tx_config_registers(tp); -	RTL_W8(Cfg9346, Cfg9346_Lock); -  	RTL_R8(IntrMask);  	rtl_set_rx_mode(dev); -	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); -  	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000);  	RTL_W16(IntrMask, tp->intr_event); @@ -4639,12 +4653,33 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)  			break;  		} -		/* Work around for rx fifo overflow */ -		if (unlikely(status & RxFIFOOver) && -		(tp->mac_version == RTL_GIGA_MAC_VER_11)) { -			netif_stop_queue(dev); -			rtl8169_tx_timeout(dev); -			break; +		if (unlikely(status & RxFIFOOver)) { +			switch (tp->mac_version) { +			/* Work around for rx fifo overflow */ +			case RTL_GIGA_MAC_VER_11: +			case RTL_GIGA_MAC_VER_22: +			case RTL_GIGA_MAC_VER_26: +				netif_stop_queue(dev); +				rtl8169_tx_timeout(dev); +				goto done; +			/* Testers needed. */ +			case RTL_GIGA_MAC_VER_17: +			case RTL_GIGA_MAC_VER_19: +			case RTL_GIGA_MAC_VER_20: +			case RTL_GIGA_MAC_VER_21: +			case RTL_GIGA_MAC_VER_23: +			case RTL_GIGA_MAC_VER_24: +			case RTL_GIGA_MAC_VER_27: +			case RTL_GIGA_MAC_VER_28: +			/* Experimental science. Pktgen proof. */ +			case RTL_GIGA_MAC_VER_12: +			case RTL_GIGA_MAC_VER_25: +				if (status == RxFIFOOver) +					goto done; +				break; +			default: +				break; +			}  		}  		if (unlikely(status & SYSErr)) { @@ -4680,7 +4715,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)  			(status & RxFIFOOver) ? (status | RxOverflow) : status);  		status = RTL_R16(IntrStatus);  	} - +done:  	return IRQ_RETVAL(handled);  }  | 
