aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/synclink_gt.c
diff options
context:
space:
mode:
authorPaul Fulghum <paulkf@microgate.com>2006-06-25 08:49:21 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:01:24 -0400
commit04b374d0f5a97761b91a0c3ff6d10f80abd206b0 (patch)
tree29fe696a534c6df75a149251031ba0be4f159083 /drivers/char/synclink_gt.c
parent643f3319b9132c768081ce94f938a29139a16de9 (diff)
[PATCH] add synclink_gt crc return feature
Add ability to return HDLC CRC to user application. Signed-off-by: Paul Fulghum <paulkf@microgate.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/synclink_gt.c')
-rw-r--r--drivers/char/synclink_gt.c55
1 files changed, 33 insertions, 22 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 6f93a0149fbf..03a7f20db49a 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -3077,7 +3077,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3077 3077
3078static int alloc_tmp_rbuf(struct slgt_info *info) 3078static int alloc_tmp_rbuf(struct slgt_info *info)
3079{ 3079{
3080 info->tmp_rbuf = kmalloc(info->max_frame_size, GFP_KERNEL); 3080 info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL);
3081 if (info->tmp_rbuf == NULL) 3081 if (info->tmp_rbuf == NULL)
3082 return -ENOMEM; 3082 return -ENOMEM;
3083 return 0; 3083 return 0;
@@ -4011,7 +4011,7 @@ static void hdlc_mode(struct slgt_info *info)
4011 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; 4011 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break;
4012 } 4012 }
4013 4013
4014 switch (info->params.crc_type) 4014 switch (info->params.crc_type & HDLC_CRC_MASK)
4015 { 4015 {
4016 case HDLC_CRC_16_CCITT: val |= BIT9; break; 4016 case HDLC_CRC_16_CCITT: val |= BIT9; break;
4017 case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; 4017 case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break;
@@ -4072,7 +4072,7 @@ static void hdlc_mode(struct slgt_info *info)
4072 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; 4072 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break;
4073 } 4073 }
4074 4074
4075 switch (info->params.crc_type) 4075 switch (info->params.crc_type & HDLC_CRC_MASK)
4076 { 4076 {
4077 case HDLC_CRC_16_CCITT: val |= BIT9; break; 4077 case HDLC_CRC_16_CCITT: val |= BIT9; break;
4078 case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; 4078 case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break;
@@ -4333,6 +4333,12 @@ static int rx_get_frame(struct slgt_info *info)
4333 unsigned long flags; 4333 unsigned long flags;
4334 struct tty_struct *tty = info->tty; 4334 struct tty_struct *tty = info->tty;
4335 unsigned char addr_field = 0xff; 4335 unsigned char addr_field = 0xff;
4336 unsigned int crc_size = 0;
4337
4338 switch (info->params.crc_type & HDLC_CRC_MASK) {
4339 case HDLC_CRC_16_CCITT: crc_size = 2; break;
4340 case HDLC_CRC_32_CCITT: crc_size = 4; break;
4341 }
4336 4342
4337check_again: 4343check_again:
4338 4344
@@ -4377,7 +4383,7 @@ check_again:
4377 status = desc_status(info->rbufs[end]); 4383 status = desc_status(info->rbufs[end]);
4378 4384
4379 /* ignore CRC bit if not using CRC (bit is undefined) */ 4385 /* ignore CRC bit if not using CRC (bit is undefined) */
4380 if (info->params.crc_type == HDLC_CRC_NONE) 4386 if ((info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_NONE)
4381 status &= ~BIT1; 4387 status &= ~BIT1;
4382 4388
4383 if (framesize == 0 || 4389 if (framesize == 0 ||
@@ -4386,34 +4392,34 @@ check_again:
4386 goto check_again; 4392 goto check_again;
4387 } 4393 }
4388 4394
4389 if (framesize < 2 || status & (BIT1+BIT0)) { 4395 if (framesize < (2 + crc_size) || status & BIT0) {
4390 if (framesize < 2 || (status & BIT0)) 4396 info->icount.rxshort++;
4391 info->icount.rxshort++;
4392 else
4393 info->icount.rxcrc++;
4394 framesize = 0; 4397 framesize = 0;
4398 } else if (status & BIT1) {
4399 info->icount.rxcrc++;
4400 if (!(info->params.crc_type & HDLC_CRC_RETURN_EX))
4401 framesize = 0;
4402 }
4395 4403
4396#ifdef CONFIG_HDLC 4404#ifdef CONFIG_HDLC
4397 { 4405 if (framesize == 0) {
4398 struct net_device_stats *stats = hdlc_stats(info->netdev); 4406 struct net_device_stats *stats = hdlc_stats(info->netdev);
4399 stats->rx_errors++; 4407 stats->rx_errors++;
4400 stats->rx_frame_errors++; 4408 stats->rx_frame_errors++;
4401 }
4402#endif
4403 } else {
4404 /* adjust frame size for CRC, if any */
4405 if (info->params.crc_type == HDLC_CRC_16_CCITT)
4406 framesize -= 2;
4407 else if (info->params.crc_type == HDLC_CRC_32_CCITT)
4408 framesize -= 4;
4409 } 4409 }
4410#endif
4410 4411
4411 DBGBH(("%s rx frame status=%04X size=%d\n", 4412 DBGBH(("%s rx frame status=%04X size=%d\n",
4412 info->device_name, status, framesize)); 4413 info->device_name, status, framesize));
4413 DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx"); 4414 DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx");
4414 4415
4415 if (framesize) { 4416 if (framesize) {
4416 if (framesize > info->max_frame_size) 4417 if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) {
4418 framesize -= crc_size;
4419 crc_size = 0;
4420 }
4421
4422 if (framesize > info->max_frame_size + crc_size)
4417 info->icount.rxlong++; 4423 info->icount.rxlong++;
4418 else { 4424 else {
4419 /* copy dma buffer(s) to contiguous temp buffer */ 4425 /* copy dma buffer(s) to contiguous temp buffer */
@@ -4433,6 +4439,11 @@ check_again:
4433 i = 0; 4439 i = 0;
4434 } 4440 }
4435 4441
4442 if (info->params.crc_type & HDLC_CRC_RETURN_EX) {
4443 *p = (status & BIT1) ? RX_CRC_ERROR : RX_OK;
4444 framesize++;
4445 }
4446
4436#ifdef CONFIG_HDLC 4447#ifdef CONFIG_HDLC
4437 if (info->netcount) 4448 if (info->netcount)
4438 hdlcdev_rx(info,info->tmp_rbuf, framesize); 4449 hdlcdev_rx(info,info->tmp_rbuf, framesize);