/*
 *  PS3 gelic network driver.
 *
 * Copyright (C) 2007 Sony Computer Entertainment Inc.
 * Copyright 2006, 2007 Sony Corporation
 *
 * This file is based on: spider_net.c
 *
 * (C) Copyright IBM Corp. 2005
 *
 * Authors : Utz Bacher <utz.bacher@de.ibm.com>
 *           Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#undef DEBUG

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

#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>

#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>

#include <linux/dma-mapping.h>
#include <net/checksum.h>
#include <asm/firmware.h>
#include <asm/ps3.h>
#include <asm/lv1call.h>

#include "ps3_gelic_net.h"
#include "ps3_gelic_wireless.h"

#define DRV_NAME "Gelic Network Driver"
#define DRV_VERSION "2.0"

MODULE_AUTHOR("SCE Inc.");
MODULE_DESCRIPTION("Gelic Network driver");
MODULE_LICENSE("GPL");


static inline void gelic_card_enable_rxdmac(struct gelic_card *card);
static inline void gelic_card_disable_rxdmac(struct gelic_card *card);
static inline void gelic_card_disable_txdmac(struct gelic_card *card);
static inline void gelic_card_reset_chain(struct gelic_card *card,
					  struct gelic_descr_chain *chain,
					  struct gelic_descr *start_descr);

/* set irq_mask */
int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask)
{
	int status;

	status = lv1_net_set_interrupt_mask(bus_id(card), dev_id(card),
					    mask, 0);
	if (status)
		dev_info(ctodev(card),
			 "%s failed %d\n", __func__, status);
	return status;
}

static inline void gelic_card_rx_irq_on(struct gelic_card *card)
{
	card->irq_mask |= GELIC_CARD_RXINT;
	gelic_card_set_irq_mask(card, card->irq_mask);
}
static inline void gelic_card_rx_irq_off(struct gelic_card *card)
{
	card->irq_mask &= ~GELIC_CARD_RXINT;
	gelic_card_set_irq_mask(card, card->irq_mask);
}

static void gelic_card_get_ether_port_status(struct gelic_card *card,
					     int inform)
{
	u64 v2;
	struct net_device *ether_netdev;

	lv1_net_control(bus_id(card), dev_id(card),
			GELIC_LV1_GET_ETH_PORT_STATUS,
			GELIC_LV1_VLAN_TX_ETHERNET, 0, 0,
			&card->ether_port_status, &v2);

	if (inform) {
		ether_netdev = card->netdev[GELIC_PORT_ETHERNET];
		if (card->ether_port_status & GELIC_LV1_ETHER_LINK_UP)
			netif_carrier_on(ether_netdev);
		else
			netif_carrier_off(ether_netdev);
	}
}

void gelic_card_up(struct gelic_card *card)
{
	pr_debug("%s: called\n", __func__);
	mutex_lock(&card->updown_lock);
	if (atomic_inc_return(&card->users) == 1) {
		pr_debug("%s: real do\n", __func__);
		/* enable irq */
		gelic_card_set_irq_mask(card, card->irq_mask);
		/* start rx */
		gelic_card_enable_rxdmac(card);

		napi_enable(&card->napi);
	}
	mutex_unlock(&card->updown_lock);
	pr_debug("%s: done\n", __func__);
}

void gelic_card_down(struct gelic_card *card)
{
	u64 mask;
	pr_debug("%s: called\n", __func__);
	mutex_lock(&card->updown_lock);
	if (atomic_dec_if_positive(&card->users) == 0) {
		pr_debug("%s: real do\n", __func__);
		napi_disable(&card->napi);
		/*
		 * Disable irq. Wireless interrupts will
		 * be disabled later if any
		 */
		mask = card->irq_mask & (GELIC_CARD_WLAN_EVENT_RECEIVED |
					 GELIC_CARD_WLAN_COMMAND_COMPLETED);
		gelic_card_set_irq_mask(card, mask);
		/* stop rx */
		gelic_card_disable_rxdmac(card);
		gelic_card_reset_chain(card, &card->rx_chain,
				       card->descr + GELIC_NET_TX_DESCRIPTORS);
		/* stop tx */
		gelic_card_disable_txdmac(card);
	}
	mutex_unlock(&card->updown_lock);
	pr_debug("%s: done\n", __func__);
}

/**
 * gelic_descr_get_status -- returns the status of a descriptor
 * @descr: descriptor to look at
 *
 * returns the status as in the dmac_cmd_status field of the descriptor
 */
static enum gelic_descr_dma_status
gelic_descr_get_status(struct gelic_descr *descr)
{
	return be32_to_cpu(descr->dmac_cmd_status) & GELIC_DESCR_DMA_STAT_MASK;
}

/**
 * gelic_descr_set_status -- sets the status of a descriptor
 * @descr: descriptor to change
 * @status: status to set in the descriptor
 *
 * changes the status to the specified value. Doesn't change other bits
 * in the status
 */
static void gelic_descr_set_status(struct gelic_descr *descr,
				   enum gelic_descr_dma_status status)
{
	descr->dmac_cmd_status = cpu_to_be32(status |
			(be32_to_cpu(descr->dmac_cmd_status) &
			 ~GELIC_DESCR_DMA_STAT_MASK));
	/*
	 * dma_cmd_status field is used to indicate whether the descriptor
	 * is valid or not.
	 * Usually caller of this function wants to inform that to the
	 * hardware, so we assure here the hardware sees the change.
	 */
	wmb();
}

/**
 * gelic_card_free_chain - free descriptor chain
 * @card: card structure
 * @descr_in: address of desc
 */
static void gelic_card_free_chain(struct gelic_card *card,
				  struct gelic_descr *descr_in)
{
	struct gelic_descr *descr;

	for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) {
		dma_unmap_single(ctodev(card), descr->bus_addr,
				 GELIC_DESCR_SIZE, DMA_BIDIRECTIONAL);
		descr->bus_addr = 0;
	}
}

/**
 * gelic_card_init_chain - links descriptor chain
 * @card: card structure
 * @chain: address of chain
 * @start_descr: address of descriptor array
 * @no: number of descriptors
 *
 * we manage a circular list that mirrors the hardware structure,
 * except that the hardware uses bus addresses.
 *
 * returns 0 on success, <0 on failure
 */
static int gelic_card_init_chain(struct gelic_card *card,
				 struct gelic_descr_chain *chain,
				 struct gelic_descr *start_descr, int no)
{
	int i;
	struct gelic_descr *descr;

	descr = start_descr;
	memset(descr, 0, sizeof(*descr) * no);

	/* set up the hardware pointers in each descriptor */
	for (i = 0; i < no; i++, descr++) {
		gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
		descr->bus_addr =
			dma_map_single(ctodev(card), descr,
				       GELIC_DESCR_SIZE,
				       DMA_BIDIRECTIONAL);

		if (!descr->bus_addr)
			goto iommu_error;

		descr->next = descr + 1;
		descr->prev = descr - 1;
	}
	/* make them as ring */
	(descr - 1)->next = start_descr;
	start_descr->prev = (descr - 1);

	/* chain bus addr of hw descriptor */
	descr = start_descr;
	for (i = 0; i < no; i++, descr++) {
		descr->next_descr_addr = cpu_to_be32(descr->next->bus_addr);
	}

	chain->head = start_descr;
	chain->tail = start_descr;

	/* do not chain last hw descriptor */
	(descr - 1)->next_descr_addr = 0;

	return 0;

iommu_error:
	for (i--, descr--; 0 <= i; i--, descr--)
		if (descr->bus_addr)
			dma_unmap_single(ctodev(card), descr->bus_addr,
					 GELIC_DESCR_SIZE,
					 DMA_BIDIRECTIONAL);
	return -ENOMEM;
}

/**
 * gelic_card_reset_chain - reset status of a descriptor chain
 * @card: card structure
 * @chain: address of chain
 * @start_descr: address of descriptor array
 *
 * Reset the status of dma descriptors to ready state
 * and re-initialize the hardware chain for later use
 */
static void gelic_card_reset_chain(struct gelic_card *card,
				   struct gelic_descr_chain *chain,
				   struct gelic_descr *start_descr)
{
	struct gelic_descr *descr;

	for (descr = start_descr; start_descr != descr->next; descr++) {
		gelic_descr_set_status(descr, GELIC_DESCR_DMA_CARDOWNED);
		descr->next_descr_addr = cpu_to_be32(descr->next->bus_addr);
	}

	chain->head = start_descr;
	chain->tail = (descr - 1);

	(descr - 1)->next_descr_addr = 0;
}
/**
 * gelic_descr_prepare_rx - reinitializes a rx descriptor
 * @card: card structure
 * @descr: descriptor to re-init
 *
 * return 0 on succes, <0 on failure
 *
 * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
 * Activate the descriptor state-wise
 */
static int gelic_descr_prepare_rx(struct gelic_card *card,
				  struct gelic_descr *descr)
{
	int offset;
	unsigned int bufsize;

	if (gelic_descr_get_status(descr) !=  GELIC_DESCR_DMA_NOT_IN_USE)
		dev_info(ctodev(card), "%s: ERROR status \n", __func__);
	/* we need to round up the buffer size to a multiple of 128 */
	bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);

	/* and we need to have it 128 byte aligned, therefore we allocate a
	 * bit more */
	descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
	if (!descr->skb) {
		descr->buf_addr = 0; /* tell DMAC don't touch memory */
		dev_info(ctodev(card),
			 "%s:allocate skb failed !!\n", __func__);
		return -ENOMEM;
	}
	descr->buf_size = cpu_to_be32(bufsize);
	descr->dmac_cmd_status = 0;
	descr->result_size = 0;
	descr->valid_size = 0;
	descr->data_error = 0;

	offset = ((unsigned long)descr->skb->data) &
		(GELIC_NET_RXBUF_ALIGN - 1);
	if (offset)
		skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
	/* io-mmu-map the skb */
	descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card),
						     descr->skb->data,
						     GELIC_NET_MAX_MTU,
						     DMA_FROM_DEVICE));
	if (!descr->buf_addr) {
		dev_kfree_skb_any(descr->skb);
		descr->skb = NULL;
		dev_info(ctodev(card),
			 "%s:Could not iommu-map rx buffer\n", __func__);
		gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
		return -ENOMEM;
	} else {
		gelic_descr_set_status(descr, GELIC_DESCR_DMA_CARDOWNED);
		return 0;
	}
}

/**
 * gelic_card_release_rx_chain - free all skb of rx descr
 * @card: card structure
 *
 */
static void gelic_card_release_rx_chain(struct gelic_card *card)
{
	struct gelic_descr *descr = card->rx_chain.head;

	do {
		if (descr->skb) {
			dma_unmap_single(ctodev(card),
					 be32_to_cpu(descr->buf_addr),
					 descr->skb->len,
					 DMA_FROM_DEVICE);
			descr->buf_addr = 0;
			dev_kfree_skb_any(descr->skb);
			descr->skb = NULL;
			gelic_descr_set_status(descr,
					       GELIC_DESCR_DMA_NOT_IN_USE);
		}
		descr = descr->next;
	} while (descr != card->rx_chain.head);
}

/**
 * gelic_card_fill_rx_chain - fills descriptors/skbs in the rx chains
 * @card: card structure
 *
 * fills all descriptors in the rx chain: allocates skbs
 * and iommu-maps them.
 * returns 0 on success, < 0 on failure
 */
static int gelic_card_fill_rx_chain(struct gelic_card *card)
{
	struct gelic_descr *descr = card->rx_chain.head;
	int ret;

	do {
		if (!descr->skb) {
			ret = gelic_descr_prepare_rx(card, descr);
			if (ret)
				goto rewind;
		}
		descr = descr->next;
	} while (descr != card->rx_chain.head);

	return 0;
rewind:
	gelic_card_release_rx_chain(card);
	return ret;
}

/**
 * gelic_card_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
 * @card: card structure
 *
 * returns 0 on success, < 0 on failure
 */
static int gelic_card_alloc_rx_skbs(struct gelic_card *card)
{
	struct gelic_descr_chain *chain;
	int ret;
	chain = &card->rx_chain;
	ret = gelic_card_fill_rx_chain(card);
	chain->tail = card->rx_top->prev; /* point to the last */
	return ret;
}

/**
 * gelic_descr_release_tx - processes a used tx descriptor
 * @card: card structure
 * @descr: descriptor to release
 *
 * releases a used tx descriptor (unmapping, freeing of skb)
 */
static void gelic_descr_release_tx(struct gelic_card *card,
				       struct gelic_descr *descr)
{
	struct sk_buff *skb = descr->skb;

	BUG_ON(!(be32_to_cpu(descr->data_status) & GELIC_DESCR_TX_TAIL));

	dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr), skb->len,
			 DMA_TO_DEVICE);
	dev_kfree_skb_any(skb);

	descr->buf_addr = 0;
	descr->buf_size = 0;
	descr->next_descr_addr = 0;
	descr->result_size = 0;
	descr->valid_size = 0;
	descr->data_status = 0;
	descr->data_error = 0;
	descr->skb = NULL;

	/* set descr status */
	gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
}

static void gelic_card_stop_queues(struct gelic_card *card)
{
	netif_stop_queue(card->netdev[GELIC_PORT_ETHERNET]);

	if (card->netdev[GELIC_PORT_WIRELESS])
		netif_stop_queue(card->netdev[GELIC_PORT_WIRELESS]);
}
static void gelic_card_wake_queues(struct gelic_card *card)
{
	netif_wake_queue(card->netdev[GELIC_PORT_ETHERNET]);

	if (card->netdev[GELIC_PORT_WIRELESS])
		netif_wake_queue(card->netdev[GELIC_PORT_WIRELESS]);
}
/**
 * gelic_card_release_tx_chain - processes sent tx descriptors
 * @card: adapter structure
 * @stop: net_stop sequence
 *
 * releases the tx descriptors that gelic has finished with
 */
static void gelic_card_release_tx_chain(struct gelic_card *card, int stop)
{
	struct gelic_descr_chain *tx_chain;
	enum gelic_descr_dma_status status;
	struct net_device *netdev;
	int release = 0;

	for (tx_chain = &card->tx_chain;
	     tx_chain->head != tx_chain->tail && tx_chain->tail;
	     tx_chain->tail = tx_chain->tail->next) {
		status = gelic_descr_get_status(tx_chain->tail);
		netdev = tx_chain->tail->skb->dev;
		switch (status) {
		case GELIC_DESCR_DMA_RESPONSE_ERROR:
		case GELIC_DESCR_DMA_PROTECTION_ERROR:
		case GELIC_DESCR_DMA_FORCE_END:
			if (printk_ratelimit())
				dev_info(ctodev(card),
					 "%s: forcing end of tx descriptor " \
					 "with status %x\n",
					 __func__, status);
			netdev->stats.tx_dropped++;
			break;

		case GELIC_DESCR_DMA_COMPLETE:
			if (tx_chain->tail->skb) {
				netdev->stats.tx_packets++;
				netdev->stats.tx_bytes +=
					tx_chain->tail->skb->len;
			}
			break;

		case GELIC_DESCR_DMA_CARDOWNED:
			/* pending tx request */
		default:
			/* any other value (== GELIC_DESCR_DMA_NOT_IN_USE) */
			if (!stop)
				goto out;
		}
		gelic_descr_release_tx(card, tx_chain->tail);
		release ++;
	}
out:
	if (!stop && release)
		gelic_card_wake_queues(card);
}

/**
 * gelic_net_set_multi - sets multicast addresses and promisc flags
 * @netdev: interface device structure
 *
 * gelic_net_set_multi configures multicast addresses as needed for the
 * netdev interface. It also sets up multicast, allmulti and promisc
 * flags appropriately
 */
void gelic_net_set_multi(struct net_device *netdev)
{
	struct gelic_card *card = netdev_card(netdev);
	struct dev_mc_list *mc;
	unsigned int i;
	uint8_t *p;
	u64 addr;
	int status;

	/* clear all multicast address */
	status = lv1_net_remove_multicast_address(bus_id(card), dev_id(card),
						  0, 1);
	if (status)
		dev_err(ctodev(card),
			"lv1_net_remove_multicast_address failed %d\n",
			status);
	/* set broadcast address */
	status = lv1_net_add_multicast_address(bus_id(card), dev_id(card),
					       GELIC_NET_BROADCAST_ADDR, 0);
	if (status)
		dev_err(ctodev(card),
			"lv1_net_add_multicast_address failed, %d\n",
			status);

	if ((netdev->flags & IFF_ALLMULTI) ||
	    (netdev->mc_count > GELIC_NET_MC_COUNT_MAX)) {
		status = lv1_net_add_multicast_address(bus_id(card),
						       dev_id(card),
						       0, 1);
		if (status)
			dev_err(ctodev(card),
				"lv1_net_add_multicast_address failed, %d\n",
				status);
		return;
	}

	/* set multicast addresses */
	for (mc = netdev->mc_list; mc; mc = mc->next) {
		addr = 0;
		p = mc->dmi_addr;
		for (i = 0; i < ETH_ALEN; i++) {
			addr <<= 8;
			addr |= *p++;
		}
		status = lv1_net_add_multicast_address(bus_id(card),
						       dev_id(card),
						       addr, 0);
		if (status)
			dev_err(ctodev(card),
				"lv1_net_add_multicast_address failed, %d\n",
				status);
	}
}

/**
 * gelic_card_enable_rxdmac - enables the receive DMA controller
 * @card: card structure
 *
 * gelic_card_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
 * in the GDADMACCNTR register
 */
static inline void gelic_card_enable_rxdmac(struct gelic_card *card)
{
	int status;

#ifdef DEBUG
	if (gelic_descr_get_status(card->rx_chain.head) !=
	    GELIC_DESCR_DMA_CARDOWNED) {
		printk(KERN_ERR "%s: status=%x\n", __func__,
		       be32_to_cpu(card->rx_chain.head->dmac_cmd_status));
		printk(KERN_ERR "%s: nextphy=%x\n", __func__,
		       be32_to_cpu(card->rx_chain.head->next_descr_addr));
		printk(KERN_ERR "%s: head=%p\n", __func__,
		       card->rx_chain.head);
	}
#endif
	status = lv1_net_start_rx_dma(bus_id(card), dev_id(card),
				card->rx_chain.head->bus_addr, 0);
	if (status)
		dev_info(ctodev(card),
			 "lv1_net_start_rx_dma failed, status=%d\n", status);
}

/**
 * gelic_card_disable_rxdmac - disables the receive DMA controller
 * @card: card structure
 *
 * gelic_card_disable_rxdmac terminates processing on the DMA controller by
 * turing off DMA and issueing a force end
 */
static inline void gelic_card_disable_rxdmac(struct gelic_card *card)
{
	int status;

	/* this hvc blocks until the DMA in progress really stopped */
	status = lv1_net_stop_rx_dma(bus_id(card), dev_id(card), 0);
	if (status)
		dev_err(ctodev(card),
			"lv1_net_stop_rx_dma faild, %d\n", status);
}

/**
 * gelic_card_disable_txdmac - disables the transmit DMA controller
 * @card: card structure
 *
 * gelic_card_disable_txdmac terminates processing on the DMA controller by
 * turing off DMA and issueing a force end
 */
static inline void gelic_card_disable_txdmac(struct gelic_card *card)
{
	int status;

	/* this hvc blocks until the DMA in progress really stopped */
	status = lv1_net_stop_tx_dma(bus_id(card), dev_id(card), 0);
	if (status)
		dev_err(ctodev(card),
			"lv1_net_stop_tx_dma faild, status=%d\n", status);
}

/**
 * gelic_net_stop - called upon ifconfig down
 * @netdev: interface device structure
 *
 * always returns 0
 */
int gelic_net_stop(struct net_device *netdev)
{
	struct gelic_card *card;

	pr_debug("%s: start\n", __func__);

	netif_stop_queue(netdev);
	netif_carrier_off(netdev);

	card = netdev_card(netdev);
	gelic_card_down(card);

	pr_debug("%s: done\n", __func__);
	return 0;
}

/**
 * gelic_card_get_next_tx_descr - returns the next available tx descriptor
 * @card: device structure to get descriptor from
 *
 * returns the address of the next descriptor, or NULL if not available.
 */
static struct gelic_descr *
gelic_card_get_next_tx_descr(struct gelic_card *card)
{
	if (!card->tx_chain.head)
		return NULL;
	/*  see if the next descriptor is free */
	if (card->tx_chain.tail != card->tx_chain.head->next &&
	    gelic_descr_get_status(card->tx_chain.head) ==
	    GELIC_DESCR_DMA_NOT_IN_USE)
		return card->tx_chain.head;
	else
		return NULL;

}

/**
 * gelic_net_set_txdescr_cmdstat - sets the tx descriptor command field
 * @descr: descriptor structure to fill out
 * @skb: packet to consider
 *
 * fills out the command and status field of the descriptor structure,
 * depending on hardware checksum settings. This function assumes a wmb()
 * has executed before.
 */
static void gelic_descr_set_tx_cmdstat(struct gelic_descr *descr,
				       struct sk_buff *skb)
{
	if (skb->ip_summed != CHECKSUM_PARTIAL)
		descr->dmac_cmd_status =
			cpu_to_be32(GELIC_DESCR_DMA_CMD_NO_CHKSUM |
				    GELIC_DESCR_TX_DMA_FRAME_TAIL);
	else {
		/* is packet ip?
		 * if yes: tcp? udp? */
		if (skb->protocol == htons(ETH_P_IP)) {
			if (ip_hdr(skb)->protocol == IPPROTO_TCP)
				descr->dmac_cmd_status =
				cpu_to_be32(GELIC_DESCR_DMA_CMD_TCP_CHKSUM |
					    GELIC_DESCR_TX_DMA_FRAME_TAIL);

			else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
				descr->dmac_cmd_status =
				cpu_to_be32(GELIC_DESCR_DMA_CMD_UDP_CHKSUM |
					    GELIC_DESCR_TX_DMA_FRAME_TAIL);
			else	/*
				 * the stack should checksum non-tcp and non-udp
				 * packets on his own: NETIF_F_IP_CSUM
				 */
				descr->dmac_cmd_status =
				cpu_to_be32(GELIC_DESCR_DMA_CMD_NO_CHKSUM |
					    GELIC_DESCR_TX_DMA_FRAME_TAIL);
		}
	}
}

static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb,
						 unsigned short tag)
{
	struct vlan_ethhdr *veth;
	static unsigned int c;

	if (skb_headroom(skb) < VLAN_HLEN) {
		struct sk_buff *sk_tmp = skb;
		pr_debug("%s: hd=%d c=%ud\n", __func__, skb_headroom(skb), c);
		skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
		if (!skb)
			return NULL;
		dev_kfree_skb_any(sk_tmp);
	}
	veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);

	/* Move the mac addresses to the top of buffer */
	memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);

	veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
	veth->h_vlan_TCI = htons(tag);

	return skb;
}

/**
 * gelic_descr_prepare_tx - setup a descriptor for sending packets
 * @card: card structure
 * @descr: descriptor structure
 * @skb: packet to use
 *
 * returns 0 on success, <0 on failure.
 *
 */
static int gelic_descr_prepare_tx(struct gelic_card *card,
				  struct gelic_descr *descr,
				  struct sk_buff *skb)
{
	dma_addr_t buf;

	if (card->vlan_required) {
		struct sk_buff *skb_tmp;
		enum gelic_port_type type;

		type = netdev_port(skb->dev)->type;
		skb_tmp = gelic_put_vlan_tag(skb,
					     card->vlan[type].tx);
		if (!skb_tmp)
			return -ENOMEM;
		skb = skb_tmp;
	}

	buf = dma_map_single(ctodev(card), skb->data, skb->len, DMA_TO_DEVICE);

	if (!buf) {
		dev_err(ctodev(card),
			"dma map 2 failed (%p, %i). Dropping packet\n",
			skb->data, skb->len);
		return -ENOMEM;
	}

	descr->buf_addr = cpu_to_be32(buf);
	descr->buf_size = cpu_to_be32(skb->len);
	descr->skb = skb;
	descr->data_status = 0;
	descr->next_descr_addr = 0; /* terminate hw descr */
	gelic_descr_set_tx_cmdstat(descr, skb);

	/* bump free descriptor pointer */
	card->tx_chain.head = descr->next;
	return 0;
}

/**
 * gelic_card_kick_txdma - enables TX DMA processing
 * @card: card structure
 * @descr: descriptor address to enable TX processing at
 *
 */
static int gelic_card_kick_txdma(struct gelic_card *card,
				 struct gelic_descr *descr)
{
	int status = 0;

	if (card->tx_dma_progress)
		return 0;

	if (gelic_descr_get_status(descr) == GELIC_DESCR_DMA_CARDOWNED) {
		card->tx_dma_progress = 1;
		status = lv1_net_start_tx_dma(bus_id(card), dev_id(card),
					      descr->bus_addr, 0);
		if (status)
			dev_info(ctodev(card), "lv1_net_start_txdma failed," \
				 "status=%d\n", status);
	}
	return status;
}

/**
 * gelic_net_xmit - transmits a frame over the device
 * @skb: packet to send out
 * @netdev: interface device structure
 *
 * returns 0 on success, <0 on failure
 */
int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
{
	struct gelic_card *card = netdev_card(netdev);
	struct gelic_descr *descr;
	int result;
	unsigned long flags;

	spin_lock_irqsave(&card->tx_lock, flags);

	gelic_card_release_tx_chain(card, 0);

	descr = gelic_card_get_next_tx_descr(card);
	if (!descr) {
		/*
		 * no more descriptors free
		 */
		gelic_card_stop_queues(card);
		spin_unlock_irqrestore(&card->tx_lock, flags);
		return NETDEV_TX_BUSY;
	}

	result = gelic_descr_prepare_tx(card, descr, skb);
	if (result) {
		/*
		 * DMA map failed.  As chanses are that failure
		 * would continue, just release skb and return
		 */
		netdev->stats.tx_dropped++;
		dev_kfree_skb_any(skb);
		spin_unlock_irqrestore(&card->tx_lock, flags);
		return NETDEV_TX_OK;
	}
	/*
	 * link this prepared descriptor to previous one
	 * to achieve high performance
	 */
	descr->prev->next_descr_addr = cpu_to_be32(descr->bus_addr);
	/*
	 * as hardware descriptor is modified in the above lines,
	 * ensure that the hardware sees it
	 */
	wmb();
	if (gelic_card_kick_txdma(card, descr)) {
		/*
		 * kick failed.
		 * release descriptors which were just prepared
		 */
		netdev->stats.tx_dropped++;
		gelic_descr_release_tx(card, descr);
		gelic_descr_release_tx(card, descr->next);
		card->tx_chain.tail = descr->next->next;
		dev_info(ctodev(card), "%s: kick failure\n", __func__);
	} else {
		/* OK, DMA started/reserved */
		netdev->trans_start = jiffies;
	}

	spin_unlock_irqrestore(&card->tx_lock, flags);
	return NETDEV_TX_OK;
}

/**
 * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on
 * @descr: descriptor to process
 * @card: card structure
 * @netdev: net_device structure to be passed packet
 *
 * iommu-unmaps the skb, fills out skb structure and passes the data to the
 * stack. The descriptor state is not changed.
 */
static void gelic_net_pass_skb_up(struct gelic_descr *descr,
				  struct gelic_card *card,
				  struct net_device *netdev)

{
	struct sk_buff *skb = descr->skb;
	u32 data_status, data_error;

	data_status = be32_to_cpu(descr->data_status);
	data_error = be32_to_cpu(descr->data_error);
	/* unmap skb buffer */
	dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr),
			 GELIC_NET_MAX_MTU,
			 DMA_FROM_DEVICE);

	skb_put(skb, be32_to_cpu(descr->valid_size)?
		be32_to_cpu(descr->valid_size) :
		be32_to_cpu(descr->result_size));
	if (!descr->valid_size)
		dev_info(ctodev(card), "buffer full %x %x %x\n",
			 be32_to_cpu(descr->result_size),
			 be32_to_cpu(descr->buf_size),
			 be32_to_cpu(descr->dmac_cmd_status));

	descr->skb = NULL;
	/*
	 * the card put 2 bytes vlan tag in front
	 * of the ethernet frame
	 */
	skb_pull(skb, 2);
	skb->protocol = eth_type_trans(skb, netdev);

	/* checksum offload */
	if (card->rx_csum) {
		if ((data_status & GELIC_DESCR_DATA_STATUS_CHK_MASK) &&
		    (!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK)))
			skb->ip_summed = CHECKSUM_UNNECESSARY;
		else
			skb->ip_summed = CHECKSUM_NONE;
	} else
		skb->ip_summed = CHECKSUM_NONE;

	/* update netdevice statistics */
	netdev->stats.rx_packets++;
	netdev->stats.rx_bytes += skb->len;

	/* pass skb up to stack */
	netif_receive_skb(skb);
}

/**
 * gelic_card_decode_one_descr - processes an rx descriptor
 * @card: card structure
 *
 * returns 1 if a packet has been sent to the stack, otherwise 0
 *
 * processes an rx descriptor by iommu-unmapping the data buffer and passing
 * the packet up to the stack
 */
static int gelic_card_decode_one_descr(struct gelic_card *card)
{
	enum gelic_descr_dma_status status;
	struct gelic_descr_chain *chain = &card->rx_chain;
	struct gelic_descr *descr = chain->head;
	struct net_device *netdev = NULL;
	int dmac_chain_ended;

	status = gelic_descr_get_status(descr);
	/* is this descriptor terminated with next_descr == NULL? */
	dmac_chain_ended =
		be32_to_cpu(descr->dmac_cmd_status) &
		GELIC_DESCR_RX_DMA_CHAIN_END;

	if (status == GELIC_DESCR_DMA_CARDOWNED)
		return 0;

	if (status == GELIC_DESCR_DMA_NOT_IN_USE) {
		dev_dbg(ctodev(card), "dormant descr? %p\n", descr);
		return 0;
	}

	/* netdevice select */
	if (card->vlan_required) {
		unsigned int i;
		u16 vid;
		vid = *(u16 *)(descr->skb->data) & VLAN_VID_MASK;
		for (i = 0; i < GELIC_PORT_MAX; i++) {
			if (card->vlan[i].rx == vid) {
				netdev = card->netdev[i];
				break;
			}
		};
		if (GELIC_PORT_MAX <= i) {
			pr_info("%s: unknown packet vid=%x\n", __func__, vid);
			goto refill;
		}
	} else
		netdev = card->netdev[GELIC_PORT_ETHERNET];

	if ((status == GELIC_DESCR_DMA_RESPONSE_ERROR) ||
	    (status == GELIC_DESCR_DMA_PROTECTION_ERROR) ||
	    (status == GELIC_DESCR_DMA_FORCE_END)) {
		dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
			 status);
		netdev->stats.rx_dropped++;
		goto refill;
	}

	if (status == GELIC_DESCR_DMA_BUFFER_FULL) {
		/*
		 * Buffer full would occur if and only if
		 * the frame length was longer than the size of this
		 * descriptor's buffer.  If the frame length was equal
		 * to or shorter than buffer'size, FRAME_END condition
		 * would occur.
		 * Anyway this frame was longer than the MTU,
		 * just drop it.
		 */
		dev_info(ctodev(card), "overlength frame\n");
		goto refill;
	}
	/*
	 * descriptoers any other than FRAME_END here should
	 * be treated as error.
	 */
	if (status != GELIC_DESCR_DMA_FRAME_END) {
		dev_dbg(ctodev(card), "RX descriptor with state %x\n",
			status);
		goto refill;
	}

	/* ok, we've got a packet in descr */
	gelic_net_pass_skb_up(descr, card, netdev);
refill:
	/*
	 * So that always DMAC can see the end
	 * of the descriptor chain to avoid
	 * from unwanted DMAC overrun.
	 */
	descr->next_descr_addr = 0;

	/* change the descriptor state: */
	gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);

	/*
	 * this call can fail, but for now, just leave this
	 * decriptor without skb
	 */
	gelic_descr_prepare_rx(card, descr);

	chain->tail = descr;
	chain->head = descr->next;

	/*
	 * Set this descriptor the end of the chain.
	 */
	descr->prev->next_descr_addr = cpu_to_be32(descr->bus_addr);

	/*
	 * If dmac chain was met, DMAC stopped.
	 * thus re-enable it
	 */
	if (dmac_chain_ended) {
		card->rx_dma_restart_required = 1;
		dev_dbg(ctodev(card), "reenable rx dma scheduled\n");
	}

	return 1;
}

/**
 * gelic_net_poll - NAPI poll function called by the stack to return packets
 * @napi: napi structure
 * @budget: number of packets we can pass to the stack at most
 *
 * returns the number of the processed packets
 *
 */
static int gelic_net_poll(struct napi_struct *napi, int budget)
{
	struct gelic_card *card = container_of(napi, struct gelic_card, napi);
	int packets_done = 0;

	while (packets_done < budget) {
		if (!gelic_card_decode_one_descr(card))
			break;

		packets_done++;
	}

	if (packets_done < budget) {
		napi_complete(napi);
		gelic_card_rx_irq_on(card);
	}
	return packets_done;
}
/**
 * gelic_net_change_mtu - changes the MTU of an interface
 * @netdev: interface device structure
 * @new_mtu: new MTU value
 *
 * returns 0 on success, <0 on failure
 */
int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
{
	/* no need to re-alloc skbs or so -- the max mtu is about 2.3k
	 * and mtu is outbound only anyway */
	if ((new_mtu < GELIC_NET_MIN_MTU) ||
	    (new_mtu > GELIC_NET_MAX_MTU)) {
		return -EINVAL;
	}
	netdev->mtu = new_mtu;
	return 0;
}

/**
 * gelic_card_interrupt - event handler for gelic_net
 */
static irqreturn_t gelic_card_interrupt(int irq, void *ptr)
{
	unsigned long flags;
	struct gelic_card *card = ptr;
	u64 status;

	status = card->irq_status;

	if (!status)
		return IRQ_NONE;

	status &= card->irq_mask;

	if (card->rx_dma_restart_required) {
		card->rx_dma_restart_required = 0;
		gelic_card_enable_rxdmac(card);
	}

	if (status & GELIC_CARD_RXINT) {
		gelic_card_rx_irq_off(card);
		napi_schedule(&card->napi);
	}

	if (status & GELIC_CARD_TXINT) {
		spin_lock_irqsave(&card->tx_lock, flags);
		card->tx_dma_progress = 0;
		gelic_card_release_tx_chain(card, 0);
		/* kick outstanding tx descriptor if any */
		gelic_card_kick_txdma(card, card->tx_chain.tail);
		spin_unlock_irqrestore(&card->tx_lock, flags);
	}

	/* ether port status changed */
	if (status & GELIC_CARD_PORT_STATUS_CHANGED)
		gelic_card_get_ether_port_status(card, 1);

#ifdef CONFIG_GELIC_WIRELESS
	if (status & (GELIC_CARD_WLAN_EVENT_RECEIVED |
		      GELIC_CARD_WLAN_COMMAND_COMPLETED))
		gelic_wl_interrupt(card->netdev[GELIC_PORT_WIRELESS], status);
#endif

	return IRQ_HANDLED;
}

#ifdef CONFIG_NET_POLL_CONTROLLER
/**
 * gelic_net_poll_controller - artificial interrupt for netconsole etc.
 * @netdev: interface device structure
 *
 * see Documentation/networking/netconsole.txt
 */
void gelic_net_poll_controller(struct net_device *netdev)
{
	struct gelic_card *card = netdev_card(netdev);

	gelic_card_set_irq_mask(card, 0);
	gelic_card_interrupt(netdev->irq, netdev);
	gelic_card_set_irq_mask(card, card->irq_mask);
}
#endif /* CONFIG_NET_POLL_CONTROLLER */

/**
 * gelic_net_open - called upon ifonfig up
 * @netdev: interface device structure
 *
 * returns 0 on success, <0 on failure
 *
 * gelic_net_open allocates all the descriptors and memory needed for
 * operation, sets up multicast list and enables interrupts
 */
int gelic_net_open(struct net_device *netdev)
{
	struct gelic_card *card = netdev_card(netdev);

	dev_dbg(ctodev(card), " -> %s %p\n", __func__, netdev);

	gelic_card_up(card);

	netif_start_queue(netdev);
	gelic_card_get_ether_port_status(card, 1);

	dev_dbg(ctodev(card), " <- %s\n", __func__);
	return 0;
}

void gelic_net_get_drvinfo(struct net_device *netdev,
			   struct ethtool_drvinfo *info)
{
	strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1);
	strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1);
}

static int gelic_ether_get_settings(struct net_device *netdev,
				    struct ethtool_cmd *cmd)
{
	struct gelic_card *card = netdev_card(netdev);

	gelic_card_get_ether_port_status(card, 0);

	if (card->ether_port_status & GELIC_LV1_ETHER_FULL_DUPLEX)
		cmd->duplex = DUPLEX_FULL;
	else
		cmd->duplex = DUPLEX_HALF;

	switch (card->ether_port_status & GELIC_LV1_ETHER_SPEED_MASK) {
	case GELIC_LV1_ETHER_SPEED_10:
		cmd->speed = SPEED_10;
		break;
	case GELIC_LV1_ETHER_SPEED_100:
		cmd->speed = SPEED_100;
		break;
	case GELIC_LV1_ETHER_SPEED_1000:
		cmd->speed = SPEED_1000;
		break;
	default:
		pr_info("%s: speed unknown\n", __func__);
		cmd->speed = SPEED_10;
		break;
	}

	cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
			SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
			SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
			SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
	cmd->advertising = cmd->supported;
	cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
	cmd->port = PORT_TP;

	return 0;
}

u32 gelic_net_get_rx_csum(struct net_device *netdev)
{
	struct gelic_card *card = netdev_card(netdev);

	return card->rx_csum;
}

int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
{
	struct gelic_card *card = netdev_card(netdev);

	card->rx_csum = data;
	return 0;
}

static void gelic_net_get_wol(struct net_device *netdev,
			      struct ethtool_wolinfo *wol)
{
	if (0 <= ps3_compare_firmware_version(2, 2, 0))
		wol->supported = WAKE_MAGIC;
	else
		wol->supported = 0;

	wol->wolopts = ps3_sys_manager_get_wol() ? wol->supported : 0;
	memset(&wol->sopass, 0, sizeof(wol->sopass));
}
static int gelic_net_set_wol(struct net_device *netdev,
			     struct ethtool_wolinfo *wol)
{
	int status;
	struct gelic_card *card;
	u64 v1, v2;

	if (ps3_compare_firmware_version(2, 2, 0) < 0 ||
	    !capable(CAP_NET_ADMIN))
		return -EPERM;

	if (wol->wolopts & ~WAKE_MAGIC)
		return -EINVAL;

	card = netdev_card(netdev);
	if (wol->wolopts & WAKE_MAGIC) {
		status = lv1_net_control(bus_id(card), dev_id(card),
					 GELIC_LV1_SET_WOL,
					 GELIC_LV1_WOL_MAGIC_PACKET,
					 0, GELIC_LV1_WOL_MP_ENABLE,
					 &v1, &v2);
		if (status) {
			pr_info("%s: enabling WOL failed %d\n", __func__,
				status);
			status = -EIO;
			goto done;
		}
		status = lv1_net_control(bus_id(card), dev_id(card),
					 GELIC_LV1_SET_WOL,
					 GELIC_LV1_WOL_ADD_MATCH_ADDR,
					 0, GELIC_LV1_WOL_MATCH_ALL,
					 &v1, &v2);
		if (!status)
			ps3_sys_manager_set_wol(1);
		else {
			pr_info("%s: enabling WOL filter failed %d\n",
				__func__, status);
			status = -EIO;
		}
	} else {
		status = lv1_net_control(bus_id(card), dev_id(card),
					 GELIC_LV1_SET_WOL,
					 GELIC_LV1_WOL_MAGIC_PACKET,
					 0, GELIC_LV1_WOL_MP_DISABLE,
					 &v1, &v2);
		if (status) {
			pr_info("%s: disabling WOL failed %d\n", __func__,
				status);
			status = -EIO;
			goto done;
		}
		status = lv1_net_control(bus_id(card), dev_id(card),
					 GELIC_LV1_SET_WOL,
					 GELIC_LV1_WOL_DELETE_MATCH_ADDR,
					 0, GELIC_LV1_WOL_MATCH_ALL,
					 &v1, &v2);
		if (!status)
			ps3_sys_manager_set_wol(0);
		else {
			pr_info("%s: removing WOL filter failed %d\n",
				__func__, status);
			status = -EIO;
		}
	}
done:
	return status;
}

static struct ethtool_ops gelic_ether_ethtool_ops = {
	.get_drvinfo	= gelic_net_get_drvinfo,
	.get_settings	= gelic_ether_get_settings,
	.get_link	= ethtool_op_get_link,
	.get_tx_csum	= ethtool_op_get_tx_csum,
	.set_tx_csum	= ethtool_op_set_tx_csum,
	.get_rx_csum	= gelic_net_get_rx_csum,
	.set_rx_csum	= gelic_net_set_rx_csum,
	.get_wol	= gelic_net_get_wol,
	.set_wol	= gelic_net_set_wol,
};

/**
 * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout
 * function (to be called not under interrupt status)
 * @work: work is context of tx timout task
 *
 * called as task when tx hangs, resets interface (if interface is up)
 */
static void gelic_net_tx_timeout_task(struct work_struct *work)
{
	struct gelic_card *card =
		container_of(work, struct gelic_card, tx_timeout_task);
	struct net_device *netdev = card->netdev[GELIC_PORT_ETHERNET];

	dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__);

	if (!(netdev->flags & IFF_UP))
		goto out;

	netif_device_detach(netdev);
	gelic_net_stop(netdev);

	gelic_net_open(netdev);
	netif_device_attach(netdev);

out:
	atomic_dec(&card->tx_timeout_task_counter);
}

/**
 * gelic_net_tx_timeout - called when the tx timeout watchdog kicks in.
 * @netdev: interface device structure
 *
 * called, if tx hangs. Schedules a task that resets the interface
 */
void gelic_net_tx_timeout(struct net_device *netdev)
{
	struct gelic_card *card;

	card = netdev_card(netdev);
	atomic_inc(&card->tx_timeout_task_counter);
	if (netdev->flags & IFF_UP)
		schedule_work(&card->tx_timeout_task);
	else
		atomic_dec(&card->tx_timeout_task_counter);
}

/**
 * gelic_ether_setup_netdev_ops - initialization of net_device operations
 * @netdev: net_device structure
 *
 * fills out function pointers in the net_device structure
 */
static void gelic_ether_setup_netdev_ops(struct net_device *netdev,
					 struct napi_struct *napi)
{
	netdev->open = &gelic_net_open;
	netdev->stop = &gelic_net_stop;
	netdev->hard_start_xmit = &gelic_net_xmit;
	netdev->set_multicast_list = &gelic_net_set_multi;
	netdev->change_mtu = &gelic_net_change_mtu;
	/* tx watchdog */
	netdev->tx_timeout = &gelic_net_tx_timeout;
	netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
	/* NAPI */
	netif_napi_add(netdev, napi,
		       gelic_net_poll, GELIC_NET_NAPI_WEIGHT);
	netdev->ethtool_ops = &gelic_ether_ethtool_ops;
#ifdef CONFIG_NET_POLL_CONTROLLER
	netdev->poll_controller = gelic_net_poll_controller;
#endif
}

/**
 * gelic_ether_setup_netdev - initialization of net_device
 * @netdev: net_device structure
 * @card: card structure
 *
 * Returns 0 on success or <0 on failure
 *
 * gelic_ether_setup_netdev initializes the net_device structure
 * and register it.
 **/
int gelic_net_setup_netdev(struct net_device *netdev, struct gelic_card *card)
{
	int status;
	u64 v1, v2;

	netdev->features = NETIF_F_IP_CSUM;

	status = lv1_net_control(bus_id(card), dev_id(card),
				 GELIC_LV1_GET_MAC_ADDRESS,
				 0, 0, 0, &v1, &v2);
	v1 <<= 16;
	if (status || !is_valid_ether_addr((u8 *)&v1)) {
		dev_info(ctodev(card),
			 "%s:lv1_net_control GET_MAC_ADDR failed %d\n",
			 __func__, status);
		return -EINVAL;
	}
	memcpy(netdev->dev_addr, &v1, ETH_ALEN);

	if (card->vlan_required) {
		netdev->hard_header_len += VLAN_HLEN;
		/*
		 * As vlan is internally used,
		 * we can not receive vlan packets
		 */
		netdev->features |= NETIF_F_VLAN_CHALLENGED;
	}

	status = register_netdev(netdev);
	if (status) {
		dev_err(ctodev(card), "%s:Couldn't register %s %d\n",
			__func__, netdev->name, status);
		return status;
	}
	dev_info(ctodev(card), "%s: MAC addr %pM\n",
		 netdev->name, netdev->dev_addr);

	return 0;
}

/**
 * gelic_alloc_card_net - allocates net_device and card structure
 *
 * returns the card structure or NULL in case of errors
 *
 * the card and net_device structures are linked to each other
 */
#define GELIC_ALIGN (32)
static struct gelic_card *gelic_alloc_card_net(struct net_device **netdev)
{
	struct gelic_card *card;
	struct gelic_port *port;
	void *p;
	size_t alloc_size;
	/*
	 * gelic requires dma descriptor is 32 bytes aligned and
	 * the hypervisor requires irq_status is 8 bytes aligned.
	 */
	BUILD_BUG_ON(offsetof(struct gelic_card, irq_status) % 8);
	BUILD_BUG_ON(offsetof(struct gelic_card, descr) % 32);
	alloc_size =
		sizeof(struct gelic_card) +
		sizeof(struct gelic_descr) * GELIC_NET_RX_DESCRIPTORS +
		sizeof(struct gelic_descr) * GELIC_NET_TX_DESCRIPTORS +
		GELIC_ALIGN - 1;

	p  = kzalloc(alloc_size, GFP_KERNEL);
	if (!p)
		return NULL;
	card = PTR_ALIGN(p, GELIC_ALIGN);
	card->unalign = p;

	/*
	 * alloc netdev
	 */
	*netdev = alloc_etherdev(sizeof(struct gelic_port));
	if (!netdev) {
		kfree(card->unalign);
		return NULL;
	}
	port = netdev_priv(*netdev);

	/* gelic_port */
	port->netdev = *netdev;
	port->card = card;
	port->type = GELIC_PORT_ETHERNET;

	/* gelic_card */
	card->netdev[GELIC_PORT_ETHERNET] = *netdev;

	INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
	init_waitqueue_head(&card->waitq);
	atomic_set(&card->tx_timeout_task_counter, 0);
	mutex_init(&card->updown_lock);
	atomic_set(&card->users, 0);

	return card;
}

static void gelic_card_get_vlan_info(struct gelic_card *card)
{
	u64 v1, v2;
	int status;
	unsigned int i;
	struct {
		int tx;
		int rx;
	} vlan_id_ix[2] = {
		[GELIC_PORT_ETHERNET] = {
			.tx = GELIC_LV1_VLAN_TX_ETHERNET,
			.rx = GELIC_LV1_VLAN_RX_ETHERNET
		},
		[GELIC_PORT_WIRELESS] = {
			.tx = GELIC_LV1_VLAN_TX_WIRELESS,
			.rx = GELIC_LV1_VLAN_RX_WIRELESS
		}
	};

	for (i = 0; i < ARRAY_SIZE(vlan_id_ix); i++) {
		/* tx tag */
		status = lv1_net_control(bus_id(card), dev_id(card),
					 GELIC_LV1_GET_VLAN_ID,
					 vlan_id_ix[i].tx,
					 0, 0, &v1, &v2);
		if (status || !v1) {
			if (status != LV1_NO_ENTRY)
				dev_dbg(ctodev(card),
					"get vlan id for tx(%d) failed(%d)\n",
					vlan_id_ix[i].tx, status);
			card->vlan[i].tx = 0;
			card->vlan[i].rx = 0;
			continue;
		}
		card->vlan[i].tx = (u16)v1;

		/* rx tag */
		status = lv1_net_control(bus_id(card), dev_id(card),
					 GELIC_LV1_GET_VLAN_ID,
					 vlan_id_ix[i].rx,
					 0, 0, &v1, &v2);
		if (status || !v1) {
			if (status != LV1_NO_ENTRY)
				dev_info(ctodev(card),
					 "get vlan id for rx(%d) failed(%d)\n",
					 vlan_id_ix[i].rx, status);
			card->vlan[i].tx = 0;
			card->vlan[i].rx = 0;
			continue;
		}
		card->vlan[i].rx = (u16)v1;

		dev_dbg(ctodev(card), "vlan_id[%d] tx=%02x rx=%02x\n",
			i, card->vlan[i].tx, card->vlan[i].rx);
	}

	if (card->vlan[GELIC_PORT_ETHERNET].tx) {
		BUG_ON(!card->vlan[GELIC_PORT_WIRELESS].tx);
		card->vlan_required = 1;
	} else
		card->vlan_required = 0;

	/* check wirelss capable firmware */
	if (ps3_compare_firmware_version(1, 6, 0) < 0) {
		card->vlan[GELIC_PORT_WIRELESS].tx = 0;
		card->vlan[GELIC_PORT_WIRELESS].rx = 0;
	}

	dev_info(ctodev(card), "internal vlan %s\n",
		 card->vlan_required? "enabled" : "disabled");
}
/**
 * ps3_gelic_driver_probe - add a device to the control of this driver
 */
static int ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
{
	struct gelic_card *card;
	struct net_device *netdev;
	int result;

	pr_debug("%s: called\n", __func__);
	result = ps3_open_hv_device(dev);

	if (result) {
		dev_dbg(&dev->core, "%s:ps3_open_hv_device failed\n",
			__func__);
		goto fail_open;
	}

	result = ps3_dma_region_create(dev->d_region);

	if (result) {
		dev_dbg(&dev->core, "%s:ps3_dma_region_create failed(%d)\n",
			__func__, result);
		BUG_ON("check region type");
		goto fail_dma_region;
	}

	/* alloc card/netdevice */
	card = gelic_alloc_card_net(&netdev);
	if (!card) {
		dev_info(&dev->core, "%s:gelic_net_alloc_card failed\n",
			 __func__);
		result = -ENOMEM;
		goto fail_alloc_card;
	}
	ps3_system_bus_set_driver_data(dev, card);
	card->dev = dev;

	/* get internal vlan info */
	gelic_card_get_vlan_info(card);

	/* setup interrupt */
	result = lv1_net_set_interrupt_status_indicator(bus_id(card),
							dev_id(card),
		ps3_mm_phys_to_lpar(__pa(&card->irq_status)),
		0);

	if (result) {
		dev_dbg(&dev->core,
			"%s:set_interrupt_status_indicator failed: %s\n",
			__func__, ps3_result(result));
		result = -EIO;
		goto fail_status_indicator;
	}

	result = ps3_sb_event_receive_port_setup(dev, PS3_BINDING_CPU_ANY,
		&card->irq);

	if (result) {
		dev_info(ctodev(card),
			 "%s:gelic_net_open_device failed (%d)\n",
			 __func__, result);
		result = -EPERM;
		goto fail_alloc_irq;
	}
	result = request_irq(card->irq, gelic_card_interrupt,
			     IRQF_DISABLED, netdev->name, card);

	if (result) {
		dev_info(ctodev(card), "%s:request_irq failed (%d)\n",
			__func__, result);
		goto fail_request_irq;
	}

	/* setup card structure */
	card->irq_mask = GELIC_CARD_RXINT | GELIC_CARD_TXINT |
		GELIC_CARD_PORT_STATUS_CHANGED;
	card->rx_csum = GELIC_CARD_RX_CSUM_DEFAULT;


	if (gelic_card_init_chain(card, &card->tx_chain,
			card->descr, GELIC_NET_TX_DESCRIPTORS))
		goto fail_alloc_tx;
	if (gelic_card_init_chain(card, &card->rx_chain,
				 card->descr + GELIC_NET_TX_DESCRIPTORS,
				 GELIC_NET_RX_DESCRIPTORS))
		goto fail_alloc_rx;

	/* head of chain */
	card->tx_top = card->tx_chain.head;
	card->rx_top = card->rx_chain.head;
	dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n",
		card->rx_top, card->tx_top, sizeof(struct gelic_descr),
		GELIC_NET_RX_DESCRIPTORS);
	/* allocate rx skbs */
	if (gelic_card_alloc_rx_skbs(card))
		goto fail_alloc_skbs;

	spin_lock_init(&card->tx_lock);
	card->tx_dma_progress = 0;

	/* setup net_device structure */
	netdev->irq = card->irq;
	SET_NETDEV_DEV(netdev, &card->dev->core);
	gelic_ether_setup_netdev_ops(netdev, &card->napi);
	result = gelic_net_setup_netdev(netdev, card);
	if (result) {
		dev_dbg(&dev->core, "%s: setup_netdev failed %d",
			__func__, result);
		goto fail_setup_netdev;
	}

#ifdef CONFIG_GELIC_WIRELESS
	if (gelic_wl_driver_probe(card)) {
		dev_dbg(&dev->core, "%s: WL init failed\n", __func__);
		goto fail_setup_netdev;
	}
#endif
	pr_debug("%s: done\n", __func__);
	return 0;

fail_setup_netdev:
fail_alloc_skbs:
	gelic_card_free_chain(card, card->rx_chain.head);
fail_alloc_rx:
	gelic_card_free_chain(card, card->tx_chain.head);
fail_alloc_tx:
	free_irq(card->irq, card);
	netdev->irq = NO_IRQ;
fail_request_irq:
	ps3_sb_event_receive_port_destroy(dev, card->irq);
fail_alloc_irq:
	lv1_net_set_interrupt_status_indicator(bus_id(card),
					       bus_id(card),
					       0, 0);
fail_status_indicator:
	ps3_system_bus_set_driver_data(dev, NULL);
	kfree(netdev_card(netdev)->unalign);
	free_netdev(netdev);
fail_alloc_card:
	ps3_dma_region_free(dev->d_region);
fail_dma_region:
	ps3_close_hv_device(dev);
fail_open:
	return result;
}

/**
 * ps3_gelic_driver_remove - remove a device from the control of this driver
 */

static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev)
{
	struct gelic_card *card = ps3_system_bus_get_driver_data(dev);
	struct net_device *netdev0;
	pr_debug("%s: called\n", __func__);

#ifdef CONFIG_GELIC_WIRELESS
	gelic_wl_driver_remove(card);
#endif
	/* stop interrupt */
	gelic_card_set_irq_mask(card, 0);

	/* turn off DMA, force end */
	gelic_card_disable_rxdmac(card);
	gelic_card_disable_txdmac(card);

	/* release chains */
	gelic_card_release_tx_chain(card, 1);
	gelic_card_release_rx_chain(card);

	gelic_card_free_chain(card, card->tx_top);
	gelic_card_free_chain(card, card->rx_top);

	netdev0 = card->netdev[GELIC_PORT_ETHERNET];
	/* disconnect event port */
	free_irq(card->irq, card);
	netdev0->irq = NO_IRQ;
	ps3_sb_event_receive_port_destroy(card->dev, card->irq);

	wait_event(card->waitq,
		   atomic_read(&card->tx_timeout_task_counter) == 0);

	lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card),
					       0 , 0);

	unregister_netdev(netdev0);
	kfree(netdev_card(netdev0)->unalign);
	free_netdev(netdev0);

	ps3_system_bus_set_driver_data(dev, NULL);

	ps3_dma_region_free(dev->d_region);

	ps3_close_hv_device(dev);

	pr_debug("%s: done\n", __func__);
	return 0;
}

static struct ps3_system_bus_driver ps3_gelic_driver = {
	.match_id = PS3_MATCH_ID_GELIC,
	.probe = ps3_gelic_driver_probe,
	.remove = ps3_gelic_driver_remove,
	.shutdown = ps3_gelic_driver_remove,
	.core.name = "ps3_gelic_driver",
	.core.owner = THIS_MODULE,
};

static int __init ps3_gelic_driver_init (void)
{
	return firmware_has_feature(FW_FEATURE_PS3_LV1)
		? ps3_system_bus_driver_register(&ps3_gelic_driver)
		: -ENODEV;
}

static void __exit ps3_gelic_driver_exit (void)
{
	ps3_system_bus_driver_unregister(&ps3_gelic_driver);
}

module_init(ps3_gelic_driver_init);
module_exit(ps3_gelic_driver_exit);

MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC);

