diff options
Diffstat (limited to 'drivers/net/wan/z85230.c')
-rw-r--r-- | drivers/net/wan/z85230.c | 193 |
1 files changed, 77 insertions, 116 deletions
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c index 98ef400908b8..243bd8d918fe 100644 --- a/drivers/net/wan/z85230.c +++ b/drivers/net/wan/z85230.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/netdevice.h> | 43 | #include <linux/netdevice.h> |
44 | #include <linux/if_arp.h> | 44 | #include <linux/if_arp.h> |
45 | #include <linux/delay.h> | 45 | #include <linux/delay.h> |
46 | #include <linux/hdlc.h> | ||
46 | #include <linux/ioport.h> | 47 | #include <linux/ioport.h> |
47 | #include <linux/init.h> | 48 | #include <linux/init.h> |
48 | #include <asm/dma.h> | 49 | #include <asm/dma.h> |
@@ -51,7 +52,6 @@ | |||
51 | #define RT_UNLOCK | 52 | #define RT_UNLOCK |
52 | #include <linux/spinlock.h> | 53 | #include <linux/spinlock.h> |
53 | 54 | ||
54 | #include <net/syncppp.h> | ||
55 | #include "z85230.h" | 55 | #include "z85230.h" |
56 | 56 | ||
57 | 57 | ||
@@ -440,51 +440,46 @@ static void z8530_tx(struct z8530_channel *c) | |||
440 | * A status event occurred in PIO synchronous mode. There are several | 440 | * A status event occurred in PIO synchronous mode. There are several |
441 | * reasons the chip will bother us here. A transmit underrun means we | 441 | * reasons the chip will bother us here. A transmit underrun means we |
442 | * failed to feed the chip fast enough and just broke a packet. A DCD | 442 | * failed to feed the chip fast enough and just broke a packet. A DCD |
443 | * change is a line up or down. We communicate that back to the protocol | 443 | * change is a line up or down. |
444 | * layer for synchronous PPP to renegotiate. | ||
445 | */ | 444 | */ |
446 | 445 | ||
447 | static void z8530_status(struct z8530_channel *chan) | 446 | static void z8530_status(struct z8530_channel *chan) |
448 | { | 447 | { |
449 | u8 status, altered; | 448 | u8 status, altered; |
450 | 449 | ||
451 | status=read_zsreg(chan, R0); | 450 | status = read_zsreg(chan, R0); |
452 | altered=chan->status^status; | 451 | altered = chan->status ^ status; |
453 | 452 | ||
454 | chan->status=status; | 453 | chan->status = status; |
455 | 454 | ||
456 | if(status&TxEOM) | 455 | if (status & TxEOM) { |
457 | { | ||
458 | /* printk("%s: Tx underrun.\n", chan->dev->name); */ | 456 | /* printk("%s: Tx underrun.\n", chan->dev->name); */ |
459 | chan->stats.tx_fifo_errors++; | 457 | chan->netdevice->stats.tx_fifo_errors++; |
460 | write_zsctrl(chan, ERR_RES); | 458 | write_zsctrl(chan, ERR_RES); |
461 | z8530_tx_done(chan); | 459 | z8530_tx_done(chan); |
462 | } | 460 | } |
463 | 461 | ||
464 | if(altered&chan->dcdcheck) | 462 | if (altered & chan->dcdcheck) |
465 | { | 463 | { |
466 | if(status&chan->dcdcheck) | 464 | if (status & chan->dcdcheck) { |
467 | { | ||
468 | printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); | 465 | printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); |
469 | write_zsreg(chan, R3, chan->regs[3]|RxENABLE); | 466 | write_zsreg(chan, R3, chan->regs[3] | RxENABLE); |
470 | if(chan->netdevice && | 467 | if (chan->netdevice) |
471 | ((chan->netdevice->type == ARPHRD_HDLC) || | 468 | netif_carrier_on(chan->netdevice); |
472 | (chan->netdevice->type == ARPHRD_PPP))) | 469 | } else { |
473 | sppp_reopen(chan->netdevice); | ||
474 | } | ||
475 | else | ||
476 | { | ||
477 | printk(KERN_INFO "%s: DCD lost\n", chan->dev->name); | 470 | printk(KERN_INFO "%s: DCD lost\n", chan->dev->name); |
478 | write_zsreg(chan, R3, chan->regs[3]&~RxENABLE); | 471 | write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE); |
479 | z8530_flush_fifo(chan); | 472 | z8530_flush_fifo(chan); |
473 | if (chan->netdevice) | ||
474 | netif_carrier_off(chan->netdevice); | ||
480 | } | 475 | } |
481 | 476 | ||
482 | } | 477 | } |
483 | write_zsctrl(chan, RES_EXT_INT); | 478 | write_zsctrl(chan, RES_EXT_INT); |
484 | write_zsctrl(chan, RES_H_IUS); | 479 | write_zsctrl(chan, RES_H_IUS); |
485 | } | 480 | } |
486 | 481 | ||
487 | struct z8530_irqhandler z8530_sync= | 482 | struct z8530_irqhandler z8530_sync = |
488 | { | 483 | { |
489 | z8530_rx, | 484 | z8530_rx, |
490 | z8530_tx, | 485 | z8530_tx, |
@@ -556,8 +551,7 @@ static void z8530_dma_tx(struct z8530_channel *chan) | |||
556 | * | 551 | * |
557 | * A status event occurred on the Z8530. We receive these for two reasons | 552 | * A status event occurred on the Z8530. We receive these for two reasons |
558 | * when in DMA mode. Firstly if we finished a packet transfer we get one | 553 | * when in DMA mode. Firstly if we finished a packet transfer we get one |
559 | * and kick the next packet out. Secondly we may see a DCD change and | 554 | * and kick the next packet out. Secondly we may see a DCD change. |
560 | * have to poke the protocol layer. | ||
561 | * | 555 | * |
562 | */ | 556 | */ |
563 | 557 | ||
@@ -586,24 +580,21 @@ static void z8530_dma_status(struct z8530_channel *chan) | |||
586 | } | 580 | } |
587 | } | 581 | } |
588 | 582 | ||
589 | if(altered&chan->dcdcheck) | 583 | if (altered & chan->dcdcheck) |
590 | { | 584 | { |
591 | if(status&chan->dcdcheck) | 585 | if (status & chan->dcdcheck) { |
592 | { | ||
593 | printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); | 586 | printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); |
594 | write_zsreg(chan, R3, chan->regs[3]|RxENABLE); | 587 | write_zsreg(chan, R3, chan->regs[3] | RxENABLE); |
595 | if(chan->netdevice && | 588 | if (chan->netdevice) |
596 | ((chan->netdevice->type == ARPHRD_HDLC) || | 589 | netif_carrier_on(chan->netdevice); |
597 | (chan->netdevice->type == ARPHRD_PPP))) | 590 | } else { |
598 | sppp_reopen(chan->netdevice); | ||
599 | } | ||
600 | else | ||
601 | { | ||
602 | printk(KERN_INFO "%s:DCD lost\n", chan->dev->name); | 591 | printk(KERN_INFO "%s:DCD lost\n", chan->dev->name); |
603 | write_zsreg(chan, R3, chan->regs[3]&~RxENABLE); | 592 | write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE); |
604 | z8530_flush_fifo(chan); | 593 | z8530_flush_fifo(chan); |
594 | if (chan->netdevice) | ||
595 | netif_carrier_off(chan->netdevice); | ||
605 | } | 596 | } |
606 | } | 597 | } |
607 | 598 | ||
608 | write_zsctrl(chan, RES_EXT_INT); | 599 | write_zsctrl(chan, RES_EXT_INT); |
609 | write_zsctrl(chan, RES_H_IUS); | 600 | write_zsctrl(chan, RES_H_IUS); |
@@ -1459,10 +1450,10 @@ static void z8530_tx_begin(struct z8530_channel *c) | |||
1459 | /* | 1450 | /* |
1460 | * Check if we crapped out. | 1451 | * Check if we crapped out. |
1461 | */ | 1452 | */ |
1462 | if(get_dma_residue(c->txdma)) | 1453 | if (get_dma_residue(c->txdma)) |
1463 | { | 1454 | { |
1464 | c->stats.tx_dropped++; | 1455 | c->netdevice->stats.tx_dropped++; |
1465 | c->stats.tx_fifo_errors++; | 1456 | c->netdevice->stats.tx_fifo_errors++; |
1466 | } | 1457 | } |
1467 | release_dma_lock(flags); | 1458 | release_dma_lock(flags); |
1468 | } | 1459 | } |
@@ -1534,21 +1525,21 @@ static void z8530_tx_begin(struct z8530_channel *c) | |||
1534 | * packet. This code is fairly timing sensitive. | 1525 | * packet. This code is fairly timing sensitive. |
1535 | * | 1526 | * |
1536 | * Called with the register lock held. | 1527 | * Called with the register lock held. |
1537 | */ | 1528 | */ |
1538 | 1529 | ||
1539 | static void z8530_tx_done(struct z8530_channel *c) | 1530 | static void z8530_tx_done(struct z8530_channel *c) |
1540 | { | 1531 | { |
1541 | struct sk_buff *skb; | 1532 | struct sk_buff *skb; |
1542 | 1533 | ||
1543 | /* Actually this can happen.*/ | 1534 | /* Actually this can happen.*/ |
1544 | if(c->tx_skb==NULL) | 1535 | if (c->tx_skb == NULL) |
1545 | return; | 1536 | return; |
1546 | 1537 | ||
1547 | skb=c->tx_skb; | 1538 | skb = c->tx_skb; |
1548 | c->tx_skb=NULL; | 1539 | c->tx_skb = NULL; |
1549 | z8530_tx_begin(c); | 1540 | z8530_tx_begin(c); |
1550 | c->stats.tx_packets++; | 1541 | c->netdevice->stats.tx_packets++; |
1551 | c->stats.tx_bytes+=skb->len; | 1542 | c->netdevice->stats.tx_bytes += skb->len; |
1552 | dev_kfree_skb_irq(skb); | 1543 | dev_kfree_skb_irq(skb); |
1553 | } | 1544 | } |
1554 | 1545 | ||
@@ -1558,7 +1549,7 @@ static void z8530_tx_done(struct z8530_channel *c) | |||
1558 | * @skb: The buffer | 1549 | * @skb: The buffer |
1559 | * | 1550 | * |
1560 | * We point the receive handler at this function when idle. Instead | 1551 | * We point the receive handler at this function when idle. Instead |
1561 | * of syncppp processing the frames we get to throw them away. | 1552 | * of processing the frames we get to throw them away. |
1562 | */ | 1553 | */ |
1563 | 1554 | ||
1564 | void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb) | 1555 | void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb) |
@@ -1635,10 +1626,11 @@ static void z8530_rx_done(struct z8530_channel *c) | |||
1635 | else | 1626 | else |
1636 | /* Can't occur as we dont reenable the DMA irq until | 1627 | /* Can't occur as we dont reenable the DMA irq until |
1637 | after the flip is done */ | 1628 | after the flip is done */ |
1638 | printk(KERN_WARNING "%s: DMA flip overrun!\n", c->netdevice->name); | 1629 | printk(KERN_WARNING "%s: DMA flip overrun!\n", |
1639 | 1630 | c->netdevice->name); | |
1631 | |||
1640 | release_dma_lock(flags); | 1632 | release_dma_lock(flags); |
1641 | 1633 | ||
1642 | /* | 1634 | /* |
1643 | * Shove the old buffer into an sk_buff. We can't DMA | 1635 | * Shove the old buffer into an sk_buff. We can't DMA |
1644 | * directly into one on a PC - it might be above the 16Mb | 1636 | * directly into one on a PC - it might be above the 16Mb |
@@ -1646,27 +1638,23 @@ static void z8530_rx_done(struct z8530_channel *c) | |||
1646 | * can avoid the copy. Optimisation 2 - make the memcpy | 1638 | * can avoid the copy. Optimisation 2 - make the memcpy |
1647 | * a copychecksum. | 1639 | * a copychecksum. |
1648 | */ | 1640 | */ |
1649 | 1641 | ||
1650 | skb=dev_alloc_skb(ct); | 1642 | skb = dev_alloc_skb(ct); |
1651 | if(skb==NULL) | 1643 | if (skb == NULL) { |
1652 | { | 1644 | c->netdevice->stats.rx_dropped++; |
1653 | c->stats.rx_dropped++; | 1645 | printk(KERN_WARNING "%s: Memory squeeze.\n", |
1654 | printk(KERN_WARNING "%s: Memory squeeze.\n", c->netdevice->name); | 1646 | c->netdevice->name); |
1655 | } | 1647 | } else { |
1656 | else | ||
1657 | { | ||
1658 | skb_put(skb, ct); | 1648 | skb_put(skb, ct); |
1659 | skb_copy_to_linear_data(skb, rxb, ct); | 1649 | skb_copy_to_linear_data(skb, rxb, ct); |
1660 | c->stats.rx_packets++; | 1650 | c->netdevice->stats.rx_packets++; |
1661 | c->stats.rx_bytes+=ct; | 1651 | c->netdevice->stats.rx_bytes += ct; |
1662 | } | 1652 | } |
1663 | c->dma_ready=1; | 1653 | c->dma_ready = 1; |
1664 | } | 1654 | } else { |
1665 | else | 1655 | RT_LOCK; |
1666 | { | 1656 | skb = c->skb; |
1667 | RT_LOCK; | 1657 | |
1668 | skb=c->skb; | ||
1669 | |||
1670 | /* | 1658 | /* |
1671 | * The game we play for non DMA is similar. We want to | 1659 | * The game we play for non DMA is similar. We want to |
1672 | * get the controller set up for the next packet as fast | 1660 | * get the controller set up for the next packet as fast |
@@ -1677,48 +1665,39 @@ static void z8530_rx_done(struct z8530_channel *c) | |||
1677 | * if you build a system where the sync irq isnt blocked | 1665 | * if you build a system where the sync irq isnt blocked |
1678 | * by the kernel IRQ disable then you need only block the | 1666 | * by the kernel IRQ disable then you need only block the |
1679 | * sync IRQ for the RT_LOCK area. | 1667 | * sync IRQ for the RT_LOCK area. |
1680 | * | 1668 | * |
1681 | */ | 1669 | */ |
1682 | ct=c->count; | 1670 | ct=c->count; |
1683 | 1671 | ||
1684 | c->skb = c->skb2; | 1672 | c->skb = c->skb2; |
1685 | c->count = 0; | 1673 | c->count = 0; |
1686 | c->max = c->mtu; | 1674 | c->max = c->mtu; |
1687 | if(c->skb) | 1675 | if (c->skb) { |
1688 | { | ||
1689 | c->dptr = c->skb->data; | 1676 | c->dptr = c->skb->data; |
1690 | c->max = c->mtu; | 1677 | c->max = c->mtu; |
1691 | } | 1678 | } else { |
1692 | else | 1679 | c->count = 0; |
1693 | { | ||
1694 | c->count= 0; | ||
1695 | c->max = 0; | 1680 | c->max = 0; |
1696 | } | 1681 | } |
1697 | RT_UNLOCK; | 1682 | RT_UNLOCK; |
1698 | 1683 | ||
1699 | c->skb2 = dev_alloc_skb(c->mtu); | 1684 | c->skb2 = dev_alloc_skb(c->mtu); |
1700 | if(c->skb2==NULL) | 1685 | if (c->skb2 == NULL) |
1701 | printk(KERN_WARNING "%s: memory squeeze.\n", | 1686 | printk(KERN_WARNING "%s: memory squeeze.\n", |
1702 | c->netdevice->name); | 1687 | c->netdevice->name); |
1703 | else | 1688 | else |
1704 | { | 1689 | skb_put(c->skb2, c->mtu); |
1705 | skb_put(c->skb2,c->mtu); | 1690 | c->netdevice->stats.rx_packets++; |
1706 | } | 1691 | c->netdevice->stats.rx_bytes += ct; |
1707 | c->stats.rx_packets++; | ||
1708 | c->stats.rx_bytes+=ct; | ||
1709 | |||
1710 | } | 1692 | } |
1711 | /* | 1693 | /* |
1712 | * If we received a frame we must now process it. | 1694 | * If we received a frame we must now process it. |
1713 | */ | 1695 | */ |
1714 | if(skb) | 1696 | if (skb) { |
1715 | { | ||
1716 | skb_trim(skb, ct); | 1697 | skb_trim(skb, ct); |
1717 | c->rx_function(c,skb); | 1698 | c->rx_function(c, skb); |
1718 | } | 1699 | } else { |
1719 | else | 1700 | c->netdevice->stats.rx_dropped++; |
1720 | { | ||
1721 | c->stats.rx_dropped++; | ||
1722 | printk(KERN_ERR "%s: Lost a frame\n", c->netdevice->name); | 1701 | printk(KERN_ERR "%s: Lost a frame\n", c->netdevice->name); |
1723 | } | 1702 | } |
1724 | } | 1703 | } |
@@ -1730,7 +1709,7 @@ static void z8530_rx_done(struct z8530_channel *c) | |||
1730 | * Returns true if the buffer cross a DMA boundary on a PC. The poor | 1709 | * Returns true if the buffer cross a DMA boundary on a PC. The poor |
1731 | * thing can only DMA within a 64K block not across the edges of it. | 1710 | * thing can only DMA within a 64K block not across the edges of it. |
1732 | */ | 1711 | */ |
1733 | 1712 | ||
1734 | static inline int spans_boundary(struct sk_buff *skb) | 1713 | static inline int spans_boundary(struct sk_buff *skb) |
1735 | { | 1714 | { |
1736 | unsigned long a=(unsigned long)skb->data; | 1715 | unsigned long a=(unsigned long)skb->data; |
@@ -1799,24 +1778,6 @@ int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb) | |||
1799 | 1778 | ||
1800 | EXPORT_SYMBOL(z8530_queue_xmit); | 1779 | EXPORT_SYMBOL(z8530_queue_xmit); |
1801 | 1780 | ||
1802 | /** | ||
1803 | * z8530_get_stats - Get network statistics | ||
1804 | * @c: The channel to use | ||
1805 | * | ||
1806 | * Get the statistics block. We keep the statistics in software as | ||
1807 | * the chip doesn't do it for us. | ||
1808 | * | ||
1809 | * Locking is ignored here - we could lock for a copy but its | ||
1810 | * not likely to be that big an issue | ||
1811 | */ | ||
1812 | |||
1813 | struct net_device_stats *z8530_get_stats(struct z8530_channel *c) | ||
1814 | { | ||
1815 | return &c->stats; | ||
1816 | } | ||
1817 | |||
1818 | EXPORT_SYMBOL(z8530_get_stats); | ||
1819 | |||
1820 | /* | 1781 | /* |
1821 | * Module support | 1782 | * Module support |
1822 | */ | 1783 | */ |