Lines Matching +full:rx +full:- +full:pcs +full:- +full:input

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * yam.c -- YAM radio modem driver.
61 /* --------------------------------------------------------------------- */
67 /* --------------------------------------------------------------------- */
94 #define DEFAULT_PERS 64 /* 0->255 */
127 /* Rx section */
147 /* --------------------------------------------------------------------- */
175 #define IER_RX 1 /* enable rx interrupt */
184 #define MCR_OUT2 0x08 /* Master Interrupt enable (must be set on PCs) */
188 #define MSR_DCTS 0x01 /* Delta CTS input */
192 #define MSR_CTS 0x10 /* CTS input */
193 #define MSR_DSR 0x20 /* DSR input */
194 #define MSR_RING 0x40 /* RI input */
195 #define MSR_DCD 0x80 /* DCD input */
219 /* YAM Modem <-> UART Port mapping */
228 #define ENABLE_RXINT IER_RX /* enable uart rx interrupt during rx */
326 return -1; in fpga_write()
352 predef--; in add_mcs()
358 err = request_firmware(&fw, fw_name[predef], &pdev->dev); in add_mcs()
365 if (fw->size != YAM_FPGA_SIZE) { in add_mcs()
367 fw->size, fw_name[predef]); in add_mcs()
371 bits = (unsigned char *)fw->data; in add_mcs()
381 if (p->bitrate == bitrate) { in add_mcs()
382 memcpy(p->bits, bits, YAM_FPGA_SIZE); in add_mcs()
385 p = p->next; in add_mcs()
393 memcpy(p->bits, bits, YAM_FPGA_SIZE); in add_mcs()
394 p->bitrate = bitrate; in add_mcs()
395 p->next = yam_data; in add_mcs()
399 return p->bits; in add_mcs()
408 if (p->bitrate == bitrate) in get_mcs()
409 return p->bits; in get_mcs()
410 p = p->next; in get_mcs()
436 return -1; in fpga_download()
442 return -1; /* write... */ in fpga_download()
452 return (rc & MSR_DSR) ? 0 : -1; in fpga_download()
463 int divisor = 115200 / yp->baudrate; in yam_set_uart()
465 outb(0, IER(dev->base_addr)); in yam_set_uart()
466 outb(LCR_DLAB | LCR_BIT8, LCR(dev->base_addr)); in yam_set_uart()
467 outb(divisor, DLL(dev->base_addr)); in yam_set_uart()
468 outb(0, DLM(dev->base_addr)); in yam_set_uart()
469 outb(LCR_BIT8, LCR(dev->base_addr)); in yam_set_uart()
470 outb(PTT_OFF, MCR(dev->base_addr)); in yam_set_uart()
471 outb(0x00, FCR(dev->base_addr)); in yam_set_uart()
475 inb(RBR(dev->base_addr)); in yam_set_uart()
476 inb(MSR(dev->base_addr)); in yam_set_uart()
478 /* Enable rx irq */ in yam_set_uart()
480 outb(ENABLE_RTXINT, IER(dev->base_addr)); in yam_set_uart()
484 /* --------------------------------------------------------------------- */
526 * Rx Section
530 if (yp->dcd && yp->rx_len >= 3 && yp->rx_len < YAM_MAX_FRAME) { in yam_rx_flag()
531 int pkt_len = yp->rx_len - 2 + 1; /* -CRC + kiss */ in yam_rx_flag()
534 if ((yp->rx_crch & yp->rx_crcl) != 0xFF) { in yam_rx_flag()
538 printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name); in yam_rx_flag()
539 ++dev->stats.rx_dropped; in yam_rx_flag()
544 memcpy(cp, yp->rx_buf, pkt_len - 1); in yam_rx_flag()
545 skb->protocol = ax25_type_trans(skb, dev); in yam_rx_flag()
547 ++dev->stats.rx_packets; in yam_rx_flag()
551 yp->rx_len = 0; in yam_rx_flag()
552 yp->rx_crcl = 0x21; in yam_rx_flag()
553 yp->rx_crch = 0xf3; in yam_rx_flag()
558 if (yp->rx_len < YAM_MAX_FRAME) { in yam_rx_byte()
559 unsigned char c = yp->rx_crcl; in yam_rx_byte()
560 yp->rx_crcl = (chktabl[c] ^ yp->rx_crch); in yam_rx_byte()
561 yp->rx_crch = (chktabh[c] ^ rxb); in yam_rx_byte()
562 yp->rx_buf[yp->rx_len++] = rxb; in yam_rx_byte()
572 outb(PTT_ON, MCR(dev->base_addr)); in ptt_on()
577 outb(PTT_OFF, MCR(dev->base_addr)); in ptt_off()
585 if (skb->protocol == htons(ETH_P_IP)) in yam_send_packet()
588 skb_queue_tail(&yp->send_queue, skb); in yam_send_packet()
595 if ((yp->tx_state == TX_TAIL) || (yp->txd == 0)) in yam_start_tx()
596 yp->tx_count = 1; in yam_start_tx()
598 yp->tx_count = (yp->bitrate * yp->txd) / 8000; in yam_start_tx()
599 yp->tx_state = TX_HEAD; in yam_start_tx()
607 if (yp->magic != YAM_MAGIC || yp->tx_state != TX_OFF || in yam_arbitrate()
608 skb_queue_empty(&yp->send_queue)) in yam_arbitrate()
612 if (yp->dupmode) { in yam_arbitrate()
617 if (yp->dcd) { in yam_arbitrate()
619 yp->slotcnt = yp->slot / 10; in yam_arbitrate()
623 if ((--yp->slotcnt) > 0) in yam_arbitrate()
626 yp->slotcnt = yp->slot / 10; in yam_arbitrate()
629 if (get_random_u8() > yp->pers) in yam_arbitrate()
653 switch (yp->tx_state) { in yam_tx_byte()
657 if (--yp->tx_count <= 0) { in yam_tx_byte()
658 if (!(skb = skb_dequeue(&yp->send_queue))) { in yam_tx_byte()
660 yp->tx_state = TX_OFF; in yam_tx_byte()
663 yp->tx_state = TX_DATA; in yam_tx_byte()
664 if (skb->data[0] != 0) { in yam_tx_byte()
665 /* do_kiss_params(s, skb->data, skb->len); */ in yam_tx_byte()
669 yp->tx_len = skb->len - 1; /* strip KISS byte */ in yam_tx_byte()
670 if (yp->tx_len >= YAM_MAX_FRAME || yp->tx_len < 2) { in yam_tx_byte()
675 yp->tx_buf, in yam_tx_byte()
676 yp->tx_len); in yam_tx_byte()
678 yp->tx_count = 0; in yam_tx_byte()
679 yp->tx_crcl = 0x21; in yam_tx_byte()
680 yp->tx_crch = 0xf3; in yam_tx_byte()
681 yp->tx_state = TX_DATA; in yam_tx_byte()
685 b = yp->tx_buf[yp->tx_count++]; in yam_tx_byte()
686 outb(b, THR(dev->base_addr)); in yam_tx_byte()
687 temp = yp->tx_crcl; in yam_tx_byte()
688 yp->tx_crcl = chktabl[temp] ^ yp->tx_crch; in yam_tx_byte()
689 yp->tx_crch = chktabh[temp] ^ b; in yam_tx_byte()
690 if (yp->tx_count >= yp->tx_len) { in yam_tx_byte()
691 yp->tx_state = TX_CRC1; in yam_tx_byte()
695 yp->tx_crch = chktabl[yp->tx_crcl] ^ yp->tx_crch; in yam_tx_byte()
696 yp->tx_crcl = chktabh[yp->tx_crcl] ^ chktabl[yp->tx_crch] ^ 0xff; in yam_tx_byte()
697 outb(yp->tx_crcl, THR(dev->base_addr)); in yam_tx_byte()
698 yp->tx_state = TX_CRC2; in yam_tx_byte()
701 outb(chktabh[yp->tx_crch] ^ 0xFF, THR(dev->base_addr)); in yam_tx_byte()
702 if (skb_queue_empty(&yp->send_queue)) { in yam_tx_byte()
703 yp->tx_count = (yp->bitrate * yp->txtail) / 8000; in yam_tx_byte()
704 if (yp->dupmode == 2) in yam_tx_byte()
705 yp->tx_count += (yp->bitrate * yp->holdd) / 8; in yam_tx_byte()
706 if (yp->tx_count == 0) in yam_tx_byte()
707 yp->tx_count = 1; in yam_tx_byte()
708 yp->tx_state = TX_TAIL; in yam_tx_byte()
710 yp->tx_count = 1; in yam_tx_byte()
711 yp->tx_state = TX_HEAD; in yam_tx_byte()
713 ++dev->stats.tx_packets; in yam_tx_byte()
716 if (--yp->tx_count <= 0) { in yam_tx_byte()
717 yp->tx_state = TX_OFF; in yam_tx_byte()
744 while ((iir = IIR_MASK & inb(IIR(dev->base_addr))) != IIR_NOPEND) { in yam_interrupt()
745 unsigned char msr = inb(MSR(dev->base_addr)); in yam_interrupt()
746 unsigned char lsr = inb(LSR(dev->base_addr)); in yam_interrupt()
752 ++dev->stats.rx_fifo_errors; in yam_interrupt()
754 yp->dcd = (msr & RX_DCD) ? 1 : 0; in yam_interrupt()
756 if (--counter <= 0) { in yam_interrupt()
758 dev->name, iir); in yam_interrupt()
762 ++yp->nb_mdint; in yam_interrupt()
766 ++yp->nb_rxint; in yam_interrupt()
767 rxb = inb(RBR(dev->base_addr)); in yam_interrupt()
801 seq_printf(seq, "Device %s\n", dev->name); in yam_seq_show()
803 seq_printf(seq, " Speed %u\n", yp->bitrate); in yam_seq_show()
804 seq_printf(seq, " IoBase 0x%x\n", yp->iobase); in yam_seq_show()
805 seq_printf(seq, " BaudRate %u\n", yp->baudrate); in yam_seq_show()
806 seq_printf(seq, " IRQ %u\n", yp->irq); in yam_seq_show()
807 seq_printf(seq, " TxState %u\n", yp->tx_state); in yam_seq_show()
808 seq_printf(seq, " Duplex %u\n", yp->dupmode); in yam_seq_show()
809 seq_printf(seq, " HoldDly %u\n", yp->holdd); in yam_seq_show()
810 seq_printf(seq, " TxDelay %u\n", yp->txd); in yam_seq_show()
811 seq_printf(seq, " TxTail %u\n", yp->txtail); in yam_seq_show()
812 seq_printf(seq, " SlotTime %u\n", yp->slot); in yam_seq_show()
813 seq_printf(seq, " Persist %u\n", yp->pers); in yam_seq_show()
814 seq_printf(seq, " TxFrames %lu\n", dev->stats.tx_packets); in yam_seq_show()
815 seq_printf(seq, " RxFrames %lu\n", dev->stats.rx_packets); in yam_seq_show()
816 seq_printf(seq, " TxInt %u\n", yp->nb_mdint); in yam_seq_show()
817 seq_printf(seq, " RxInt %u\n", yp->nb_rxint); in yam_seq_show()
818 seq_printf(seq, " RxOver %lu\n", dev->stats.rx_fifo_errors); in yam_seq_show()
832 /* --------------------------------------------------------------------- */
841 printk(KERN_INFO "Trying %s at iobase 0x%lx irq %u\n", dev->name, dev->base_addr, dev->irq); in yam_open()
843 if (!yp->bitrate) in yam_open()
844 return -ENXIO; in yam_open()
845 if (!dev->base_addr || dev->base_addr > 0x1000 - YAM_EXTENT || in yam_open()
846 dev->irq < 2 || dev->irq > 15) { in yam_open()
847 return -ENXIO; in yam_open()
849 if (!request_region(dev->base_addr, YAM_EXTENT, dev->name)) in yam_open()
851 printk(KERN_ERR "%s: cannot 0x%lx busy\n", dev->name, dev->base_addr); in yam_open()
852 return -EACCES; in yam_open()
854 if ((u = yam_check_uart(dev->base_addr)) == c_uart_unknown) { in yam_open()
855 printk(KERN_ERR "%s: cannot find uart type\n", dev->name); in yam_open()
856 ret = -EIO; in yam_open()
859 if (fpga_download(dev->base_addr, yp->bitrate)) { in yam_open()
860 printk(KERN_ERR "%s: cannot init FPGA\n", dev->name); in yam_open()
861 ret = -EIO; in yam_open()
864 outb(0, IER(dev->base_addr)); in yam_open()
865 if (request_irq(dev->irq, yam_interrupt, IRQF_SHARED, dev->name, dev)) { in yam_open()
866 printk(KERN_ERR "%s: irq %d busy\n", dev->name, dev->irq); in yam_open()
867 ret = -EBUSY; in yam_open()
875 yp->slotcnt = yp->slot / 10; in yam_open()
877 /* Reset overruns for all ports - FPGA programming makes overruns */ in yam_open()
881 inb(LSR(yam_dev->base_addr)); in yam_open()
882 yam_dev->stats.rx_fifo_errors = 0; in yam_open()
885 printk(KERN_INFO "%s at iobase 0x%lx irq %u uart %s\n", dev->name, dev->base_addr, dev->irq, in yam_open()
890 release_region(dev->base_addr, YAM_EXTENT); in yam_open()
894 /* --------------------------------------------------------------------- */
902 return -EINVAL; in yam_close()
907 outb(0, IER(dev->base_addr)); in yam_close()
908 outb(1, MCR(dev->base_addr)); in yam_close()
910 free_irq(dev->irq,dev); in yam_close()
911 release_region(dev->base_addr, YAM_EXTENT); in yam_close()
913 while ((skb = skb_dequeue(&yp->send_queue))) in yam_close()
917 yam_drvname, dev->base_addr, dev->irq); in yam_close()
921 /* --------------------------------------------------------------------- */
931 return -EFAULT; in yam_siocdevprivate()
933 if (yp->magic != YAM_MAGIC) in yam_siocdevprivate()
934 return -EINVAL; in yam_siocdevprivate()
937 return -EPERM; in yam_siocdevprivate()
940 return -EINVAL; in yam_siocdevprivate()
945 return -EINVAL; /* unused */ in yam_siocdevprivate()
949 return -EINVAL; /* Cannot change this parameter when up */ in yam_siocdevprivate()
953 if (ym->cmd != SIOCYAMSMCS || ym->bitrate > YAM_MAXBITRATE) { in yam_siocdevprivate()
955 return -EINVAL; in yam_siocdevprivate()
958 add_mcs(ym->bits, ym->bitrate, 0); in yam_siocdevprivate()
964 return -EPERM; in yam_siocdevprivate()
966 return -EFAULT; in yam_siocdevprivate()
969 return -EINVAL; in yam_siocdevprivate()
971 return -EINVAL; /* Cannot change this parameter when up */ in yam_siocdevprivate()
973 return -EINVAL; /* Cannot change this parameter when up */ in yam_siocdevprivate()
975 return -EINVAL; /* Cannot change this parameter when up */ in yam_siocdevprivate()
977 return -EINVAL; /* Cannot change this parameter when up */ in yam_siocdevprivate()
980 yp->iobase = yi.cfg.iobase; in yam_siocdevprivate()
981 dev->base_addr = yi.cfg.iobase; in yam_siocdevprivate()
985 return -EINVAL; in yam_siocdevprivate()
986 yp->irq = yi.cfg.irq; in yam_siocdevprivate()
987 dev->irq = yi.cfg.irq; in yam_siocdevprivate()
991 return -EINVAL; in yam_siocdevprivate()
992 yp->bitrate = yi.cfg.bitrate; in yam_siocdevprivate()
996 return -EINVAL; in yam_siocdevprivate()
997 yp->baudrate = yi.cfg.baudrate; in yam_siocdevprivate()
1001 return -EINVAL; in yam_siocdevprivate()
1002 yp->dupmode = yi.cfg.mode; in yam_siocdevprivate()
1006 return -EINVAL; in yam_siocdevprivate()
1007 yp->holdd = yi.cfg.holddly; in yam_siocdevprivate()
1011 return -EINVAL; in yam_siocdevprivate()
1012 yp->txd = yi.cfg.txdelay; in yam_siocdevprivate()
1016 return -EINVAL; in yam_siocdevprivate()
1017 yp->txtail = yi.cfg.txtail; in yam_siocdevprivate()
1021 return -EINVAL; in yam_siocdevprivate()
1022 yp->pers = yi.cfg.persist; in yam_siocdevprivate()
1026 return -EINVAL; in yam_siocdevprivate()
1027 yp->slot = yi.cfg.slottime; in yam_siocdevprivate()
1028 yp->slotcnt = yp->slot / 10; in yam_siocdevprivate()
1035 yi.cfg.iobase = yp->iobase; in yam_siocdevprivate()
1036 yi.cfg.irq = yp->irq; in yam_siocdevprivate()
1037 yi.cfg.bitrate = yp->bitrate; in yam_siocdevprivate()
1038 yi.cfg.baudrate = yp->baudrate; in yam_siocdevprivate()
1039 yi.cfg.mode = yp->dupmode; in yam_siocdevprivate()
1040 yi.cfg.txdelay = yp->txd; in yam_siocdevprivate()
1041 yi.cfg.holddly = yp->holdd; in yam_siocdevprivate()
1042 yi.cfg.txtail = yp->txtail; in yam_siocdevprivate()
1043 yi.cfg.persist = yp->pers; in yam_siocdevprivate()
1044 yi.cfg.slottime = yp->slot; in yam_siocdevprivate()
1046 return -EFAULT; in yam_siocdevprivate()
1050 return -EINVAL; in yam_siocdevprivate()
1057 /* --------------------------------------------------------------------- */
1064 dev_addr_set(dev, sa->sa_data); in yam_set_mac_address()
1068 /* --------------------------------------------------------------------- */
1082 yp->magic = YAM_MAGIC; in yam_setup()
1083 yp->bitrate = DEFAULT_BITRATE; in yam_setup()
1084 yp->baudrate = DEFAULT_BITRATE * 2; in yam_setup()
1085 yp->iobase = 0; in yam_setup()
1086 yp->irq = 0; in yam_setup()
1087 yp->dupmode = 0; in yam_setup()
1088 yp->holdd = DEFAULT_HOLDD; in yam_setup()
1089 yp->txd = DEFAULT_TXD; in yam_setup()
1090 yp->txtail = DEFAULT_TXTAIL; in yam_setup()
1091 yp->slot = DEFAULT_SLOT; in yam_setup()
1092 yp->pers = DEFAULT_PERS; in yam_setup()
1093 yp->dev = dev; in yam_setup()
1095 dev->base_addr = yp->iobase; in yam_setup()
1096 dev->irq = yp->irq; in yam_setup()
1098 skb_queue_head_init(&yp->send_queue); in yam_setup()
1100 dev->netdev_ops = &yam_netdev_ops; in yam_setup()
1101 dev->header_ops = &ax25_header_ops; in yam_setup()
1103 dev->type = ARPHRD_AX25; in yam_setup()
1104 dev->hard_header_len = AX25_MAX_HEADER_LEN; in yam_setup()
1105 dev->mtu = AX25_MTU; in yam_setup()
1106 dev->addr_len = AX25_ADDR_LEN; in yam_setup()
1107 memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN); in yam_setup()
1126 err = -ENOMEM; in yam_init_driver()
1132 printk(KERN_WARNING "yam: cannot register net device %s\n", dev->name); in yam_init_driver()
1147 while (--i >= 0) { in yam_init_driver()
1154 /* --------------------------------------------------------------------- */
1172 yam_data = yam_data->next; in yam_cleanup_driver()
1179 /* --------------------------------------------------------------------- */
1190 /* --------------------------------------------------------------------- */