diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/synclink_gt.c | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 2f07b085536b..bd3821679ac8 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -461,7 +461,7 @@ static int adapter_test(struct slgt_info *info); | |||
461 | static void reset_adapter(struct slgt_info *info); | 461 | static void reset_adapter(struct slgt_info *info); |
462 | static void reset_port(struct slgt_info *info); | 462 | static void reset_port(struct slgt_info *info); |
463 | static void async_mode(struct slgt_info *info); | 463 | static void async_mode(struct slgt_info *info); |
464 | static void hdlc_mode(struct slgt_info *info); | 464 | static void sync_mode(struct slgt_info *info); |
465 | 465 | ||
466 | static void rx_stop(struct slgt_info *info); | 466 | static void rx_stop(struct slgt_info *info); |
467 | static void rx_start(struct slgt_info *info); | 467 | static void rx_start(struct slgt_info *info); |
@@ -881,7 +881,9 @@ static int write(struct tty_struct *tty, | |||
881 | if (!count) | 881 | if (!count) |
882 | goto cleanup; | 882 | goto cleanup; |
883 | 883 | ||
884 | if (info->params.mode == MGSL_MODE_RAW) { | 884 | if (info->params.mode == MGSL_MODE_RAW || |
885 | info->params.mode == MGSL_MODE_MONOSYNC || | ||
886 | info->params.mode == MGSL_MODE_BISYNC) { | ||
885 | unsigned int bufs_needed = (count/DMABUFSIZE); | 887 | unsigned int bufs_needed = (count/DMABUFSIZE); |
886 | unsigned int bufs_free = free_tbuf_count(info); | 888 | unsigned int bufs_free = free_tbuf_count(info); |
887 | if (count % DMABUFSIZE) | 889 | if (count % DMABUFSIZE) |
@@ -1897,6 +1899,8 @@ static void bh_handler(void* context) | |||
1897 | while(rx_get_frame(info)); | 1899 | while(rx_get_frame(info)); |
1898 | break; | 1900 | break; |
1899 | case MGSL_MODE_RAW: | 1901 | case MGSL_MODE_RAW: |
1902 | case MGSL_MODE_MONOSYNC: | ||
1903 | case MGSL_MODE_BISYNC: | ||
1900 | while(rx_get_buf(info)); | 1904 | while(rx_get_buf(info)); |
1901 | break; | 1905 | break; |
1902 | } | 1906 | } |
@@ -2362,10 +2366,9 @@ static void program_hw(struct slgt_info *info) | |||
2362 | rx_stop(info); | 2366 | rx_stop(info); |
2363 | tx_stop(info); | 2367 | tx_stop(info); |
2364 | 2368 | ||
2365 | if (info->params.mode == MGSL_MODE_HDLC || | 2369 | if (info->params.mode != MGSL_MODE_ASYNC || |
2366 | info->params.mode == MGSL_MODE_RAW || | ||
2367 | info->netcount) | 2370 | info->netcount) |
2368 | hdlc_mode(info); | 2371 | sync_mode(info); |
2369 | else | 2372 | else |
2370 | async_mode(info); | 2373 | async_mode(info); |
2371 | 2374 | ||
@@ -2564,6 +2567,10 @@ static int rx_enable(struct slgt_info *info, int enable) | |||
2564 | if (enable) { | 2567 | if (enable) { |
2565 | if (!info->rx_enabled) | 2568 | if (!info->rx_enabled) |
2566 | rx_start(info); | 2569 | rx_start(info); |
2570 | else if (enable == 2) { | ||
2571 | /* force hunt mode (write 1 to RCR[3]) */ | ||
2572 | wr_reg16(info, RCR, rd_reg16(info, RCR) | BIT3); | ||
2573 | } | ||
2567 | } else { | 2574 | } else { |
2568 | if (info->rx_enabled) | 2575 | if (info->rx_enabled) |
2569 | rx_stop(info); | 2576 | rx_stop(info); |
@@ -3748,7 +3755,7 @@ static void tx_start(struct slgt_info *info) | |||
3748 | { | 3755 | { |
3749 | if (!info->tx_enabled) { | 3756 | if (!info->tx_enabled) { |
3750 | wr_reg16(info, TCR, | 3757 | wr_reg16(info, TCR, |
3751 | (unsigned short)(rd_reg16(info, TCR) | BIT1)); | 3758 | (unsigned short)((rd_reg16(info, TCR) | BIT1) & ~BIT2)); |
3752 | info->tx_enabled = TRUE; | 3759 | info->tx_enabled = TRUE; |
3753 | } | 3760 | } |
3754 | 3761 | ||
@@ -3775,13 +3782,18 @@ static void tx_start(struct slgt_info *info) | |||
3775 | tdma_reset(info); | 3782 | tdma_reset(info); |
3776 | /* set 1st descriptor address */ | 3783 | /* set 1st descriptor address */ |
3777 | wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); | 3784 | wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); |
3778 | if (info->params.mode == MGSL_MODE_RAW) | 3785 | switch(info->params.mode) { |
3786 | case MGSL_MODE_RAW: | ||
3787 | case MGSL_MODE_MONOSYNC: | ||
3788 | case MGSL_MODE_BISYNC: | ||
3779 | wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */ | 3789 | wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */ |
3780 | else | 3790 | break; |
3791 | default: | ||
3781 | wr_reg32(info, TDCSR, BIT0); /* DMA enable */ | 3792 | wr_reg32(info, TDCSR, BIT0); /* DMA enable */ |
3793 | } | ||
3782 | } | 3794 | } |
3783 | 3795 | ||
3784 | if (info->params.mode != MGSL_MODE_RAW) { | 3796 | if (info->params.mode == MGSL_MODE_HDLC) { |
3785 | info->tx_timer.expires = jiffies + msecs_to_jiffies(5000); | 3797 | info->tx_timer.expires = jiffies + msecs_to_jiffies(5000); |
3786 | add_timer(&info->tx_timer); | 3798 | add_timer(&info->tx_timer); |
3787 | } | 3799 | } |
@@ -3814,7 +3826,6 @@ static void tx_stop(struct slgt_info *info) | |||
3814 | /* reset and disable transmitter */ | 3826 | /* reset and disable transmitter */ |
3815 | val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */ | 3827 | val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */ |
3816 | wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ | 3828 | wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ |
3817 | wr_reg16(info, TCR, val); /* clear reset */ | ||
3818 | 3829 | ||
3819 | slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); | 3830 | slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); |
3820 | 3831 | ||
@@ -3982,7 +3993,7 @@ static void async_mode(struct slgt_info *info) | |||
3982 | enable_loopback(info); | 3993 | enable_loopback(info); |
3983 | } | 3994 | } |
3984 | 3995 | ||
3985 | static void hdlc_mode(struct slgt_info *info) | 3996 | static void sync_mode(struct slgt_info *info) |
3986 | { | 3997 | { |
3987 | unsigned short val; | 3998 | unsigned short val; |
3988 | 3999 | ||
@@ -3992,7 +4003,7 @@ static void hdlc_mode(struct slgt_info *info) | |||
3992 | 4003 | ||
3993 | /* TCR (tx control) | 4004 | /* TCR (tx control) |
3994 | * | 4005 | * |
3995 | * 15..13 mode, 000=HDLC 001=raw sync | 4006 | * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync |
3996 | * 12..10 encoding | 4007 | * 12..10 encoding |
3997 | * 09 CRC enable | 4008 | * 09 CRC enable |
3998 | * 08 CRC32 | 4009 | * 08 CRC32 |
@@ -4006,8 +4017,11 @@ static void hdlc_mode(struct slgt_info *info) | |||
4006 | */ | 4017 | */ |
4007 | val = 0; | 4018 | val = 0; |
4008 | 4019 | ||
4009 | if (info->params.mode == MGSL_MODE_RAW) | 4020 | switch(info->params.mode) { |
4010 | val |= BIT13; | 4021 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; |
4022 | case MGSL_MODE_BISYNC: val |= BIT15; break; | ||
4023 | case MGSL_MODE_RAW: val |= BIT13; break; | ||
4024 | } | ||
4011 | if (info->if_mode & MGSL_INTERFACE_RTS_EN) | 4025 | if (info->if_mode & MGSL_INTERFACE_RTS_EN) |
4012 | val |= BIT7; | 4026 | val |= BIT7; |
4013 | 4027 | ||
@@ -4058,7 +4072,7 @@ static void hdlc_mode(struct slgt_info *info) | |||
4058 | 4072 | ||
4059 | /* RCR (rx control) | 4073 | /* RCR (rx control) |
4060 | * | 4074 | * |
4061 | * 15..13 mode, 000=HDLC 001=raw sync | 4075 | * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync |
4062 | * 12..10 encoding | 4076 | * 12..10 encoding |
4063 | * 09 CRC enable | 4077 | * 09 CRC enable |
4064 | * 08 CRC32 | 4078 | * 08 CRC32 |
@@ -4069,8 +4083,11 @@ static void hdlc_mode(struct slgt_info *info) | |||
4069 | */ | 4083 | */ |
4070 | val = 0; | 4084 | val = 0; |
4071 | 4085 | ||
4072 | if (info->params.mode == MGSL_MODE_RAW) | 4086 | switch(info->params.mode) { |
4073 | val |= BIT13; | 4087 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; |
4088 | case MGSL_MODE_BISYNC: val |= BIT15; break; | ||
4089 | case MGSL_MODE_RAW: val |= BIT13; break; | ||
4090 | } | ||
4074 | 4091 | ||
4075 | switch(info->params.encoding) | 4092 | switch(info->params.encoding) |
4076 | { | 4093 | { |
@@ -4309,10 +4326,15 @@ static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last | |||
4309 | while(!done) { | 4326 | while(!done) { |
4310 | /* reset current buffer for reuse */ | 4327 | /* reset current buffer for reuse */ |
4311 | info->rbufs[i].status = 0; | 4328 | info->rbufs[i].status = 0; |
4312 | if (info->params.mode == MGSL_MODE_RAW) | 4329 | switch(info->params.mode) { |
4330 | case MGSL_MODE_RAW: | ||
4331 | case MGSL_MODE_MONOSYNC: | ||
4332 | case MGSL_MODE_BISYNC: | ||
4313 | set_desc_count(info->rbufs[i], info->raw_rx_size); | 4333 | set_desc_count(info->rbufs[i], info->raw_rx_size); |
4314 | else | 4334 | break; |
4335 | default: | ||
4315 | set_desc_count(info->rbufs[i], DMABUFSIZE); | 4336 | set_desc_count(info->rbufs[i], DMABUFSIZE); |
4337 | } | ||
4316 | 4338 | ||
4317 | if (i == last) | 4339 | if (i == last) |
4318 | done = 1; | 4340 | done = 1; |
@@ -4477,13 +4499,24 @@ cleanup: | |||
4477 | static int rx_get_buf(struct slgt_info *info) | 4499 | static int rx_get_buf(struct slgt_info *info) |
4478 | { | 4500 | { |
4479 | unsigned int i = info->rbuf_current; | 4501 | unsigned int i = info->rbuf_current; |
4502 | unsigned int count; | ||
4480 | 4503 | ||
4481 | if (!desc_complete(info->rbufs[i])) | 4504 | if (!desc_complete(info->rbufs[i])) |
4482 | return 0; | 4505 | return 0; |
4483 | DBGDATA(info, info->rbufs[i].buf, desc_count(info->rbufs[i]), "rx"); | 4506 | count = desc_count(info->rbufs[i]); |
4484 | DBGINFO(("rx_get_buf size=%d\n", desc_count(info->rbufs[i]))); | 4507 | switch(info->params.mode) { |
4485 | ldisc_receive_buf(info->tty, info->rbufs[i].buf, | 4508 | case MGSL_MODE_MONOSYNC: |
4486 | info->flag_buf, desc_count(info->rbufs[i])); | 4509 | case MGSL_MODE_BISYNC: |
4510 | /* ignore residue in byte synchronous modes */ | ||
4511 | if (desc_residue(info->rbufs[i])) | ||
4512 | count--; | ||
4513 | break; | ||
4514 | } | ||
4515 | DBGDATA(info, info->rbufs[i].buf, count, "rx"); | ||
4516 | DBGINFO(("rx_get_buf size=%d\n", count)); | ||
4517 | if (count) | ||
4518 | ldisc_receive_buf(info->tty, info->rbufs[i].buf, | ||
4519 | info->flag_buf, count); | ||
4487 | free_rbufs(info, i, i); | 4520 | free_rbufs(info, i, i); |
4488 | return 1; | 4521 | return 1; |
4489 | } | 4522 | } |
@@ -4549,8 +4582,13 @@ static void tx_load(struct slgt_info *info, const char *buf, unsigned int size) | |||
4549 | size -= count; | 4582 | size -= count; |
4550 | buf += count; | 4583 | buf += count; |
4551 | 4584 | ||
4552 | if (!size && info->params.mode != MGSL_MODE_RAW) | 4585 | /* |
4553 | set_desc_eof(*d, 1); /* HDLC: set EOF of last desc */ | 4586 | * set EOF bit for last buffer of HDLC frame or |
4587 | * for every buffer in raw mode | ||
4588 | */ | ||
4589 | if ((!size && info->params.mode == MGSL_MODE_HDLC) || | ||
4590 | info->params.mode == MGSL_MODE_RAW) | ||
4591 | set_desc_eof(*d, 1); | ||
4554 | else | 4592 | else |
4555 | set_desc_eof(*d, 0); | 4593 | set_desc_eof(*d, 0); |
4556 | 4594 | ||