/*
 * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * $Id: ipoib_ib.c 1386 2004-12-27 16:23:17Z roland $
 */

#include <linux/delay.h>
#include <linux/dma-mapping.h>

#include <ib_cache.h>

#include "ipoib.h"

#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA
static int data_debug_level;

module_param(data_debug_level, int, 0644);
MODULE_PARM_DESC(data_debug_level,
		 "Enable data path debug tracing if > 0");
#endif

#define	IPOIB_OP_RECV	(1ul << 31)

static DECLARE_MUTEX(pkey_sem);

struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
				 struct ib_pd *pd, struct ib_ah_attr *attr)
{
	struct ipoib_ah *ah;

	ah = kmalloc(sizeof *ah, GFP_KERNEL);
	if (!ah)
		return NULL;

	ah->dev       = dev;
	ah->last_send = 0;
	kref_init(&ah->ref);

	ah->ah = ib_create_ah(pd, attr);
	if (IS_ERR(ah->ah)) {
		kfree(ah);
		ah = NULL;
	} else
		ipoib_dbg(netdev_priv(dev), "Created ah %p\n", ah->ah);

	return ah;
}

void ipoib_free_ah(struct kref *kref)
{
	struct ipoib_ah *ah = container_of(kref, struct ipoib_ah, ref);
	struct ipoib_dev_priv *priv = netdev_priv(ah->dev);

	unsigned long flags;

	if (ah->last_send <= priv->tx_tail) {
		ipoib_dbg(priv, "Freeing ah %p\n", ah->ah);
		ib_destroy_ah(ah->ah);
		kfree(ah);
	} else {
		spin_lock_irqsave(&priv->lock, flags);
		list_add_tail(&ah->list, &priv->dead_ahs);
		spin_unlock_irqrestore(&priv->lock, flags);
	}
}

static inline int ipoib_ib_receive(struct ipoib_dev_priv *priv,
				   unsigned int wr_id,
				   dma_addr_t addr)
{
	struct ib_sge list = {
		.addr    = addr,
		.length  = IPOIB_BUF_SIZE,
		.lkey    = priv->mr->lkey,
	};
	struct ib_recv_wr param = {
		.wr_id 	    = wr_id | IPOIB_OP_RECV,
		.sg_list    = &list,
		.num_sge    = 1,
	};
	struct ib_recv_wr *bad_wr;

	return ib_post_recv(priv->qp, &param, &bad_wr);
}

static int ipoib_ib_post_receive(struct net_device *dev, int id)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	struct sk_buff *skb;
	dma_addr_t addr;
	int ret;

	skb = dev_alloc_skb(IPOIB_BUF_SIZE + 4);
	if (!skb) {
		ipoib_warn(priv, "failed to allocate receive buffer\n");

		priv->rx_ring[id].skb = NULL;
		return -ENOMEM;
	}
	skb_reserve(skb, 4);	/* 16 byte align IP header */
	priv->rx_ring[id].skb = skb;
	addr = dma_map_single(priv->ca->dma_device,
			      skb->data, IPOIB_BUF_SIZE,
			      DMA_FROM_DEVICE);
	pci_unmap_addr_set(&priv->rx_ring[id], mapping, addr);

	ret = ipoib_ib_receive(priv, id, addr);
	if (ret) {
		ipoib_warn(priv, "ipoib_ib_receive failed for buf %d (%d)\n",
			   id, ret);
		dma_unmap_single(priv->ca->dma_device, addr,
				 IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
		dev_kfree_skb_any(skb);
		priv->rx_ring[id].skb = NULL;
	}

	return ret;
}

static int ipoib_ib_post_receives(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	int i;

	for (i = 0; i < IPOIB_RX_RING_SIZE; ++i) {
		if (ipoib_ib_post_receive(dev, i)) {
			ipoib_warn(priv, "ipoib_ib_post_receive failed for buf %d\n", i);
			return -EIO;
		}
	}

	return 0;
}

static void ipoib_ib_handle_wc(struct net_device *dev,
			       struct ib_wc *wc)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	unsigned int wr_id = wc->wr_id;

	ipoib_dbg_data(priv, "called: id %d, op %d, status: %d\n",
		       wr_id, wc->opcode, wc->status);

	if (wr_id & IPOIB_OP_RECV) {
		wr_id &= ~IPOIB_OP_RECV;

		if (wr_id < IPOIB_RX_RING_SIZE) {
			struct sk_buff *skb = priv->rx_ring[wr_id].skb;

			priv->rx_ring[wr_id].skb = NULL;

			dma_unmap_single(priv->ca->dma_device,
					 pci_unmap_addr(&priv->rx_ring[wr_id],
							mapping),
					 IPOIB_BUF_SIZE,
					 DMA_FROM_DEVICE);

			if (wc->status != IB_WC_SUCCESS) {
				if (wc->status != IB_WC_WR_FLUSH_ERR)
					ipoib_warn(priv, "failed recv event "
						   "(status=%d, wrid=%d vend_err %x)\n",
						   wc->status, wr_id, wc->vendor_err);
				dev_kfree_skb_any(skb);
				return;
			}

			ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n",
				       wc->byte_len, wc->slid);

			skb_put(skb, wc->byte_len);
			skb_pull(skb, IB_GRH_BYTES);

			if (wc->slid != priv->local_lid ||
			    wc->src_qp != priv->qp->qp_num) {
				skb->protocol = ((struct ipoib_header *) skb->data)->proto;
				skb->mac.raw = skb->data;
				skb_pull(skb, IPOIB_ENCAP_LEN);

				dev->last_rx = jiffies;
				++priv->stats.rx_packets;
				priv->stats.rx_bytes += skb->len;

				skb->dev = dev;
				/* XXX get correct PACKET_ type here */
				skb->pkt_type = PACKET_HOST;
				netif_rx_ni(skb);
			} else {
				ipoib_dbg_data(priv, "dropping loopback packet\n");
				dev_kfree_skb_any(skb);
			}

			/* repost receive */
			if (ipoib_ib_post_receive(dev, wr_id))
				ipoib_warn(priv, "ipoib_ib_post_receive failed "
					   "for buf %d\n", wr_id);
		} else
			ipoib_warn(priv, "completion event with wrid %d\n",
				   wr_id);

	} else {
		struct ipoib_buf *tx_req;
		unsigned long flags;

		if (wr_id >= IPOIB_TX_RING_SIZE) {
			ipoib_warn(priv, "completion event with wrid %d (> %d)\n",
				   wr_id, IPOIB_TX_RING_SIZE);
			return;
		}

		ipoib_dbg_data(priv, "send complete, wrid %d\n", wr_id);

		tx_req = &priv->tx_ring[wr_id];

		dma_unmap_single(priv->ca->dma_device,
				 pci_unmap_addr(tx_req, mapping),
				 tx_req->skb->len,
				 DMA_TO_DEVICE);

		++priv->stats.tx_packets;
		priv->stats.tx_bytes += tx_req->skb->len;

		dev_kfree_skb_any(tx_req->skb);

		spin_lock_irqsave(&priv->tx_lock, flags);
		++priv->tx_tail;
		if (netif_queue_stopped(dev) &&
		    priv->tx_head - priv->tx_tail <= IPOIB_TX_RING_SIZE / 2)
			netif_wake_queue(dev);
		spin_unlock_irqrestore(&priv->tx_lock, flags);

		if (wc->status != IB_WC_SUCCESS &&
		    wc->status != IB_WC_WR_FLUSH_ERR)
			ipoib_warn(priv, "failed send event "
				   "(status=%d, wrid=%d vend_err %x)\n",
				   wc->status, wr_id, wc->vendor_err);
	}
}

void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
{
	struct net_device *dev = (struct net_device *) dev_ptr;
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	int n, i;

	ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
	do {
		n = ib_poll_cq(cq, IPOIB_NUM_WC, priv->ibwc);
		for (i = 0; i < n; ++i)
			ipoib_ib_handle_wc(dev, priv->ibwc + i);
	} while (n == IPOIB_NUM_WC);
}

static inline int post_send(struct ipoib_dev_priv *priv,
			    unsigned int wr_id,
			    struct ib_ah *address, u32 qpn,
			    dma_addr_t addr, int len)
{
	struct ib_send_wr *bad_wr;

	priv->tx_sge.addr             = addr;
	priv->tx_sge.length           = len;

	priv->tx_wr.wr_id 	      = wr_id;
	priv->tx_wr.wr.ud.remote_qpn  = qpn;
	priv->tx_wr.wr.ud.ah 	      = address;

	return ib_post_send(priv->qp, &priv->tx_wr, &bad_wr);
}

void ipoib_send(struct net_device *dev, struct sk_buff *skb,
		struct ipoib_ah *address, u32 qpn)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	struct ipoib_buf *tx_req;
	dma_addr_t addr;

	if (skb->len > dev->mtu + INFINIBAND_ALEN) {
		ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
			   skb->len, dev->mtu + INFINIBAND_ALEN);
		++priv->stats.tx_dropped;
		++priv->stats.tx_errors;
		dev_kfree_skb_any(skb);
		return;
	}

	ipoib_dbg_data(priv, "sending packet, length=%d address=%p qpn=0x%06x\n",
		       skb->len, address, qpn);

	/*
	 * We put the skb into the tx_ring _before_ we call post_send()
	 * because it's entirely possible that the completion handler will
	 * run before we execute anything after the post_send().  That
	 * means we have to make sure everything is properly recorded and
	 * our state is consistent before we call post_send().
	 */
	tx_req = &priv->tx_ring[priv->tx_head & (IPOIB_TX_RING_SIZE - 1)];
	tx_req->skb = skb;
	addr = dma_map_single(priv->ca->dma_device, skb->data, skb->len,
			      DMA_TO_DEVICE);
	pci_unmap_addr_set(tx_req, mapping, addr);

	if (unlikely(post_send(priv, priv->tx_head & (IPOIB_TX_RING_SIZE - 1),
			       address->ah, qpn, addr, skb->len))) {
		ipoib_warn(priv, "post_send failed\n");
		++priv->stats.tx_errors;
		dma_unmap_single(priv->ca->dma_device, addr, skb->len,
				 DMA_TO_DEVICE);
		dev_kfree_skb_any(skb);
	} else {
		dev->trans_start = jiffies;

		address->last_send = priv->tx_head;
		++priv->tx_head;

		if (priv->tx_head - priv->tx_tail == IPOIB_TX_RING_SIZE) {
			ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
			netif_stop_queue(dev);
		}
	}
}

static void __ipoib_reap_ah(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	struct ipoib_ah *ah, *tah;
	LIST_HEAD(remove_list);

	spin_lock_irq(&priv->lock);
	list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)
		if (ah->last_send <= priv->tx_tail) {
			list_del(&ah->list);
			list_add_tail(&ah->list, &remove_list);
		}
	spin_unlock_irq(&priv->lock);

	list_for_each_entry_safe(ah, tah, &remove_list, list) {
		ipoib_dbg(priv, "Reaping ah %p\n", ah->ah);
		ib_destroy_ah(ah->ah);
		kfree(ah);
	}
}

void ipoib_reap_ah(void *dev_ptr)
{
	struct net_device *dev = dev_ptr;
	struct ipoib_dev_priv *priv = netdev_priv(dev);

	__ipoib_reap_ah(dev);

	if (!test_bit(IPOIB_STOP_REAPER, &priv->flags))
		queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);
}

int ipoib_ib_dev_open(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	int ret;

	ret = ipoib_qp_create(dev);
	if (ret) {
		ipoib_warn(priv, "ipoib_qp_create returned %d\n", ret);
		return -1;
	}

	ret = ipoib_ib_post_receives(dev);
	if (ret) {
		ipoib_warn(priv, "ipoib_ib_post_receives returned %d\n", ret);
		return -1;
	}

	clear_bit(IPOIB_STOP_REAPER, &priv->flags);
	queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);

	return 0;
}

int ipoib_ib_dev_up(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);

	set_bit(IPOIB_FLAG_OPER_UP, &priv->flags);

	return ipoib_mcast_start_thread(dev);
}

int ipoib_ib_dev_down(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);

	ipoib_dbg(priv, "downing ib_dev\n");

	clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
	netif_carrier_off(dev);

	/* Shutdown the P_Key thread if still active */
	if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {
		down(&pkey_sem);
		set_bit(IPOIB_PKEY_STOP, &priv->flags);
		cancel_delayed_work(&priv->pkey_task);
		up(&pkey_sem);
		flush_workqueue(ipoib_workqueue);
	}

	ipoib_mcast_stop_thread(dev);

	/*
	 * Flush the multicast groups first so we stop any multicast joins. The
	 * completion thread may have already died and we may deadlock waiting
	 * for the completion thread to finish some multicast joins.
	 */
	ipoib_mcast_dev_flush(dev);

	/* Delete broadcast and local addresses since they will be recreated */
	ipoib_mcast_dev_down(dev);

	ipoib_flush_paths(dev);

	return 0;
}

static int recvs_pending(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	int pending = 0;
	int i;

	for (i = 0; i < IPOIB_RX_RING_SIZE; ++i)
		if (priv->rx_ring[i].skb)
			++pending;

	return pending;
}

int ipoib_ib_dev_stop(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	struct ib_qp_attr qp_attr;
	int attr_mask;
	unsigned long begin;
	struct ipoib_buf *tx_req;
	int i;

	/* Kill the existing QP and allocate a new one */
	qp_attr.qp_state = IB_QPS_ERR;
	attr_mask        = IB_QP_STATE;
	if (ib_modify_qp(priv->qp, &qp_attr, attr_mask))
		ipoib_warn(priv, "Failed to modify QP to ERROR state\n");

	/* Wait for all sends and receives to complete */
	begin = jiffies;

	while (priv->tx_head != priv->tx_tail || recvs_pending(dev)) {
		if (time_after(jiffies, begin + 5 * HZ)) {
			ipoib_warn(priv, "timing out; %d sends %d receives not completed\n",
				   priv->tx_head - priv->tx_tail, recvs_pending(dev));

			/*
			 * assume the HW is wedged and just free up
			 * all our pending work requests.
			 */
			while (priv->tx_tail < priv->tx_head) {
				tx_req = &priv->tx_ring[priv->tx_tail &
							(IPOIB_TX_RING_SIZE - 1)];
				dma_unmap_single(priv->ca->dma_device,
						 pci_unmap_addr(tx_req, mapping),
						 tx_req->skb->len,
						 DMA_TO_DEVICE);
				dev_kfree_skb_any(tx_req->skb);
				++priv->tx_tail;
			}

			for (i = 0; i < IPOIB_RX_RING_SIZE; ++i)
				if (priv->rx_ring[i].skb) {
					dma_unmap_single(priv->ca->dma_device,
							 pci_unmap_addr(&priv->rx_ring[i],
									mapping),
							 IPOIB_BUF_SIZE,
							 DMA_FROM_DEVICE);
					dev_kfree_skb_any(priv->rx_ring[i].skb);
					priv->rx_ring[i].skb = NULL;
				}

			goto timeout;
		}

		msleep(1);
	}

	ipoib_dbg(priv, "All sends and receives done.\n");

timeout:
	qp_attr.qp_state = IB_QPS_RESET;
	attr_mask        = IB_QP_STATE;
	if (ib_modify_qp(priv->qp, &qp_attr, attr_mask))
		ipoib_warn(priv, "Failed to modify QP to RESET state\n");

	/* Wait for all AHs to be reaped */
	set_bit(IPOIB_STOP_REAPER, &priv->flags);
	cancel_delayed_work(&priv->ah_reap_task);
	flush_workqueue(ipoib_workqueue);

	begin = jiffies;

	while (!list_empty(&priv->dead_ahs)) {
		__ipoib_reap_ah(dev);

		if (time_after(jiffies, begin + HZ)) {
			ipoib_warn(priv, "timing out; will leak address handles\n");
			break;
		}

		msleep(1);
	}

	return 0;
}

int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);

	priv->ca = ca;
	priv->port = port;
	priv->qp = NULL;

	if (ipoib_transport_dev_init(dev, ca)) {
		printk(KERN_WARNING "%s: ipoib_transport_dev_init failed\n", ca->name);
		return -ENODEV;
	}

	if (dev->flags & IFF_UP) {
		if (ipoib_ib_dev_open(dev)) {
			ipoib_transport_dev_cleanup(dev);
			return -ENODEV;
		}
	}

	return 0;
}

void ipoib_ib_dev_flush(void *_dev)
{
	struct net_device *dev = (struct net_device *)_dev;
	struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv;

	if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
		return;

	ipoib_dbg(priv, "flushing\n");

	ipoib_ib_dev_down(dev);

	/*
	 * The device could have been brought down between the start and when
	 * we get here, don't bring it back up if it's not configured up
	 */
	if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
		ipoib_ib_dev_up(dev);

	/* Flush any child interfaces too */
	list_for_each_entry(cpriv, &priv->child_intfs, list)
		ipoib_ib_dev_flush(&cpriv->dev);
}

void ipoib_ib_dev_cleanup(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);

	ipoib_dbg(priv, "cleaning up ib_dev\n");

	ipoib_mcast_stop_thread(dev);

	/* Delete the broadcast address and the local address */
	ipoib_mcast_dev_down(dev);

	ipoib_transport_dev_cleanup(dev);
}

/*
 * Delayed P_Key Assigment Interim Support
 *
 * The following is initial implementation of delayed P_Key assigment
 * mechanism. It is using the same approach implemented for the multicast
 * group join. The single goal of this implementation is to quickly address
 * Bug #2507. This implementation will probably be removed when the P_Key
 * change async notification is available.
 */
int ipoib_open(struct net_device *dev);

static void ipoib_pkey_dev_check_presence(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	u16 pkey_index = 0;

	if (ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index))
		clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
	else
		set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
}

void ipoib_pkey_poll(void *dev_ptr)
{
	struct net_device *dev = dev_ptr;
	struct ipoib_dev_priv *priv = netdev_priv(dev);

	ipoib_pkey_dev_check_presence(dev);

	if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags))
		ipoib_open(dev);
	else {
		down(&pkey_sem);
		if (!test_bit(IPOIB_PKEY_STOP, &priv->flags))
			queue_delayed_work(ipoib_workqueue,
					   &priv->pkey_task,
					   HZ);
		up(&pkey_sem);
	}
}

int ipoib_pkey_dev_delay_open(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);

	/* Look for the interface pkey value in the IB Port P_Key table and */
	/* set the interface pkey assigment flag                            */
	ipoib_pkey_dev_check_presence(dev);

	/* P_Key value not assigned yet - start polling */
	if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {
		down(&pkey_sem);
		clear_bit(IPOIB_PKEY_STOP, &priv->flags);
		queue_delayed_work(ipoib_workqueue,
				   &priv->pkey_task,
				   HZ);
		up(&pkey_sem);
		return 1;
	}

	return 0;
}
