aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/sis190.c54
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
521static int sis190_try_rx_copy(struct sis190_private *tp, 521static 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;
541out:
542 return done;
540} 543}
541 544
542static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats) 545static 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