/*
 * Copyright (c) 2007-2008 Atheros Communications Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
/*                                                                      */
/*  Module Name : zdusb.c                                               */
/*                                                                      */
/*  Abstract                                                            */
/*     This module contains plug and play handling for USB device driver*/
/*                                                                      */
/*  NOTES                                                               */
/*     Platform dependent.                                              */
/*                                                                      */
/************************************************************************/

#ifdef MODVERSIONS
#include <linux/modversions.h>
#endif

#include <linux/module.h>
#include <linux/usb.h>

#include "usbdrv.h"
#include "zdusb.h"

int zfLnxAllocAllUrbs(struct usbdrv_private *macp);
void zfLnxFreeAllUrbs(struct usbdrv_private *macp);
void zfLnxUnlinkAllUrbs(struct usbdrv_private *macp);

MODULE_AUTHOR("Atheros Communications");
MODULE_DESCRIPTION("Atheros 802.11n Wireless LAN adapter");
MODULE_LICENSE("Dual BSD/GPL");

static const char driver_name[] = "Otus";

/* table of devices that work with this driver */
static struct usb_device_id zd1221_ids [] = {
	{ USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) },
        { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) },
	{ USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) },
	{ USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WN111v2) },
	{ }					/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, zd1221_ids);

extern u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp);
extern int usbdrv_close(struct net_device *dev);
extern u8_t zfLnxClearStructs(struct net_device *dev);
extern int zfWdsClose(struct net_device *dev);
extern int zfUnregisterWdsDev(struct net_device* parentDev, u16_t wdsId);
extern int zfLnxVapClose(struct net_device *dev);
extern int zfLnxUnregisterVapDev(struct net_device* parentDev, u16_t vapId);

/* WDS */
extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];

/* VAP */
extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER];

static int zfLnxProbe(struct usb_interface *interface,
	const struct usb_device_id *id)
{
    struct usb_device *dev = interface_to_usbdev(interface);

    struct net_device *net = NULL;
    struct usbdrv_private *macp = NULL;
    int vendor_id, product_id;
    int result = 0;

    usb_get_dev(dev);

    vendor_id = dev->descriptor.idVendor;
    product_id = dev->descriptor.idProduct;

#ifdef HMAC_DEBUG
    printk(KERN_NOTICE "vendor_id = %04x\n", vendor_id);
    printk(KERN_NOTICE "product_id = %04x\n", product_id);

    if (dev->speed == USB_SPEED_HIGH)
        printk(KERN_NOTICE "USB 2.0 Host\n");
    else
        printk(KERN_NOTICE "USB 1.1 Host\n");
#endif

    if (!(macp = kmalloc(sizeof(struct usbdrv_private), GFP_KERNEL)))
    {
        printk(KERN_ERR "out of memory allocating device structure\n");
        result = -ENOMEM;
        goto fail;
    }

    /* Zero the memory */
    memset(macp, 0, sizeof(struct usbdrv_private));

    net = alloc_etherdev(0);

    if (net == NULL)
    {
        printk(KERN_ERR "zfLnxProbe: Not able to alloc etherdev struct\n");
        result = -ENOMEM;
        goto fail1;
    }

    strcpy(net->name, "ath%d");

    net->ml_priv = macp;   //kernel 2.6
    macp->udev = dev;
    macp->device = net;

    /* set up the endpoint information */
    /* check out the endpoints */
    macp->interface = interface;

    //init_waitqueue_head(&macp->regSet_wait);
    //init_waitqueue_head(&macp->iorwRsp_wait);
    //init_waitqueue_head(&macp->term_wait);

    if (!zfLnxAllocAllUrbs(macp))
    {
        result = -ENOMEM;
        goto fail2;
    }

    if (!zfLnxInitSetup(net, macp))
    {
        result = -EIO;
        goto fail3;
    }
    else
    {
        usb_set_intfdata(interface, macp);
        SET_NETDEV_DEV(net, &interface->dev);

        if (register_netdev(net) != 0)
        {
            usb_set_intfdata(interface, NULL);
            goto fail3;
        }
    }

    netif_carrier_off(net);
    goto done;

fail3:
    zfLnxFreeAllUrbs(macp);
fail2:
    free_netdev(net);  //kernel 2.6
fail1:
    kfree(macp);

fail:
    usb_put_dev(dev);
    macp = NULL;

done:
    return result;
}

static void zfLnxDisconnect(struct usb_interface *interface)
{
    struct usbdrv_private *macp = (struct usbdrv_private *) usb_get_intfdata(interface);

    printk(KERN_DEBUG "zfLnxDisconnect\n");

    if (!macp)
    {
        printk(KERN_ERR "unregistering non-existant device\n");
        return;
    }

    if (macp->driver_isolated)
    {
        if (macp->device->flags & IFF_UP)
            usbdrv_close(macp->device);
    }

#if 0
    /* Close WDS */
    //zfWdsClose(wds[0].dev);
    /* Unregister WDS */
    //zfUnregisterWdsDev(macp->device, 0);

    /* Close VAP */
    zfLnxVapClose(vap[0].dev);
    /* Unregister VAP */
    zfLnxUnregisterVapDev(macp->device, 0);
#endif

    zfLnxClearStructs(macp->device);

    unregister_netdev(macp->device);

    usb_put_dev(interface_to_usbdev(interface));

    //printk(KERN_ERR "3. zfLnxUnlinkAllUrbs\n");
    //zfLnxUnlinkAllUrbs(macp);

    /* Free network interface */
    free_netdev(macp->device);

    zfLnxFreeAllUrbs(macp);
    //zfLnxClearStructs(macp->device);
    kfree(macp);
    macp = NULL;

    usb_set_intfdata(interface, NULL);
}

static struct usb_driver zd1221_driver = {
	.name         = driver_name,
	.probe        = zfLnxProbe,
	.disconnect   = zfLnxDisconnect,
	.id_table     = zd1221_ids,
};

int __init zfLnxIinit(void)
{
    printk(KERN_NOTICE "%s - version %s\n",  DRIVER_NAME, VERSIONID);
    return usb_register(&zd1221_driver);
}

void __exit zfLnxExit(void)
{
    usb_deregister(&zd1221_driver);
}

module_init(zfLnxIinit);
module_exit(zfLnxExit);
