aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/synclink_gt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/synclink_gt.c')
-rw-r--r--drivers/char/synclink_gt.c72
1 files changed, 30 insertions, 42 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 1386625fc4ca..a2e67e6df3a1 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -467,7 +467,6 @@ static unsigned int free_tbuf_count(struct slgt_info *info);
467static unsigned int tbuf_bytes(struct slgt_info *info); 467static unsigned int tbuf_bytes(struct slgt_info *info);
468static void reset_tbufs(struct slgt_info *info); 468static void reset_tbufs(struct slgt_info *info);
469static void tdma_reset(struct slgt_info *info); 469static void tdma_reset(struct slgt_info *info);
470static void tdma_start(struct slgt_info *info);
471static void tx_load(struct slgt_info *info, const char *buf, unsigned int count); 470static void tx_load(struct slgt_info *info, const char *buf, unsigned int count);
472 471
473static void get_signals(struct slgt_info *info); 472static void get_signals(struct slgt_info *info);
@@ -795,6 +794,18 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
795 } 794 }
796} 795}
797 796
797static void update_tx_timer(struct slgt_info *info)
798{
799 /*
800 * use worst case speed of 1200bps to calculate transmit timeout
801 * based on data in buffers (tbuf_bytes) and FIFO (128 bytes)
802 */
803 if (info->params.mode == MGSL_MODE_HDLC) {
804 int timeout = (tbuf_bytes(info) * 7) + 1000;
805 mod_timer(&info->tx_timer, jiffies + msecs_to_jiffies(timeout));
806 }
807}
808
798static int write(struct tty_struct *tty, 809static int write(struct tty_struct *tty,
799 const unsigned char *buf, int count) 810 const unsigned char *buf, int count)
800{ 811{
@@ -838,8 +849,18 @@ start:
838 spin_lock_irqsave(&info->lock,flags); 849 spin_lock_irqsave(&info->lock,flags);
839 if (!info->tx_active) 850 if (!info->tx_active)
840 tx_start(info); 851 tx_start(info);
841 else 852 else if (!(rd_reg32(info, TDCSR) & BIT0)) {
842 tdma_start(info); 853 /* transmit still active but transmit DMA stopped */
854 unsigned int i = info->tbuf_current;
855 if (!i)
856 i = info->tbuf_count;
857 i--;
858 /* if DMA buf unsent must try later after tx idle */
859 if (desc_count(info->tbufs[i]))
860 ret = 0;
861 }
862 if (ret > 0)
863 update_tx_timer(info);
843 spin_unlock_irqrestore(&info->lock,flags); 864 spin_unlock_irqrestore(&info->lock,flags);
844 } 865 }
845 866
@@ -1502,10 +1523,9 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
1502 /* save start time for transmit timeout detection */ 1523 /* save start time for transmit timeout detection */
1503 dev->trans_start = jiffies; 1524 dev->trans_start = jiffies;
1504 1525
1505 /* start hardware transmitter if necessary */
1506 spin_lock_irqsave(&info->lock,flags); 1526 spin_lock_irqsave(&info->lock,flags);
1507 if (!info->tx_active) 1527 tx_start(info);
1508 tx_start(info); 1528 update_tx_timer(info);
1509 spin_unlock_irqrestore(&info->lock,flags); 1529 spin_unlock_irqrestore(&info->lock,flags);
1510 1530
1511 return 0; 1531 return 0;
@@ -3946,50 +3966,19 @@ static void tx_start(struct slgt_info *info)
3946 slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE); 3966 slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE);
3947 /* clear tx idle and underrun status bits */ 3967 /* clear tx idle and underrun status bits */
3948 wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); 3968 wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER));
3949 if (info->params.mode == MGSL_MODE_HDLC)
3950 mod_timer(&info->tx_timer, jiffies +
3951 msecs_to_jiffies(5000));
3952 } else { 3969 } else {
3953 slgt_irq_off(info, IRQ_TXDATA); 3970 slgt_irq_off(info, IRQ_TXDATA);
3954 slgt_irq_on(info, IRQ_TXIDLE); 3971 slgt_irq_on(info, IRQ_TXIDLE);
3955 /* clear tx idle status bit */ 3972 /* clear tx idle status bit */
3956 wr_reg16(info, SSR, IRQ_TXIDLE); 3973 wr_reg16(info, SSR, IRQ_TXIDLE);
3957 } 3974 }
3958 tdma_start(info); 3975 /* set 1st descriptor address and start DMA */
3976 wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
3977 wr_reg32(info, TDCSR, BIT2 + BIT0);
3959 info->tx_active = true; 3978 info->tx_active = true;
3960 } 3979 }
3961} 3980}
3962 3981
3963/*
3964 * start transmit DMA if inactive and there are unsent buffers
3965 */
3966static void tdma_start(struct slgt_info *info)
3967{
3968 unsigned int i;
3969
3970 if (rd_reg32(info, TDCSR) & BIT0)
3971 return;
3972
3973 /* transmit DMA inactive, check for unsent buffers */
3974 i = info->tbuf_start;
3975 while (!desc_count(info->tbufs[i])) {
3976 if (++i == info->tbuf_count)
3977 i = 0;
3978 if (i == info->tbuf_current)
3979 return;
3980 }
3981 info->tbuf_start = i;
3982
3983 /* there are unsent buffers, start transmit DMA */
3984
3985 /* reset needed if previous error condition */
3986 tdma_reset(info);
3987
3988 /* set 1st descriptor address */
3989 wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
3990 wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
3991}
3992
3993static void tx_stop(struct slgt_info *info) 3982static void tx_stop(struct slgt_info *info)
3994{ 3983{
3995 unsigned short val; 3984 unsigned short val;
@@ -5004,8 +4993,7 @@ static void tx_timeout(unsigned long context)
5004 info->icount.txtimeout++; 4993 info->icount.txtimeout++;
5005 } 4994 }
5006 spin_lock_irqsave(&info->lock,flags); 4995 spin_lock_irqsave(&info->lock,flags);
5007 info->tx_active = false; 4996 tx_stop(info);
5008 info->tx_count = 0;
5009 spin_unlock_irqrestore(&info->lock,flags); 4997 spin_unlock_irqrestore(&info->lock,flags);
5010 4998
5011#if SYNCLINK_GENERIC_HDLC 4999#if SYNCLINK_GENERIC_HDLC