Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Moxa C101 synchronous serial card driver for Linux
0004  *
0005  * Copyright (C) 2000-2003 Krzysztof Halasa <khc@pm.waw.pl>
0006  *
0007  * For information see <https://www.kernel.org/pub/linux/utils/net/hdlc/>
0008  *
0009  * Sources of information:
0010  *    Hitachi HD64570 SCA User's Manual
0011  *    Moxa C101 User's Manual
0012  */
0013 
0014 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0015 
0016 #include <linux/module.h>
0017 #include <linux/kernel.h>
0018 #include <linux/capability.h>
0019 #include <linux/slab.h>
0020 #include <linux/types.h>
0021 #include <linux/string.h>
0022 #include <linux/errno.h>
0023 #include <linux/init.h>
0024 #include <linux/netdevice.h>
0025 #include <linux/hdlc.h>
0026 #include <linux/delay.h>
0027 #include <asm/io.h>
0028 
0029 #include "hd64570.h"
0030 
0031 static const char *version = "Moxa C101 driver version: 1.15";
0032 static const char *devname = "C101";
0033 
0034 #undef DEBUG_PKT
0035 #define DEBUG_RINGS
0036 
0037 #define C101_PAGE 0x1D00
0038 #define C101_DTR 0x1E00
0039 #define C101_SCA 0x1F00
0040 #define C101_WINDOW_SIZE 0x2000
0041 #define C101_MAPPED_RAM_SIZE 0x4000
0042 
0043 #define RAM_SIZE (256 * 1024)
0044 #define TX_RING_BUFFERS 10
0045 #define RX_RING_BUFFERS ((RAM_SIZE - C101_WINDOW_SIZE) /        \
0046              (sizeof(pkt_desc) + HDLC_MAX_MRU) - TX_RING_BUFFERS)
0047 
0048 #define CLOCK_BASE 9830400  /* 9.8304 MHz */
0049 #define PAGE0_ALWAYS_MAPPED
0050 
0051 static char *hw;        /* pointer to hw=xxx command line string */
0052 
0053 typedef struct card_s {
0054     struct net_device *dev;
0055     spinlock_t lock;    /* TX lock */
0056     u8 __iomem *win0base;   /* ISA window base address */
0057     u32 phy_winbase;    /* ISA physical base address */
0058     sync_serial_settings settings;
0059     int rxpart;     /* partial frame received, next frame invalid*/
0060     unsigned short encoding;
0061     unsigned short parity;
0062     u16 rx_ring_buffers;    /* number of buffers in a ring */
0063     u16 tx_ring_buffers;
0064     u16 buff_offset;    /* offset of first buffer of first channel */
0065     u16 rxin;       /* rx ring buffer 'in' pointer */
0066     u16 txin;       /* tx ring buffer 'in' and 'last' pointers */
0067     u16 txlast;
0068     u8 rxs, txs, tmc;   /* SCA registers */
0069     u8 irq;         /* IRQ (3-15) */
0070     u8 page;
0071 
0072     struct card_s *next_card;
0073 } card_t;
0074 
0075 typedef card_t port_t;
0076 
0077 static card_t *first_card;
0078 static card_t **new_card = &first_card;
0079 
0080 #define sca_in(reg, card)      readb((card)->win0base + C101_SCA + (reg))
0081 #define sca_out(value, reg, card)  writeb(value, (card)->win0base + C101_SCA + (reg))
0082 #define sca_inw(reg, card)     readw((card)->win0base + C101_SCA + (reg))
0083 
0084 /* EDA address register must be set in EDAL, EDAH order - 8 bit ISA bus */
0085 #define sca_outw(value, reg, card) do { \
0086     writeb(value & 0xFF, (card)->win0base + C101_SCA + (reg)); \
0087     writeb((value >> 8) & 0xFF, (card)->win0base + C101_SCA + (reg + 1));\
0088 } while (0)
0089 
0090 #define port_to_card(port)     (port)
0091 #define log_node(port)         (0)
0092 #define phy_node(port)         (0)
0093 #define winsize(card)          (C101_WINDOW_SIZE)
0094 #define win0base(card)         ((card)->win0base)
0095 #define winbase(card)          ((card)->win0base + 0x2000)
0096 #define get_port(card, port)       (card)
0097 static void sca_msci_intr(port_t *port);
0098 
0099 static inline u8 sca_get_page(card_t *card)
0100 {
0101     return card->page;
0102 }
0103 
0104 static inline void openwin(card_t *card, u8 page)
0105 {
0106     card->page = page;
0107     writeb(page, card->win0base + C101_PAGE);
0108 }
0109 
0110 #include "hd64570.c"
0111 
0112 static inline void set_carrier(port_t *port)
0113 {
0114     if (!(sca_in(MSCI1_OFFSET + ST3, port) & ST3_DCD))
0115         netif_carrier_on(port_to_dev(port));
0116     else
0117         netif_carrier_off(port_to_dev(port));
0118 }
0119 
0120 static void sca_msci_intr(port_t *port)
0121 {
0122     u8 stat = sca_in(MSCI0_OFFSET + ST1, port); /* read MSCI ST1 status */
0123 
0124     /* Reset MSCI TX underrun and CDCD (ignored) status bit */
0125     sca_out(stat & (ST1_UDRN | ST1_CDCD), MSCI0_OFFSET + ST1, port);
0126 
0127     if (stat & ST1_UDRN) {
0128         /* TX Underrun error detected */
0129         port_to_dev(port)->stats.tx_errors++;
0130         port_to_dev(port)->stats.tx_fifo_errors++;
0131     }
0132 
0133     stat = sca_in(MSCI1_OFFSET + ST1, port); /* read MSCI1 ST1 status */
0134     /* Reset MSCI CDCD status bit - uses ch#2 DCD input */
0135     sca_out(stat & ST1_CDCD, MSCI1_OFFSET + ST1, port);
0136 
0137     if (stat & ST1_CDCD)
0138         set_carrier(port);
0139 }
0140 
0141 static void c101_set_iface(port_t *port)
0142 {
0143     u8 rxs = port->rxs & CLK_BRG_MASK;
0144     u8 txs = port->txs & CLK_BRG_MASK;
0145 
0146     switch (port->settings.clock_type) {
0147     case CLOCK_INT:
0148         rxs |= CLK_BRG_RX; /* TX clock */
0149         txs |= CLK_RXCLK_TX; /* BRG output */
0150         break;
0151 
0152     case CLOCK_TXINT:
0153         rxs |= CLK_LINE_RX; /* RXC input */
0154         txs |= CLK_BRG_TX; /* BRG output */
0155         break;
0156 
0157     case CLOCK_TXFROMRX:
0158         rxs |= CLK_LINE_RX; /* RXC input */
0159         txs |= CLK_RXCLK_TX; /* RX clock */
0160         break;
0161 
0162     default:    /* EXTernal clock */
0163         rxs |= CLK_LINE_RX; /* RXC input */
0164         txs |= CLK_LINE_TX; /* TXC input */
0165     }
0166 
0167     port->rxs = rxs;
0168     port->txs = txs;
0169     sca_out(rxs, MSCI1_OFFSET + RXS, port);
0170     sca_out(txs, MSCI1_OFFSET + TXS, port);
0171     sca_set_port(port);
0172 }
0173 
0174 static int c101_open(struct net_device *dev)
0175 {
0176     port_t *port = dev_to_port(dev);
0177     int result;
0178 
0179     result = hdlc_open(dev);
0180     if (result)
0181         return result;
0182 
0183     writeb(1, port->win0base + C101_DTR);
0184     sca_out(0, MSCI1_OFFSET + CTL, port); /* RTS uses ch#2 output */
0185     sca_open(dev);
0186     /* DCD is connected to port 2 !@#$%^& - disable MSCI0 CDCD interrupt */
0187     sca_out(IE1_UDRN, MSCI0_OFFSET + IE1, port);
0188     sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port);
0189 
0190     set_carrier(port);
0191 
0192     /* enable MSCI1 CDCD interrupt */
0193     sca_out(IE1_CDCD, MSCI1_OFFSET + IE1, port);
0194     sca_out(IE0_RXINTA, MSCI1_OFFSET + IE0, port);
0195     sca_out(0x48, IER0, port); /* TXINT #0 and RXINT #1 */
0196     c101_set_iface(port);
0197     return 0;
0198 }
0199 
0200 static int c101_close(struct net_device *dev)
0201 {
0202     port_t *port = dev_to_port(dev);
0203 
0204     sca_close(dev);
0205     writeb(0, port->win0base + C101_DTR);
0206     sca_out(CTL_NORTS, MSCI1_OFFSET + CTL, port);
0207     hdlc_close(dev);
0208     return 0;
0209 }
0210 
0211 static int c101_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
0212                    void __user *data, int cmd)
0213 {
0214 #ifdef DEBUG_RINGS
0215     port_t *port = dev_to_port(dev);
0216 
0217     if (cmd == SIOCDEVPRIVATE) {
0218         sca_dump_rings(dev);
0219         printk(KERN_DEBUG "MSCI1: ST: %02x %02x %02x %02x\n",
0220                sca_in(MSCI1_OFFSET + ST0, port),
0221                sca_in(MSCI1_OFFSET + ST1, port),
0222                sca_in(MSCI1_OFFSET + ST2, port),
0223                sca_in(MSCI1_OFFSET + ST3, port));
0224         return 0;
0225     }
0226 #endif
0227 
0228     return -EOPNOTSUPP;
0229 }
0230 
0231 static int c101_ioctl(struct net_device *dev, struct if_settings *ifs)
0232 {
0233     const size_t size = sizeof(sync_serial_settings);
0234     sync_serial_settings new_line;
0235     sync_serial_settings __user *line = ifs->ifs_ifsu.sync;
0236     port_t *port = dev_to_port(dev);
0237 
0238     switch (ifs->type) {
0239     case IF_GET_IFACE:
0240         ifs->type = IF_IFACE_SYNC_SERIAL;
0241         if (ifs->size < size) {
0242             ifs->size = size; /* data size wanted */
0243             return -ENOBUFS;
0244         }
0245         if (copy_to_user(line, &port->settings, size))
0246             return -EFAULT;
0247         return 0;
0248 
0249     case IF_IFACE_SYNC_SERIAL:
0250         if (!capable(CAP_NET_ADMIN))
0251             return -EPERM;
0252 
0253         if (copy_from_user(&new_line, line, size))
0254             return -EFAULT;
0255 
0256         if (new_line.clock_type != CLOCK_EXT &&
0257             new_line.clock_type != CLOCK_TXFROMRX &&
0258             new_line.clock_type != CLOCK_INT &&
0259             new_line.clock_type != CLOCK_TXINT)
0260             return -EINVAL; /* No such clock setting */
0261 
0262         if (new_line.loopback != 0 && new_line.loopback != 1)
0263             return -EINVAL;
0264 
0265         memcpy(&port->settings, &new_line, size); /* Update settings */
0266         c101_set_iface(port);
0267         return 0;
0268 
0269     default:
0270         return hdlc_ioctl(dev, ifs);
0271     }
0272 }
0273 
0274 static void c101_destroy_card(card_t *card)
0275 {
0276     readb(card->win0base + C101_PAGE); /* Resets SCA? */
0277 
0278     if (card->irq)
0279         free_irq(card->irq, card);
0280 
0281     if (card->win0base) {
0282         iounmap(card->win0base);
0283         release_mem_region(card->phy_winbase, C101_MAPPED_RAM_SIZE);
0284     }
0285 
0286     free_netdev(card->dev);
0287 
0288     kfree(card);
0289 }
0290 
0291 static const struct net_device_ops c101_ops = {
0292     .ndo_open       = c101_open,
0293     .ndo_stop       = c101_close,
0294     .ndo_start_xmit = hdlc_start_xmit,
0295     .ndo_siocwandev = c101_ioctl,
0296     .ndo_siocdevprivate = c101_siocdevprivate,
0297 };
0298 
0299 static int __init c101_run(unsigned long irq, unsigned long winbase)
0300 {
0301     struct net_device *dev;
0302     hdlc_device *hdlc;
0303     card_t *card;
0304     int result;
0305 
0306     if (irq < 3 || irq > 15 || irq == 6) /* FIXME */ {
0307         pr_err("invalid IRQ value\n");
0308         return -ENODEV;
0309     }
0310 
0311     if (winbase < 0xC0000 || winbase > 0xDFFFF || (winbase & 0x3FFF) != 0) {
0312         pr_err("invalid RAM value\n");
0313         return -ENODEV;
0314     }
0315 
0316     card = kzalloc(sizeof(card_t), GFP_KERNEL);
0317     if (!card)
0318         return -ENOBUFS;
0319 
0320     card->dev = alloc_hdlcdev(card);
0321     if (!card->dev) {
0322         pr_err("unable to allocate memory\n");
0323         kfree(card);
0324         return -ENOBUFS;
0325     }
0326 
0327     if (request_irq(irq, sca_intr, 0, devname, card)) {
0328         pr_err("could not allocate IRQ\n");
0329         c101_destroy_card(card);
0330         return -EBUSY;
0331     }
0332     card->irq = irq;
0333 
0334     if (!request_mem_region(winbase, C101_MAPPED_RAM_SIZE, devname)) {
0335         pr_err("could not request RAM window\n");
0336         c101_destroy_card(card);
0337         return -EBUSY;
0338     }
0339     card->phy_winbase = winbase;
0340     card->win0base = ioremap(winbase, C101_MAPPED_RAM_SIZE);
0341     if (!card->win0base) {
0342         pr_err("could not map I/O address\n");
0343         c101_destroy_card(card);
0344         return -EFAULT;
0345     }
0346 
0347     card->tx_ring_buffers = TX_RING_BUFFERS;
0348     card->rx_ring_buffers = RX_RING_BUFFERS;
0349     card->buff_offset = C101_WINDOW_SIZE; /* Bytes 1D00-1FFF reserved */
0350 
0351     readb(card->win0base + C101_PAGE); /* Resets SCA? */
0352     udelay(100);
0353     writeb(0, card->win0base + C101_PAGE);
0354     writeb(0, card->win0base + C101_DTR); /* Power-up for RAM? */
0355 
0356     sca_init(card, 0);
0357 
0358     dev = port_to_dev(card);
0359     hdlc = dev_to_hdlc(dev);
0360 
0361     spin_lock_init(&card->lock);
0362     dev->irq = irq;
0363     dev->mem_start = winbase;
0364     dev->mem_end = winbase + C101_MAPPED_RAM_SIZE - 1;
0365     dev->tx_queue_len = 50;
0366     dev->netdev_ops = &c101_ops;
0367     hdlc->attach = sca_attach;
0368     hdlc->xmit = sca_xmit;
0369     card->settings.clock_type = CLOCK_EXT;
0370 
0371     result = register_hdlc_device(dev);
0372     if (result) {
0373         pr_warn("unable to register hdlc device\n");
0374         c101_destroy_card(card);
0375         return result;
0376     }
0377 
0378     sca_init_port(card); /* Set up C101 memory */
0379     set_carrier(card);
0380 
0381     netdev_info(dev, "Moxa C101 on IRQ%u, using %u TX + %u RX packets rings\n",
0382             card->irq, card->tx_ring_buffers, card->rx_ring_buffers);
0383 
0384     *new_card = card;
0385     new_card = &card->next_card;
0386     return 0;
0387 }
0388 
0389 static int __init c101_init(void)
0390 {
0391     if (!hw) {
0392 #ifdef MODULE
0393         pr_info("no card initialized\n");
0394 #endif
0395         return -EINVAL; /* no parameters specified, abort */
0396     }
0397 
0398     pr_info("%s\n", version);
0399 
0400     do {
0401         unsigned long irq, ram;
0402 
0403         irq = simple_strtoul(hw, &hw, 0);
0404 
0405         if (*hw++ != ',')
0406             break;
0407         ram = simple_strtoul(hw, &hw, 0);
0408 
0409         if (*hw == ':' || *hw == '\x0')
0410             c101_run(irq, ram);
0411 
0412         if (*hw == '\x0')
0413             return first_card ? 0 : -EINVAL;
0414     } while (*hw++ == ':');
0415 
0416     pr_err("invalid hardware parameters\n");
0417     return first_card ? 0 : -EINVAL;
0418 }
0419 
0420 static void __exit c101_cleanup(void)
0421 {
0422     card_t *card = first_card;
0423 
0424     while (card) {
0425         card_t *ptr = card;
0426 
0427         card = card->next_card;
0428         unregister_hdlc_device(port_to_dev(ptr));
0429         c101_destroy_card(ptr);
0430     }
0431 }
0432 
0433 module_init(c101_init);
0434 module_exit(c101_cleanup);
0435 
0436 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
0437 MODULE_DESCRIPTION("Moxa C101 serial port driver");
0438 MODULE_LICENSE("GPL v2");
0439 module_param(hw, charp, 0444);
0440 MODULE_PARM_DESC(hw, "irq,ram:irq,...");