diff options
| author | Patrick McHardy <kaber@trash.net> | 2010-05-10 18:39:28 +0200 | 
|---|---|---|
| committer | Patrick McHardy <kaber@trash.net> | 2010-05-10 18:39:28 +0200 | 
| commit | 1e4b1057121bc756b91758a434b504d2010f6088 (patch) | |
| tree | b016cf2c728289c7e36d9e4e488f30ab0bd0ae6e /drivers/net/e1000e/netdev.c | |
| parent | 3b254c54ec46eb022cb26ee6ab37fae23f5f7d6a (diff) | |
| parent | 3ee943728fff536edaf8f59faa58aaa1aa7366e3 (diff) | |
| download | olio-linux-3.10-1e4b1057121bc756b91758a434b504d2010f6088.tar.xz olio-linux-3.10-1e4b1057121bc756b91758a434b504d2010f6088.zip  | |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
	net/bridge/br_device.c
	net/bridge/br_forward.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
| -rw-r--r-- | drivers/net/e1000e/netdev.c | 627 | 
1 files changed, 506 insertions, 121 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 5f70c437fa4..c5f65a29865 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -52,7 +52,7 @@  #include "e1000.h" -#define DRV_VERSION "1.0.2-k2" +#define DRV_VERSION "1.0.2-k4"  char e1000e_driver_name[] = "e1000e";  const char e1000e_driver_version[] = DRV_VERSION; @@ -69,6 +69,361 @@ static const struct e1000_info *e1000_info_tbl[] = {  	[board_pchlan]		= &e1000_pch_info,  }; +struct e1000_reg_info { +	u32 ofs; +	char *name; +}; + +#define E1000_RDFH	0x02410 /* Rx Data FIFO Head - RW */ +#define E1000_RDFT	0x02418 /* Rx Data FIFO Tail - RW */ +#define E1000_RDFHS	0x02420 /* Rx Data FIFO Head Saved - RW */ +#define E1000_RDFTS	0x02428 /* Rx Data FIFO Tail Saved - RW */ +#define E1000_RDFPC	0x02430 /* Rx Data FIFO Packet Count - RW */ + +#define E1000_TDFH	0x03410 /* Tx Data FIFO Head - RW */ +#define E1000_TDFT	0x03418 /* Tx Data FIFO Tail - RW */ +#define E1000_TDFHS	0x03420 /* Tx Data FIFO Head Saved - RW */ +#define E1000_TDFTS	0x03428 /* Tx Data FIFO Tail Saved - RW */ +#define E1000_TDFPC	0x03430 /* Tx Data FIFO Packet Count - RW */ + +static const struct e1000_reg_info e1000_reg_info_tbl[] = { + +	/* General Registers */ +	{E1000_CTRL, "CTRL"}, +	{E1000_STATUS, "STATUS"}, +	{E1000_CTRL_EXT, "CTRL_EXT"}, + +	/* Interrupt Registers */ +	{E1000_ICR, "ICR"}, + +	/* RX Registers */ +	{E1000_RCTL, "RCTL"}, +	{E1000_RDLEN, "RDLEN"}, +	{E1000_RDH, "RDH"}, +	{E1000_RDT, "RDT"}, +	{E1000_RDTR, "RDTR"}, +	{E1000_RXDCTL(0), "RXDCTL"}, +	{E1000_ERT, "ERT"}, +	{E1000_RDBAL, "RDBAL"}, +	{E1000_RDBAH, "RDBAH"}, +	{E1000_RDFH, "RDFH"}, +	{E1000_RDFT, "RDFT"}, +	{E1000_RDFHS, "RDFHS"}, +	{E1000_RDFTS, "RDFTS"}, +	{E1000_RDFPC, "RDFPC"}, + +	/* TX Registers */ +	{E1000_TCTL, "TCTL"}, +	{E1000_TDBAL, "TDBAL"}, +	{E1000_TDBAH, "TDBAH"}, +	{E1000_TDLEN, "TDLEN"}, +	{E1000_TDH, "TDH"}, +	{E1000_TDT, "TDT"}, +	{E1000_TIDV, "TIDV"}, +	{E1000_TXDCTL(0), "TXDCTL"}, +	{E1000_TADV, "TADV"}, +	{E1000_TARC(0), "TARC"}, +	{E1000_TDFH, "TDFH"}, +	{E1000_TDFT, "TDFT"}, +	{E1000_TDFHS, "TDFHS"}, +	{E1000_TDFTS, "TDFTS"}, +	{E1000_TDFPC, "TDFPC"}, + +	/* List Terminator */ +	{} +}; + +/* + * e1000_regdump - register printout routine + */ +static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo) +{ +	int n = 0; +	char rname[16]; +	u32 regs[8]; + +	switch (reginfo->ofs) { +	case E1000_RXDCTL(0): +		for (n = 0; n < 2; n++) +			regs[n] = __er32(hw, E1000_RXDCTL(n)); +		break; +	case E1000_TXDCTL(0): +		for (n = 0; n < 2; n++) +			regs[n] = __er32(hw, E1000_TXDCTL(n)); +		break; +	case E1000_TARC(0): +		for (n = 0; n < 2; n++) +			regs[n] = __er32(hw, E1000_TARC(n)); +		break; +	default: +		printk(KERN_INFO "%-15s %08x\n", +			reginfo->name, __er32(hw, reginfo->ofs)); +		return; +	} + +	snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]"); +	printk(KERN_INFO "%-15s ", rname); +	for (n = 0; n < 2; n++) +		printk(KERN_CONT "%08x ", regs[n]); +	printk(KERN_CONT "\n"); +} + + +/* + * e1000e_dump - Print registers, tx-ring and rx-ring + */ +static void e1000e_dump(struct e1000_adapter *adapter) +{ +	struct net_device *netdev = adapter->netdev; +	struct e1000_hw *hw = &adapter->hw; +	struct e1000_reg_info *reginfo; +	struct e1000_ring *tx_ring = adapter->tx_ring; +	struct e1000_tx_desc *tx_desc; +	struct my_u0 { u64 a; u64 b; } *u0; +	struct e1000_buffer *buffer_info; +	struct e1000_ring *rx_ring = adapter->rx_ring; +	union e1000_rx_desc_packet_split *rx_desc_ps; +	struct e1000_rx_desc *rx_desc; +	struct my_u1 { u64 a; u64 b; u64 c; u64 d; } *u1; +	u32 staterr; +	int i = 0; + +	if (!netif_msg_hw(adapter)) +		return; + +	/* 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); +	} + +	/* Print Registers */ +	dev_info(&adapter->pdev->dev, "Register Dump\n"); +	printk(KERN_INFO " Register Name   Value\n"); +	for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl; +	     reginfo->name; reginfo++) { +		e1000_regdump(hw, reginfo); +	} + +	/* Print TX Ring Summary */ +	if (!netdev || !netif_running(netdev)) +		goto exit; + +	dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); +	printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma  ]" +		" leng ntw timestamp\n"); +	buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean]; +	printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n", +		0, 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 */ +	if (!netif_msg_tx_done(adapter)) +		goto rx_ring_summary; + +	dev_info(&adapter->pdev->dev, "TX Rings Dump\n"); + +	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended) +	 * +	 * Legacy Transmit Descriptor +	 *   +--------------------------------------------------------------+ +	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       | +	 *   +--------------------------------------------------------------+ +	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  | +	 *   +--------------------------------------------------------------+ +	 *   63       48 47        36 35    32 31     24 23    16 15        0 +	 * +	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload +	 *   63      48 47    40 39       32 31             16 15    8 7      0 +	 *   +----------------------------------------------------------------+ +	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS | +	 *   +----------------------------------------------------------------+ +	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      | +	 *   +----------------------------------------------------------------+ +	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0 +	 * +	 * Extended Data Descriptor (DTYP=0x1) +	 *   +----------------------------------------------------------------+ +	 * 0 |                     Buffer Address [63:0]                      | +	 *   +----------------------------------------------------------------+ +	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  | +	 *   +----------------------------------------------------------------+ +	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0 +	 */ +	printk(KERN_INFO "Tl[desc]     [address 63:0  ] [SpeCssSCmCsLen]" +		" [bi->dma       ] leng  ntw timestamp        bi->skb " +		"<-- Legacy format\n"); +	printk(KERN_INFO "Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen]" +		" [bi->dma       ] leng  ntw timestamp        bi->skb " +		"<-- Ext Context format\n"); +	printk(KERN_INFO "Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen]" +		" [bi->dma       ] leng  ntw timestamp        bi->skb " +		"<-- Ext Data format\n"); +	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { +		tx_desc = E1000_TX_DESC(*tx_ring, i); +		buffer_info = &tx_ring->buffer_info[i]; +		u0 = (struct my_u0 *)tx_desc; +		printk(KERN_INFO "T%c[0x%03X]    %016llX %016llX %016llX " +			"%04X  %3X %016llX %p", +		       (!(le64_to_cpu(u0->b) & (1<<29)) ? 'l' : +			((le64_to_cpu(u0->b) & (1<<20)) ? 'd' : 'c')), 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"); + +		if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) +			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, +					16, 1, phys_to_virt(buffer_info->dma), +					buffer_info->length, true); +	} + +	/* Print RX Rings Summary */ +rx_ring_summary: +	dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); +	printk(KERN_INFO "Queue [NTU] [NTC]\n"); +	printk(KERN_INFO " %5d %5X %5X\n", 0, +		rx_ring->next_to_use, rx_ring->next_to_clean); + +	/* Print RX Rings */ +	if (!netif_msg_rx_status(adapter)) +		goto exit; + +	dev_info(&adapter->pdev->dev, "RX Rings Dump\n"); +	switch (adapter->rx_ps_pages) { +	case 1: +	case 2: +	case 3: +		/* [Extended] Packet Split Receive Descriptor Format +		 * +		 *    +-----------------------------------------------------+ +		 *  0 |                Buffer Address 0 [63:0]              | +		 *    +-----------------------------------------------------+ +		 *  8 |                Buffer Address 1 [63:0]              | +		 *    +-----------------------------------------------------+ +		 * 16 |                Buffer Address 2 [63:0]              | +		 *    +-----------------------------------------------------+ +		 * 24 |                Buffer Address 3 [63:0]              | +		 *    +-----------------------------------------------------+ +		 */ +		printk(KERN_INFO "R  [desc]      [buffer 0 63:0 ] " +			"[buffer 1 63:0 ] " +		       "[buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma       ] " +		       "[bi->skb] <-- Ext Pkt Split format\n"); +		/* [Extended] Receive Descriptor (Write-Back) Format +		 * +		 *   63       48 47    32 31     13 12    8 7    4 3        0 +		 *   +------------------------------------------------------+ +		 * 0 | Packet   | IP     |  Rsvd   | MRQ   | Rsvd | MRQ RSS | +		 *   | Checksum | Ident  |         | Queue |      |  Type   | +		 *   +------------------------------------------------------+ +		 * 8 | VLAN Tag | Length | Extended Error | Extended Status | +		 *   +------------------------------------------------------+ +		 *   63       48 47    32 31            20 19               0 +		 */ +		printk(KERN_INFO "RWB[desc]      [ck ipid mrqhsh] " +			"[vl   l0 ee  es] " +		       "[ l3  l2  l1 hs] [reserved      ] ---------------- " +		       "[bi->skb] <-- Ext Rx Write-Back format\n"); +		for (i = 0; i < rx_ring->count; i++) { +			buffer_info = &rx_ring->buffer_info[i]; +			rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i); +			u1 = (struct my_u1 *)rx_desc_ps; +			staterr = +				le32_to_cpu(rx_desc_ps->wb.middle.status_error); +			if (staterr & E1000_RXD_STAT_DD) { +				/* Descriptor Done */ +				printk(KERN_INFO "RWB[0x%03X]     %016llX " +					"%016llX %016llX %016llX " +					"---------------- %p", i, +					le64_to_cpu(u1->a), +					le64_to_cpu(u1->b), +					le64_to_cpu(u1->c), +					le64_to_cpu(u1->d), +					buffer_info->skb); +			} else { +				printk(KERN_INFO "R  [0x%03X]     %016llX " +					"%016llX %016llX %016llX %016llX %p", i, +					le64_to_cpu(u1->a), +					le64_to_cpu(u1->b), +					le64_to_cpu(u1->c), +					le64_to_cpu(u1->d), +					(u64)buffer_info->dma, +					buffer_info->skb); + +				if (netif_msg_pktdata(adapter)) +					print_hex_dump(KERN_INFO, "", +						DUMP_PREFIX_ADDRESS, 16, 1, +						phys_to_virt(buffer_info->dma), +						adapter->rx_ps_bsize0, 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"); +		} +		break; +	default: +	case 0: +		/* Legacy Receive Descriptor Format +		 * +		 * +-----------------------------------------------------+ +		 * |                Buffer Address [63:0]                | +		 * +-----------------------------------------------------+ +		 * | VLAN Tag | Errors | Status 0 | Packet csum | Length | +		 * +-----------------------------------------------------+ +		 * 63       48 47    40 39      32 31         16 15      0 +		 */ +		printk(KERN_INFO "Rl[desc]     [address 63:0  ] " +			"[vl er S cks ln] [bi->dma       ] [bi->skb] " +			"<-- Legacy format\n"); +		for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) { +			rx_desc = E1000_RX_DESC(*rx_ring, i); +			buffer_info = &rx_ring->buffer_info[i]; +			u0 = (struct my_u0 *)rx_desc; +			printk(KERN_INFO "Rl[0x%03X]    %016llX %016llX " +				"%016llX %p", +				i, le64_to_cpu(u0->a), le64_to_cpu(u0->b), +				(u64)buffer_info->dma, buffer_info->skb); +			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"); + +			if (netif_msg_pktdata(adapter)) +				print_hex_dump(KERN_INFO, "", +					DUMP_PREFIX_ADDRESS, +					16, 1, phys_to_virt(buffer_info->dma), +					adapter->rx_buffer_len, true); +		} +	} + +exit: +	return; +} +  /**   * e1000_desc_unused - calculate if we have unused descriptors   **/ @@ -181,10 +536,10 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,  		buffer_info->skb = skb;  map_skb: -		buffer_info->dma = pci_map_single(pdev, skb->data, +		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,  						  adapter->rx_buffer_len, -						  PCI_DMA_FROMDEVICE); -		if (pci_dma_mapping_error(pdev, buffer_info->dma)) { +						  DMA_FROM_DEVICE); +		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {  			dev_err(&pdev->dev, "RX DMA map failed\n");  			adapter->rx_dma_failed++;  			break; @@ -193,26 +548,23 @@ map_skb:  		rx_desc = E1000_RX_DESC(*rx_ring, i);  		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); +		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) { +			/* +			 * Force memory writes to complete before letting h/w +			 * know there are new descriptors to fetch.  (Only +			 * applicable for weak-ordered memory model archs, +			 * such as IA-64). +			 */ +			wmb(); +			writel(i, adapter->hw.hw_addr + rx_ring->tail); +		}  		i++;  		if (i == rx_ring->count)  			i = 0;  		buffer_info = &rx_ring->buffer_info[i];  	} -	if (rx_ring->next_to_use != i) { -		rx_ring->next_to_use = i; -		if (i-- == 0) -			i = (rx_ring->count - 1); - -		/* -		 * Force memory writes to complete before letting h/w -		 * know there are new descriptors to fetch.  (Only -		 * applicable for weak-ordered memory model archs, -		 * such as IA-64). -		 */ -		wmb(); -		writel(i, adapter->hw.hw_addr + rx_ring->tail); -	} +	rx_ring->next_to_use = i;  }  /** @@ -250,11 +602,12 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,  					adapter->alloc_rx_buff_failed++;  					goto no_buffers;  				} -				ps_page->dma = pci_map_page(pdev, -						   ps_page->page, -						   0, PAGE_SIZE, -						   PCI_DMA_FROMDEVICE); -				if (pci_dma_mapping_error(pdev, ps_page->dma)) { +				ps_page->dma = dma_map_page(&pdev->dev, +							    ps_page->page, +							    0, PAGE_SIZE, +							    DMA_FROM_DEVICE); +				if (dma_mapping_error(&pdev->dev, +						      ps_page->dma)) {  					dev_err(&adapter->pdev->dev,  					  "RX DMA page map failed\n");  					adapter->rx_dma_failed++; @@ -279,10 +632,10 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,  		}  		buffer_info->skb = skb; -		buffer_info->dma = pci_map_single(pdev, skb->data, +		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,  						  adapter->rx_ps_bsize0, -						  PCI_DMA_FROMDEVICE); -		if (pci_dma_mapping_error(pdev, buffer_info->dma)) { +						  DMA_FROM_DEVICE); +		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {  			dev_err(&pdev->dev, "RX DMA map failed\n");  			adapter->rx_dma_failed++;  			/* cleanup skb */ @@ -293,6 +646,17 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,  		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma); +		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) { +			/* +			 * Force memory writes to complete before letting h/w +			 * know there are new descriptors to fetch.  (Only +			 * applicable for weak-ordered memory model archs, +			 * such as IA-64). +			 */ +			wmb(); +			writel(i<<1, adapter->hw.hw_addr + rx_ring->tail); +		} +  		i++;  		if (i == rx_ring->count)  			i = 0; @@ -300,26 +664,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,  	}  no_buffers: -	if (rx_ring->next_to_use != i) { -		rx_ring->next_to_use = i; - -		if (!(i--)) -			i = (rx_ring->count - 1); - -		/* -		 * Force memory writes to complete before letting h/w -		 * know there are new descriptors to fetch.  (Only -		 * applicable for weak-ordered memory model archs, -		 * such as IA-64). -		 */ -		wmb(); -		/* -		 * Hardware increments by 16 bytes, but packet split -		 * descriptors are 32 bytes...so we increment tail -		 * twice as much. -		 */ -		writel(i<<1, adapter->hw.hw_addr + rx_ring->tail); -	} +	rx_ring->next_to_use = i;  }  /** @@ -369,10 +714,10 @@ check_page:  		}  		if (!buffer_info->dma) -			buffer_info->dma = pci_map_page(pdev, +			buffer_info->dma = dma_map_page(&pdev->dev,  			                                buffer_info->page, 0,  			                                PAGE_SIZE, -			                                PCI_DMA_FROMDEVICE); +							DMA_FROM_DEVICE);  		rx_desc = E1000_RX_DESC(*rx_ring, i);  		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); @@ -446,10 +791,10 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,  		cleaned = 1;  		cleaned_count++; -		pci_unmap_single(pdev, +		dma_unmap_single(&pdev->dev,  				 buffer_info->dma,  				 adapter->rx_buffer_len, -				 PCI_DMA_FROMDEVICE); +				 DMA_FROM_DEVICE);  		buffer_info->dma = 0;  		length = le16_to_cpu(rx_desc->length); @@ -550,12 +895,11 @@ static void e1000_put_txbuf(struct e1000_adapter *adapter,  {  	if (buffer_info->dma) {  		if (buffer_info->mapped_as_page) -			pci_unmap_page(adapter->pdev, buffer_info->dma, -				       buffer_info->length, PCI_DMA_TODEVICE); +			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma, +				       buffer_info->length, DMA_TO_DEVICE);  		else -			pci_unmap_single(adapter->pdev,	buffer_info->dma, -					 buffer_info->length, -					 PCI_DMA_TODEVICE); +			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma, +					 buffer_info->length, DMA_TO_DEVICE);  		buffer_info->dma = 0;  	}  	if (buffer_info->skb) { @@ -646,14 +990,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)  			cleaned = (i == eop);  			if (cleaned) { -				struct sk_buff *skb = buffer_info->skb; -				unsigned int segs, bytecount; -				segs = skb_shinfo(skb)->gso_segs ?: 1; -				/* multiply data chunks by size of headers */ -				bytecount = ((segs - 1) * skb_headlen(skb)) + -					    skb->len; -				total_tx_packets += segs; -				total_tx_bytes += bytecount; +				total_tx_packets += buffer_info->segs; +				total_tx_bytes += buffer_info->bytecount;  			}  			e1000_put_txbuf(adapter, buffer_info); @@ -756,9 +1094,9 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,  		cleaned = 1;  		cleaned_count++; -		pci_unmap_single(pdev, buffer_info->dma, +		dma_unmap_single(&pdev->dev, buffer_info->dma,  				 adapter->rx_ps_bsize0, -				 PCI_DMA_FROMDEVICE); +				 DMA_FROM_DEVICE);  		buffer_info->dma = 0;  		/* see !EOP comment in other rx routine */ @@ -814,13 +1152,13 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,  			 * kmap_atomic, so we can't hold the mapping  			 * very long  			 */ -			pci_dma_sync_single_for_cpu(pdev, ps_page->dma, -				PAGE_SIZE, PCI_DMA_FROMDEVICE); +			dma_sync_single_for_cpu(&pdev->dev, ps_page->dma, +						PAGE_SIZE, DMA_FROM_DEVICE);  			vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ);  			memcpy(skb_tail_pointer(skb), vaddr, l1);  			kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); -			pci_dma_sync_single_for_device(pdev, ps_page->dma, -				PAGE_SIZE, PCI_DMA_FROMDEVICE); +			dma_sync_single_for_device(&pdev->dev, ps_page->dma, +						   PAGE_SIZE, DMA_FROM_DEVICE);  			/* remove the CRC */  			if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) @@ -837,8 +1175,8 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,  				break;  			ps_page = &buffer_info->ps_pages[j]; -			pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE, -				       PCI_DMA_FROMDEVICE); +			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE, +				       DMA_FROM_DEVICE);  			ps_page->dma = 0;  			skb_fill_page_desc(skb, j, ps_page->page, 0, length);  			ps_page->page = NULL; @@ -956,8 +1294,8 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,  		cleaned = true;  		cleaned_count++; -		pci_unmap_page(pdev, buffer_info->dma, PAGE_SIZE, -		               PCI_DMA_FROMDEVICE); +		dma_unmap_page(&pdev->dev, buffer_info->dma, PAGE_SIZE, +			       DMA_FROM_DEVICE);  		buffer_info->dma = 0;  		length = le16_to_cpu(rx_desc->length); @@ -1093,17 +1431,17 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)  		buffer_info = &rx_ring->buffer_info[i];  		if (buffer_info->dma) {  			if (adapter->clean_rx == e1000_clean_rx_irq) -				pci_unmap_single(pdev, buffer_info->dma, +				dma_unmap_single(&pdev->dev, buffer_info->dma,  						 adapter->rx_buffer_len, -						 PCI_DMA_FROMDEVICE); +						 DMA_FROM_DEVICE);  			else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq) -				pci_unmap_page(pdev, buffer_info->dma, +				dma_unmap_page(&pdev->dev, buffer_info->dma,  				               PAGE_SIZE, -				               PCI_DMA_FROMDEVICE); +					       DMA_FROM_DEVICE);  			else if (adapter->clean_rx == e1000_clean_rx_irq_ps) -				pci_unmap_single(pdev, buffer_info->dma, +				dma_unmap_single(&pdev->dev, buffer_info->dma,  						 adapter->rx_ps_bsize0, -						 PCI_DMA_FROMDEVICE); +						 DMA_FROM_DEVICE);  			buffer_info->dma = 0;  		} @@ -1121,8 +1459,8 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)  			ps_page = &buffer_info->ps_pages[j];  			if (!ps_page->page)  				break; -			pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE, -				       PCI_DMA_FROMDEVICE); +			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE, +				       DMA_FROM_DEVICE);  			ps_page->dma = 0;  			put_page(ps_page->page);  			ps_page->page = NULL; @@ -3732,6 +4070,22 @@ link_up:  		}  	} +	/* Simple mode for Interrupt Throttle Rate (ITR) */ +	if (adapter->itr_setting == 4) { +		/* +		 * Symmetric Tx/Rx gets a reduced ITR=2000; +		 * Total asymmetrical Tx or Rx gets ITR=8000; +		 * everyone else is between 2000-8000. +		 */ +		u32 goc = (adapter->gotc + adapter->gorc) / 10000; +		u32 dif = (adapter->gotc > adapter->gorc ? +			    adapter->gotc - adapter->gorc : +			    adapter->gorc - adapter->gotc) / 10000; +		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000; + +		ew32(ITR, 1000000000 / (itr * 256)); +	} +  	/* Cause software interrupt to ensure Rx ring is cleaned */  	if (adapter->msix_entries)  		ew32(ICS, adapter->rx_ring->ims_val); @@ -3906,7 +4260,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,  	struct e1000_buffer *buffer_info;  	unsigned int len = skb_headlen(skb);  	unsigned int offset = 0, size, count = 0, i; -	unsigned int f; +	unsigned int f, bytecount, segs;  	i = tx_ring->next_to_use; @@ -3917,10 +4271,11 @@ static int e1000_tx_map(struct e1000_adapter *adapter,  		buffer_info->length = size;  		buffer_info->time_stamp = jiffies;  		buffer_info->next_to_watch = i; -		buffer_info->dma = pci_map_single(pdev,	skb->data + offset, -						  size,	PCI_DMA_TODEVICE); +		buffer_info->dma = dma_map_single(&pdev->dev, +						  skb->data + offset, +						  size,	DMA_TO_DEVICE);  		buffer_info->mapped_as_page = false; -		if (pci_dma_mapping_error(pdev, buffer_info->dma)) +		if (dma_mapping_error(&pdev->dev, buffer_info->dma))  			goto dma_error;  		len -= size; @@ -3952,11 +4307,11 @@ static int e1000_tx_map(struct e1000_adapter *adapter,  			buffer_info->length = size;  			buffer_info->time_stamp = jiffies;  			buffer_info->next_to_watch = i; -			buffer_info->dma = pci_map_page(pdev, frag->page, +			buffer_info->dma = dma_map_page(&pdev->dev, frag->page,  							offset, size, -							PCI_DMA_TODEVICE); +							DMA_TO_DEVICE);  			buffer_info->mapped_as_page = true; -			if (pci_dma_mapping_error(pdev, buffer_info->dma)) +			if (dma_mapping_error(&pdev->dev, buffer_info->dma))  				goto dma_error;  			len -= size; @@ -3965,7 +4320,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter,  		}  	} +	segs = skb_shinfo(skb)->gso_segs ?: 1; +	/* multiply data chunks by size of headers */ +	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len; +  	tx_ring->buffer_info[i].skb = skb; +	tx_ring->buffer_info[i].segs = segs; +	tx_ring->buffer_info[i].bytecount = bytecount;  	tx_ring->buffer_info[first].next_to_watch = i;  	return count; @@ -4268,6 +4629,8 @@ static void e1000_reset_task(struct work_struct *work)  	struct e1000_adapter *adapter;  	adapter = container_of(work, struct e1000_adapter, reset_task); +	e1000e_dump(adapter); +	e_err("Reset adapter\n");  	e1000e_reinit_locked(adapter);  } @@ -4310,6 +4673,14 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)  		return -EINVAL;  	} +	/* 82573 Errata 17 */ +	if (((adapter->hw.mac.type == e1000_82573) || +	     (adapter->hw.mac.type == e1000_82574)) && +	    (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) { +		adapter->flags2 |= FLAG2_DISABLE_ASPM_L1; +		e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1); +	} +  	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))  		msleep(1);  	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */ @@ -4634,29 +5005,42 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,  	}  } -static void e1000e_disable_l1aspm(struct pci_dev *pdev) +#ifdef CONFIG_PCIEASPM +static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state) +{ +	pci_disable_link_state(pdev, state); +} +#else +static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)  {  	int pos; -	u16 val; +	u16 reg16;  	/* -	 * 82573 workaround - disable L1 ASPM on mobile chipsets -	 * -	 * L1 ASPM on various mobile (ich7) chipsets do not behave properly -	 * resulting in lost data or garbage information on the pci-e link -	 * level. This could result in (false) bad EEPROM checksum errors, -	 * long ping times (up to 2s) or even a system freeze/hang. -	 * -	 * Unfortunately this feature saves about 1W power consumption when -	 * active. +	 * Both device and parent should have the same ASPM setting. +	 * Disable ASPM in downstream component first and then upstream.  	 */ -	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); -	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val); -	if (val & 0x2) { -		dev_warn(&pdev->dev, "Disabling L1 ASPM\n"); -		val &= ~0x2; -		pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val); -	} +	pos = pci_pcie_cap(pdev); +	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); +	reg16 &= ~state; +	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); + +	if (!pdev->bus->self) +		return; + +	pos = pci_pcie_cap(pdev->bus->self); +	pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, ®16); +	reg16 &= ~state; +	pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16); +} +#endif +void e1000e_disable_aspm(struct pci_dev *pdev, u16 state) +{ +	dev_info(&pdev->dev, "Disabling ASPM %s %s\n", +		 (state & PCIE_LINK_STATE_L0S) ? "L0s" : "", +		 (state & PCIE_LINK_STATE_L1) ? "L1" : ""); + +	__e1000e_disable_aspm(pdev, state);  }  #ifdef CONFIG_PM_OPS @@ -4672,7 +5056,11 @@ static int __e1000_resume(struct pci_dev *pdev)  	struct e1000_hw *hw = &adapter->hw;  	u32 err; -	e1000e_disable_l1aspm(pdev); +	pci_set_power_state(pdev, PCI_D0); +	pci_restore_state(pdev); +	pci_save_state(pdev); +	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) +		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);  	e1000e_set_interrupt_capability(adapter);  	if (netif_running(netdev)) { @@ -4877,7 +5265,8 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)  	int err;  	pci_ers_result_t result; -	e1000e_disable_l1aspm(pdev); +	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) +		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);  	err = pci_enable_device_mem(pdev);  	if (err) {  		dev_err(&pdev->dev, @@ -4971,13 +5360,6 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)  		dev_warn(&adapter->pdev->dev,  			 "Warning: detected DSPD enabled in EEPROM\n");  	} - -	ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf); -	if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) { -		/* ASPM enable */ -		dev_warn(&adapter->pdev->dev, -			 "Warning: detected ASPM enabled in EEPROM\n"); -	}  }  static const struct net_device_ops e1000e_netdev_ops = { @@ -5026,23 +5408,24 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  	u16 eeprom_data = 0;  	u16 eeprom_apme_mask = E1000_EEPROM_APME; -	e1000e_disable_l1aspm(pdev); +	if (ei->flags2 & FLAG2_DISABLE_ASPM_L1) +		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);  	err = pci_enable_device_mem(pdev);  	if (err)  		return err;  	pci_using_dac = 0; -	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); +	err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));  	if (!err) { -		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); +		err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));  		if (!err)  			pci_using_dac = 1;  	} else { -		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); +		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));  		if (err) { -			err = pci_set_consistent_dma_mask(pdev, -							  DMA_BIT_MASK(32)); +			err = dma_set_coherent_mask(&pdev->dev, +						    DMA_BIT_MASK(32));  			if (err) {  				dev_err(&pdev->dev, "No usable DMA "  					"configuration, aborting\n"); @@ -5073,6 +5456,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  	SET_NETDEV_DEV(netdev, &pdev->dev); +	netdev->irq = pdev->irq; +  	pci_set_drvdata(pdev, netdev);  	adapter = netdev_priv(netdev);  	hw = &adapter->hw;  |