diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sis190.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 97aa18dd9a4b..0b22e75633a2 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c | |||
@@ -518,25 +518,28 @@ static u32 sis190_rx_fill(struct sis190_private *tp, struct net_device *dev, | |||
518 | return cur - start; | 518 | return cur - start; |
519 | } | 519 | } |
520 | 520 | ||
521 | static int sis190_try_rx_copy(struct sis190_private *tp, | 521 | static bool sis190_try_rx_copy(struct sis190_private *tp, |
522 | struct sk_buff **sk_buff, int pkt_size, | 522 | struct sk_buff **sk_buff, int pkt_size, |
523 | struct RxDesc *desc) | 523 | dma_addr_t addr) |
524 | { | 524 | { |
525 | int ret = -1; | 525 | struct sk_buff *skb; |
526 | bool done = false; | ||
526 | 527 | ||
527 | if (pkt_size < rx_copybreak) { | 528 | if (pkt_size >= rx_copybreak) |
528 | struct sk_buff *skb; | 529 | goto out; |
529 | 530 | ||
530 | skb = netdev_alloc_skb(tp->dev, pkt_size + 2); | 531 | skb = netdev_alloc_skb(tp->dev, pkt_size + 2); |
531 | if (skb) { | 532 | if (!skb) |
532 | skb_reserve(skb, 2); | 533 | goto out; |
533 | skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size); | 534 | |
534 | *sk_buff = skb; | 535 | pci_dma_sync_single_for_device(tp->pci_dev, addr, pkt_size, |
535 | sis190_give_to_asic(desc, tp->rx_buf_sz); | 536 | PCI_DMA_FROMDEVICE); |
536 | ret = 0; | 537 | skb_reserve(skb, 2); |
537 | } | 538 | skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size); |
538 | } | 539 | *sk_buff = skb; |
539 | return ret; | 540 | done = true; |
541 | out: | ||
542 | return done; | ||
540 | } | 543 | } |
541 | 544 | ||
542 | static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats) | 545 | static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats) |
@@ -586,9 +589,9 @@ static int sis190_rx_interrupt(struct net_device *dev, | |||
586 | sis190_give_to_asic(desc, tp->rx_buf_sz); | 589 | sis190_give_to_asic(desc, tp->rx_buf_sz); |
587 | else { | 590 | else { |
588 | struct sk_buff *skb = tp->Rx_skbuff[entry]; | 591 | struct sk_buff *skb = tp->Rx_skbuff[entry]; |
592 | dma_addr_t addr = le32_to_cpu(desc->addr); | ||
589 | int pkt_size = (status & RxSizeMask) - 4; | 593 | int pkt_size = (status & RxSizeMask) - 4; |
590 | void (*pci_action)(struct pci_dev *, dma_addr_t, | 594 | struct pci_dev *pdev = tp->pci_dev; |
591 | size_t, int) = pci_dma_sync_single_for_device; | ||
592 | 595 | ||
593 | if (unlikely(pkt_size > tp->rx_buf_sz)) { | 596 | if (unlikely(pkt_size > tp->rx_buf_sz)) { |
594 | net_intr(tp, KERN_INFO | 597 | net_intr(tp, KERN_INFO |
@@ -600,19 +603,18 @@ static int sis190_rx_interrupt(struct net_device *dev, | |||
600 | continue; | 603 | continue; |
601 | } | 604 | } |
602 | 605 | ||
603 | pci_dma_sync_single_for_cpu(tp->pci_dev, | ||
604 | le32_to_cpu(desc->addr), tp->rx_buf_sz, | ||
605 | PCI_DMA_FROMDEVICE); | ||
606 | 606 | ||
607 | if (sis190_try_rx_copy(tp, &skb, pkt_size, desc)) { | 607 | if (sis190_try_rx_copy(tp, &skb, pkt_size, addr)) { |
608 | pci_action = pci_unmap_single; | 608 | pci_dma_sync_single_for_device(pdev, addr, |
609 | tp->rx_buf_sz, PCI_DMA_FROMDEVICE); | ||
610 | sis190_give_to_asic(desc, tp->rx_buf_sz); | ||
611 | } else { | ||
612 | pci_unmap_single(pdev, addr, tp->rx_buf_sz, | ||
613 | PCI_DMA_FROMDEVICE); | ||
609 | tp->Rx_skbuff[entry] = NULL; | 614 | tp->Rx_skbuff[entry] = NULL; |
610 | sis190_make_unusable_by_asic(desc); | 615 | sis190_make_unusable_by_asic(desc); |
611 | } | 616 | } |
612 | 617 | ||
613 | pci_action(tp->pci_dev, le32_to_cpu(desc->addr), | ||
614 | tp->rx_buf_sz, PCI_DMA_FROMDEVICE); | ||
615 | |||
616 | skb_put(skb, pkt_size); | 618 | skb_put(skb, pkt_size); |
617 | skb->protocol = eth_type_trans(skb, dev); | 619 | skb->protocol = eth_type_trans(skb, dev); |
618 | 620 | ||