Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0fe13151 authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2014-09-12

This series contains updates to e1000, ixgbe and ixgbevf.

Mark provide two fixes to reduce compile warnings produce by ixgbe
and ixgbevf.

Alex provides two patches for ixgbe, first removes the receive buffer
allocation at the end of the ixgbe_clean_rx_irq().  The reason for
removing this is to avoid the extra latency introduced by the MMIO write.
Second patch addresses several issues in the current ixgbe implementation
of busy poll sockets.  It was possible for frames to be delivered out of
order if they were held in GRO, so address this by flushing the GRO
buffers before releasing the q_vector back to the idle state.  Also, we
were having to take a spinlock on changing the state to and from idle,
so to resolve this, replaced the state value with an atomic and use
atomic_cmpxchg to change the value from idle, and a simple atomic set
to restore it back to idle after we have acquired it.  This allows us
to only use a locked operation on acquiring the vector without a need
for a locked operation to release it.

Florian Westphal provides several patches for e1000 which does some
cleanup and updating of the driver.  Moved e1000_tbi_adjust_stats()
so that he could make the function static.  Added a helper function
to deal with the tbi workaround that was located in 2 different
Rx clean functions.  Added a e1000_rx_buffer struct for use on receive
since the transmit and receive have different requirements.  Updates
e1000 to use napi_gro_frags API.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 54996b52 de591c78
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -148,16 +148,23 @@ struct e1000_adapter;
/* wrapper around a pointer to a socket buffer,
 * so a DMA handle can be stored along with the buffer
 */
struct e1000_buffer {
struct e1000_tx_buffer {
	struct sk_buff *skb;
	dma_addr_t dma;
	struct page *page;
	unsigned long time_stamp;
	u16 length;
	u16 next_to_watch;
	unsigned int segs;
	bool mapped_as_page;
	unsigned short segs;
	unsigned int bytecount;
	u16 mapped_as_page;
};

struct e1000_rx_buffer {
	union {
		struct page *page; /* jumbo: alloc_page */
		u8 *data; /* else, netdev_alloc_frag */
	} rxbuf;
	dma_addr_t dma;
};

struct e1000_tx_ring {
@@ -174,7 +181,7 @@ struct e1000_tx_ring {
	/* next descriptor to check for DD status bit */
	unsigned int next_to_clean;
	/* array of buffer information structs */
	struct e1000_buffer *buffer_info;
	struct e1000_tx_buffer *buffer_info;

	u16 tdh;
	u16 tdt;
@@ -195,7 +202,7 @@ struct e1000_rx_ring {
	/* next descriptor to check for DD status bit */
	unsigned int next_to_clean;
	/* array of buffer information structs */
	struct e1000_buffer *buffer_info;
	struct e1000_rx_buffer *buffer_info;
	struct sk_buff *rx_skb_top;

	/* cpu for rx queue */
+19 −19
Original line number Diff line number Diff line
@@ -968,10 +968,9 @@ static void e1000_free_desc_rings(struct e1000_adapter *adapter)
			if (rxdr->buffer_info[i].dma)
				dma_unmap_single(&pdev->dev,
						 rxdr->buffer_info[i].dma,
						 rxdr->buffer_info[i].length,
						 E1000_RXBUFFER_2048,
						 DMA_FROM_DEVICE);
			if (rxdr->buffer_info[i].skb)
				dev_kfree_skb(rxdr->buffer_info[i].skb);
			kfree(rxdr->buffer_info[i].rxbuf.data);
		}
	}

@@ -1006,7 +1005,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
	if (!txdr->count)
		txdr->count = E1000_DEFAULT_TXD;

	txdr->buffer_info = kcalloc(txdr->count, sizeof(struct e1000_buffer),
	txdr->buffer_info = kcalloc(txdr->count, sizeof(struct e1000_tx_buffer),
				    GFP_KERNEL);
	if (!txdr->buffer_info) {
		ret_val = 1;
@@ -1065,7 +1064,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
	if (!rxdr->count)
		rxdr->count = E1000_DEFAULT_RXD;

	rxdr->buffer_info = kcalloc(rxdr->count, sizeof(struct e1000_buffer),
	rxdr->buffer_info = kcalloc(rxdr->count, sizeof(struct e1000_rx_buffer),
				    GFP_KERNEL);
	if (!rxdr->buffer_info) {
		ret_val = 5;
@@ -1095,25 +1094,25 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)

	for (i = 0; i < rxdr->count; i++) {
		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
		struct sk_buff *skb;
		u8 *buf;

		skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL);
		if (!skb) {
		buf = kzalloc(E1000_RXBUFFER_2048 + NET_SKB_PAD + NET_IP_ALIGN,
			      GFP_KERNEL);
		if (!buf) {
			ret_val = 7;
			goto err_nomem;
		}
		skb_reserve(skb, NET_IP_ALIGN);
		rxdr->buffer_info[i].skb = skb;
		rxdr->buffer_info[i].length = E1000_RXBUFFER_2048;
		rxdr->buffer_info[i].rxbuf.data = buf;

		rxdr->buffer_info[i].dma =
			dma_map_single(&pdev->dev, skb->data,
			dma_map_single(&pdev->dev,
				       buf + NET_SKB_PAD + NET_IP_ALIGN,
				       E1000_RXBUFFER_2048, DMA_FROM_DEVICE);
		if (dma_mapping_error(&pdev->dev, rxdr->buffer_info[i].dma)) {
			ret_val = 8;
			goto err_nomem;
		}
		rx_desc->buffer_addr = cpu_to_le64(rxdr->buffer_info[i].dma);
		memset(skb->data, 0x00, skb->len);
	}

	return 0;
@@ -1386,13 +1385,13 @@ static void e1000_create_lbtest_frame(struct sk_buff *skb,
	memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
}

static int e1000_check_lbtest_frame(struct sk_buff *skb,
static int e1000_check_lbtest_frame(const unsigned char *data,
				    unsigned int frame_size)
{
	frame_size &= ~1;
	if (skb->data[3] == 0xFF) {
		if (skb->data[frame_size / 2 + 10] == 0xBE &&
		    skb->data[frame_size / 2 + 12] == 0xAF) {
	if (*(data + 3) == 0xFF) {
		if ((*(data + frame_size / 2 + 10) == 0xBE) &&
		    (*(data + frame_size / 2 + 12) == 0xAF)) {
			return 0;
		}
	}
@@ -1440,11 +1439,12 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)
		do { /* receive the sent packets */
			dma_sync_single_for_cpu(&pdev->dev,
						rxdr->buffer_info[l].dma,
						rxdr->buffer_info[l].length,
						E1000_RXBUFFER_2048,
						DMA_FROM_DEVICE);

			ret_val = e1000_check_lbtest_frame(
					rxdr->buffer_info[l].skb,
					rxdr->buffer_info[l].rxbuf.data +
					NET_SKB_PAD + NET_IP_ALIGN,
					1024);
			if (!ret_val)
				good_cnt++;
+0 −78
Original line number Diff line number Diff line
@@ -4836,84 +4836,6 @@ void e1000_update_adaptive(struct e1000_hw *hw)
	}
}

/**
 * e1000_tbi_adjust_stats
 * @hw: Struct containing variables accessed by shared code
 * @frame_len: The length of the frame in question
 * @mac_addr: The Ethernet destination address of the frame in question
 *
 * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
 */
void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
			    u32 frame_len, u8 *mac_addr)
{
	u64 carry_bit;

	/* First adjust the frame length. */
	frame_len--;
	/* We need to adjust the statistics counters, since the hardware
	 * counters overcount this packet as a CRC error and undercount
	 * the packet as a good packet
	 */
	/* This packet should not be counted as a CRC error. */
	stats->crcerrs--;
	/* This packet does count as a Good Packet Received. */
	stats->gprc++;

	/* Adjust the Good Octets received counters */
	carry_bit = 0x80000000 & stats->gorcl;
	stats->gorcl += frame_len;
	/* If the high bit of Gorcl (the low 32 bits of the Good Octets
	 * Received Count) was one before the addition,
	 * AND it is zero after, then we lost the carry out,
	 * need to add one to Gorch (Good Octets Received Count High).
	 * This could be simplified if all environments supported
	 * 64-bit integers.
	 */
	if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
		stats->gorch++;
	/* Is this a broadcast or multicast?  Check broadcast first,
	 * since the test for a multicast frame will test positive on
	 * a broadcast frame.
	 */
	if (is_broadcast_ether_addr(mac_addr))
		/* Broadcast packet */
		stats->bprc++;
	else if (is_multicast_ether_addr(mac_addr))
		/* Multicast packet */
		stats->mprc++;

	if (frame_len == hw->max_frame_size) {
		/* In this case, the hardware has overcounted the number of
		 * oversize frames.
		 */
		if (stats->roc > 0)
			stats->roc--;
	}

	/* Adjust the bin counters when the extra byte put the frame in the
	 * wrong bin. Remember that the frame_len was adjusted above.
	 */
	if (frame_len == 64) {
		stats->prc64++;
		stats->prc127--;
	} else if (frame_len == 127) {
		stats->prc127++;
		stats->prc255--;
	} else if (frame_len == 255) {
		stats->prc255++;
		stats->prc511--;
	} else if (frame_len == 511) {
		stats->prc511++;
		stats->prc1023--;
	} else if (frame_len == 1023) {
		stats->prc1023++;
		stats->prc1522--;
	} else if (frame_len == 1522) {
		stats->prc1522++;
	}
}

/**
 * e1000_get_bus_info
 * @hw: Struct containing variables accessed by shared code
+0 −2
Original line number Diff line number Diff line
@@ -393,8 +393,6 @@ s32 e1000_blink_led_start(struct e1000_hw *hw);
/* Everything else */
void e1000_reset_adaptive(struct e1000_hw *hw);
void e1000_update_adaptive(struct e1000_hw *hw);
void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
			    u32 frame_len, u8 * mac_addr);
void e1000_get_bus_info(struct e1000_hw *hw);
void e1000_pci_set_mwi(struct e1000_hw *hw);
void e1000_pci_clear_mwi(struct e1000_hw *hw);
+307 −191

File changed.

Preview size limit exceeded, changes collapsed.

Loading