/*
 * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/etherdevice.h>
#include <asm/byteorder.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <linux/in.h>

#include "gdm_wimax.h"
#include "hci.h"
#include "wm_ioctl.h"
#include "netlink_k.h"

#define gdm_wimax_send(n, d, l)	\
	(n->phy_dev->send_func)(n->phy_dev->priv_dev, d, l, NULL, NULL)
#define gdm_wimax_send_with_cb(n, d, l, c, b)	\
	(n->phy_dev->send_func)(n->phy_dev->priv_dev, d, l, c, b)
#define gdm_wimax_rcv_with_cb(n, c, b)	\
	(n->phy_dev->rcv_func)(n->phy_dev->priv_dev, c, b)

#define EVT_MAX_SIZE	2048

struct evt_entry {
	struct	list_head list;
	struct	net_device *dev;
	char	evt_data[EVT_MAX_SIZE];
	int	size;
};

static void __gdm_wimax_event_send(struct work_struct *work);
static inline struct evt_entry *alloc_event_entry(void);
static inline void free_event_entry(struct evt_entry *e);
static struct evt_entry *get_event_entry(void);
static void put_event_entry(struct evt_entry *e);

static struct {
	int ref_cnt;
	struct sock *sock;
	struct list_head evtq;
	spinlock_t evt_lock;
	struct list_head freeq;
	struct work_struct ws;
} wm_event;

static u8 gdm_wimax_macaddr[6] = {0x00, 0x0a, 0x3b, 0xf0, 0x01, 0x30};

static void gdm_wimax_ind_fsm_update(struct net_device *dev, struct fsm_s *fsm);
static void gdm_wimax_ind_if_updown(struct net_device *dev, int if_up);

static const char *get_protocol_name(u16 protocol)
{
	static char buf[32];
	const char *name = "-";

	switch (protocol) {
	case ETH_P_ARP:
		name = "ARP";
		break;
	case ETH_P_IP:
		name = "IP";
		break;
	case ETH_P_IPV6:
		name = "IPv6";
		break;
	}

	sprintf(buf, "0x%04x(%s)", protocol, name);
	return buf;
}

static const char *get_ip_protocol_name(u8 ip_protocol)
{
	static char buf[32];
	const char *name = "-";

	switch (ip_protocol) {
	case IPPROTO_TCP:
		name = "TCP";
		break;
	case IPPROTO_UDP:
		name = "UDP";
		break;
	case IPPROTO_ICMP:
		name = "ICMP";
		break;
	}

	sprintf(buf, "%u(%s)", ip_protocol, name);
	return buf;
}

static const char *get_port_name(u16 port)
{
	static char buf[32];
	const char *name = "-";

	switch (port) {
	case 67:
		name = "DHCP-Server";
		break;
	case 68:
		name = "DHCP-Client";
		break;
	case 69:
		name = "TFTP";
		break;
	}

	sprintf(buf, "%u(%s)", port, name);
	return buf;
}

static void dump_eth_packet(struct net_device *dev, const char *title,
			    u8 *data, int len)
{
	struct iphdr *ih = NULL;
	struct udphdr *uh = NULL;
	u16 protocol = 0;
	u8 ip_protocol = 0;
	u16 port = 0;

	protocol = (data[12]<<8) | data[13];
	ih = (struct iphdr *)(data+ETH_HLEN);

	if (protocol == ETH_P_IP) {
		uh = (struct udphdr *)((char *)ih + sizeof(struct iphdr));
		ip_protocol = ih->protocol;
		port = ntohs(uh->dest);
	} else if (protocol == ETH_P_IPV6) {
		struct ipv6hdr *i6h = (struct ipv6hdr *)data;

		uh = (struct udphdr *)((char *)i6h + sizeof(struct ipv6hdr));
		ip_protocol = i6h->nexthdr;
		port = ntohs(uh->dest);
	}

	netdev_dbg(dev, "[%s] len=%d, %s, %s, %s\n", title, len,
		   get_protocol_name(protocol),
		   get_ip_protocol_name(ip_protocol),
		   get_port_name(port));

	if (!(data[0] == 0xff && data[1] == 0xff)) {
		if (protocol == ETH_P_IP)
			netdev_dbg(dev, "     src=%pI4\n", &ih->saddr);
		else if (protocol == ETH_P_IPV6)
			netdev_dbg(dev, "     src=%pI6\n", &ih->saddr);
	}

	print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, data, len, false);
}

static inline int gdm_wimax_header(struct sk_buff **pskb)
{
	u16 buf[HCI_HEADER_SIZE / sizeof(u16)];
	struct sk_buff *skb = *pskb;

	if (unlikely(skb_headroom(skb) < HCI_HEADER_SIZE)) {
		struct sk_buff *skb2;

		skb2 = skb_realloc_headroom(skb, HCI_HEADER_SIZE);
		if (skb2 == NULL)
			return -ENOMEM;
		if (skb->sk)
			skb_set_owner_w(skb2, skb->sk);
		kfree_skb(skb);
		skb = skb2;
	}

	skb_push(skb, HCI_HEADER_SIZE);
	buf[0] = H2B(WIMAX_TX_SDU);
	buf[1] = H2B(skb->len - HCI_HEADER_SIZE);
	memcpy(skb->data, buf, HCI_HEADER_SIZE);

	*pskb = skb;
	return 0;
}

static void gdm_wimax_event_rcv(struct net_device *dev, u16 type, void *msg,
				int len)
{
	struct nic *nic = netdev_priv(dev);

	u8 *buf = (u8 *)msg;
	u16 hci_cmd =  (buf[0]<<8) | buf[1];
	u16 hci_len = (buf[2]<<8) | buf[3];

	netdev_dbg(dev, "H=>D: 0x%04x(%d)\n", hci_cmd, hci_len);

	gdm_wimax_send(nic, msg, len);
}

static int gdm_wimax_event_init(void)
{
	if (!wm_event.ref_cnt) {
		wm_event.sock = netlink_init(NETLINK_WIMAX,
						gdm_wimax_event_rcv);
		if (wm_event.sock) {
			INIT_LIST_HEAD(&wm_event.evtq);
			INIT_LIST_HEAD(&wm_event.freeq);
			INIT_WORK(&wm_event.ws, __gdm_wimax_event_send);
			spin_lock_init(&wm_event.evt_lock);
		}
	}

	if (wm_event.sock) {
		wm_event.ref_cnt++;
		return 0;
	}

	pr_err("Creating WiMax Event netlink is failed\n");
	return -1;
}

static void gdm_wimax_event_exit(void)
{
	if (wm_event.sock && --wm_event.ref_cnt == 0) {
		struct evt_entry *e, *temp;
		unsigned long flags;

		spin_lock_irqsave(&wm_event.evt_lock, flags);

		list_for_each_entry_safe(e, temp, &wm_event.evtq, list) {
			list_del(&e->list);
			free_event_entry(e);
		}
		list_for_each_entry_safe(e, temp, &wm_event.freeq, list) {
			list_del(&e->list);
			free_event_entry(e);
		}

		spin_unlock_irqrestore(&wm_event.evt_lock, flags);
		netlink_exit(wm_event.sock);
		wm_event.sock = NULL;
	}
}

static inline struct evt_entry *alloc_event_entry(void)
{
	return kmalloc(sizeof(struct evt_entry), GFP_ATOMIC);
}

static inline void free_event_entry(struct evt_entry *e)
{
	kfree(e);
}

static struct evt_entry *get_event_entry(void)
{
	struct evt_entry *e;

	if (list_empty(&wm_event.freeq)) {
		e = alloc_event_entry();
	} else {
		e = list_entry(wm_event.freeq.next, struct evt_entry, list);
		list_del(&e->list);
	}

	return e;
}

static void put_event_entry(struct evt_entry *e)
{
	BUG_ON(!e);

	list_add_tail(&e->list, &wm_event.freeq);
}

static void __gdm_wimax_event_send(struct work_struct *work)
{
	int idx;
	unsigned long flags;
	struct evt_entry *e;

	spin_lock_irqsave(&wm_event.evt_lock, flags);

	while (!list_empty(&wm_event.evtq)) {
		e = list_entry(wm_event.evtq.next, struct evt_entry, list);
		spin_unlock_irqrestore(&wm_event.evt_lock, flags);

		sscanf(e->dev->name, "wm%d", &idx);
		netlink_send(wm_event.sock, idx, 0, e->evt_data, e->size);

		spin_lock_irqsave(&wm_event.evt_lock, flags);
		list_del(&e->list);
		put_event_entry(e);
	}

	spin_unlock_irqrestore(&wm_event.evt_lock, flags);
}

static int gdm_wimax_event_send(struct net_device *dev, char *buf, int size)
{
	struct evt_entry *e;
	unsigned long flags;

	u16 hci_cmd =  ((u8)buf[0]<<8) | (u8)buf[1];
	u16 hci_len = ((u8)buf[2]<<8) | (u8)buf[3];

	netdev_dbg(dev, "D=>H: 0x%04x(%d)\n", hci_cmd, hci_len);

	spin_lock_irqsave(&wm_event.evt_lock, flags);

	e = get_event_entry();
	if (!e) {
		netdev_err(dev, "%s: No memory for event\n", __func__);
		spin_unlock_irqrestore(&wm_event.evt_lock, flags);
		return -ENOMEM;
	}

	e->dev = dev;
	e->size = size;
	memcpy(e->evt_data, buf, size);

	list_add_tail(&e->list, &wm_event.evtq);
	spin_unlock_irqrestore(&wm_event.evt_lock, flags);

	schedule_work(&wm_event.ws);

	return 0;
}

static void tx_complete(void *arg)
{
	struct nic *nic = arg;

	if (netif_queue_stopped(nic->netdev))
		netif_wake_queue(nic->netdev);
}

int gdm_wimax_send_tx(struct sk_buff *skb, struct net_device *dev)
{
	int ret = 0;
	struct nic *nic = netdev_priv(dev);

	ret = gdm_wimax_send_with_cb(nic, skb->data, skb->len, tx_complete,
				     nic);
	if (ret == -ENOSPC) {
		netif_stop_queue(dev);
		ret = 0;
	}

	if (ret) {
		skb_pull(skb, HCI_HEADER_SIZE);
		return ret;
	}

	nic->stats.tx_packets++;
	nic->stats.tx_bytes += skb->len - HCI_HEADER_SIZE;
	kfree_skb(skb);
	return ret;
}

static int gdm_wimax_tx(struct sk_buff *skb, struct net_device *dev)
{
	int ret = 0;
	struct nic *nic = netdev_priv(dev);
	struct fsm_s *fsm = (struct fsm_s *)nic->sdk_data[SIOC_DATA_FSM].buf;

	dump_eth_packet(dev, "TX", skb->data, skb->len);

	ret = gdm_wimax_header(&skb);
	if (ret < 0) {
		skb_pull(skb, HCI_HEADER_SIZE);
		return ret;
	}

	#if !defined(LOOPBACK_TEST)
	if (!fsm) {
		netdev_err(dev, "ASSERTION ERROR: fsm is NULL!!\n");
	} else if (fsm->m_status != M_CONNECTED) {
		netdev_emerg(dev, "ASSERTION ERROR: Device is NOT ready. status=%d\n",
			     fsm->m_status);
		kfree_skb(skb);
		return 0;
	}
	#endif

#if defined(CONFIG_WIMAX_GDM72XX_QOS)
	ret = gdm_qos_send_hci_pkt(skb, dev);
#else
	ret = gdm_wimax_send_tx(skb, dev);
#endif
	return ret;
}

static int gdm_wimax_set_config(struct net_device *dev, struct ifmap *map)
{
	if (dev->flags & IFF_UP)
		return -EBUSY;

	return 0;
}

static void __gdm_wimax_set_mac_addr(struct net_device *dev, char *mac_addr)
{
	u16 hci_pkt_buf[32 / sizeof(u16)];
	u8 *pkt = (u8 *)&hci_pkt_buf[0];
	struct nic *nic = netdev_priv(dev);

	/* Since dev is registered as a ethernet device,
	 * ether_setup has made dev->addr_len to be ETH_ALEN
	 */
	memcpy(dev->dev_addr, mac_addr, dev->addr_len);

	/* Let lower layer know of this change by sending
	 * SetInformation(MAC Address)
	 */
	hci_pkt_buf[0] = H2B(WIMAX_SET_INFO);	/* cmd_evt */
	hci_pkt_buf[1] = H2B(8);			/* size */
	pkt[4] = 0; /* T */
	pkt[5] = 6; /* L */
	memcpy(pkt + 6, mac_addr, dev->addr_len); /* V */

	gdm_wimax_send(nic, pkt, HCI_HEADER_SIZE + 8);
}

/* A driver function */
static int gdm_wimax_set_mac_addr(struct net_device *dev, void *p)
{
	struct sockaddr *addr = p;

	if (netif_running(dev))
		return -EBUSY;

	if (!is_valid_ether_addr(addr->sa_data))
		return -EADDRNOTAVAIL;

	__gdm_wimax_set_mac_addr(dev, addr->sa_data);

	return 0;
}

static struct net_device_stats *gdm_wimax_stats(struct net_device *dev)
{
	struct nic *nic = netdev_priv(dev);

	return &nic->stats;
}

static int gdm_wimax_open(struct net_device *dev)
{
	struct nic *nic = netdev_priv(dev);
	struct fsm_s *fsm = (struct fsm_s *)nic->sdk_data[SIOC_DATA_FSM].buf;

	netif_start_queue(dev);

	if (fsm && fsm->m_status != M_INIT)
		gdm_wimax_ind_if_updown(dev, 1);
	return 0;
}

static int gdm_wimax_close(struct net_device *dev)
{
	struct nic *nic = netdev_priv(dev);
	struct fsm_s *fsm = (struct fsm_s *)nic->sdk_data[SIOC_DATA_FSM].buf;

	netif_stop_queue(dev);

	if (fsm && fsm->m_status != M_INIT)
		gdm_wimax_ind_if_updown(dev, 0);
	return 0;
}

static void kdelete(void **buf)
{
	if (buf && *buf) {
		kfree(*buf);
		*buf = NULL;
	}
}

static int gdm_wimax_ioctl_get_data(struct data_s *dst, struct data_s *src)
{
	int size;

	size = dst->size < src->size ? dst->size : src->size;

	dst->size = size;
	if (src->size) {
		if (!dst->buf)
			return -EINVAL;
		if (copy_to_user((void __user *)dst->buf, src->buf, size))
			return -EFAULT;
	}
	return 0;
}

static int gdm_wimax_ioctl_set_data(struct data_s *dst, struct data_s *src)
{
	if (!src->size) {
		dst->size = 0;
		return 0;
	}

	if (!src->buf)
		return -EINVAL;

	if (!(dst->buf && dst->size == src->size)) {
		kdelete(&dst->buf);
		dst->buf = kmalloc(src->size, GFP_KERNEL);
		if (dst->buf == NULL)
			return -ENOMEM;
	}

	if (copy_from_user(dst->buf, (void __user *)src->buf, src->size)) {
		kdelete(&dst->buf);
		return -EFAULT;
	}
	dst->size = src->size;
	return 0;
}

static void gdm_wimax_cleanup_ioctl(struct net_device *dev)
{
	struct nic *nic = netdev_priv(dev);
	int i;

	for (i = 0; i < SIOC_DATA_MAX; i++)
		kdelete(&nic->sdk_data[i].buf);
}

static void gdm_update_fsm(struct net_device *dev, struct fsm_s *new_fsm)
{
	struct nic *nic = netdev_priv(dev);
	struct fsm_s *cur_fsm = (struct fsm_s *)
					nic->sdk_data[SIOC_DATA_FSM].buf;

	if (!cur_fsm)
		return;

	if (cur_fsm->m_status != new_fsm->m_status ||
	    cur_fsm->c_status != new_fsm->c_status) {
		if (new_fsm->m_status == M_CONNECTED) {
			netif_carrier_on(dev);
		} else if (cur_fsm->m_status == M_CONNECTED) {
			netif_carrier_off(dev);
			#if defined(CONFIG_WIMAX_GDM72XX_QOS)
			gdm_qos_release_list(nic);
			#endif
		}
		gdm_wimax_ind_fsm_update(dev, new_fsm);
	}
}

static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct wm_req_s *req = (struct wm_req_s *)ifr;
	struct nic *nic = netdev_priv(dev);
	int ret;

	if (cmd != SIOCWMIOCTL)
		return -EOPNOTSUPP;

	switch (req->cmd) {
	case SIOCG_DATA:
	case SIOCS_DATA:
		if (req->data_id >= SIOC_DATA_MAX) {
			netdev_err(dev, "%s error: data-index(%d) is invalid!!\n",
				   __func__, req->data_id);
			return -EOPNOTSUPP;
		}
		if (req->cmd == SIOCG_DATA) {
			ret = gdm_wimax_ioctl_get_data(
				&req->data, &nic->sdk_data[req->data_id]);
			if (ret < 0)
				return ret;
		} else if (req->cmd == SIOCS_DATA) {
			if (req->data_id == SIOC_DATA_FSM) {
				/*NOTE: gdm_update_fsm should be called
				before gdm_wimax_ioctl_set_data is called*/
				gdm_update_fsm(dev,
					       (struct fsm_s *)req->data.buf);
			}
			ret = gdm_wimax_ioctl_set_data(
				&nic->sdk_data[req->data_id], &req->data);
			if (ret < 0)
				return ret;
		}
		break;
	default:
		netdev_err(dev, "%s: %x unknown ioctl\n", __func__, cmd);
		return -EOPNOTSUPP;
	}

	return 0;
}

static void gdm_wimax_prepare_device(struct net_device *dev)
{
	struct nic *nic = netdev_priv(dev);
	u16 buf[32 / sizeof(u16)];
	struct hci_s *hci = (struct hci_s *)buf;
	u16 len = 0;
	u32 val = 0;

	#define BIT_MULTI_CS	0
	#define BIT_WIMAX		1
	#define BIT_QOS			2
	#define BIT_AGGREGATION	3

	/* GetInformation mac address */
	len = 0;
	hci->cmd_evt = H2B(WIMAX_GET_INFO);
	hci->data[len++] = TLV_T(T_MAC_ADDRESS);
	hci->length = H2B(len);
	gdm_wimax_send(nic, hci, HCI_HEADER_SIZE+len);

	val = (1<<BIT_WIMAX) | (1<<BIT_MULTI_CS);
	#if defined(CONFIG_WIMAX_GDM72XX_QOS)
	val |= (1<<BIT_QOS);
	#endif
	#if defined(CONFIG_WIMAX_GDM72XX_WIMAX2)
	val |= (1<<BIT_AGGREGATION);
	#endif

	/* Set capability */
	len = 0;
	hci->cmd_evt = H2B(WIMAX_SET_INFO);
	hci->data[len++] = TLV_T(T_CAPABILITY);
	hci->data[len++] = TLV_L(T_CAPABILITY);
	val = DH2B(val);
	memcpy(&hci->data[len], &val, TLV_L(T_CAPABILITY));
	len += TLV_L(T_CAPABILITY);
	hci->length = H2B(len);
	gdm_wimax_send(nic, hci, HCI_HEADER_SIZE+len);

	netdev_info(dev, "GDM WiMax Set CAPABILITY: 0x%08X\n", DB2H(val));
}

static int gdm_wimax_hci_get_tlv(u8 *buf, u8 *T, u16 *L, u8 **V)
{
	#define __U82U16(b) ((u16)((u8 *)(b))[0] | ((u16)((u8 *)(b))[1] << 8))
	int next_pos;

	*T = buf[0];
	if (buf[1] == 0x82) {
		*L = B2H(__U82U16(&buf[2]));
		next_pos = 1/*type*/+3/*len*/;
	} else {
		*L = buf[1];
		next_pos = 1/*type*/+1/*len*/;
	}
	*V = &buf[next_pos];

	next_pos += *L/*length of val*/;
	return next_pos;
}

static int gdm_wimax_get_prepared_info(struct net_device *dev, char *buf,
				       int len)
{
	u8 T, *V;
	u16 L;
	u16 cmd_evt, cmd_len;
	int pos = HCI_HEADER_SIZE;

	cmd_evt = B2H(*(u16 *)&buf[0]);
	cmd_len = B2H(*(u16 *)&buf[2]);

	if (len < cmd_len + HCI_HEADER_SIZE) {
		netdev_err(dev, "%s: invalid length [%d/%d]\n", __func__,
			   cmd_len + HCI_HEADER_SIZE, len);
		return -1;
	}

	if (cmd_evt == WIMAX_GET_INFO_RESULT) {
		if (cmd_len < 2) {
			netdev_err(dev, "%s: len is too short [%x/%d]\n",
				   __func__, cmd_evt, len);
			return -1;
		}

		pos += gdm_wimax_hci_get_tlv(&buf[pos], &T, &L, &V);
		if (T == TLV_T(T_MAC_ADDRESS)) {
			if (L != dev->addr_len) {
				netdev_err(dev,
					   "%s Invalid inofrmation result T/L [%x/%d]\n",
					   __func__, T, L);
				return -1;
			}
			netdev_info(dev, "MAC change [%pM]->[%pM]\n",
				    dev->dev_addr, V);
			memcpy(dev->dev_addr, V, dev->addr_len);
			return 1;
		}
	}

	gdm_wimax_event_send(dev, buf, len);
	return 0;
}

static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len)
{
	struct nic *nic = netdev_priv(dev);
	struct sk_buff *skb;
	int ret;

	dump_eth_packet(dev, "RX", buf, len);

	skb = dev_alloc_skb(len + 2);
	if (!skb) {
		netdev_err(dev, "%s: dev_alloc_skb failed!\n", __func__);
		return;
	}
	skb_reserve(skb, 2);

	nic->stats.rx_packets++;
	nic->stats.rx_bytes += len;

	memcpy(skb_put(skb, len), buf, len);

	skb->dev = dev;
	skb->protocol = eth_type_trans(skb, dev); /* what will happen? */

	ret = in_interrupt() ? netif_rx(skb) : netif_rx_ni(skb);
	if (ret == NET_RX_DROP)
		netdev_err(dev, "%s skb dropped\n", __func__);
}

static void gdm_wimax_transmit_aggr_pkt(struct net_device *dev, char *buf,
					int len)
{
	#define HCI_PADDING_BYTE	4
	#define HCI_RESERVED_BYTE	4
	struct hci_s *hci;
	int length;

	while (len > 0) {
		hci = (struct hci_s *)buf;

		if (B2H(hci->cmd_evt) != WIMAX_RX_SDU) {
			netdev_err(dev, "Wrong cmd_evt(0x%04X)\n",
				   B2H(hci->cmd_evt));
			break;
		}

		length = B2H(hci->length);
		gdm_wimax_netif_rx(dev, hci->data, length);

		if (length & 0x3) {
			/* Add padding size */
			length += HCI_PADDING_BYTE - (length & 0x3);
		}

		length += HCI_HEADER_SIZE + HCI_RESERVED_BYTE;
		len -= length;
		buf += length;
	}
}

static void gdm_wimax_transmit_pkt(struct net_device *dev, char *buf, int len)
{
	#if defined(CONFIG_WIMAX_GDM72XX_QOS)
	struct nic *nic = netdev_priv(dev);
	#endif
	u16 cmd_evt, cmd_len;

	/* This code is added for certain rx packet to be ignored. */
	if (len == 0)
		return;

	cmd_evt = B2H(*(u16 *)&buf[0]);
	cmd_len = B2H(*(u16 *)&buf[2]);

	if (len < cmd_len + HCI_HEADER_SIZE) {
		if (len)
			netdev_err(dev, "%s: invalid length [%d/%d]\n",
				   __func__, cmd_len + HCI_HEADER_SIZE, len);
		return;
	}

	switch (cmd_evt) {
	case WIMAX_RX_SDU_AGGR:
		gdm_wimax_transmit_aggr_pkt(dev, &buf[HCI_HEADER_SIZE],
					    cmd_len);
		break;
	case WIMAX_RX_SDU:
		gdm_wimax_netif_rx(dev, &buf[HCI_HEADER_SIZE], cmd_len);
		break;
	#if defined(CONFIG_WIMAX_GDM72XX_QOS)
	case WIMAX_EVT_MODEM_REPORT:
		gdm_recv_qos_hci_packet(nic, buf, len);
		break;
	#endif
	case WIMAX_SDU_TX_FLOW:
		if (buf[4] == 0) {
			if (!netif_queue_stopped(dev))
				netif_stop_queue(dev);
		} else if (buf[4] == 1) {
			if (netif_queue_stopped(dev))
				netif_wake_queue(dev);
		}
		break;
	default:
		gdm_wimax_event_send(dev, buf, len);
		break;
	}
}

static void gdm_wimax_ind_fsm_update(struct net_device *dev, struct fsm_s *fsm)
{
	u16 buf[32 / sizeof(u16)];
	u8 *hci_pkt_buf = (u8 *)&buf[0];

	/* Indicate updating fsm */
	buf[0] = H2B(WIMAX_FSM_UPDATE);
	buf[1] = H2B(sizeof(struct fsm_s));
	memcpy(&hci_pkt_buf[HCI_HEADER_SIZE], fsm, sizeof(struct fsm_s));

	gdm_wimax_event_send(dev, hci_pkt_buf,
			     HCI_HEADER_SIZE + sizeof(struct fsm_s));
}

static void gdm_wimax_ind_if_updown(struct net_device *dev, int if_up)
{
	u16 buf[32 / sizeof(u16)];
	struct hci_s *hci = (struct hci_s *)buf;
	unsigned char up_down;

	up_down = if_up ? WIMAX_IF_UP : WIMAX_IF_DOWN;

	/* Indicate updating fsm */
	hci->cmd_evt = H2B(WIMAX_IF_UPDOWN);
	hci->length = H2B(sizeof(up_down));
	hci->data[0] = up_down;

	gdm_wimax_event_send(dev, (char *)hci, HCI_HEADER_SIZE+sizeof(up_down));
}

static void rx_complete(void *arg, void *data, int len)
{
	struct nic *nic = arg;

	gdm_wimax_transmit_pkt(nic->netdev, data, len);
	gdm_wimax_rcv_with_cb(nic, rx_complete, nic);
}

static void prepare_rx_complete(void *arg, void *data, int len)
{
	struct nic *nic = arg;
	int ret;

	ret = gdm_wimax_get_prepared_info(nic->netdev, data, len);
	if (ret == 1) {
		gdm_wimax_rcv_with_cb(nic, rx_complete, nic);
	} else {
		if (ret < 0)
			netdev_err(nic->netdev,
				   "get_prepared_info failed(%d)\n", ret);
		gdm_wimax_rcv_with_cb(nic, prepare_rx_complete, nic);
	}
}

static void start_rx_proc(struct nic *nic)
{
	gdm_wimax_rcv_with_cb(nic, prepare_rx_complete, nic);
}

static struct net_device_ops gdm_netdev_ops = {
	.ndo_open		= gdm_wimax_open,
	.ndo_stop		= gdm_wimax_close,
	.ndo_set_config		= gdm_wimax_set_config,
	.ndo_start_xmit		= gdm_wimax_tx,
	.ndo_get_stats		= gdm_wimax_stats,
	.ndo_set_mac_address	= gdm_wimax_set_mac_addr,
	.ndo_do_ioctl		= gdm_wimax_ioctl,
};

int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev)
{
	struct nic *nic = NULL;
	struct net_device *dev;
	int ret;

	dev = alloc_netdev(sizeof(*nic), "wm%d", ether_setup);

	if (dev == NULL) {
		pr_err("alloc_etherdev failed\n");
		return -ENOMEM;
	}

	SET_NETDEV_DEV(dev, pdev);
	dev->mtu = 1400;
	dev->netdev_ops = &gdm_netdev_ops;
	dev->flags &= ~IFF_MULTICAST;
	memcpy(dev->dev_addr, gdm_wimax_macaddr, sizeof(gdm_wimax_macaddr));

	nic = netdev_priv(dev);
	memset(nic, 0, sizeof(*nic));

	nic->netdev = dev;
	nic->phy_dev = phy_dev;
	phy_dev->netdev = dev;

	/* event socket init */
	ret = gdm_wimax_event_init();
	if (ret < 0) {
		pr_err("Cannot create event.\n");
		goto cleanup;
	}

	ret = register_netdev(dev);
	if (ret)
		goto cleanup;

	#if defined(LOOPBACK_TEST)
	netif_start_queue(dev);
	netif_carrier_on(dev);
	#else
	netif_carrier_off(dev);
	#endif

#ifdef CONFIG_WIMAX_GDM72XX_QOS
	gdm_qos_init(nic);
#endif

	start_rx_proc(nic);

	/* Prepare WiMax device */
	gdm_wimax_prepare_device(dev);

	return 0;

cleanup:
	pr_err("register_netdev failed\n");
	free_netdev(dev);
	return ret;
}

void unregister_wimax_device(struct phy_dev *phy_dev)
{
	struct nic *nic = netdev_priv(phy_dev->netdev);
	struct fsm_s *fsm = (struct fsm_s *)nic->sdk_data[SIOC_DATA_FSM].buf;

	if (fsm)
		fsm->m_status = M_INIT;
	unregister_netdev(nic->netdev);

	gdm_wimax_event_exit();

#if defined(CONFIG_WIMAX_GDM72XX_QOS)
	gdm_qos_release_list(nic);
#endif

	gdm_wimax_cleanup_ioctl(phy_dev->netdev);

	free_netdev(nic->netdev);
}
