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.c119
1 files changed, 78 insertions, 41 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index b4d1f4eea435..4e35d4181224 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -101,6 +101,7 @@ MODULE_LICENSE("GPL");
101 101
102static struct pci_device_id pci_table[] = { 102static struct pci_device_id pci_table[] = {
103 {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, 103 {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
104 {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT2_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
104 {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, 105 {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
105 {PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, 106 {PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
106 {0,}, /* terminate list */ 107 {0,}, /* terminate list */
@@ -870,7 +871,7 @@ static int write(struct tty_struct *tty,
870 goto cleanup; 871 goto cleanup;
871 DBGINFO(("%s write count=%d\n", info->device_name, count)); 872 DBGINFO(("%s write count=%d\n", info->device_name, count));
872 873
873 if (!tty || !info->tx_buf) 874 if (!info->tx_buf)
874 goto cleanup; 875 goto cleanup;
875 876
876 if (count > info->max_frame_size) { 877 if (count > info->max_frame_size) {
@@ -924,7 +925,7 @@ static void put_char(struct tty_struct *tty, unsigned char ch)
924 if (sanity_check(info, tty->name, "put_char")) 925 if (sanity_check(info, tty->name, "put_char"))
925 return; 926 return;
926 DBGINFO(("%s put_char(%d)\n", info->device_name, ch)); 927 DBGINFO(("%s put_char(%d)\n", info->device_name, ch));
927 if (!tty || !info->tx_buf) 928 if (!info->tx_buf)
928 return; 929 return;
929 spin_lock_irqsave(&info->lock,flags); 930 spin_lock_irqsave(&info->lock,flags);
930 if (!info->tx_active && (info->tx_count < info->max_frame_size)) 931 if (!info->tx_active && (info->tx_count < info->max_frame_size))
@@ -2515,7 +2516,8 @@ static int set_txidle(struct slgt_info *info, int idle_mode)
2515 DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode)); 2516 DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode));
2516 spin_lock_irqsave(&info->lock,flags); 2517 spin_lock_irqsave(&info->lock,flags);
2517 info->idle_mode = idle_mode; 2518 info->idle_mode = idle_mode;
2518 tx_set_idle(info); 2519 if (info->params.mode != MGSL_MODE_ASYNC)
2520 tx_set_idle(info);
2519 spin_unlock_irqrestore(&info->lock,flags); 2521 spin_unlock_irqrestore(&info->lock,flags);
2520 return 0; 2522 return 0;
2521} 2523}
@@ -3076,7 +3078,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3076 3078
3077static int alloc_tmp_rbuf(struct slgt_info *info) 3079static int alloc_tmp_rbuf(struct slgt_info *info)
3078{ 3080{
3079 info->tmp_rbuf = kmalloc(info->max_frame_size, GFP_KERNEL); 3081 info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL);
3080 if (info->tmp_rbuf == NULL) 3082 if (info->tmp_rbuf == NULL)
3081 return -ENOMEM; 3083 return -ENOMEM;
3082 return 0; 3084 return 0;
@@ -3276,6 +3278,9 @@ static void add_device(struct slgt_info *info)
3276 case SYNCLINK_GT_DEVICE_ID: 3278 case SYNCLINK_GT_DEVICE_ID:
3277 devstr = "GT"; 3279 devstr = "GT";
3278 break; 3280 break;
3281 case SYNCLINK_GT2_DEVICE_ID:
3282 devstr = "GT2";
3283 break;
3279 case SYNCLINK_GT4_DEVICE_ID: 3284 case SYNCLINK_GT4_DEVICE_ID:
3280 devstr = "GT4"; 3285 devstr = "GT4";
3281 break; 3286 break;
@@ -3353,7 +3358,9 @@ static void device_init(int adapter_num, struct pci_dev *pdev)
3353 int i; 3358 int i;
3354 int port_count = 1; 3359 int port_count = 1;
3355 3360
3356 if (pdev->device == SYNCLINK_GT4_DEVICE_ID) 3361 if (pdev->device == SYNCLINK_GT2_DEVICE_ID)
3362 port_count = 2;
3363 else if (pdev->device == SYNCLINK_GT4_DEVICE_ID)
3357 port_count = 4; 3364 port_count = 4;
3358 3365
3359 /* allocate device instances for all ports */ 3366 /* allocate device instances for all ports */
@@ -3940,8 +3947,6 @@ static void async_mode(struct slgt_info *info)
3940 3947
3941 msc_set_vcr(info); 3948 msc_set_vcr(info);
3942 3949
3943 tx_set_idle(info);
3944
3945 /* SCR (serial control) 3950 /* SCR (serial control)
3946 * 3951 *
3947 * 15 1=tx req on FIFO half empty 3952 * 15 1=tx req on FIFO half empty
@@ -4012,7 +4017,7 @@ static void hdlc_mode(struct slgt_info *info)
4012 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; 4017 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break;
4013 } 4018 }
4014 4019
4015 switch (info->params.crc_type) 4020 switch (info->params.crc_type & HDLC_CRC_MASK)
4016 { 4021 {
4017 case HDLC_CRC_16_CCITT: val |= BIT9; break; 4022 case HDLC_CRC_16_CCITT: val |= BIT9; break;
4018 case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; 4023 case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break;
@@ -4073,7 +4078,7 @@ static void hdlc_mode(struct slgt_info *info)
4073 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; 4078 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break;
4074 } 4079 }
4075 4080
4076 switch (info->params.crc_type) 4081 switch (info->params.crc_type & HDLC_CRC_MASK)
4077 { 4082 {
4078 case HDLC_CRC_16_CCITT: val |= BIT9; break; 4083 case HDLC_CRC_16_CCITT: val |= BIT9; break;
4079 case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; 4084 case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break;
@@ -4175,17 +4180,38 @@ static void hdlc_mode(struct slgt_info *info)
4175 */ 4180 */
4176static void tx_set_idle(struct slgt_info *info) 4181static void tx_set_idle(struct slgt_info *info)
4177{ 4182{
4178 unsigned char val = 0xff; 4183 unsigned char val;
4184 unsigned short tcr;
4179 4185
4180 switch(info->idle_mode) 4186 /* if preamble enabled (tcr[6] == 1) then tx idle size = 8 bits
4181 { 4187 * else tcr[5:4] = tx idle size: 00 = 8 bits, 01 = 16 bits
4182 case HDLC_TXIDLE_FLAGS: val = 0x7e; break; 4188 */
4183 case HDLC_TXIDLE_ALT_ZEROS_ONES: val = 0xaa; break; 4189 tcr = rd_reg16(info, TCR);
4184 case HDLC_TXIDLE_ZEROS: val = 0x00; break; 4190 if (info->idle_mode & HDLC_TXIDLE_CUSTOM_16) {
4185 case HDLC_TXIDLE_ONES: val = 0xff; break; 4191 /* disable preamble, set idle size to 16 bits */
4186 case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break; 4192 tcr = (tcr & ~(BIT6 + BIT5)) | BIT4;
4187 case HDLC_TXIDLE_SPACE: val = 0x00; break; 4193 /* MSB of 16 bit idle specified in tx preamble register (TPR) */
4188 case HDLC_TXIDLE_MARK: val = 0xff; break; 4194 wr_reg8(info, TPR, (unsigned char)((info->idle_mode >> 8) & 0xff));
4195 } else if (!(tcr & BIT6)) {
4196 /* preamble is disabled, set idle size to 8 bits */
4197 tcr &= ~(BIT5 + BIT4);
4198 }
4199 wr_reg16(info, TCR, tcr);
4200
4201 if (info->idle_mode & (HDLC_TXIDLE_CUSTOM_8 | HDLC_TXIDLE_CUSTOM_16)) {
4202 /* LSB of custom tx idle specified in tx idle register */
4203 val = (unsigned char)(info->idle_mode & 0xff);
4204 } else {
4205 /* standard 8 bit idle patterns */
4206 switch(info->idle_mode)
4207 {
4208 case HDLC_TXIDLE_FLAGS: val = 0x7e; break;
4209 case HDLC_TXIDLE_ALT_ZEROS_ONES:
4210 case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break;
4211 case HDLC_TXIDLE_ZEROS:
4212 case HDLC_TXIDLE_SPACE: val = 0x00; break;
4213 default: val = 0xff;
4214 }
4189 } 4215 }
4190 4216
4191 wr_reg8(info, TIR, val); 4217 wr_reg8(info, TIR, val);
@@ -4313,6 +4339,12 @@ static int rx_get_frame(struct slgt_info *info)
4313 unsigned long flags; 4339 unsigned long flags;
4314 struct tty_struct *tty = info->tty; 4340 struct tty_struct *tty = info->tty;
4315 unsigned char addr_field = 0xff; 4341 unsigned char addr_field = 0xff;
4342 unsigned int crc_size = 0;
4343
4344 switch (info->params.crc_type & HDLC_CRC_MASK) {
4345 case HDLC_CRC_16_CCITT: crc_size = 2; break;
4346 case HDLC_CRC_32_CCITT: crc_size = 4; break;
4347 }
4316 4348
4317check_again: 4349check_again:
4318 4350
@@ -4357,7 +4389,7 @@ check_again:
4357 status = desc_status(info->rbufs[end]); 4389 status = desc_status(info->rbufs[end]);
4358 4390
4359 /* ignore CRC bit if not using CRC (bit is undefined) */ 4391 /* ignore CRC bit if not using CRC (bit is undefined) */
4360 if (info->params.crc_type == HDLC_CRC_NONE) 4392 if ((info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_NONE)
4361 status &= ~BIT1; 4393 status &= ~BIT1;
4362 4394
4363 if (framesize == 0 || 4395 if (framesize == 0 ||
@@ -4366,34 +4398,34 @@ check_again:
4366 goto check_again; 4398 goto check_again;
4367 } 4399 }
4368 4400
4369 if (framesize < 2 || status & (BIT1+BIT0)) { 4401 if (framesize < (2 + crc_size) || status & BIT0) {
4370 if (framesize < 2 || (status & BIT0)) 4402 info->icount.rxshort++;
4371 info->icount.rxshort++;
4372 else
4373 info->icount.rxcrc++;
4374 framesize = 0; 4403 framesize = 0;
4404 } else if (status & BIT1) {
4405 info->icount.rxcrc++;
4406 if (!(info->params.crc_type & HDLC_CRC_RETURN_EX))
4407 framesize = 0;
4408 }
4375 4409
4376#ifdef CONFIG_HDLC 4410#ifdef CONFIG_HDLC
4377 { 4411 if (framesize == 0) {
4378 struct net_device_stats *stats = hdlc_stats(info->netdev); 4412 struct net_device_stats *stats = hdlc_stats(info->netdev);
4379 stats->rx_errors++; 4413 stats->rx_errors++;
4380 stats->rx_frame_errors++; 4414 stats->rx_frame_errors++;
4381 }
4382#endif
4383 } else {
4384 /* adjust frame size for CRC, if any */
4385 if (info->params.crc_type == HDLC_CRC_16_CCITT)
4386 framesize -= 2;
4387 else if (info->params.crc_type == HDLC_CRC_32_CCITT)
4388 framesize -= 4;
4389 } 4415 }
4416#endif
4390 4417
4391 DBGBH(("%s rx frame status=%04X size=%d\n", 4418 DBGBH(("%s rx frame status=%04X size=%d\n",
4392 info->device_name, status, framesize)); 4419 info->device_name, status, framesize));
4393 DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx"); 4420 DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx");
4394 4421
4395 if (framesize) { 4422 if (framesize) {
4396 if (framesize > info->max_frame_size) 4423 if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) {
4424 framesize -= crc_size;
4425 crc_size = 0;
4426 }
4427
4428 if (framesize > info->max_frame_size + crc_size)
4397 info->icount.rxlong++; 4429 info->icount.rxlong++;
4398 else { 4430 else {
4399 /* copy dma buffer(s) to contiguous temp buffer */ 4431 /* copy dma buffer(s) to contiguous temp buffer */
@@ -4413,6 +4445,11 @@ check_again:
4413 i = 0; 4445 i = 0;
4414 } 4446 }
4415 4447
4448 if (info->params.crc_type & HDLC_CRC_RETURN_EX) {
4449 *p = (status & BIT1) ? RX_CRC_ERROR : RX_OK;
4450 framesize++;
4451 }
4452
4416#ifdef CONFIG_HDLC 4453#ifdef CONFIG_HDLC
4417 if (info->netcount) 4454 if (info->netcount)
4418 hdlcdev_rx(info,info->tmp_rbuf, framesize); 4455 hdlcdev_rx(info,info->tmp_rbuf, framesize);
@@ -4671,13 +4708,13 @@ static int loopback_test(struct slgt_info *info)
4671static int adapter_test(struct slgt_info *info) 4708static int adapter_test(struct slgt_info *info)
4672{ 4709{
4673 DBGINFO(("testing %s\n", info->device_name)); 4710 DBGINFO(("testing %s\n", info->device_name));
4674 if ((info->init_error = register_test(info)) < 0) { 4711 if (register_test(info) < 0) {
4675 printk("register test failure %s addr=%08X\n", 4712 printk("register test failure %s addr=%08X\n",
4676 info->device_name, info->phys_reg_addr); 4713 info->device_name, info->phys_reg_addr);
4677 } else if ((info->init_error = irq_test(info)) < 0) { 4714 } else if (irq_test(info) < 0) {
4678 printk("IRQ test failure %s IRQ=%d\n", 4715 printk("IRQ test failure %s IRQ=%d\n",
4679 info->device_name, info->irq_level); 4716 info->device_name, info->irq_level);
4680 } else if ((info->init_error = loopback_test(info)) < 0) { 4717 } else if (loopback_test(info) < 0) {
4681 printk("loopback test failure %s\n", info->device_name); 4718 printk("loopback test failure %s\n", info->device_name);
4682 } 4719 }
4683 return info->init_error; 4720 return info->init_error;