linux/drivers/net/wan/hostess_sv11.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*      Comtrol SV11 card driver
   3 *
   4 *      This is a slightly odd Z85230 synchronous driver. All you need to
   5 *      know basically is
   6 *
   7 *      Its a genuine Z85230
   8 *
   9 *      It supports DMA using two DMA channels in SYNC mode. The driver doesn't
  10 *      use these facilities
  11 *
  12 *      The control port is at io+1, the data at io+3 and turning off the DMA
  13 *      is done by writing 0 to io+4
  14 *
  15 *      The hardware does the bus handling to avoid the need for delays between
  16 *      touching control registers.
  17 *
  18 *      Port B isn't wired (why - beats me)
  19 *
  20 *      Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
  21 */
  22
  23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  24
  25#include <linux/module.h>
  26#include <linux/kernel.h>
  27#include <linux/mm.h>
  28#include <linux/net.h>
  29#include <linux/skbuff.h>
  30#include <linux/netdevice.h>
  31#include <linux/if_arp.h>
  32#include <linux/delay.h>
  33#include <linux/hdlc.h>
  34#include <linux/ioport.h>
  35#include <linux/slab.h>
  36#include <net/arp.h>
  37
  38#include <asm/irq.h>
  39#include <asm/io.h>
  40#include <asm/dma.h>
  41#include <asm/byteorder.h>
  42#include "z85230.h"
  43
  44static int dma;
  45
  46/*      Network driver support routines
  47 */
  48
  49static inline struct z8530_dev *dev_to_sv(struct net_device *dev)
  50{
  51        return (struct z8530_dev *)dev_to_hdlc(dev)->priv;
  52}
  53
  54/*      Frame receive. Simple for our card as we do HDLC and there
  55 *      is no funny garbage involved
  56 */
  57
  58static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
  59{
  60        /* Drop the CRC - it's not a good idea to try and negotiate it ;) */
  61        skb_trim(skb, skb->len - 2);
  62        skb->protocol = hdlc_type_trans(skb, c->netdevice);
  63        skb_reset_mac_header(skb);
  64        skb->dev = c->netdevice;
  65        /*      Send it to the PPP layer. We don't have time to process
  66         *      it right now.
  67         */
  68        netif_rx(skb);
  69}
  70
  71/*      We've been placed in the UP state
  72 */
  73
  74static int hostess_open(struct net_device *d)
  75{
  76        struct z8530_dev *sv11 = dev_to_sv(d);
  77        int err = -1;
  78
  79        /*      Link layer up
  80         */
  81        switch (dma) {
  82        case 0:
  83                err = z8530_sync_open(d, &sv11->chanA);
  84                break;
  85        case 1:
  86                err = z8530_sync_dma_open(d, &sv11->chanA);
  87                break;
  88        case 2:
  89                err = z8530_sync_txdma_open(d, &sv11->chanA);
  90                break;
  91        }
  92
  93        if (err)
  94                return err;
  95
  96        err = hdlc_open(d);
  97        if (err) {
  98                switch (dma) {
  99                case 0:
 100                        z8530_sync_close(d, &sv11->chanA);
 101                        break;
 102                case 1:
 103                        z8530_sync_dma_close(d, &sv11->chanA);
 104                        break;
 105                case 2:
 106                        z8530_sync_txdma_close(d, &sv11->chanA);
 107                        break;
 108                }
 109                return err;
 110        }
 111        sv11->chanA.rx_function = hostess_input;
 112
 113        /*
 114         *      Go go go
 115         */
 116
 117        netif_start_queue(d);
 118        return 0;
 119}
 120
 121static int hostess_close(struct net_device *d)
 122{
 123        struct z8530_dev *sv11 = dev_to_sv(d);
 124        /*      Discard new frames
 125         */
 126        sv11->chanA.rx_function = z8530_null_rx;
 127
 128        hdlc_close(d);
 129        netif_stop_queue(d);
 130
 131        switch (dma) {
 132        case 0:
 133                z8530_sync_close(d, &sv11->chanA);
 134                break;
 135        case 1:
 136                z8530_sync_dma_close(d, &sv11->chanA);
 137                break;
 138        case 2:
 139                z8530_sync_txdma_close(d, &sv11->chanA);
 140                break;
 141        }
 142        return 0;
 143}
 144
 145/*      Passed network frames, fire them downwind.
 146 */
 147
 148static netdev_tx_t hostess_queue_xmit(struct sk_buff *skb,
 149                                      struct net_device *d)
 150{
 151        return z8530_queue_xmit(&dev_to_sv(d)->chanA, skb);
 152}
 153
 154static int hostess_attach(struct net_device *dev, unsigned short encoding,
 155                          unsigned short parity)
 156{
 157        if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
 158                return 0;
 159        return -EINVAL;
 160}
 161
 162/*      Description block for a Comtrol Hostess SV11 card
 163 */
 164
 165static const struct net_device_ops hostess_ops = {
 166        .ndo_open       = hostess_open,
 167        .ndo_stop       = hostess_close,
 168        .ndo_start_xmit = hdlc_start_xmit,
 169        .ndo_siocwandev = hdlc_ioctl,
 170};
 171
 172static struct z8530_dev *sv11_init(int iobase, int irq)
 173{
 174        struct z8530_dev *sv;
 175        struct net_device *netdev;
 176        /*      Get the needed I/O space
 177         */
 178
 179        if (!request_region(iobase, 8, "Comtrol SV11")) {
 180                pr_warn("I/O 0x%X already in use\n", iobase);
 181                return NULL;
 182        }
 183
 184        sv = kzalloc(sizeof(struct z8530_dev), GFP_KERNEL);
 185        if (!sv)
 186                goto err_kzalloc;
 187
 188        /*      Stuff in the I/O addressing
 189         */
 190
 191        sv->active = 0;
 192
 193        sv->chanA.ctrlio = iobase + 1;
 194        sv->chanA.dataio = iobase + 3;
 195        sv->chanB.ctrlio = -1;
 196        sv->chanB.dataio = -1;
 197        sv->chanA.irqs = &z8530_nop;
 198        sv->chanB.irqs = &z8530_nop;
 199
 200        outb(0, iobase + 4);            /* DMA off */
 201
 202        /* We want a fast IRQ for this device. Actually we'd like an even faster
 203         * IRQ ;) - This is one driver RtLinux is made for
 204         */
 205
 206        if (request_irq(irq, z8530_interrupt, 0,
 207                        "Hostess SV11", sv) < 0) {
 208                pr_warn("IRQ %d already in use\n", irq);
 209                goto err_irq;
 210        }
 211
 212        sv->irq = irq;
 213        sv->chanA.private = sv;
 214        sv->chanA.dev = sv;
 215        sv->chanB.dev = sv;
 216
 217        if (dma) {
 218                /*      You can have DMA off or 1 and 3 thats the lot
 219                 *      on the Comtrol.
 220                 */
 221                sv->chanA.txdma = 3;
 222                sv->chanA.rxdma = 1;
 223                outb(0x03 | 0x08, iobase + 4);          /* DMA on */
 224                if (request_dma(sv->chanA.txdma, "Hostess SV/11 (TX)"))
 225                        goto err_txdma;
 226
 227                if (dma == 1)
 228                        if (request_dma(sv->chanA.rxdma, "Hostess SV/11 (RX)"))
 229                                goto err_rxdma;
 230        }
 231
 232        /* Kill our private IRQ line the hostess can end up chattering
 233         * until the configuration is set
 234         */
 235        disable_irq(irq);
 236
 237        /*      Begin normal initialise
 238         */
 239
 240        if (z8530_init(sv)) {
 241                pr_err("Z8530 series device not found\n");
 242                enable_irq(irq);
 243                goto free_dma;
 244        }
 245        z8530_channel_load(&sv->chanB, z8530_dead_port);
 246        if (sv->type == Z85C30)
 247                z8530_channel_load(&sv->chanA, z8530_hdlc_kilostream);
 248        else
 249                z8530_channel_load(&sv->chanA, z8530_hdlc_kilostream_85230);
 250
 251        enable_irq(irq);
 252
 253        /*      Now we can take the IRQ
 254         */
 255
 256        sv->chanA.netdevice = netdev = alloc_hdlcdev(sv);
 257        if (!netdev)
 258                goto free_dma;
 259
 260        dev_to_hdlc(netdev)->attach = hostess_attach;
 261        dev_to_hdlc(netdev)->xmit = hostess_queue_xmit;
 262        netdev->netdev_ops = &hostess_ops;
 263        netdev->base_addr = iobase;
 264        netdev->irq = irq;
 265
 266        if (register_hdlc_device(netdev)) {
 267                pr_err("unable to register HDLC device\n");
 268                free_netdev(netdev);
 269                goto free_dma;
 270        }
 271
 272        z8530_describe(sv, "I/O", iobase);
 273        sv->active = 1;
 274        return sv;
 275
 276free_dma:
 277        if (dma == 1)
 278                free_dma(sv->chanA.rxdma);
 279err_rxdma:
 280        if (dma)
 281                free_dma(sv->chanA.txdma);
 282err_txdma:
 283        free_irq(irq, sv);
 284err_irq:
 285        kfree(sv);
 286err_kzalloc:
 287        release_region(iobase, 8);
 288        return NULL;
 289}
 290
 291static void sv11_shutdown(struct z8530_dev *dev)
 292{
 293        unregister_hdlc_device(dev->chanA.netdevice);
 294        z8530_shutdown(dev);
 295        free_irq(dev->irq, dev);
 296        if (dma) {
 297                if (dma == 1)
 298                        free_dma(dev->chanA.rxdma);
 299                free_dma(dev->chanA.txdma);
 300        }
 301        release_region(dev->chanA.ctrlio - 1, 8);
 302        free_netdev(dev->chanA.netdevice);
 303        kfree(dev);
 304}
 305
 306static int io = 0x200;
 307static int irq = 9;
 308
 309module_param_hw(io, int, ioport, 0);
 310MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card");
 311module_param_hw(dma, int, dma, 0);
 312MODULE_PARM_DESC(dma, "Set this to 1 to use DMA1/DMA3 for TX/RX");
 313module_param_hw(irq, int, irq, 0);
 314MODULE_PARM_DESC(irq, "The interrupt line setting for the Comtrol Hostess SV11 card");
 315
 316MODULE_AUTHOR("Alan Cox");
 317MODULE_LICENSE("GPL");
 318MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11");
 319
 320static struct z8530_dev *sv11_unit;
 321
 322static int sv11_module_init(void)
 323{
 324        sv11_unit = sv11_init(io, irq);
 325        if (!sv11_unit)
 326                return -ENODEV;
 327        return 0;
 328}
 329module_init(sv11_module_init);
 330
 331static void sv11_module_cleanup(void)
 332{
 333        if (sv11_unit)
 334                sv11_shutdown(sv11_unit);
 335}
 336module_exit(sv11_module_cleanup);
 337