diff options
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 128 |
1 files changed, 55 insertions, 73 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 04e007dcf47..f388a017932 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -57,6 +57,7 @@ static const struct e1000_info *e1000_info_tbl[] = { [board_82572] = &e1000_82572_info, [board_82573] = &e1000_82573_info, [board_82574] = &e1000_82574_info, + [board_82583] = &e1000_82583_info, [board_80003es2lan] = &e1000_es2_info, [board_ich8lan] = &e1000_ich8_info, [board_ich9lan] = &e1000_ich9_info, @@ -566,15 +567,14 @@ next_desc: static void e1000_put_txbuf(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info) { - if (buffer_info->dma) { - pci_unmap_page(adapter->pdev, buffer_info->dma, - buffer_info->length, PCI_DMA_TODEVICE); - buffer_info->dma = 0; - } + buffer_info->dma = 0; if (buffer_info->skb) { + skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb, + DMA_TO_DEVICE); dev_kfree_skb_any(buffer_info->skb); buffer_info->skb = NULL; } + buffer_info->time_stamp = 0; } static void e1000_print_tx_hang(struct e1000_adapter *adapter) @@ -679,12 +679,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) } if (adapter->detect_tx_hung) { - /* - * Detect a transmit hang in hardware, this serializes the - * check with the clearing of time_stamp and movement of i - */ + /* Detect a transmit hang in hardware, this serializes the + * check with the clearing of time_stamp and movement of i */ adapter->detect_tx_hung = 0; - if (tx_ring->buffer_info[eop].dma && + if (tx_ring->buffer_info[eop].time_stamp && time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + (adapter->tx_timeout_factor * HZ)) && !(er32(STATUS) & E1000_STATUS_TXOFF)) { @@ -3309,7 +3307,7 @@ void e1000e_update_stats(struct e1000_adapter *adapter) adapter->stats.algnerrc += er32(ALGNERRC); adapter->stats.rxerrc += er32(RXERRC); - if (hw->mac.type != e1000_82574) + if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583)) adapter->stats.tncrs += er32(TNCRS); adapter->stats.cexterr += er32(CEXTERR); adapter->stats.tsctc += er32(TSCTC); @@ -3766,11 +3764,17 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) unsigned int i; u8 css; u32 cmd_len = E1000_TXD_CMD_DEXT; + __be16 protocol; if (skb->ip_summed != CHECKSUM_PARTIAL) return 0; - switch (skb->protocol) { + if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) + protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; + else + protocol = skb->protocol; + + switch (protocol) { case cpu_to_be16(ETH_P_IP): if (ip_hdr(skb)->protocol == IPPROTO_TCP) cmd_len |= E1000_TXD_CMD_TCP; @@ -3782,7 +3786,8 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) break; default: if (unlikely(net_ratelimit())) - e_warn("checksum_partial proto=%x!\n", skb->protocol); + e_warn("checksum_partial proto=%x!\n", + be16_to_cpu(protocol)); break; } @@ -3821,42 +3826,40 @@ static int e1000_tx_map(struct e1000_adapter *adapter, { struct e1000_ring *tx_ring = adapter->tx_ring; struct e1000_buffer *buffer_info; - unsigned int len = skb->len - skb->data_len; - unsigned int offset = 0, size, count = 0, i; + unsigned int len = skb_headlen(skb); + unsigned int offset, size, count = 0, i; unsigned int f; + dma_addr_t *map; i = tx_ring->next_to_use; + if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) { + dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); + adapter->tx_dma_failed++; + return 0; + } + + map = skb_shinfo(skb)->dma_maps; + offset = 0; + while (len) { buffer_info = &tx_ring->buffer_info[i]; size = min(len, max_per_txd); - /* Workaround for premature desc write-backs - * in TSO mode. Append 4-byte sentinel desc */ - if (mss && !nr_frags && size == len && size > 8) - size -= 4; - buffer_info->length = size; - /* set time_stamp *before* dma to help avoid a possible race */ buffer_info->time_stamp = jiffies; - buffer_info->dma = - pci_map_single(adapter->pdev, - skb->data + offset, - size, - PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(adapter->pdev, buffer_info->dma)) { - dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); - adapter->tx_dma_failed++; - return -1; - } buffer_info->next_to_watch = i; + buffer_info->dma = map[0] + offset; + count++; len -= size; offset += size; - count++; - i++; - if (i == tx_ring->count) - i = 0; + + if (len) { + i++; + if (i == tx_ring->count) + i = 0; + } } for (f = 0; f < nr_frags; f++) { @@ -3864,49 +3867,27 @@ static int e1000_tx_map(struct e1000_adapter *adapter, frag = &skb_shinfo(skb)->frags[f]; len = frag->size; - offset = frag->page_offset; + offset = 0; while (len) { + i++; + if (i == tx_ring->count) + i = 0; + buffer_info = &tx_ring->buffer_info[i]; size = min(len, max_per_txd); - /* Workaround for premature desc write-backs - * in TSO mode. Append 4-byte sentinel desc */ - if (mss && f == (nr_frags-1) && size == len && size > 8) - size -= 4; buffer_info->length = size; buffer_info->time_stamp = jiffies; - buffer_info->dma = - pci_map_page(adapter->pdev, - frag->page, - offset, - size, - PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(adapter->pdev, - buffer_info->dma)) { - dev_err(&adapter->pdev->dev, - "TX DMA page map failed\n"); - adapter->tx_dma_failed++; - return -1; - } - buffer_info->next_to_watch = i; + buffer_info->dma = map[f + 1] + offset; len -= size; offset += size; count++; - - i++; - if (i == tx_ring->count) - i = 0; } } - if (i == 0) - i = tx_ring->count - 1; - else - i--; - tx_ring->buffer_info[i].skb = skb; tx_ring->buffer_info[first].next_to_watch = i; @@ -4159,20 +4140,20 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (skb->protocol == htons(ETH_P_IP)) tx_flags |= E1000_TX_FLAGS_IPV4; + /* if count is 0 then mapping error has occured */ count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss); - if (count < 0) { - /* handle pci_map_single() error in e1000_tx_map */ + if (count) { + e1000_tx_queue(adapter, tx_flags, count); + netdev->trans_start = jiffies; + /* Make sure there is space in the ring for the next send. */ + e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2); + + } else { dev_kfree_skb_any(skb); - return NETDEV_TX_OK; + tx_ring->buffer_info[first].time_stamp = 0; + tx_ring->next_to_use = first; } - e1000_tx_queue(adapter, tx_flags, count); - - netdev->trans_start = jiffies; - - /* Make sure there is space in the ring for the next send. */ - e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2); - return NETDEV_TX_OK; } @@ -5149,6 +5130,7 @@ static struct pci_device_id e1000_pci_tbl[] = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT), board_80003es2lan }, |