Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'sis190' of git://git.kernel.org/pub/scm/linux/kernel/git/romieu/netdev-2.6 into upstream

authored by

Jeff Garzik and committed by
Jeff Garzik
090bf621 8ceee660

+81 -55
+81 -55
drivers/net/sis190.c
··· 212 212 THOL2 = 0x20000000, 213 213 THOL1 = 0x10000000, 214 214 THOL0 = 0x00000000, 215 + 216 + WND = 0x00080000, 217 + TABRT = 0x00040000, 218 + FIFO = 0x00020000, 219 + LINK = 0x00010000, 220 + ColCountMask = 0x0000ffff, 215 221 /* RxDesc.status */ 216 222 IPON = 0x20000000, 217 223 TCPON = 0x10000000, ··· 486 480 desc->status = 0x0; 487 481 } 488 482 489 - static int sis190_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, 490 - struct RxDesc *desc, u32 rx_buf_sz) 483 + static struct sk_buff *sis190_alloc_rx_skb(struct sis190_private *tp, 484 + struct RxDesc *desc) 491 485 { 486 + u32 rx_buf_sz = tp->rx_buf_sz; 492 487 struct sk_buff *skb; 493 - dma_addr_t mapping; 494 - int ret = 0; 495 488 496 - skb = dev_alloc_skb(rx_buf_sz); 497 - if (!skb) 498 - goto err_out; 489 + skb = netdev_alloc_skb(tp->dev, rx_buf_sz); 490 + if (likely(skb)) { 491 + dma_addr_t mapping; 499 492 500 - *sk_buff = skb; 493 + mapping = pci_map_single(tp->pci_dev, skb->data, tp->rx_buf_sz, 494 + PCI_DMA_FROMDEVICE); 495 + sis190_map_to_asic(desc, mapping, rx_buf_sz); 496 + } else 497 + sis190_make_unusable_by_asic(desc); 501 498 502 - mapping = pci_map_single(pdev, skb->data, rx_buf_sz, 503 - PCI_DMA_FROMDEVICE); 504 - 505 - sis190_map_to_asic(desc, mapping, rx_buf_sz); 506 - out: 507 - return ret; 508 - 509 - err_out: 510 - ret = -ENOMEM; 511 - sis190_make_unusable_by_asic(desc); 512 - goto out; 499 + return skb; 513 500 } 514 501 515 502 static u32 sis190_rx_fill(struct sis190_private *tp, struct net_device *dev, ··· 511 512 u32 cur; 512 513 513 514 for (cur = start; cur < end; cur++) { 514 - int ret, i = cur % NUM_RX_DESC; 515 + unsigned int i = cur % NUM_RX_DESC; 515 516 516 517 if (tp->Rx_skbuff[i]) 517 518 continue; 518 519 519 - ret = sis190_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i, 520 - tp->RxDescRing + i, tp->rx_buf_sz); 521 - if (ret < 0) 520 + tp->Rx_skbuff[i] = sis190_alloc_rx_skb(tp, tp->RxDescRing + i); 521 + 522 + if (!tp->Rx_skbuff[i]) 522 523 break; 523 524 } 524 525 return cur - start; 525 526 } 526 527 527 - static inline int sis190_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, 528 - struct RxDesc *desc, int rx_buf_sz) 528 + static bool sis190_try_rx_copy(struct sis190_private *tp, 529 + struct sk_buff **sk_buff, int pkt_size, 530 + dma_addr_t addr) 529 531 { 530 - int ret = -1; 532 + struct sk_buff *skb; 533 + bool done = false; 531 534 532 - if (pkt_size < rx_copybreak) { 533 - struct sk_buff *skb; 535 + if (pkt_size >= rx_copybreak) 536 + goto out; 534 537 535 - skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); 536 - if (skb) { 537 - skb_reserve(skb, NET_IP_ALIGN); 538 - skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size); 539 - *sk_buff = skb; 540 - sis190_give_to_asic(desc, rx_buf_sz); 541 - ret = 0; 542 - } 543 - } 544 - return ret; 538 + skb = netdev_alloc_skb(tp->dev, pkt_size + 2); 539 + if (!skb) 540 + goto out; 541 + 542 + pci_dma_sync_single_for_device(tp->pci_dev, addr, pkt_size, 543 + PCI_DMA_FROMDEVICE); 544 + skb_reserve(skb, 2); 545 + skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size); 546 + *sk_buff = skb; 547 + done = true; 548 + out: 549 + return done; 545 550 } 546 551 547 552 static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats) ··· 595 592 sis190_give_to_asic(desc, tp->rx_buf_sz); 596 593 else { 597 594 struct sk_buff *skb = tp->Rx_skbuff[entry]; 595 + dma_addr_t addr = le32_to_cpu(desc->addr); 598 596 int pkt_size = (status & RxSizeMask) - 4; 599 - void (*pci_action)(struct pci_dev *, dma_addr_t, 600 - size_t, int) = pci_dma_sync_single_for_device; 597 + struct pci_dev *pdev = tp->pci_dev; 601 598 602 599 if (unlikely(pkt_size > tp->rx_buf_sz)) { 603 600 net_intr(tp, KERN_INFO ··· 609 606 continue; 610 607 } 611 608 612 - pci_dma_sync_single_for_cpu(tp->pci_dev, 613 - le32_to_cpu(desc->addr), tp->rx_buf_sz, 614 - PCI_DMA_FROMDEVICE); 615 609 616 - if (sis190_try_rx_copy(&skb, pkt_size, desc, 617 - tp->rx_buf_sz)) { 618 - pci_action = pci_unmap_single; 610 + if (sis190_try_rx_copy(tp, &skb, pkt_size, addr)) { 611 + pci_dma_sync_single_for_device(pdev, addr, 612 + tp->rx_buf_sz, PCI_DMA_FROMDEVICE); 613 + sis190_give_to_asic(desc, tp->rx_buf_sz); 614 + } else { 615 + pci_unmap_single(pdev, addr, tp->rx_buf_sz, 616 + PCI_DMA_FROMDEVICE); 619 617 tp->Rx_skbuff[entry] = NULL; 620 618 sis190_make_unusable_by_asic(desc); 621 619 } 622 - 623 - pci_action(tp->pci_dev, le32_to_cpu(desc->addr), 624 - tp->rx_buf_sz, PCI_DMA_FROMDEVICE); 625 620 626 621 skb_put(skb, pkt_size); 627 622 skb->protocol = eth_type_trans(skb, dev); ··· 659 658 memset(desc, 0x00, sizeof(*desc)); 660 659 } 661 660 661 + static inline int sis190_tx_pkt_err(u32 status, struct net_device_stats *stats) 662 + { 663 + #define TxErrMask (WND | TABRT | FIFO | LINK) 664 + 665 + if (!unlikely(status & TxErrMask)) 666 + return 0; 667 + 668 + if (status & WND) 669 + stats->tx_window_errors++; 670 + if (status & TABRT) 671 + stats->tx_aborted_errors++; 672 + if (status & FIFO) 673 + stats->tx_fifo_errors++; 674 + if (status & LINK) 675 + stats->tx_carrier_errors++; 676 + 677 + stats->tx_errors++; 678 + 679 + return -1; 680 + } 681 + 662 682 static void sis190_tx_interrupt(struct net_device *dev, 663 683 struct sis190_private *tp, void __iomem *ioaddr) 664 684 { 685 + struct net_device_stats *stats = &dev->stats; 665 686 u32 pending, dirty_tx = tp->dirty_tx; 666 687 /* 667 688 * It would not be needed if queueing was allowed to be enabled ··· 698 675 for (; pending; pending--, dirty_tx++) { 699 676 unsigned int entry = dirty_tx % NUM_TX_DESC; 700 677 struct TxDesc *txd = tp->TxDescRing + entry; 678 + u32 status = le32_to_cpu(txd->status); 701 679 struct sk_buff *skb; 702 680 703 - if (le32_to_cpu(txd->status) & OWNbit) 681 + if (status & OWNbit) 704 682 break; 705 683 706 684 skb = tp->Tx_skbuff[entry]; 707 685 708 - dev->stats.tx_packets++; 709 - dev->stats.tx_bytes += skb->len; 686 + if (likely(sis190_tx_pkt_err(status, stats) == 0)) { 687 + stats->tx_packets++; 688 + stats->tx_bytes += skb->len; 689 + stats->collisions += ((status & ColCountMask) - 1); 690 + } 710 691 711 692 sis190_unmap_tx_skb(tp->pci_dev, skb, txd); 712 693 tp->Tx_skbuff[entry] = NULL; ··· 931 904 mod_timer(&tp->timer, jiffies + HZ/10); 932 905 } else if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) & 933 906 BMSR_ANEGCOMPLETE)) { 934 - net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n", 935 - dev->name); 936 907 netif_carrier_off(dev); 937 - mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET); 908 + net_link(tp, KERN_WARNING "%s: auto-negotiating...\n", 909 + dev->name); 938 910 mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT); 939 911 } else { 940 912 /* Rejoice ! */