diff options
Diffstat (limited to 'drivers/net/ethernet/intel/e1000')
-rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000.h | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 187 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000_hw.c | 78 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000_hw.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000_main.c | 524 |
5 files changed, 431 insertions, 379 deletions
diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index 10a0f221b18..69707108d23 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h @@ -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 */ diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index cca5bca44e7..b691eb4f637 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c @@ -1,35 +1,30 @@ /******************************************************************************* - - Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2006 Intel Corporation. - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information: - Linux NICS <linux.nics@intel.com> - e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ + * Intel PRO/1000 Linux driver + * Copyright(c) 1999 - 2006 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Linux NICS <linux.nics@intel.com> + * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + ******************************************************************************/ /* ethtool support for e1000 */ #include "e1000.h" -#include <asm/uaccess.h> +#include <linux/uaccess.h> enum {NETDEV_STATS, E1000_STATS}; @@ -42,7 +37,7 @@ struct e1000_stats { #define E1000_STAT(m) E1000_STATS, \ sizeof(((struct e1000_adapter *)0)->m), \ - offsetof(struct e1000_adapter, m) + offsetof(struct e1000_adapter, m) #define E1000_NETDEV_STAT(m) NETDEV_STATS, \ sizeof(((struct net_device *)0)->m), \ offsetof(struct net_device, m) @@ -104,6 +99,7 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = { "Interrupt test (offline)", "Loopback test (offline)", "Link test (on/offline)" }; + #define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test) static int e1000_get_settings(struct net_device *netdev, @@ -113,7 +109,6 @@ static int e1000_get_settings(struct net_device *netdev, struct e1000_hw *hw = &adapter->hw; if (hw->media_type == e1000_media_type_copper) { - ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | @@ -155,9 +150,8 @@ static int e1000_get_settings(struct net_device *netdev, } if (er32(STATUS) & E1000_STATUS_LU) { - e1000_get_speed_and_duplex(hw, &adapter->link_speed, - &adapter->link_duplex); + &adapter->link_duplex); ethtool_cmd_speed_set(ecmd, adapter->link_speed); /* unfortunately FULL_DUPLEX != DUPLEX_FULL @@ -247,9 +241,9 @@ static int e1000_set_settings(struct net_device *netdev, if (netif_running(adapter->netdev)) { e1000_down(adapter); e1000_up(adapter); - } else + } else { e1000_reset(adapter); - + } clear_bit(__E1000_RESETTING, &adapter->flags); return 0; } @@ -279,11 +273,11 @@ static void e1000_get_pauseparam(struct net_device *netdev, pause->autoneg = (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE); - if (hw->fc == E1000_FC_RX_PAUSE) + if (hw->fc == E1000_FC_RX_PAUSE) { pause->rx_pause = 1; - else if (hw->fc == E1000_FC_TX_PAUSE) + } else if (hw->fc == E1000_FC_TX_PAUSE) { pause->tx_pause = 1; - else if (hw->fc == E1000_FC_FULL) { + } else if (hw->fc == E1000_FC_FULL) { pause->rx_pause = 1; pause->tx_pause = 1; } @@ -316,8 +310,9 @@ static int e1000_set_pauseparam(struct net_device *netdev, if (netif_running(adapter->netdev)) { e1000_down(adapter); e1000_up(adapter); - } else + } else { e1000_reset(adapter); + } } else retval = ((hw->media_type == e1000_media_type_fiber) ? e1000_setup_link(hw) : e1000_force_mac_fc(hw)); @@ -329,12 +324,14 @@ static int e1000_set_pauseparam(struct net_device *netdev, static u32 e1000_get_msglevel(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); + return adapter->msg_enable; } static void e1000_set_msglevel(struct net_device *netdev, u32 data) { struct e1000_adapter *adapter = netdev_priv(netdev); + adapter->msg_enable = data; } @@ -526,7 +523,7 @@ static int e1000_set_eeprom(struct net_device *netdev, * only the first byte of the word is being modified */ ret_val = e1000_read_eeprom(hw, last_word, 1, - &eeprom_buff[last_word - first_word]); + &eeprom_buff[last_word - first_word]); } /* Device's eeprom is always little-endian, word addressable */ @@ -618,13 +615,12 @@ static int e1000_set_ringparam(struct net_device *netdev, adapter->tx_ring = txdr; adapter->rx_ring = rxdr; - rxdr->count = max(ring->rx_pending,(u32)E1000_MIN_RXD); - rxdr->count = min(rxdr->count,(u32)(mac_type < e1000_82544 ? + rxdr->count = max(ring->rx_pending, (u32)E1000_MIN_RXD); + rxdr->count = min(rxdr->count, (u32)(mac_type < e1000_82544 ? E1000_MAX_RXD : E1000_MAX_82544_RXD)); rxdr->count = ALIGN(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE); - - txdr->count = max(ring->tx_pending,(u32)E1000_MIN_TXD); - txdr->count = min(txdr->count,(u32)(mac_type < e1000_82544 ? + txdr->count = max(ring->tx_pending, (u32)E1000_MIN_TXD); + txdr->count = min(txdr->count, (u32)(mac_type < e1000_82544 ? E1000_MAX_TXD : E1000_MAX_82544_TXD)); txdr->count = ALIGN(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); @@ -680,8 +676,9 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, int reg, u32 mask, u32 write) { struct e1000_hw *hw = &adapter->hw; - static const u32 test[] = - {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; + static const u32 test[] = { + 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF + }; u8 __iomem *address = hw->hw_addr + reg; u32 read; int i; @@ -793,8 +790,8 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF); value = E1000_RAR_ENTRIES; for (i = 0; i < value; i++) { - REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF, - 0xFFFFFFFF); + REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), + 0x8003FFFF, 0xFFFFFFFF); } } else { REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x01FFFFFF); @@ -877,7 +874,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) /* Test each interrupt */ for (; i < 10; i++) { - /* Interrupt to test */ mask = 1 << i; @@ -972,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); } } @@ -1010,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; @@ -1069,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; @@ -1099,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; @@ -1149,8 +1144,7 @@ static void e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter) */ e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg); phy_reg |= M88E1000_EPSCR_TX_CLK_25; - e1000_write_phy_reg(hw, - M88E1000_EXT_PHY_SPEC_CTRL, phy_reg); + e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_reg); /* In addition, because of the s/w reset above, we need to enable * CRS on TX. This must be set for both full and half duplex @@ -1158,8 +1152,7 @@ static void e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter) */ e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_reg); phy_reg |= M88E1000_PSCR_ASSERT_CRS_ON_TX; - e1000_write_phy_reg(hw, - M88E1000_PHY_SPEC_CTRL, phy_reg); + e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_reg); } static int e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter) @@ -1216,7 +1209,7 @@ static int e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter) /* Check Phy Configuration */ e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg); if (phy_reg != 0x4100) - return 9; + return 9; e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg); if (phy_reg != 0x0070) @@ -1261,7 +1254,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) E1000_CTRL_FD); /* Force Duplex to FULL */ if (hw->media_type == e1000_media_type_copper && - hw->phy_type == e1000_phy_m88) + hw->phy_type == e1000_phy_m88) ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */ else { /* Set the ILOS bit on the fiber Nic is half @@ -1299,7 +1292,7 @@ static int e1000_set_phy_loopback(struct e1000_adapter *adapter) * attempt this 10 times. */ while (e1000_nonintegrated_phy_loopback(adapter) && - count++ < 10); + count++ < 10); if (count < 11) return 0; } @@ -1348,8 +1341,9 @@ static int e1000_setup_loopback_test(struct e1000_adapter *adapter) ew32(RCTL, rctl); return 0; } - } else if (hw->media_type == e1000_media_type_copper) + } else if (hw->media_type == e1000_media_type_copper) { return e1000_set_phy_loopback(adapter); + } return 7; } @@ -1391,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; } } @@ -1410,7 +1404,7 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) struct e1000_tx_ring *txdr = &adapter->test_tx_ring; struct e1000_rx_ring *rxdr = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; - int i, j, k, l, lc, good_cnt, ret_val=0; + int i, j, k, l, lc, good_cnt, ret_val = 0; unsigned long time; ew32(RDT, rxdr->count - 1); @@ -1429,12 +1423,13 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) for (j = 0; j <= lc; j++) { /* loop count loop */ for (i = 0; i < 64; i++) { /* send the packets */ e1000_create_lbtest_frame(txdr->buffer_info[i].skb, - 1024); + 1024); dma_sync_single_for_device(&pdev->dev, txdr->buffer_info[k].dma, txdr->buffer_info[k].length, DMA_TO_DEVICE); - if (unlikely(++k == txdr->count)) k = 0; + if (unlikely(++k == txdr->count)) + k = 0; } ew32(TDT, k); E1000_WRITE_FLUSH(); @@ -1444,15 +1439,17 @@ 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++; - if (unlikely(++l == rxdr->count)) l = 0; + if (unlikely(++l == rxdr->count)) + l = 0; /* time + 20 msecs (200 msecs on 2.4) is more than * enough time to complete the receives, if it's * exceeded, break and error off @@ -1494,6 +1491,7 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data) *data = 0; if (hw->media_type == e1000_media_type_internal_serdes) { int i = 0; + hw->serdes_has_link = false; /* On some blade server designs, link establishment @@ -1512,9 +1510,8 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data) if (hw->autoneg) /* if auto_neg is set wait for it */ msleep(4000); - if (!(er32(STATUS) & E1000_STATUS_LU)) { + if (!(er32(STATUS) & E1000_STATUS_LU)) *data = 1; - } } return *data; } @@ -1665,8 +1662,7 @@ static void e1000_get_wol(struct net_device *netdev, struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - wol->supported = WAKE_UCAST | WAKE_MCAST | - WAKE_BCAST | WAKE_MAGIC; + wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; wol->wolopts = 0; /* this function will set ->supported = 0 and return 1 if wol is not @@ -1819,6 +1815,7 @@ static int e1000_set_coalesce(struct net_device *netdev, static int e1000_nway_reset(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); + if (netif_running(netdev)) e1000_reinit_locked(adapter); return 0; @@ -1830,22 +1827,29 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, struct e1000_adapter *adapter = netdev_priv(netdev); int i; char *p = NULL; + const struct e1000_stats *stat = e1000_gstrings_stats; e1000_update_stats(adapter); for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { - switch (e1000_gstrings_stats[i].type) { + switch (stat->type) { case NETDEV_STATS: - p = (char *) netdev + - e1000_gstrings_stats[i].stat_offset; + p = (char *)netdev + stat->stat_offset; break; case E1000_STATS: - p = (char *) adapter + - e1000_gstrings_stats[i].stat_offset; + p = (char *)adapter + stat->stat_offset; + break; + default: + WARN_ONCE(1, "Invalid E1000 stat type: %u index %d\n", + stat->type, i); break; } - data[i] = (e1000_gstrings_stats[i].sizeof_stat == - sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + if (stat->sizeof_stat == sizeof(u64)) + data[i] = *(u64 *)p; + else + data[i] = *(u32 *)p; + + stat++; } /* BUG_ON(i != E1000_STATS_LEN); */ } @@ -1858,8 +1862,7 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset, switch (stringset) { case ETH_SS_TEST: - memcpy(data, *e1000_gstrings_test, - sizeof(e1000_gstrings_test)); + memcpy(data, e1000_gstrings_test, sizeof(e1000_gstrings_test)); break; case ETH_SS_STATS: for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { diff --git a/drivers/net/ethernet/intel/e1000/e1000_hw.c b/drivers/net/ethernet/intel/e1000/e1000_hw.c index 1acf5034db1..45c8c864104 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_hw.c +++ b/drivers/net/ethernet/intel/e1000/e1000_hw.c @@ -4837,84 +4837,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 * diff --git a/drivers/net/ethernet/intel/e1000/e1000_hw.h b/drivers/net/ethernet/intel/e1000/e1000_hw.h index 11578c8978d..5cf7268cc4e 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_hw.h +++ b/drivers/net/ethernet/intel/e1000/e1000_hw.h @@ -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); diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 660971f304b..24f3986cfae 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -46,7 +46,7 @@ static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation * Macro expands to... * {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)} */ -static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = { +static const struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x1000), INTEL_E1000_ETHERNET_DEVICE(0x1001), INTEL_E1000_ETHERNET_DEVICE(0x1004), @@ -1075,7 +1075,10 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) NETIF_F_HW_CSUM | NETIF_F_SG); - netdev->priv_flags |= IFF_UNICAST_FLT; + /* Do not set IFF_UNICAST_FLT for VMWare's 82545EM */ + if (hw->device_id != E1000_DEV_ID_82545EM_COPPER || + hw->subsystem_vendor_id != PCI_VENDOR_ID_VMWARE) + netdev->priv_flags |= IFF_UNICAST_FLT; adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw); @@ -1497,7 +1500,7 @@ static int e1000_setup_tx_resources(struct e1000_adapter *adapter, struct pci_dev *pdev = adapter->pdev; int size; - size = sizeof(struct e1000_buffer) * txdr->count; + size = sizeof(struct e1000_tx_buffer) * txdr->count; txdr->buffer_info = vzalloc(size); if (!txdr->buffer_info) return -ENOMEM; @@ -1687,7 +1690,7 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, struct pci_dev *pdev = adapter->pdev; int size, desc_len; - size = sizeof(struct e1000_buffer) * rxdr->count; + size = sizeof(struct e1000_rx_buffer) * rxdr->count; rxdr->buffer_info = vzalloc(size); if (!rxdr->buffer_info) return -ENOMEM; @@ -1947,8 +1950,9 @@ void e1000_free_all_tx_resources(struct e1000_adapter *adapter) e1000_free_tx_resources(adapter, &adapter->tx_ring[i]); } -static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, - struct e1000_buffer *buffer_info) +static void +e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, + struct e1000_tx_buffer *buffer_info) { if (buffer_info->dma) { if (buffer_info->mapped_as_page) @@ -1977,7 +1981,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring) { struct e1000_hw *hw = &adapter->hw; - struct e1000_buffer *buffer_info; + struct e1000_tx_buffer *buffer_info; unsigned long size; unsigned int i; @@ -1989,7 +1993,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter, } netdev_reset_queue(adapter->netdev); - size = sizeof(struct e1000_buffer) * tx_ring->count; + size = sizeof(struct e1000_tx_buffer) * tx_ring->count; memset(tx_ring->buffer_info, 0, size); /* Zero out the descriptor ring */ @@ -2053,6 +2057,28 @@ void e1000_free_all_rx_resources(struct e1000_adapter *adapter) e1000_free_rx_resources(adapter, &adapter->rx_ring[i]); } +#define E1000_HEADROOM (NET_SKB_PAD + NET_IP_ALIGN) +static unsigned int e1000_frag_len(const struct e1000_adapter *a) +{ + return SKB_DATA_ALIGN(a->rx_buffer_len + E1000_HEADROOM) + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +} + +static void *e1000_alloc_frag(const struct e1000_adapter *a) +{ + unsigned int len = e1000_frag_len(a); + u8 *data = netdev_alloc_frag(len); + + if (likely(data)) + data += E1000_HEADROOM; + return data; +} + +static void e1000_free_frag(const void *data) +{ + put_page(virt_to_head_page(data)); +} + /** * e1000_clean_rx_ring - Free Rx Buffers per Queue * @adapter: board private structure @@ -2062,44 +2088,42 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring) { struct e1000_hw *hw = &adapter->hw; - struct e1000_buffer *buffer_info; + struct e1000_rx_buffer *buffer_info; struct pci_dev *pdev = adapter->pdev; unsigned long size; unsigned int i; - /* Free all the Rx ring sk_buffs */ + /* Free all the Rx netfrags */ for (i = 0; i < rx_ring->count; i++) { buffer_info = &rx_ring->buffer_info[i]; - if (buffer_info->dma && - adapter->clean_rx == e1000_clean_rx_irq) { - dma_unmap_single(&pdev->dev, buffer_info->dma, - buffer_info->length, - DMA_FROM_DEVICE); - } else if (buffer_info->dma && - adapter->clean_rx == e1000_clean_jumbo_rx_irq) { - dma_unmap_page(&pdev->dev, buffer_info->dma, - buffer_info->length, - DMA_FROM_DEVICE); + if (adapter->clean_rx == e1000_clean_rx_irq) { + if (buffer_info->dma) + dma_unmap_single(&pdev->dev, buffer_info->dma, + adapter->rx_buffer_len, + DMA_FROM_DEVICE); + if (buffer_info->rxbuf.data) { + e1000_free_frag(buffer_info->rxbuf.data); + buffer_info->rxbuf.data = NULL; + } + } else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq) { + if (buffer_info->dma) + dma_unmap_page(&pdev->dev, buffer_info->dma, + adapter->rx_buffer_len, + DMA_FROM_DEVICE); + if (buffer_info->rxbuf.page) { + put_page(buffer_info->rxbuf.page); + buffer_info->rxbuf.page = NULL; + } } buffer_info->dma = 0; - if (buffer_info->page) { - put_page(buffer_info->page); - buffer_info->page = NULL; - } - if (buffer_info->skb) { - dev_kfree_skb(buffer_info->skb); - buffer_info->skb = NULL; - } } /* there also may be some cached data from a chained receive */ - if (rx_ring->rx_skb_top) { - dev_kfree_skb(rx_ring->rx_skb_top); - rx_ring->rx_skb_top = NULL; - } + napi_free_frags(&adapter->napi); + rx_ring->rx_skb_top = NULL; - size = sizeof(struct e1000_buffer) * rx_ring->count; + size = sizeof(struct e1000_rx_buffer) * rx_ring->count; memset(rx_ring->buffer_info, 0, size); /* Zero out the descriptor ring */ @@ -2674,10 +2698,11 @@ set_itr_now: #define E1000_TX_FLAGS_VLAN_SHIFT 16 static int e1000_tso(struct e1000_adapter *adapter, - struct e1000_tx_ring *tx_ring, struct sk_buff *skb) + struct e1000_tx_ring *tx_ring, struct sk_buff *skb, + __be16 protocol) { struct e1000_context_desc *context_desc; - struct e1000_buffer *buffer_info; + struct e1000_tx_buffer *buffer_info; unsigned int i; u32 cmd_length = 0; u16 ipcse = 0, tucse, mss; @@ -2692,7 +2717,7 @@ static int e1000_tso(struct e1000_adapter *adapter, hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); mss = skb_shinfo(skb)->gso_size; - if (skb->protocol == htons(ETH_P_IP)) { + if (protocol == htons(ETH_P_IP)) { struct iphdr *iph = ip_hdr(skb); iph->tot_len = 0; iph->check = 0; @@ -2702,7 +2727,7 @@ static int e1000_tso(struct e1000_adapter *adapter, 0); cmd_length = E1000_TXD_CMD_IP; ipcse = skb_transport_offset(skb) - 1; - } else if (skb->protocol == htons(ETH_P_IPV6)) { + } else if (skb_is_gso_v6(skb)) { ipv6_hdr(skb)->payload_len = 0; tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, @@ -2745,10 +2770,11 @@ static int e1000_tso(struct e1000_adapter *adapter, } static bool e1000_tx_csum(struct e1000_adapter *adapter, - struct e1000_tx_ring *tx_ring, struct sk_buff *skb) + struct e1000_tx_ring *tx_ring, struct sk_buff *skb, + __be16 protocol) { struct e1000_context_desc *context_desc; - struct e1000_buffer *buffer_info; + struct e1000_tx_buffer *buffer_info; unsigned int i; u8 css; u32 cmd_len = E1000_TXD_CMD_DEXT; @@ -2756,7 +2782,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, if (skb->ip_summed != CHECKSUM_PARTIAL) return false; - switch (skb->protocol) { + switch (protocol) { case cpu_to_be16(ETH_P_IP): if (ip_hdr(skb)->protocol == IPPROTO_TCP) cmd_len |= E1000_TXD_CMD_TCP; @@ -2807,7 +2833,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, { struct e1000_hw *hw = &adapter->hw; struct pci_dev *pdev = adapter->pdev; - struct e1000_buffer *buffer_info; + struct e1000_tx_buffer *buffer_info; unsigned int len = skb_headlen(skb); unsigned int offset = 0, size, count = 0, i; unsigned int f, bytecount, segs; @@ -2953,7 +2979,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, { struct e1000_hw *hw = &adapter->hw; struct e1000_tx_desc *tx_desc = NULL; - struct e1000_buffer *buffer_info; + struct e1000_tx_buffer *buffer_info; u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS; unsigned int i; @@ -3097,6 +3123,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, int count = 0; int tso; unsigned int f; + __be16 protocol = vlan_get_protocol(skb); /* This goes back to the question of how to logically map a Tx queue * to a flow. Right now, performance is impacted slightly negatively @@ -3210,7 +3237,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, first = tx_ring->next_to_use; - tso = e1000_tso(adapter, tx_ring, skb); + tso = e1000_tso(adapter, tx_ring, skb, protocol); if (tso < 0) { dev_kfree_skb_any(skb); return NETDEV_TX_OK; @@ -3220,10 +3247,10 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, if (likely(hw->mac_type != e1000_82544)) tx_ring->last_tx_tso = true; tx_flags |= E1000_TX_FLAGS_TSO; - } else if (likely(e1000_tx_csum(adapter, tx_ring, skb))) + } else if (likely(e1000_tx_csum(adapter, tx_ring, skb, protocol))) tx_flags |= E1000_TX_FLAGS_CSUM; - if (likely(skb->protocol == htons(ETH_P_IP))) + if (protocol == htons(ETH_P_IP)) tx_flags |= E1000_TX_FLAGS_IPV4; if (unlikely(skb->no_fcs)) @@ -3370,7 +3397,7 @@ static void e1000_dump(struct e1000_adapter *adapter) for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i); - struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i]; + struct e1000_tx_buffer *buffer_info = &tx_ring->buffer_info[i]; struct my_u { __le64 a; __le64 b; }; struct my_u *u = (struct my_u *)tx_desc; const char *type; @@ -3412,7 +3439,7 @@ rx_ring_summary: for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) { struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i); - struct e1000_buffer *buffer_info = &rx_ring->buffer_info[i]; + struct e1000_rx_buffer *buffer_info = &rx_ring->buffer_info[i]; struct my_u { __le64 a; __le64 b; }; struct my_u *u = (struct my_u *)rx_desc; const char *type; @@ -3426,7 +3453,7 @@ rx_ring_summary: pr_info("R[0x%03X] %016llX %016llX %016llX %p %s\n", i, le64_to_cpu(u->a), le64_to_cpu(u->b), - (u64)buffer_info->dma, buffer_info->skb, type); + (u64)buffer_info->dma, buffer_info->rxbuf.data, type); } /* for */ /* dump the descriptor caches */ @@ -3808,7 +3835,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; struct e1000_tx_desc *tx_desc, *eop_desc; - struct e1000_buffer *buffer_info; + struct e1000_tx_buffer *buffer_info; unsigned int i, eop; unsigned int count = 0; unsigned int total_tx_bytes=0, total_tx_packets=0; @@ -3946,12 +3973,12 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, } /** - * e1000_consume_page - helper function + * e1000_consume_page - helper function for jumbo Rx path **/ -static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, +static void e1000_consume_page(struct e1000_rx_buffer *bi, struct sk_buff *skb, u16 length) { - bi->page = NULL; + bi->rxbuf.page = NULL; skb->len += length; skb->data_len += length; skb->truesize += PAGE_SIZE; @@ -3978,6 +4005,113 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status, } /** + * 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 + */ +static void e1000_tbi_adjust_stats(struct e1000_hw *hw, + struct e1000_hw_stats *stats, + u32 frame_len, const 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)) + stats->bprc++; + else if (is_multicast_ether_addr(mac_addr)) + 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++; + } +} + +static bool e1000_tbi_should_accept(struct e1000_adapter *adapter, + u8 status, u8 errors, + u32 length, const u8 *data) +{ + struct e1000_hw *hw = &adapter->hw; + u8 last_byte = *(data + length - 1); + + if (TBI_ACCEPT(hw, status, errors, length, last_byte)) { + unsigned long irq_flags; + + spin_lock_irqsave(&adapter->stats_lock, irq_flags); + e1000_tbi_adjust_stats(hw, &adapter->stats, length, data); + spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); + + return true; + } + + return false; +} + +static struct sk_buff *e1000_alloc_rx_skb(struct e1000_adapter *adapter, + unsigned int bufsz) +{ + struct sk_buff *skb = netdev_alloc_skb_ip_align(adapter->netdev, bufsz); + + if (unlikely(!skb)) + adapter->alloc_rx_buff_failed++; + return skb; +} + +/** * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy * @adapter: board private structure * @rx_ring: ring to clean @@ -3991,12 +4125,10 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring, int *work_done, int work_to_do) { - struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct e1000_rx_desc *rx_desc, *next_rxd; - struct e1000_buffer *buffer_info, *next_buffer; - unsigned long irq_flags; + struct e1000_rx_buffer *buffer_info, *next_buffer; u32 length; unsigned int i; int cleaned_count = 0; @@ -4017,8 +4149,6 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, rmb(); /* read descriptor and rx_buffer_info after status DD */ status = rx_desc->status; - skb = buffer_info->skb; - buffer_info->skb = NULL; if (++i == rx_ring->count) i = 0; next_rxd = E1000_RX_DESC(*rx_ring, i); @@ -4029,7 +4159,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, cleaned = true; cleaned_count++; dma_unmap_page(&pdev->dev, buffer_info->dma, - buffer_info->length, DMA_FROM_DEVICE); + adapter->rx_buffer_len, DMA_FROM_DEVICE); buffer_info->dma = 0; length = le16_to_cpu(rx_desc->length); @@ -4037,25 +4167,15 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, /* errors is only valid for DD + EOP descriptors */ if (unlikely((status & E1000_RXD_STAT_EOP) && (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) { - u8 *mapped; - u8 last_byte; - - mapped = page_address(buffer_info->page); - last_byte = *(mapped + length - 1); - if (TBI_ACCEPT(hw, status, rx_desc->errors, length, - last_byte)) { - spin_lock_irqsave(&adapter->stats_lock, - irq_flags); - e1000_tbi_adjust_stats(hw, &adapter->stats, - length, mapped); - spin_unlock_irqrestore(&adapter->stats_lock, - irq_flags); + u8 *mapped = page_address(buffer_info->rxbuf.page); + + if (e1000_tbi_should_accept(adapter, status, + rx_desc->errors, + length, mapped)) { length--; + } else if (netdev->features & NETIF_F_RXALL) { + goto process_skb; } else { - if (netdev->features & NETIF_F_RXALL) - goto process_skb; - /* recycle both page and skb */ - buffer_info->skb = skb; /* an error means any chain goes out the window * too */ @@ -4072,16 +4192,18 @@ process_skb: /* this descriptor is only the beginning (or middle) */ if (!rxtop) { /* this is the beginning of a chain */ - rxtop = skb; - skb_fill_page_desc(rxtop, 0, buffer_info->page, + rxtop = napi_get_frags(&adapter->napi); + if (!rxtop) + break; + + skb_fill_page_desc(rxtop, 0, + buffer_info->rxbuf.page, 0, length); } else { /* this is the middle of a chain */ skb_fill_page_desc(rxtop, skb_shinfo(rxtop)->nr_frags, - buffer_info->page, 0, length); - /* re-use the skb, only consumed the page */ - buffer_info->skb = skb; + buffer_info->rxbuf.page, 0, length); } e1000_consume_page(buffer_info, rxtop, length); goto next_desc; @@ -4090,32 +4212,51 @@ process_skb: /* end of the chain */ skb_fill_page_desc(rxtop, skb_shinfo(rxtop)->nr_frags, - buffer_info->page, 0, length); - /* re-use the current skb, we only consumed the - * page - */ - buffer_info->skb = skb; + buffer_info->rxbuf.page, 0, length); skb = rxtop; rxtop = NULL; e1000_consume_page(buffer_info, skb, length); } else { + struct page *p; /* no chain, got EOP, this buf is the packet * copybreak to save the put_page/alloc_page */ - if (length <= copybreak && - skb_tailroom(skb) >= length) { + p = buffer_info->rxbuf.page; + if (length <= copybreak) { u8 *vaddr; - vaddr = kmap_atomic(buffer_info->page); + + if (likely(!(netdev->features & NETIF_F_RXFCS))) + length -= 4; + skb = e1000_alloc_rx_skb(adapter, + length); + if (!skb) + break; + + vaddr = kmap_atomic(p); memcpy(skb_tail_pointer(skb), vaddr, length); kunmap_atomic(vaddr); /* re-use the page, so don't erase - * buffer_info->page + * buffer_info->rxbuf.page */ skb_put(skb, length); + e1000_rx_checksum(adapter, + status | rx_desc->errors << 24, + le16_to_cpu(rx_desc->csum), skb); + + total_rx_bytes += skb->len; + total_rx_packets++; + + e1000_receive_skb(adapter, status, + rx_desc->special, skb); + goto next_desc; } else { - skb_fill_page_desc(skb, 0, - buffer_info->page, 0, + skb = napi_get_frags(&adapter->napi); + if (!skb) { + adapter->alloc_rx_buff_failed++; + break; + } + skb_fill_page_desc(skb, 0, p, 0, length); e1000_consume_page(buffer_info, skb, length); @@ -4134,14 +4275,14 @@ process_skb: pskb_trim(skb, skb->len - 4); total_rx_packets++; - /* eth type trans needs skb->data to point to something */ - if (!pskb_may_pull(skb, ETH_HLEN)) { - e_err(drv, "pskb_may_pull failed.\n"); - dev_kfree_skb(skb); - goto next_desc; + if (status & E1000_RXD_STAT_VP) { + __le16 vlan = rx_desc->special; + u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; + + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid); } - e1000_receive_skb(adapter, status, rx_desc->special, skb); + napi_gro_frags(&adapter->napi); next_desc: rx_desc->status = 0; @@ -4172,25 +4313,25 @@ next_desc: /* this should improve performance for small packets with large amounts * of reassembly being done in the stack */ -static void e1000_check_copybreak(struct net_device *netdev, - struct e1000_buffer *buffer_info, - u32 length, struct sk_buff **skb) +static struct sk_buff *e1000_copybreak(struct e1000_adapter *adapter, + struct e1000_rx_buffer *buffer_info, + u32 length, const void *data) { - struct sk_buff *new_skb; + struct sk_buff *skb; if (length > copybreak) - return; + return NULL; - new_skb = netdev_alloc_skb_ip_align(netdev, length); - if (!new_skb) - return; + skb = e1000_alloc_rx_skb(adapter, length); + if (!skb) + return NULL; + + dma_sync_single_for_cpu(&adapter->pdev->dev, buffer_info->dma, + length, DMA_FROM_DEVICE); - skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN, - (*skb)->data - NET_IP_ALIGN, - length + NET_IP_ALIGN); - /* save the skb in buffer_info as good */ - buffer_info->skb = *skb; - *skb = new_skb; + memcpy(skb_put(skb, length), data, length); + + return skb; } /** @@ -4204,12 +4345,10 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring, int *work_done, int work_to_do) { - struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct e1000_rx_desc *rx_desc, *next_rxd; - struct e1000_buffer *buffer_info, *next_buffer; - unsigned long flags; + struct e1000_rx_buffer *buffer_info, *next_buffer; u32 length; unsigned int i; int cleaned_count = 0; @@ -4222,6 +4361,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, while (rx_desc->status & E1000_RXD_STAT_DD) { struct sk_buff *skb; + u8 *data; u8 status; if (*work_done >= work_to_do) @@ -4230,10 +4370,27 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, rmb(); /* read descriptor and rx_buffer_info after status DD */ status = rx_desc->status; - skb = buffer_info->skb; - buffer_info->skb = NULL; + length = le16_to_cpu(rx_desc->length); + + data = buffer_info->rxbuf.data; + prefetch(data); + skb = e1000_copybreak(adapter, buffer_info, length, data); + if (!skb) { + unsigned int frag_len = e1000_frag_len(adapter); + + skb = build_skb(data - E1000_HEADROOM, frag_len); + if (!skb) { + adapter->alloc_rx_buff_failed++; + break; + } - prefetch(skb->data - NET_IP_ALIGN); + skb_reserve(skb, E1000_HEADROOM); + dma_unmap_single(&pdev->dev, buffer_info->dma, + adapter->rx_buffer_len, + DMA_FROM_DEVICE); + buffer_info->dma = 0; + buffer_info->rxbuf.data = NULL; + } if (++i == rx_ring->count) i = 0; next_rxd = E1000_RX_DESC(*rx_ring, i); @@ -4243,11 +4400,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, cleaned = true; cleaned_count++; - dma_unmap_single(&pdev->dev, buffer_info->dma, - buffer_info->length, DMA_FROM_DEVICE); - buffer_info->dma = 0; - length = le16_to_cpu(rx_desc->length); /* !EOP means multiple descriptors were used to store a single * packet, if thats the case we need to toss it. In fact, we * to toss every packet with the EOP bit clear and the next @@ -4259,29 +4412,22 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, if (adapter->discarding) { /* All receives must fit into a single buffer */ - e_dbg("Receive packet consumed multiple buffers\n"); - /* recycle */ - buffer_info->skb = skb; + netdev_dbg(netdev, "Receive packet consumed multiple buffers\n"); + dev_kfree_skb(skb); if (status & E1000_RXD_STAT_EOP) adapter->discarding = false; goto next_desc; } if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) { - u8 last_byte = *(skb->data + length - 1); - if (TBI_ACCEPT(hw, status, rx_desc->errors, length, - last_byte)) { - spin_lock_irqsave(&adapter->stats_lock, flags); - e1000_tbi_adjust_stats(hw, &adapter->stats, - length, skb->data); - spin_unlock_irqrestore(&adapter->stats_lock, - flags); + if (e1000_tbi_should_accept(adapter, status, + rx_desc->errors, + length, data)) { length--; + } else if (netdev->features & NETIF_F_RXALL) { + goto process_skb; } else { - if (netdev->features & NETIF_F_RXALL) - goto process_skb; - /* recycle */ - buffer_info->skb = skb; + dev_kfree_skb(skb); goto next_desc; } } @@ -4296,9 +4442,10 @@ process_skb: */ length -= 4; - e1000_check_copybreak(netdev, buffer_info, length, &skb); - - skb_put(skb, length); + if (buffer_info->rxbuf.data == NULL) + skb_put(skb, length); + else /* copybreak skb */ + skb_trim(skb, length); /* Receive Checksum Offload */ e1000_rx_checksum(adapter, @@ -4344,38 +4491,19 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring, int cleaned_count) { - struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct e1000_rx_desc *rx_desc; - struct e1000_buffer *buffer_info; - struct sk_buff *skb; + struct e1000_rx_buffer *buffer_info; unsigned int i; - unsigned int bufsz = 256 - 16 /*for skb_reserve */ ; i = rx_ring->next_to_use; buffer_info = &rx_ring->buffer_info[i]; while (cleaned_count--) { - skb = buffer_info->skb; - if (skb) { - skb_trim(skb, 0); - goto check_page; - } - - skb = netdev_alloc_skb_ip_align(netdev, bufsz); - if (unlikely(!skb)) { - /* Better luck next round */ - adapter->alloc_rx_buff_failed++; - break; - } - - buffer_info->skb = skb; - buffer_info->length = adapter->rx_buffer_len; -check_page: /* allocate a new page if necessary */ - if (!buffer_info->page) { - buffer_info->page = alloc_page(GFP_ATOMIC); - if (unlikely(!buffer_info->page)) { + if (!buffer_info->rxbuf.page) { + buffer_info->rxbuf.page = alloc_page(GFP_ATOMIC); + if (unlikely(!buffer_info->rxbuf.page)) { adapter->alloc_rx_buff_failed++; break; } @@ -4383,17 +4511,15 @@ check_page: if (!buffer_info->dma) { buffer_info->dma = dma_map_page(&pdev->dev, - buffer_info->page, 0, - buffer_info->length, + buffer_info->rxbuf.page, 0, + adapter->rx_buffer_len, DMA_FROM_DEVICE); if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { - put_page(buffer_info->page); - dev_kfree_skb(skb); - buffer_info->page = NULL; - buffer_info->skb = NULL; + put_page(buffer_info->rxbuf.page); + buffer_info->rxbuf.page = NULL; buffer_info->dma = 0; adapter->alloc_rx_buff_failed++; - break; /* while !buffer_info->skb */ + break; } } @@ -4429,11 +4555,9 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, int cleaned_count) { struct e1000_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct e1000_rx_desc *rx_desc; - struct e1000_buffer *buffer_info; - struct sk_buff *skb; + struct e1000_rx_buffer *buffer_info; unsigned int i; unsigned int bufsz = adapter->rx_buffer_len; @@ -4441,57 +4565,52 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, buffer_info = &rx_ring->buffer_info[i]; while (cleaned_count--) { - skb = buffer_info->skb; - if (skb) { - skb_trim(skb, 0); - goto map_skb; - } + void *data; - skb = netdev_alloc_skb_ip_align(netdev, bufsz); - if (unlikely(!skb)) { + if (buffer_info->rxbuf.data) + goto skip; + + data = e1000_alloc_frag(adapter); + if (!data) { /* Better luck next round */ adapter->alloc_rx_buff_failed++; break; } /* Fix for errata 23, can't cross 64kB boundary */ - if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { - struct sk_buff *oldskb = skb; + if (!e1000_check_64k_bound(adapter, data, bufsz)) { + void *olddata = data; e_err(rx_err, "skb align check failed: %u bytes at " - "%p\n", bufsz, skb->data); + "%p\n", bufsz, data); /* Try again, without freeing the previous */ - skb = netdev_alloc_skb_ip_align(netdev, bufsz); + data = e1000_alloc_frag(adapter); /* Failed allocation, critical failure */ - if (!skb) { - dev_kfree_skb(oldskb); + if (!data) { + e1000_free_frag(olddata); adapter->alloc_rx_buff_failed++; break; } - if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { + if (!e1000_check_64k_bound(adapter, data, bufsz)) { /* give up */ - dev_kfree_skb(skb); - dev_kfree_skb(oldskb); + e1000_free_frag(data); + e1000_free_frag(olddata); adapter->alloc_rx_buff_failed++; - break; /* while !buffer_info->skb */ + break; } /* Use new allocation */ - dev_kfree_skb(oldskb); + e1000_free_frag(olddata); } - buffer_info->skb = skb; - buffer_info->length = adapter->rx_buffer_len; -map_skb: buffer_info->dma = dma_map_single(&pdev->dev, - skb->data, - buffer_info->length, + data, + adapter->rx_buffer_len, DMA_FROM_DEVICE); if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { - dev_kfree_skb(skb); - buffer_info->skb = NULL; + e1000_free_frag(data); buffer_info->dma = 0; adapter->alloc_rx_buff_failed++; - break; /* while !buffer_info->skb */ + break; } /* XXX if it was allocated cleanly it will never map to a @@ -4505,17 +4624,20 @@ map_skb: e_err(rx_err, "dma align check failed: %u bytes at " "%p\n", adapter->rx_buffer_len, (void *)(unsigned long)buffer_info->dma); - dev_kfree_skb(skb); - buffer_info->skb = NULL; dma_unmap_single(&pdev->dev, buffer_info->dma, adapter->rx_buffer_len, DMA_FROM_DEVICE); + + e1000_free_frag(data); + buffer_info->rxbuf.data = NULL; buffer_info->dma = 0; adapter->alloc_rx_buff_failed++; - break; /* while !buffer_info->skb */ + break; } + buffer_info->rxbuf.data = data; + skip: rx_desc = E1000_RX_DESC(*rx_ring, i); rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); |