linux/drivers/net/mipsnet.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 */
   6
   7#include <linux/init.h>
   8#include <linux/io.h>
   9#include <linux/kernel.h>
  10#include <linux/module.h>
  11#include <linux/netdevice.h>
  12#include <linux/etherdevice.h>
  13#include <linux/platform_device.h>
  14#include <asm/mips-boards/simint.h>
  15
  16#define MIPSNET_VERSION "2007-11-17"
  17
  18/*
  19 * Net status/control block as seen by sw in the core.
  20 */
  21struct mipsnet_regs {
  22        /*
  23         * Device info for probing, reads as MIPSNET%d where %d is some
  24         * form of version.
  25         */
  26        u64 devId;              /*0x00 */
  27
  28        /*
  29         * read only busy flag.
  30         * Set and cleared by the Net Device to indicate that an rx or a tx
  31         * is in progress.
  32         */
  33        u32 busy;               /*0x08 */
  34
  35        /*
  36         * Set by the Net Device.
  37         * The device will set it once data has been received.
  38         * The value is the number of bytes that should be read from
  39         * rxDataBuffer.  The value will decrease till 0 until all the data
  40         * from rxDataBuffer has been read.
  41         */
  42        u32 rxDataCount;        /*0x0c */
  43#define MIPSNET_MAX_RXTX_DATACOUNT (1 << 16)
  44
  45        /*
  46         * Settable from the MIPS core, cleared by the Net Device.
  47         * The core should set the number of bytes it wants to send,
  48         * then it should write those bytes of data to txDataBuffer.
  49         * The device will clear txDataCount has been processed (not
  50         * necessarily sent).
  51         */
  52        u32 txDataCount;        /*0x10 */
  53
  54        /*
  55         * Interrupt control
  56         *
  57         * Used to clear the interrupted generated by this dev.
  58         * Write a 1 to clear the interrupt. (except bit31).
  59         *
  60         * Bit0 is set if it was a tx-done interrupt.
  61         * Bit1 is set when new rx-data is available.
  62         *    Until this bit is cleared there will be no other RXs.
  63         *
  64         * Bit31 is used for testing, it clears after a read.
  65         *    Writing 1 to this bit will cause an interrupt to be generated.
  66         *    To clear the test interrupt, write 0 to this register.
  67         */
  68        u32 interruptControl;   /*0x14 */
  69#define MIPSNET_INTCTL_TXDONE     (1u << 0)
  70#define MIPSNET_INTCTL_RXDONE     (1u << 1)
  71#define MIPSNET_INTCTL_TESTBIT    (1u << 31)
  72
  73        /*
  74         * Readonly core-specific interrupt info for the device to signal
  75         * the core. The meaning of the contents of this field might change.
  76         */
  77        /* XXX: the whole memIntf interrupt scheme is messy: the device
  78         * should have no control what so ever of what VPE/register set is
  79         * being used.
  80         * The MemIntf should only expose interrupt lines, and something in
  81         * the config should be responsible for the line<->core/vpe bindings.
  82         */
  83        u32 interruptInfo;      /*0x18 */
  84
  85        /*
  86         * This is where the received data is read out.
  87         * There is more data to read until rxDataReady is 0.
  88         * Only 1 byte at this regs offset is used.
  89         */
  90        u32 rxDataBuffer;       /*0x1c */
  91
  92        /*
  93         * This is where the data to transmit is written.
  94         * Data should be written for the amount specified in the
  95         * txDataCount register.
  96         * Only 1 byte at this regs offset is used.
  97         */
  98        u32 txDataBuffer;       /*0x20 */
  99};
 100
 101#define regaddr(dev, field) \
 102  (dev->base_addr + offsetof(struct mipsnet_regs, field))
 103
 104static char mipsnet_string[] = "mipsnet";
 105
 106/*
 107 * Copy data from the MIPSNET rx data port
 108 */
 109static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
 110                        int len)
 111{
 112        for (; len > 0; len--, kdata++)
 113                *kdata = inb(regaddr(dev, rxDataBuffer));
 114
 115        return inl(regaddr(dev, rxDataCount));
 116}
 117
 118static inline void mipsnet_put_todevice(struct net_device *dev,
 119        struct sk_buff *skb)
 120{
 121        int count_to_go = skb->len;
 122        char *buf_ptr = skb->data;
 123
 124        outl(skb->len, regaddr(dev, txDataCount));
 125
 126        for (; count_to_go; buf_ptr++, count_to_go--)
 127                outb(*buf_ptr, regaddr(dev, txDataBuffer));
 128
 129        dev->stats.tx_packets++;
 130        dev->stats.tx_bytes += skb->len;
 131
 132        dev_kfree_skb(skb);
 133}
 134
 135static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
 136{
 137        /*
 138         * Only one packet at a time. Once TXDONE interrupt is serviced, the
 139         * queue will be restarted.
 140         */
 141        netif_stop_queue(dev);
 142        mipsnet_put_todevice(dev, skb);
 143
 144        return NETDEV_TX_OK;
 145}
 146
 147static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t len)
 148{
 149        struct sk_buff *skb;
 150
 151        if (!len)
 152                return len;
 153
 154        skb = dev_alloc_skb(len + NET_IP_ALIGN);
 155        if (!skb) {
 156                dev->stats.rx_dropped++;
 157                return -ENOMEM;
 158        }
 159
 160        skb_reserve(skb, NET_IP_ALIGN);
 161        if (ioiocpy_frommipsnet(dev, skb_put(skb, len), len))
 162                return -EFAULT;
 163
 164        skb->protocol = eth_type_trans(skb, dev);
 165        skb->ip_summed = CHECKSUM_UNNECESSARY;
 166
 167        netif_rx(skb);
 168
 169        dev->stats.rx_packets++;
 170        dev->stats.rx_bytes += len;
 171
 172        return len;
 173}
 174
 175static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
 176{
 177        struct net_device *dev = dev_id;
 178        u32 int_flags;
 179        irqreturn_t ret = IRQ_NONE;
 180
 181        if (irq != dev->irq)
 182                goto out_badirq;
 183
 184        /* TESTBIT is cleared on read. */
 185        int_flags = inl(regaddr(dev, interruptControl));
 186        if (int_flags & MIPSNET_INTCTL_TESTBIT) {
 187                /* TESTBIT takes effect after a write with 0. */
 188                outl(0, regaddr(dev, interruptControl));
 189                ret = IRQ_HANDLED;
 190        } else if (int_flags & MIPSNET_INTCTL_TXDONE) {
 191                /* Only one packet at a time, we are done. */
 192                dev->stats.tx_packets++;
 193                netif_wake_queue(dev);
 194                outl(MIPSNET_INTCTL_TXDONE,
 195                     regaddr(dev, interruptControl));
 196                ret = IRQ_HANDLED;
 197        } else if (int_flags & MIPSNET_INTCTL_RXDONE) {
 198                mipsnet_get_fromdev(dev, inl(regaddr(dev, rxDataCount)));
 199                outl(MIPSNET_INTCTL_RXDONE, regaddr(dev, interruptControl));
 200                ret = IRQ_HANDLED;
 201        }
 202        return ret;
 203
 204out_badirq:
 205        printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
 206               dev->name, __func__, irq);
 207        return ret;
 208}
 209
 210static int mipsnet_open(struct net_device *dev)
 211{
 212        int err;
 213
 214        err = request_irq(dev->irq, &mipsnet_interrupt,
 215                          IRQF_SHARED, dev->name, (void *) dev);
 216        if (err) {
 217                release_region(dev->base_addr, sizeof(struct mipsnet_regs));
 218                return err;
 219        }
 220
 221        netif_start_queue(dev);
 222
 223        /* test interrupt handler */
 224        outl(MIPSNET_INTCTL_TESTBIT, regaddr(dev, interruptControl));
 225
 226        return 0;
 227}
 228
 229static int mipsnet_close(struct net_device *dev)
 230{
 231        netif_stop_queue(dev);
 232        free_irq(dev->irq, dev);
 233        return 0;
 234}
 235
 236static void mipsnet_set_mclist(struct net_device *dev)
 237{
 238}
 239
 240static const struct net_device_ops mipsnet_netdev_ops = {
 241        .ndo_open               = mipsnet_open,
 242        .ndo_stop               = mipsnet_close,
 243        .ndo_start_xmit         = mipsnet_xmit,
 244        .ndo_set_multicast_list = mipsnet_set_mclist,
 245        .ndo_change_mtu         = eth_change_mtu,
 246        .ndo_validate_addr      = eth_validate_addr,
 247        .ndo_set_mac_address    = eth_mac_addr,
 248};
 249
 250static int __init mipsnet_probe(struct platform_device *dev)
 251{
 252        struct net_device *netdev;
 253        int err;
 254
 255        netdev = alloc_etherdev(0);
 256        if (!netdev) {
 257                err = -ENOMEM;
 258                goto out;
 259        }
 260
 261        platform_set_drvdata(dev, netdev);
 262
 263        netdev->netdev_ops = &mipsnet_netdev_ops;
 264
 265        /*
 266         * TODO: probe for these or load them from PARAM
 267         */
 268        netdev->base_addr = 0x4200;
 269        netdev->irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB0 +
 270                      inl(regaddr(netdev, interruptInfo));
 271
 272        /* Get the io region now, get irq on open() */
 273        if (!request_region(netdev->base_addr, sizeof(struct mipsnet_regs),
 274                            "mipsnet")) {
 275                err = -EBUSY;
 276                goto out_free_netdev;
 277        }
 278
 279        /*
 280         * Lacking any better mechanism to allocate a MAC address we use a
 281         * random one ...
 282         */
 283        random_ether_addr(netdev->dev_addr);
 284
 285        err = register_netdev(netdev);
 286        if (err) {
 287                printk(KERN_ERR "MIPSNet: failed to register netdev.\n");
 288                goto out_free_region;
 289        }
 290
 291        return 0;
 292
 293out_free_region:
 294        release_region(netdev->base_addr, sizeof(struct mipsnet_regs));
 295
 296out_free_netdev:
 297        free_netdev(netdev);
 298
 299out:
 300        return err;
 301}
 302
 303static int __devexit mipsnet_device_remove(struct platform_device *device)
 304{
 305        struct net_device *dev = platform_get_drvdata(device);
 306
 307        unregister_netdev(dev);
 308        release_region(dev->base_addr, sizeof(struct mipsnet_regs));
 309        free_netdev(dev);
 310        platform_set_drvdata(device, NULL);
 311
 312        return 0;
 313}
 314
 315static struct platform_driver mipsnet_driver = {
 316        .driver = {
 317                .name           = mipsnet_string,
 318                .owner          = THIS_MODULE,
 319        },
 320        .probe          = mipsnet_probe,
 321        .remove         = __devexit_p(mipsnet_device_remove),
 322};
 323
 324static int __init mipsnet_init_module(void)
 325{
 326        int err;
 327
 328        printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
 329               "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
 330
 331        err = platform_driver_register(&mipsnet_driver);
 332        if (err)
 333                printk(KERN_ERR "Driver registration failed\n");
 334
 335        return err;
 336}
 337
 338static void __exit mipsnet_exit_module(void)
 339{
 340        platform_driver_unregister(&mipsnet_driver);
 341}
 342
 343module_init(mipsnet_init_module);
 344module_exit(mipsnet_exit_module);
 345