[PATCH] synclink_gt: add bisync and monosync modes

Add bisync and monosync serial protocol support to the synclink_gt driver.

Signed-off-by: Paul Fulghum <paulkf@microgate.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Paul Fulghum 2006-09-30 23:27:45 -07:00 committed by Linus Torvalds
parent 3c1fcfe229
commit cb10dc9ac7
2 changed files with 66 additions and 26 deletions

View File

@ -461,7 +461,7 @@ static int adapter_test(struct slgt_info *info);
static void reset_adapter(struct slgt_info *info); static void reset_adapter(struct slgt_info *info);
static void reset_port(struct slgt_info *info); static void reset_port(struct slgt_info *info);
static void async_mode(struct slgt_info *info); static void async_mode(struct slgt_info *info);
static void hdlc_mode(struct slgt_info *info); static void sync_mode(struct slgt_info *info);
static void rx_stop(struct slgt_info *info); static void rx_stop(struct slgt_info *info);
static void rx_start(struct slgt_info *info); static void rx_start(struct slgt_info *info);
@ -881,7 +881,9 @@ static int write(struct tty_struct *tty,
if (!count) if (!count)
goto cleanup; goto cleanup;
if (info->params.mode == MGSL_MODE_RAW) { if (info->params.mode == MGSL_MODE_RAW ||
info->params.mode == MGSL_MODE_MONOSYNC ||
info->params.mode == MGSL_MODE_BISYNC) {
unsigned int bufs_needed = (count/DMABUFSIZE); unsigned int bufs_needed = (count/DMABUFSIZE);
unsigned int bufs_free = free_tbuf_count(info); unsigned int bufs_free = free_tbuf_count(info);
if (count % DMABUFSIZE) if (count % DMABUFSIZE)
@ -1897,6 +1899,8 @@ static void bh_handler(void* context)
while(rx_get_frame(info)); while(rx_get_frame(info));
break; break;
case MGSL_MODE_RAW: case MGSL_MODE_RAW:
case MGSL_MODE_MONOSYNC:
case MGSL_MODE_BISYNC:
while(rx_get_buf(info)); while(rx_get_buf(info));
break; break;
} }
@ -2362,10 +2366,9 @@ static void program_hw(struct slgt_info *info)
rx_stop(info); rx_stop(info);
tx_stop(info); tx_stop(info);
if (info->params.mode == MGSL_MODE_HDLC || if (info->params.mode != MGSL_MODE_ASYNC ||
info->params.mode == MGSL_MODE_RAW ||
info->netcount) info->netcount)
hdlc_mode(info); sync_mode(info);
else else
async_mode(info); async_mode(info);
@ -2564,6 +2567,10 @@ static int rx_enable(struct slgt_info *info, int enable)
if (enable) { if (enable) {
if (!info->rx_enabled) if (!info->rx_enabled)
rx_start(info); rx_start(info);
else if (enable == 2) {
/* force hunt mode (write 1 to RCR[3]) */
wr_reg16(info, RCR, rd_reg16(info, RCR) | BIT3);
}
} else { } else {
if (info->rx_enabled) if (info->rx_enabled)
rx_stop(info); rx_stop(info);
@ -3748,7 +3755,7 @@ static void tx_start(struct slgt_info *info)
{ {
if (!info->tx_enabled) { if (!info->tx_enabled) {
wr_reg16(info, TCR, wr_reg16(info, TCR,
(unsigned short)(rd_reg16(info, TCR) | BIT1)); (unsigned short)((rd_reg16(info, TCR) | BIT1) & ~BIT2));
info->tx_enabled = TRUE; info->tx_enabled = TRUE;
} }
@ -3775,13 +3782,18 @@ static void tx_start(struct slgt_info *info)
tdma_reset(info); tdma_reset(info);
/* set 1st descriptor address */ /* set 1st descriptor address */
wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
if (info->params.mode == MGSL_MODE_RAW) switch(info->params.mode) {
case MGSL_MODE_RAW:
case MGSL_MODE_MONOSYNC:
case MGSL_MODE_BISYNC:
wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */ wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
else break;
default:
wr_reg32(info, TDCSR, BIT0); /* DMA enable */ wr_reg32(info, TDCSR, BIT0); /* DMA enable */
} }
}
if (info->params.mode != MGSL_MODE_RAW) { if (info->params.mode == MGSL_MODE_HDLC) {
info->tx_timer.expires = jiffies + msecs_to_jiffies(5000); info->tx_timer.expires = jiffies + msecs_to_jiffies(5000);
add_timer(&info->tx_timer); add_timer(&info->tx_timer);
} }
@ -3814,7 +3826,6 @@ static void tx_stop(struct slgt_info *info)
/* reset and disable transmitter */ /* reset and disable transmitter */
val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */ val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */
wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */
wr_reg16(info, TCR, val); /* clear reset */
slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER);
@ -3982,7 +3993,7 @@ static void async_mode(struct slgt_info *info)
enable_loopback(info); enable_loopback(info);
} }
static void hdlc_mode(struct slgt_info *info) static void sync_mode(struct slgt_info *info)
{ {
unsigned short val; unsigned short val;
@ -3992,7 +4003,7 @@ static void hdlc_mode(struct slgt_info *info)
/* TCR (tx control) /* TCR (tx control)
* *
* 15..13 mode, 000=HDLC 001=raw sync * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync
* 12..10 encoding * 12..10 encoding
* 09 CRC enable * 09 CRC enable
* 08 CRC32 * 08 CRC32
@ -4006,8 +4017,11 @@ static void hdlc_mode(struct slgt_info *info)
*/ */
val = 0; val = 0;
if (info->params.mode == MGSL_MODE_RAW) switch(info->params.mode) {
val |= BIT13; case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
case MGSL_MODE_BISYNC: val |= BIT15; break;
case MGSL_MODE_RAW: val |= BIT13; break;
}
if (info->if_mode & MGSL_INTERFACE_RTS_EN) if (info->if_mode & MGSL_INTERFACE_RTS_EN)
val |= BIT7; val |= BIT7;
@ -4058,7 +4072,7 @@ static void hdlc_mode(struct slgt_info *info)
/* RCR (rx control) /* RCR (rx control)
* *
* 15..13 mode, 000=HDLC 001=raw sync * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync
* 12..10 encoding * 12..10 encoding
* 09 CRC enable * 09 CRC enable
* 08 CRC32 * 08 CRC32
@ -4069,8 +4083,11 @@ static void hdlc_mode(struct slgt_info *info)
*/ */
val = 0; val = 0;
if (info->params.mode == MGSL_MODE_RAW) switch(info->params.mode) {
val |= BIT13; case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
case MGSL_MODE_BISYNC: val |= BIT15; break;
case MGSL_MODE_RAW: val |= BIT13; break;
}
switch(info->params.encoding) switch(info->params.encoding)
{ {
@ -4309,10 +4326,15 @@ static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last
while(!done) { while(!done) {
/* reset current buffer for reuse */ /* reset current buffer for reuse */
info->rbufs[i].status = 0; info->rbufs[i].status = 0;
if (info->params.mode == MGSL_MODE_RAW) switch(info->params.mode) {
case MGSL_MODE_RAW:
case MGSL_MODE_MONOSYNC:
case MGSL_MODE_BISYNC:
set_desc_count(info->rbufs[i], info->raw_rx_size); set_desc_count(info->rbufs[i], info->raw_rx_size);
else break;
default:
set_desc_count(info->rbufs[i], DMABUFSIZE); set_desc_count(info->rbufs[i], DMABUFSIZE);
}
if (i == last) if (i == last)
done = 1; done = 1;
@ -4477,13 +4499,24 @@ static int rx_get_frame(struct slgt_info *info)
static int rx_get_buf(struct slgt_info *info) static int rx_get_buf(struct slgt_info *info)
{ {
unsigned int i = info->rbuf_current; unsigned int i = info->rbuf_current;
unsigned int count;
if (!desc_complete(info->rbufs[i])) if (!desc_complete(info->rbufs[i]))
return 0; return 0;
DBGDATA(info, info->rbufs[i].buf, desc_count(info->rbufs[i]), "rx"); count = desc_count(info->rbufs[i]);
DBGINFO(("rx_get_buf size=%d\n", desc_count(info->rbufs[i]))); switch(info->params.mode) {
case MGSL_MODE_MONOSYNC:
case MGSL_MODE_BISYNC:
/* ignore residue in byte synchronous modes */
if (desc_residue(info->rbufs[i]))
count--;
break;
}
DBGDATA(info, info->rbufs[i].buf, count, "rx");
DBGINFO(("rx_get_buf size=%d\n", count));
if (count)
ldisc_receive_buf(info->tty, info->rbufs[i].buf, ldisc_receive_buf(info->tty, info->rbufs[i].buf,
info->flag_buf, desc_count(info->rbufs[i])); info->flag_buf, count);
free_rbufs(info, i, i); free_rbufs(info, i, i);
return 1; return 1;
} }
@ -4549,8 +4582,13 @@ static void tx_load(struct slgt_info *info, const char *buf, unsigned int size)
size -= count; size -= count;
buf += count; buf += count;
if (!size && info->params.mode != MGSL_MODE_RAW) /*
set_desc_eof(*d, 1); /* HDLC: set EOF of last desc */ * set EOF bit for last buffer of HDLC frame or
* for every buffer in raw mode
*/
if ((!size && info->params.mode == MGSL_MODE_HDLC) ||
info->params.mode == MGSL_MODE_RAW)
set_desc_eof(*d, 1);
else else
set_desc_eof(*d, 0); set_desc_eof(*d, 0);

View File

@ -1,7 +1,7 @@
/* /*
* SyncLink Multiprotocol Serial Adapter Driver * SyncLink Multiprotocol Serial Adapter Driver
* *
* $Id: synclink.h,v 3.13 2006/05/23 18:25:06 paulkf Exp $ * $Id: synclink.h,v 3.14 2006/07/17 20:15:43 paulkf Exp $
* *
* Copyright (C) 1998-2000 by Microgate Corporation * Copyright (C) 1998-2000 by Microgate Corporation
* *
@ -124,6 +124,8 @@
#define MGSL_MODE_ASYNC 1 #define MGSL_MODE_ASYNC 1
#define MGSL_MODE_HDLC 2 #define MGSL_MODE_HDLC 2
#define MGSL_MODE_MONOSYNC 3
#define MGSL_MODE_BISYNC 4
#define MGSL_MODE_RAW 6 #define MGSL_MODE_RAW 6
#define MGSL_BUS_TYPE_ISA 1 #define MGSL_BUS_TYPE_ISA 1