140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/******************************************************************************
240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This software may be used and distributed according to the terms of
340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * the GNU General Public License (GPL), incorporated herein by reference.
440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Drivers based on or derived from this code fall under the GPL and must
540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * retain the authorship, copyright and license notice.  This file is not
640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * a complete program and may only be used when the entire operating
740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * system is licensed under the GPL.
840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * See the file COPYING in this distribution for more information.
940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa *
10926bd900b192986ccb742177b1492e8523579a35Jon Mason * vxge-config.c: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
1140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa *                Virtualized Server Adapter.
12926bd900b192986ccb742177b1492e8523579a35Jon Mason * Copyright(c) 2002-2010 Exar Corp.
1340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa ******************************************************************************/
1440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#include <linux/vmalloc.h>
1540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#include <linux/etherdevice.h>
1640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#include <linux/pci.h>
1740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#include <linux/pci_hotplug.h>
185a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
1940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#include "vxge-traffic.h"
2140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#include "vxge-config.h"
228424e00dfd5282026a93996a165fc4079d382169Jon Mason#include "vxge-main.h"
2340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
24528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason#define VXGE_HW_VPATH_STATS_PIO_READ(offset) {				\
25528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_stats_access(vpath,			\
26528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					      VXGE_HW_STATS_OP_READ,	\
27528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					      offset,			\
28528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					      &val64);			\
29528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)					\
30528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		return status;						\
3142821a5b393e36f5c0b267473d59d375578df7ecstephen hemminger}
3242821a5b393e36f5c0b267473d59d375578df7ecstephen hemminger
334d2a5b406c02b224bd3f50992c8b02450c65a730Jon Masonstatic void
344d2a5b406c02b224bd3f50992c8b02450c65a730Jon Masonvxge_hw_vpath_set_zero_rx_frm_len(struct vxge_hw_vpath_reg __iomem *vp_reg)
354d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason{
364d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	u64 val64;
374d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
384d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	val64 = readq(&vp_reg->rxmac_vcfg0);
394d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
404d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	writeq(val64, &vp_reg->rxmac_vcfg0);
414d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	val64 = readq(&vp_reg->rxmac_vcfg0);
424d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason}
434d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
444d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason/*
454d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason * vxge_hw_vpath_wait_receive_idle - Wait for Rx to become idle
464d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason */
474d2a5b406c02b224bd3f50992c8b02450c65a730Jon Masonint vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id)
484d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason{
494d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	struct vxge_hw_vpath_reg __iomem *vp_reg;
504d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	struct __vxge_hw_virtualpath *vpath;
514d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	u64 val64, rxd_count, rxd_spat;
524d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	int count = 0, total_count = 0;
534d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
544d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	vpath = &hldev->virtual_paths[vp_id];
554d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	vp_reg = vpath->vp_reg;
564d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
574d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	vxge_hw_vpath_set_zero_rx_frm_len(vp_reg);
584d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
594d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	/* Check that the ring controller for this vpath has enough free RxDs
604d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	 * to send frames to the host.  This is done by reading the
614d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	 * PRC_RXD_DOORBELL_VPn register and comparing the read value to the
624d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	 * RXD_SPAT value for the vpath.
634d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	 */
644d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	val64 = readq(&vp_reg->prc_cfg6);
654d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	rxd_spat = VXGE_HW_PRC_CFG6_GET_RXD_SPAT(val64) + 1;
664d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	/* Use a factor of 2 when comparing rxd_count against rxd_spat for some
674d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	 * leg room.
684d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	 */
694d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	rxd_spat *= 2;
704d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
714d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	do {
724d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		mdelay(1);
734d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
744d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		rxd_count = readq(&vp_reg->prc_rxd_doorbell);
754d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
764d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		/* Check that the ring controller for this vpath does
774d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		 * not have any frame in its pipeline.
784d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		 */
794d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		val64 = readq(&vp_reg->frm_in_progress_cnt);
804d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		if ((rxd_count <= rxd_spat) || (val64 > 0))
814d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason			count = 0;
824d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		else
834d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason			count++;
844d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		total_count++;
854d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	} while ((count < VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT) &&
864d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason			(total_count < VXGE_HW_MAX_POLLING_COUNT));
874d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
884d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	if (total_count >= VXGE_HW_MAX_POLLING_COUNT)
894d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		printk(KERN_ALERT "%s: Still Receiving traffic. Abort wait\n",
904d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason			__func__);
914d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
924d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	return total_count;
934d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason}
944d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
954d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason/* vxge_hw_device_wait_receive_idle - This function waits until all frames
964d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason * stored in the frame buffer for each vpath assigned to the given
974d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason * function (hldev) have been sent to the host.
984d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason */
994d2a5b406c02b224bd3f50992c8b02450c65a730Jon Masonvoid vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev)
1004d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason{
1014d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	int i, total_count = 0;
1024d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
1034d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
1044d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
1054d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason			continue;
1064d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
1074d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		total_count += vxge_hw_vpath_wait_receive_idle(hldev, i);
1084d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason		if (total_count >= VXGE_HW_MAX_POLLING_COUNT)
1094d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason			break;
1104d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason	}
1114d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason}
1124d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason
113528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
114528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_device_register_poll
115528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Will poll certain register for specified amount of time.
116528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Will poll until masked bit is not cleared.
117528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
118528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
119528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis)
120528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
121528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u64 val64;
122528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 i = 0;
123528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status ret = VXGE_HW_FAIL;
124528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
125528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	udelay(10);
126528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
127528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	do {
128528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64 = readq(reg);
129528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (!(val64 & mask))
130528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			return VXGE_HW_OK;
131528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		udelay(100);
132528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	} while (++i <= 9);
133528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
134528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	i = 0;
135528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	do {
136528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64 = readq(reg);
137528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (!(val64 & mask))
138528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			return VXGE_HW_OK;
139528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		mdelay(1);
140528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	} while (++i <= max_millis);
141528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
142528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return ret;
143528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
144528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
145528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic inline enum vxge_hw_status
146528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_pio_mem_write64(u64 val64, void __iomem *addr,
147528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			  u64 mask, u32 max_millis)
148528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
149528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_pio_mem_write32_lower((u32)vxge_bVALn(val64, 32, 32), addr);
150528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	wmb();
151528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), addr);
152528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	wmb();
153528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
154528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return __vxge_hw_device_register_poll(addr, mask, max_millis);
155528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
156528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1578424e00dfd5282026a93996a165fc4079d382169Jon Masonstatic enum vxge_hw_status
1588424e00dfd5282026a93996a165fc4079d382169Jon Masonvxge_hw_vpath_fw_api(struct __vxge_hw_virtualpath *vpath, u32 action,
1598424e00dfd5282026a93996a165fc4079d382169Jon Mason		     u32 fw_memo, u32 offset, u64 *data0, u64 *data1,
1608424e00dfd5282026a93996a165fc4079d382169Jon Mason		     u64 *steer_ctrl)
1618424e00dfd5282026a93996a165fc4079d382169Jon Mason{
1629f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg;
1638424e00dfd5282026a93996a165fc4079d382169Jon Mason	enum vxge_hw_status status;
1648424e00dfd5282026a93996a165fc4079d382169Jon Mason	u64 val64;
1659f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	u32 retry = 0, max_retry = 3;
1668424e00dfd5282026a93996a165fc4079d382169Jon Mason
1679f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	spin_lock(&vpath->lock);
1689f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	if (!vpath->vp_open) {
1699f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason		spin_unlock(&vpath->lock);
1709f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason		max_retry = 100;
1718424e00dfd5282026a93996a165fc4079d382169Jon Mason	}
1728424e00dfd5282026a93996a165fc4079d382169Jon Mason
1738424e00dfd5282026a93996a165fc4079d382169Jon Mason	writeq(*data0, &vp_reg->rts_access_steer_data0);
1748424e00dfd5282026a93996a165fc4079d382169Jon Mason	writeq(*data1, &vp_reg->rts_access_steer_data1);
1758424e00dfd5282026a93996a165fc4079d382169Jon Mason	wmb();
1768424e00dfd5282026a93996a165fc4079d382169Jon Mason
1778424e00dfd5282026a93996a165fc4079d382169Jon Mason	val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
1788424e00dfd5282026a93996a165fc4079d382169Jon Mason		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(fw_memo) |
1798424e00dfd5282026a93996a165fc4079d382169Jon Mason		VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset) |
1808424e00dfd5282026a93996a165fc4079d382169Jon Mason		VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
1818424e00dfd5282026a93996a165fc4079d382169Jon Mason		*steer_ctrl;
1828424e00dfd5282026a93996a165fc4079d382169Jon Mason
1838424e00dfd5282026a93996a165fc4079d382169Jon Mason	status = __vxge_hw_pio_mem_write64(val64,
1848424e00dfd5282026a93996a165fc4079d382169Jon Mason					   &vp_reg->rts_access_steer_ctrl,
1858424e00dfd5282026a93996a165fc4079d382169Jon Mason					   VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
1868424e00dfd5282026a93996a165fc4079d382169Jon Mason					   VXGE_HW_DEF_DEVICE_POLL_MILLIS);
1878424e00dfd5282026a93996a165fc4079d382169Jon Mason
1888424e00dfd5282026a93996a165fc4079d382169Jon Mason	/* The __vxge_hw_device_register_poll can udelay for a significant
18925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	 * amount of time, blocking other process from the CPU.  If it delays
1908424e00dfd5282026a93996a165fc4079d382169Jon Mason	 * for ~5secs, a NMI error can occur.  A way around this is to give up
1918424e00dfd5282026a93996a165fc4079d382169Jon Mason	 * the processor via msleep, but this is not allowed is under lock.
1928424e00dfd5282026a93996a165fc4079d382169Jon Mason	 * So, only allow it to sleep for ~4secs if open.  Otherwise, delay for
1938424e00dfd5282026a93996a165fc4079d382169Jon Mason	 * 1sec and sleep for 10ms until the firmware operation has completed
1948424e00dfd5282026a93996a165fc4079d382169Jon Mason	 * or timed-out.
1958424e00dfd5282026a93996a165fc4079d382169Jon Mason	 */
1968424e00dfd5282026a93996a165fc4079d382169Jon Mason	while ((status != VXGE_HW_OK) && retry++ < max_retry) {
1978424e00dfd5282026a93996a165fc4079d382169Jon Mason		if (!vpath->vp_open)
1988424e00dfd5282026a93996a165fc4079d382169Jon Mason			msleep(20);
1998424e00dfd5282026a93996a165fc4079d382169Jon Mason		status = __vxge_hw_device_register_poll(
2008424e00dfd5282026a93996a165fc4079d382169Jon Mason					&vp_reg->rts_access_steer_ctrl,
2018424e00dfd5282026a93996a165fc4079d382169Jon Mason					VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
2028424e00dfd5282026a93996a165fc4079d382169Jon Mason					VXGE_HW_DEF_DEVICE_POLL_MILLIS);
2038424e00dfd5282026a93996a165fc4079d382169Jon Mason	}
2048424e00dfd5282026a93996a165fc4079d382169Jon Mason
2058424e00dfd5282026a93996a165fc4079d382169Jon Mason	if (status != VXGE_HW_OK)
2068424e00dfd5282026a93996a165fc4079d382169Jon Mason		goto out;
2078424e00dfd5282026a93996a165fc4079d382169Jon Mason
2088424e00dfd5282026a93996a165fc4079d382169Jon Mason	val64 = readq(&vp_reg->rts_access_steer_ctrl);
2098424e00dfd5282026a93996a165fc4079d382169Jon Mason	if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
2108424e00dfd5282026a93996a165fc4079d382169Jon Mason		*data0 = readq(&vp_reg->rts_access_steer_data0);
2118424e00dfd5282026a93996a165fc4079d382169Jon Mason		*data1 = readq(&vp_reg->rts_access_steer_data1);
2128424e00dfd5282026a93996a165fc4079d382169Jon Mason		*steer_ctrl = val64;
2138424e00dfd5282026a93996a165fc4079d382169Jon Mason	} else
2148424e00dfd5282026a93996a165fc4079d382169Jon Mason		status = VXGE_HW_FAIL;
2158424e00dfd5282026a93996a165fc4079d382169Jon Mason
2168424e00dfd5282026a93996a165fc4079d382169Jon Masonout:
2178424e00dfd5282026a93996a165fc4079d382169Jon Mason	if (vpath->vp_open)
2188424e00dfd5282026a93996a165fc4079d382169Jon Mason		spin_unlock(&vpath->lock);
2198424e00dfd5282026a93996a165fc4079d382169Jon Mason	return status;
2208424e00dfd5282026a93996a165fc4079d382169Jon Mason}
2218424e00dfd5282026a93996a165fc4079d382169Jon Mason
222e8ac175615b9458a00193c55617b5b8865e67817Jon Masonenum vxge_hw_status
223e8ac175615b9458a00193c55617b5b8865e67817Jon Masonvxge_hw_upgrade_read_version(struct __vxge_hw_device *hldev, u32 *major,
224e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			     u32 *minor, u32 *build)
225e8ac175615b9458a00193c55617b5b8865e67817Jon Mason{
226e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	u64 data0 = 0, data1 = 0, steer_ctrl = 0;
227e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	struct __vxge_hw_virtualpath *vpath;
228e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	enum vxge_hw_status status;
229e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
230e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	vpath = &hldev->virtual_paths[hldev->first_vp_id];
231e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
232e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	status = vxge_hw_vpath_fw_api(vpath,
233e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      VXGE_HW_FW_UPGRADE_ACTION,
234e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      VXGE_HW_FW_UPGRADE_MEMO,
235e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      VXGE_HW_FW_UPGRADE_OFFSET_READ,
236e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      &data0, &data1, &steer_ctrl);
237e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	if (status != VXGE_HW_OK)
238e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		return status;
239e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
240e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	*major = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0);
241e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	*minor = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0);
242e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	*build = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0);
243e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
244e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	return status;
245e8ac175615b9458a00193c55617b5b8865e67817Jon Mason}
246e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
247e8ac175615b9458a00193c55617b5b8865e67817Jon Masonenum vxge_hw_status vxge_hw_flash_fw(struct __vxge_hw_device *hldev)
248e8ac175615b9458a00193c55617b5b8865e67817Jon Mason{
249e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	u64 data0 = 0, data1 = 0, steer_ctrl = 0;
250e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	struct __vxge_hw_virtualpath *vpath;
251e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	enum vxge_hw_status status;
252e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	u32 ret;
253e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
254e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	vpath = &hldev->virtual_paths[hldev->first_vp_id];
255e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
256e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	status = vxge_hw_vpath_fw_api(vpath,
257e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      VXGE_HW_FW_UPGRADE_ACTION,
258e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      VXGE_HW_FW_UPGRADE_MEMO,
259e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      VXGE_HW_FW_UPGRADE_OFFSET_COMMIT,
260e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      &data0, &data1, &steer_ctrl);
261e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	if (status != VXGE_HW_OK) {
262e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		vxge_debug_init(VXGE_ERR, "%s: FW upgrade failed", __func__);
263e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		goto exit;
264e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	}
265e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
266e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	ret = VXGE_HW_RTS_ACCESS_STEER_CTRL_GET_ACTION(steer_ctrl) & 0x7F;
267e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	if (ret != 1) {
268e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		vxge_debug_init(VXGE_ERR, "%s: FW commit failed with error %d",
269e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				__func__, ret);
270e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		status = VXGE_HW_FAIL;
271e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	}
272e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
273e8ac175615b9458a00193c55617b5b8865e67817Jon Masonexit:
274e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	return status;
275e8ac175615b9458a00193c55617b5b8865e67817Jon Mason}
276e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
277e8ac175615b9458a00193c55617b5b8865e67817Jon Masonenum vxge_hw_status
278e8ac175615b9458a00193c55617b5b8865e67817Jon Masonvxge_update_fw_image(struct __vxge_hw_device *hldev, const u8 *fwdata, int size)
279e8ac175615b9458a00193c55617b5b8865e67817Jon Mason{
280e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	u64 data0 = 0, data1 = 0, steer_ctrl = 0;
281e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	struct __vxge_hw_virtualpath *vpath;
282e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	enum vxge_hw_status status;
283e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	int ret_code, sec_code;
284e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
285e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	vpath = &hldev->virtual_paths[hldev->first_vp_id];
286e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
287e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	/* send upgrade start command */
288e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	status = vxge_hw_vpath_fw_api(vpath,
289e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      VXGE_HW_FW_UPGRADE_ACTION,
290e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      VXGE_HW_FW_UPGRADE_MEMO,
291e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      VXGE_HW_FW_UPGRADE_OFFSET_START,
292e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				      &data0, &data1, &steer_ctrl);
293e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	if (status != VXGE_HW_OK) {
294e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		vxge_debug_init(VXGE_ERR, " %s: Upgrade start cmd failed",
295e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				__func__);
296e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		return status;
297e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	}
298e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
299e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	/* Transfer fw image to adapter 16 bytes at a time */
300e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	for (; size > 0; size -= VXGE_HW_FW_UPGRADE_BLK_SIZE) {
301e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		steer_ctrl = 0;
302e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
303e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		/* The next 128bits of fwdata to be loaded onto the adapter */
304e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		data0 = *((u64 *)fwdata);
305e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		data1 = *((u64 *)fwdata + 1);
306e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
307e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		status = vxge_hw_vpath_fw_api(vpath,
308e8ac175615b9458a00193c55617b5b8865e67817Jon Mason					      VXGE_HW_FW_UPGRADE_ACTION,
309e8ac175615b9458a00193c55617b5b8865e67817Jon Mason					      VXGE_HW_FW_UPGRADE_MEMO,
310e8ac175615b9458a00193c55617b5b8865e67817Jon Mason					      VXGE_HW_FW_UPGRADE_OFFSET_SEND,
311e8ac175615b9458a00193c55617b5b8865e67817Jon Mason					      &data0, &data1, &steer_ctrl);
312e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		if (status != VXGE_HW_OK) {
313e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			vxge_debug_init(VXGE_ERR, "%s: Upgrade send failed",
314e8ac175615b9458a00193c55617b5b8865e67817Jon Mason					__func__);
315e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			goto out;
316e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		}
317e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
318e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		ret_code = VXGE_HW_UPGRADE_GET_RET_ERR_CODE(data0);
319e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		switch (ret_code) {
320e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		case VXGE_HW_FW_UPGRADE_OK:
321e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			/* All OK, send next 16 bytes. */
322e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			break;
323e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		case VXGE_FW_UPGRADE_BYTES2SKIP:
324e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			/* skip bytes in the stream */
325e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			fwdata += (data0 >> 8) & 0xFFFFFFFF;
326e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			break;
327e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		case VXGE_HW_FW_UPGRADE_DONE:
328e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			goto out;
329e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		case VXGE_HW_FW_UPGRADE_ERR:
330e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			sec_code = VXGE_HW_UPGRADE_GET_SEC_ERR_CODE(data0);
331e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			switch (sec_code) {
332e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1:
333e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7:
334e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				printk(KERN_ERR
335e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				       "corrupted data from .ncf file\n");
336e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				break;
337e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3:
338e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4:
339e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5:
340e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6:
341e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8:
342e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				printk(KERN_ERR "invalid .ncf file\n");
343e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				break;
344e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			case VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW:
345e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				printk(KERN_ERR "buffer overflow\n");
346e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				break;
347e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			case VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH:
348e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				printk(KERN_ERR "failed to flash the image\n");
349e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				break;
350e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			case VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN:
351e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				printk(KERN_ERR
352e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				       "generic error. Unknown error type\n");
353e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				break;
354e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			default:
355e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				printk(KERN_ERR "Unknown error of type %d\n",
356e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				       sec_code);
357e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				break;
358e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			}
359e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			status = VXGE_HW_FAIL;
360e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			goto out;
361e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		default:
362e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			printk(KERN_ERR "Unknown FW error: %d\n", ret_code);
363e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			status = VXGE_HW_FAIL;
364e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			goto out;
365e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		}
366e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		/* point to next 16 bytes */
367e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		fwdata += VXGE_HW_FW_UPGRADE_BLK_SIZE;
368e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	}
369e8ac175615b9458a00193c55617b5b8865e67817Jon Masonout:
370e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	return status;
371e8ac175615b9458a00193c55617b5b8865e67817Jon Mason}
372e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
373e8ac175615b9458a00193c55617b5b8865e67817Jon Masonenum vxge_hw_status
374e8ac175615b9458a00193c55617b5b8865e67817Jon Masonvxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev,
375e8ac175615b9458a00193c55617b5b8865e67817Jon Mason				struct eprom_image *img)
376e8ac175615b9458a00193c55617b5b8865e67817Jon Mason{
377e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	u64 data0 = 0, data1 = 0, steer_ctrl = 0;
378e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	struct __vxge_hw_virtualpath *vpath;
379e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	enum vxge_hw_status status;
380e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	int i;
381e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
382e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	vpath = &hldev->virtual_paths[hldev->first_vp_id];
383e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
384e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) {
385e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		data0 = VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(i);
386e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		data1 = steer_ctrl = 0;
387e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
388e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		status = vxge_hw_vpath_fw_api(vpath,
389e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			VXGE_HW_FW_API_GET_EPROM_REV,
3901d15f81cda496f1c1d59af7458ea0bcdeeb726f3Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
391e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			0, &data0, &data1, &steer_ctrl);
392e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		if (status != VXGE_HW_OK)
393e8ac175615b9458a00193c55617b5b8865e67817Jon Mason			break;
394e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
395e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		img[i].is_valid = VXGE_HW_GET_EPROM_IMAGE_VALID(data0);
396e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		img[i].index = VXGE_HW_GET_EPROM_IMAGE_INDEX(data0);
397e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		img[i].type = VXGE_HW_GET_EPROM_IMAGE_TYPE(data0);
398e8ac175615b9458a00193c55617b5b8865e67817Jon Mason		img[i].version = VXGE_HW_GET_EPROM_IMAGE_REV(data0);
399e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	}
400e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
401e8ac175615b9458a00193c55617b5b8865e67817Jon Mason	return status;
402e8ac175615b9458a00193c55617b5b8865e67817Jon Mason}
403e8ac175615b9458a00193c55617b5b8865e67817Jon Mason
40440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
40540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_channel_free - Free memory allocated for channel
40640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This function deallocates memory from the channel and various arrays
40740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * in the channel
40840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
4092c91308f449c6705b81bd3370a0ec647e370f35cJon Masonstatic void __vxge_hw_channel_free(struct __vxge_hw_channel *channel)
41040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
41140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	kfree(channel->work_arr);
41240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	kfree(channel->free_arr);
41340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	kfree(channel->reserve_arr);
41440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	kfree(channel->orig_arr);
41540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	kfree(channel);
41640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
41740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
41840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
41940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_channel_initialize - Initialize a channel
42040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This function initializes a channel by properly setting the
42140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * various references
42240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
4232c91308f449c6705b81bd3370a0ec647e370f35cJon Masonstatic enum vxge_hw_status
42440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_channel_initialize(struct __vxge_hw_channel *channel)
42540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
42640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i;
42740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_virtualpath *vpath;
42840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
42940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath = channel->vph->vpath;
43040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
43140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if ((channel->reserve_arr != NULL) && (channel->orig_arr != NULL)) {
43240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		for (i = 0; i < channel->length; i++)
43340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			channel->orig_arr[i] = channel->reserve_arr[i];
43440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
43540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
43640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	switch (channel->type) {
43740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case VXGE_HW_CHANNEL_TYPE_FIFO:
43840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		vpath->fifoh = (struct __vxge_hw_fifo *)channel;
43940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		channel->stats = &((struct __vxge_hw_fifo *)
44040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				channel)->stats->common_stats;
44140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
44240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case VXGE_HW_CHANNEL_TYPE_RING:
44340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		vpath->ringh = (struct __vxge_hw_ring *)channel;
44440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		channel->stats = &((struct __vxge_hw_ring *)
44540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				channel)->stats->common_stats;
44640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
44740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	default:
44840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
44940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
45040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
45140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return VXGE_HW_OK;
45240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
45340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
45440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
45540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_channel_reset - Resets a channel
45640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This function resets a channel by properly setting the various references
45740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
4582c91308f449c6705b81bd3370a0ec647e370f35cJon Masonstatic enum vxge_hw_status
45940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_channel_reset(struct __vxge_hw_channel *channel)
46040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
46140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i;
46240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
46340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < channel->length; i++) {
46440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (channel->reserve_arr != NULL)
46540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			channel->reserve_arr[i] = channel->orig_arr[i];
46640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (channel->free_arr != NULL)
46740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			channel->free_arr[i] = NULL;
46840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (channel->work_arr != NULL)
46940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			channel->work_arr[i] = NULL;
47040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
47140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	channel->free_ptr = channel->length;
47240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	channel->reserve_ptr = channel->length;
47340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	channel->reserve_top = 0;
47440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	channel->post_index = 0;
47540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	channel->compl_index = 0;
47640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
47740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return VXGE_HW_OK;
47840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
47940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
48040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
48140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_device_pci_e_init
48240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Initialize certain PCI/PCI-X configuration registers
48340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * with recommended values. Save config space for future hw resets.
48440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
4852c91308f449c6705b81bd3370a0ec647e370f35cJon Masonstatic void __vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev)
48640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
48740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u16 cmd = 0;
48840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
48940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* Set the PErr Repconse bit and SERR in PCI command register. */
49040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	pci_read_config_word(hldev->pdev, PCI_COMMAND, &cmd);
49140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	cmd |= 0x140;
49240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	pci_write_config_word(hldev->pdev, PCI_COMMAND, cmd);
49340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
49440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	pci_save_state(hldev->pdev);
49540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
49640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4974d2a5b406c02b224bd3f50992c8b02450c65a730Jon Mason/* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset
49840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * in progress
49940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine checks the vpath reset in progress register is turned zero
50040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
50142821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
50240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_device_vpath_reset_in_prog_check(u64 __iomem *vpath_rst_in_prog)
50340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
50440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status;
50540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_device_register_poll(vpath_rst_in_prog,
50640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff),
50740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_DEF_DEVICE_POLL_MILLIS);
50840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
50940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
51040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
51140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
512528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * _hw_legacy_swapper_set - Set the swapper bits for the legacy secion.
513528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Set the swapper bits appropriately for the lagacy section.
514528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
515528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
516528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg)
517528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
518528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u64 val64;
519528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
520528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
521528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&legacy_reg->toc_swapper_fb);
522528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
523528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	wmb();
524528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
525528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	switch (val64) {
526528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	case VXGE_HW_SWAPPER_INITIAL_VALUE:
527528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		return status;
528528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
529528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	case VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED:
530528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
531528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&legacy_reg->pifm_rd_swap_en);
532528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
533528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&legacy_reg->pifm_rd_flip_en);
534528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
535528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&legacy_reg->pifm_wr_swap_en);
536528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
537528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&legacy_reg->pifm_wr_flip_en);
538528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		break;
539528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
540528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	case VXGE_HW_SWAPPER_BYTE_SWAPPED:
541528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
542528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&legacy_reg->pifm_rd_swap_en);
543528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
544528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&legacy_reg->pifm_wr_swap_en);
545528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		break;
546528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
547528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	case VXGE_HW_SWAPPER_BIT_FLIPPED:
548528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
549528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&legacy_reg->pifm_rd_flip_en);
550528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
551528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&legacy_reg->pifm_wr_flip_en);
552528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		break;
553528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
554528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
555528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	wmb();
556528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
557528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&legacy_reg->toc_swapper_fb);
558528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
559528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (val64 != VXGE_HW_SWAPPER_INITIAL_VALUE)
560528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_SWAPPER_CTRL;
561528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
562528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
563528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
564528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
565528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
56640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_device_toc_get
56740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine sets the swapper and reads the toc pointer and returns the
56840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * memory mapped address of the toc
56940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
57042821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic struct vxge_hw_toc_reg __iomem *
57140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_device_toc_get(void __iomem *bar0)
57240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
57340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
57440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_toc_reg __iomem *toc = NULL;
57540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status;
57640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
57740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_legacy_reg __iomem *legacy_reg =
57840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		(struct vxge_hw_legacy_reg __iomem *)bar0;
57940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
58040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_legacy_swapper_set(legacy_reg);
58140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
58240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
58340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
58440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 =	readq(&legacy_reg->toc_first_pointer);
58543d620c82985b19008d87a437b4cf83f356264f7Joe Perches	toc = bar0 + val64;
58640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
58740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return toc;
58840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
58940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
59040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
59140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_device_reg_addr_get
59240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine sets the swapper and reads the toc pointer and initializes the
59340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * register location pointers in the device object. It waits until the ric is
59440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * completed initializing registers.
59540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
5962c91308f449c6705b81bd3370a0ec647e370f35cJon Masonstatic enum vxge_hw_status
59740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev)
59840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
59940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
60040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i;
60140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
60240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
60343d620c82985b19008d87a437b4cf83f356264f7Joe Perches	hldev->legacy_reg = hldev->bar0;
60440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
60540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->toc_reg = __vxge_hw_device_toc_get(hldev->bar0);
60640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hldev->toc_reg  == NULL) {
60740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_FAIL;
60840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
60940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
61040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
61140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&hldev->toc_reg->toc_common_pointer);
61243d620c82985b19008d87a437b4cf83f356264f7Joe Perches	hldev->common_reg = hldev->bar0 + val64;
61340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
61440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&hldev->toc_reg->toc_mrpcim_pointer);
61543d620c82985b19008d87a437b4cf83f356264f7Joe Perches	hldev->mrpcim_reg = hldev->bar0 + val64;
61640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
61740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_TITAN_SRPCIM_REG_SPACES; i++) {
61840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&hldev->toc_reg->toc_srpcim_pointer[i]);
61943d620c82985b19008d87a437b4cf83f356264f7Joe Perches		hldev->srpcim_reg[i] = hldev->bar0 + val64;
62040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
62140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
62240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_TITAN_VPMGMT_REG_SPACES; i++) {
62340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&hldev->toc_reg->toc_vpmgmt_pointer[i]);
62443d620c82985b19008d87a437b4cf83f356264f7Joe Perches		hldev->vpmgmt_reg[i] = hldev->bar0 + val64;
62540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
62640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
62740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_TITAN_VPATH_REG_SPACES; i++) {
62840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&hldev->toc_reg->toc_vpath_pointer[i]);
62943d620c82985b19008d87a437b4cf83f356264f7Joe Perches		hldev->vpath_reg[i] = hldev->bar0 + val64;
63040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
63140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
63240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&hldev->toc_reg->toc_kdfc);
63340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
63440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	switch (VXGE_HW_TOC_GET_KDFC_INITIAL_BIR(val64)) {
63540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case 0:
63643d620c82985b19008d87a437b4cf83f356264f7Joe Perches		hldev->kdfc = hldev->bar0 + VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64) ;
63740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
63840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	default:
63940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
64040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
64140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
64240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_device_vpath_reset_in_prog_check(
64340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(u64 __iomem *)&hldev->common_reg->vpath_rst_in_prog);
64440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
64540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
64640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
64740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
64840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
64940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_device_access_rights_get: Get Access Rights of the driver
65040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine returns the Access Rights of the driver
65140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
65240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepastatic u32
65340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_device_access_rights_get(u32 host_type, u32 func_id)
65440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
65540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 access_rights = VXGE_HW_DEVICE_ACCESS_RIGHT_VPATH;
65640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
65740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	switch (host_type) {
65840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION:
6591dc47a9b1b05e3ab039e7d2ab97455ff09a9e554Sreenivasa Honnur		if (func_id == 0) {
6601dc47a9b1b05e3ab039e7d2ab97455ff09a9e554Sreenivasa Honnur			access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
6611dc47a9b1b05e3ab039e7d2ab97455ff09a9e554Sreenivasa Honnur					VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
6621dc47a9b1b05e3ab039e7d2ab97455ff09a9e554Sreenivasa Honnur		}
66340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
66440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION:
66540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
66640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
66740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
66840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case VXGE_HW_NO_MR_SR_VH0_FUNCTION0:
66940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
67040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
67140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
67240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case VXGE_HW_NO_MR_SR_VH0_VIRTUAL_FUNCTION:
67340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case VXGE_HW_SR_VH_VIRTUAL_FUNCTION:
67440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case VXGE_HW_MR_SR_VH0_INVALID_CONFIG:
67540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
67640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case VXGE_HW_SR_VH_FUNCTION0:
67740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case VXGE_HW_VH_NORMAL_FUNCTION:
67840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
67940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
68040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
68140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
68240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return access_rights;
68340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
68440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
68592cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur * __vxge_hw_device_is_privilaged
68692cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur * This routine checks if the device function is privilaged or not
68792cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur */
68892cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur
68992cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnurenum vxge_hw_status
69092cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur__vxge_hw_device_is_privilaged(u32 host_type, u32 func_id)
69192cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur{
69292cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur	if (__vxge_hw_device_access_rights_get(host_type,
69392cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur		func_id) &
69492cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur		VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)
69592cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur		return VXGE_HW_OK;
69692cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur	else
69792cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur		return VXGE_HW_ERR_PRIVILAGED_OPEARATION;
69892cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur}
69992cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur
70092cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur/*
7018424e00dfd5282026a93996a165fc4079d382169Jon Mason * __vxge_hw_vpath_func_id_get - Get the function id of the vpath.
7028424e00dfd5282026a93996a165fc4079d382169Jon Mason * Returns the function number of the vpath.
7038424e00dfd5282026a93996a165fc4079d382169Jon Mason */
7048424e00dfd5282026a93996a165fc4079d382169Jon Masonstatic u32
7058424e00dfd5282026a93996a165fc4079d382169Jon Mason__vxge_hw_vpath_func_id_get(struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg)
7068424e00dfd5282026a93996a165fc4079d382169Jon Mason{
7078424e00dfd5282026a93996a165fc4079d382169Jon Mason	u64 val64;
7088424e00dfd5282026a93996a165fc4079d382169Jon Mason
7098424e00dfd5282026a93996a165fc4079d382169Jon Mason	val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1);
7108424e00dfd5282026a93996a165fc4079d382169Jon Mason
7118424e00dfd5282026a93996a165fc4079d382169Jon Mason	return
7128424e00dfd5282026a93996a165fc4079d382169Jon Mason	 (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64);
7138424e00dfd5282026a93996a165fc4079d382169Jon Mason}
7148424e00dfd5282026a93996a165fc4079d382169Jon Mason
7158424e00dfd5282026a93996a165fc4079d382169Jon Mason/*
71640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_device_host_info_get
71740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine returns the host type assignments
71840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
7198424e00dfd5282026a93996a165fc4079d382169Jon Masonstatic void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev)
72040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
72140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
72240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i;
72340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
72440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&hldev->common_reg->host_type_assignments);
72540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
72640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->host_type =
72740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	   (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
72840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
72940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->vpath_assignments = readq(&hldev->common_reg->vpath_assignments);
73040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
73140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
73240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (!(hldev->vpath_assignments & vxge_mBIT(i)))
73340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			continue;
73440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
73540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		hldev->func_id =
7368424e00dfd5282026a93996a165fc4079d382169Jon Mason			__vxge_hw_vpath_func_id_get(hldev->vpmgmt_reg[i]);
73740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
73840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		hldev->access_rights = __vxge_hw_device_access_rights_get(
73940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			hldev->host_type, hldev->func_id);
74040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
7418424e00dfd5282026a93996a165fc4079d382169Jon Mason		hldev->virtual_paths[i].vp_open = VXGE_HW_VP_NOT_OPEN;
7428424e00dfd5282026a93996a165fc4079d382169Jon Mason		hldev->virtual_paths[i].vp_reg = hldev->vpath_reg[i];
7438424e00dfd5282026a93996a165fc4079d382169Jon Mason
74440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		hldev->first_vp_id = i;
74540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
74640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
74740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
74840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
74940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
75040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_verify_pci_e_info - Validate the pci-e link parameters such as
75140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * link width and signalling rate.
75240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
75340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepastatic enum vxge_hw_status
75440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev)
75540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
75695cab7386bef62f8c7535d4726573ce230778e7bJon Mason	struct pci_dev *dev = hldev->pdev;
75740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u16 lnk;
75840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
75940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* Get the negotiated link width and speed from PCI config space */
76095cab7386bef62f8c7535d4726573ce230778e7bJon Mason	pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk);
76140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
76240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if ((lnk & PCI_EXP_LNKSTA_CLS) != 1)
76340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		return VXGE_HW_ERR_INVALID_PCI_INFO;
76440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
76540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	switch ((lnk & PCI_EXP_LNKSTA_NLW) >> 4) {
76640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case PCIE_LNK_WIDTH_RESRV:
76740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case PCIE_LNK_X1:
76840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case PCIE_LNK_X2:
76940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case PCIE_LNK_X4:
77040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case PCIE_LNK_X8:
77140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
77240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	default:
77340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		return VXGE_HW_ERR_INVALID_PCI_INFO;
77440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
77540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
77640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return VXGE_HW_OK;
77740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
77840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
77940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
78040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_device_initialize
78140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Initialize Titan-V hardware.
78240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
7832c91308f449c6705b81bd3370a0ec647e370f35cJon Masonstatic enum vxge_hw_status
7842c91308f449c6705b81bd3370a0ec647e370f35cJon Mason__vxge_hw_device_initialize(struct __vxge_hw_device *hldev)
78540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
78640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
78740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
78892cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur	if (VXGE_HW_OK == __vxge_hw_device_is_privilaged(hldev->host_type,
78992cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur				hldev->func_id)) {
7905dbc901172fb952409940cd7ca55d8e6e5a7cc2cSivakumar Subramani		/* Validate the pci-e link width and speed */
7915dbc901172fb952409940cd7ca55d8e6e5a7cc2cSivakumar Subramani		status = __vxge_hw_verify_pci_e_info(hldev);
7925dbc901172fb952409940cd7ca55d8e6e5a7cc2cSivakumar Subramani		if (status != VXGE_HW_OK)
7935dbc901172fb952409940cd7ca55d8e6e5a7cc2cSivakumar Subramani			goto exit;
7945dbc901172fb952409940cd7ca55d8e6e5a7cc2cSivakumar Subramani	}
79540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
79640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
79740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
79840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
79940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
8008424e00dfd5282026a93996a165fc4079d382169Jon Mason/*
8018424e00dfd5282026a93996a165fc4079d382169Jon Mason * __vxge_hw_vpath_fw_ver_get - Get the fw version
8028424e00dfd5282026a93996a165fc4079d382169Jon Mason * Returns FW Version
8038424e00dfd5282026a93996a165fc4079d382169Jon Mason */
8048424e00dfd5282026a93996a165fc4079d382169Jon Masonstatic enum vxge_hw_status
8058424e00dfd5282026a93996a165fc4079d382169Jon Mason__vxge_hw_vpath_fw_ver_get(struct __vxge_hw_virtualpath *vpath,
8068424e00dfd5282026a93996a165fc4079d382169Jon Mason			   struct vxge_hw_device_hw_info *hw_info)
8078424e00dfd5282026a93996a165fc4079d382169Jon Mason{
8088424e00dfd5282026a93996a165fc4079d382169Jon Mason	struct vxge_hw_device_version *fw_version = &hw_info->fw_version;
8098424e00dfd5282026a93996a165fc4079d382169Jon Mason	struct vxge_hw_device_date *fw_date = &hw_info->fw_date;
8108424e00dfd5282026a93996a165fc4079d382169Jon Mason	struct vxge_hw_device_version *flash_version = &hw_info->flash_version;
8118424e00dfd5282026a93996a165fc4079d382169Jon Mason	struct vxge_hw_device_date *flash_date = &hw_info->flash_date;
8128424e00dfd5282026a93996a165fc4079d382169Jon Mason	u64 data0, data1 = 0, steer_ctrl = 0;
8138424e00dfd5282026a93996a165fc4079d382169Jon Mason	enum vxge_hw_status status;
8148424e00dfd5282026a93996a165fc4079d382169Jon Mason
8158424e00dfd5282026a93996a165fc4079d382169Jon Mason	status = vxge_hw_vpath_fw_api(vpath,
8168424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY,
8178424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
8188424e00dfd5282026a93996a165fc4079d382169Jon Mason			0, &data0, &data1, &steer_ctrl);
8198424e00dfd5282026a93996a165fc4079d382169Jon Mason	if (status != VXGE_HW_OK)
8208424e00dfd5282026a93996a165fc4079d382169Jon Mason		goto exit;
8218424e00dfd5282026a93996a165fc4079d382169Jon Mason
8228424e00dfd5282026a93996a165fc4079d382169Jon Mason	fw_date->day =
8238424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(data0);
8248424e00dfd5282026a93996a165fc4079d382169Jon Mason	fw_date->month =
8258424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(data0);
8268424e00dfd5282026a93996a165fc4079d382169Jon Mason	fw_date->year =
8278424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(data0);
8288424e00dfd5282026a93996a165fc4079d382169Jon Mason
8298424e00dfd5282026a93996a165fc4079d382169Jon Mason	snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d",
8308424e00dfd5282026a93996a165fc4079d382169Jon Mason		 fw_date->month, fw_date->day, fw_date->year);
8318424e00dfd5282026a93996a165fc4079d382169Jon Mason
8328424e00dfd5282026a93996a165fc4079d382169Jon Mason	fw_version->major =
8338424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0);
8348424e00dfd5282026a93996a165fc4079d382169Jon Mason	fw_version->minor =
8358424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0);
8368424e00dfd5282026a93996a165fc4079d382169Jon Mason	fw_version->build =
8378424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0);
8388424e00dfd5282026a93996a165fc4079d382169Jon Mason
8398424e00dfd5282026a93996a165fc4079d382169Jon Mason	snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
8408424e00dfd5282026a93996a165fc4079d382169Jon Mason		 fw_version->major, fw_version->minor, fw_version->build);
8418424e00dfd5282026a93996a165fc4079d382169Jon Mason
8428424e00dfd5282026a93996a165fc4079d382169Jon Mason	flash_date->day =
8438424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data1);
8448424e00dfd5282026a93996a165fc4079d382169Jon Mason	flash_date->month =
8458424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data1);
8468424e00dfd5282026a93996a165fc4079d382169Jon Mason	flash_date->year =
8478424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data1);
8488424e00dfd5282026a93996a165fc4079d382169Jon Mason
8498424e00dfd5282026a93996a165fc4079d382169Jon Mason	snprintf(flash_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d",
8508424e00dfd5282026a93996a165fc4079d382169Jon Mason		 flash_date->month, flash_date->day, flash_date->year);
8518424e00dfd5282026a93996a165fc4079d382169Jon Mason
8528424e00dfd5282026a93996a165fc4079d382169Jon Mason	flash_version->major =
8538424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data1);
8548424e00dfd5282026a93996a165fc4079d382169Jon Mason	flash_version->minor =
8558424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data1);
8568424e00dfd5282026a93996a165fc4079d382169Jon Mason	flash_version->build =
8578424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data1);
8588424e00dfd5282026a93996a165fc4079d382169Jon Mason
8598424e00dfd5282026a93996a165fc4079d382169Jon Mason	snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
8608424e00dfd5282026a93996a165fc4079d382169Jon Mason		 flash_version->major, flash_version->minor,
8618424e00dfd5282026a93996a165fc4079d382169Jon Mason		 flash_version->build);
8628424e00dfd5282026a93996a165fc4079d382169Jon Mason
8638424e00dfd5282026a93996a165fc4079d382169Jon Masonexit:
8648424e00dfd5282026a93996a165fc4079d382169Jon Mason	return status;
8658424e00dfd5282026a93996a165fc4079d382169Jon Mason}
8668424e00dfd5282026a93996a165fc4079d382169Jon Mason
8678424e00dfd5282026a93996a165fc4079d382169Jon Mason/*
8688424e00dfd5282026a93996a165fc4079d382169Jon Mason * __vxge_hw_vpath_card_info_get - Get the serial numbers,
8698424e00dfd5282026a93996a165fc4079d382169Jon Mason * part number and product description.
8708424e00dfd5282026a93996a165fc4079d382169Jon Mason */
8718424e00dfd5282026a93996a165fc4079d382169Jon Masonstatic enum vxge_hw_status
8728424e00dfd5282026a93996a165fc4079d382169Jon Mason__vxge_hw_vpath_card_info_get(struct __vxge_hw_virtualpath *vpath,
8738424e00dfd5282026a93996a165fc4079d382169Jon Mason			      struct vxge_hw_device_hw_info *hw_info)
8748424e00dfd5282026a93996a165fc4079d382169Jon Mason{
8758424e00dfd5282026a93996a165fc4079d382169Jon Mason	enum vxge_hw_status status;
8768424e00dfd5282026a93996a165fc4079d382169Jon Mason	u64 data0, data1 = 0, steer_ctrl = 0;
8778424e00dfd5282026a93996a165fc4079d382169Jon Mason	u8 *serial_number = hw_info->serial_number;
8788424e00dfd5282026a93996a165fc4079d382169Jon Mason	u8 *part_number = hw_info->part_number;
8798424e00dfd5282026a93996a165fc4079d382169Jon Mason	u8 *product_desc = hw_info->product_desc;
8808424e00dfd5282026a93996a165fc4079d382169Jon Mason	u32 i, j = 0;
8818424e00dfd5282026a93996a165fc4079d382169Jon Mason
8828424e00dfd5282026a93996a165fc4079d382169Jon Mason	data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER;
8838424e00dfd5282026a93996a165fc4079d382169Jon Mason
8848424e00dfd5282026a93996a165fc4079d382169Jon Mason	status = vxge_hw_vpath_fw_api(vpath,
8858424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY,
8868424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
8878424e00dfd5282026a93996a165fc4079d382169Jon Mason			0, &data0, &data1, &steer_ctrl);
8888424e00dfd5282026a93996a165fc4079d382169Jon Mason	if (status != VXGE_HW_OK)
8898424e00dfd5282026a93996a165fc4079d382169Jon Mason		return status;
8908424e00dfd5282026a93996a165fc4079d382169Jon Mason
8918424e00dfd5282026a93996a165fc4079d382169Jon Mason	((u64 *)serial_number)[0] = be64_to_cpu(data0);
8928424e00dfd5282026a93996a165fc4079d382169Jon Mason	((u64 *)serial_number)[1] = be64_to_cpu(data1);
8938424e00dfd5282026a93996a165fc4079d382169Jon Mason
8948424e00dfd5282026a93996a165fc4079d382169Jon Mason	data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER;
8958424e00dfd5282026a93996a165fc4079d382169Jon Mason	data1 = steer_ctrl = 0;
8968424e00dfd5282026a93996a165fc4079d382169Jon Mason
8978424e00dfd5282026a93996a165fc4079d382169Jon Mason	status = vxge_hw_vpath_fw_api(vpath,
8988424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY,
8998424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
9008424e00dfd5282026a93996a165fc4079d382169Jon Mason			0, &data0, &data1, &steer_ctrl);
9018424e00dfd5282026a93996a165fc4079d382169Jon Mason	if (status != VXGE_HW_OK)
9028424e00dfd5282026a93996a165fc4079d382169Jon Mason		return status;
9038424e00dfd5282026a93996a165fc4079d382169Jon Mason
9048424e00dfd5282026a93996a165fc4079d382169Jon Mason	((u64 *)part_number)[0] = be64_to_cpu(data0);
9058424e00dfd5282026a93996a165fc4079d382169Jon Mason	((u64 *)part_number)[1] = be64_to_cpu(data1);
9068424e00dfd5282026a93996a165fc4079d382169Jon Mason
9078424e00dfd5282026a93996a165fc4079d382169Jon Mason	for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0;
9088424e00dfd5282026a93996a165fc4079d382169Jon Mason	     i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) {
9098424e00dfd5282026a93996a165fc4079d382169Jon Mason		data0 = i;
9108424e00dfd5282026a93996a165fc4079d382169Jon Mason		data1 = steer_ctrl = 0;
9118424e00dfd5282026a93996a165fc4079d382169Jon Mason
9128424e00dfd5282026a93996a165fc4079d382169Jon Mason		status = vxge_hw_vpath_fw_api(vpath,
9138424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY,
9148424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
9158424e00dfd5282026a93996a165fc4079d382169Jon Mason			0, &data0, &data1, &steer_ctrl);
9168424e00dfd5282026a93996a165fc4079d382169Jon Mason		if (status != VXGE_HW_OK)
9178424e00dfd5282026a93996a165fc4079d382169Jon Mason			return status;
9188424e00dfd5282026a93996a165fc4079d382169Jon Mason
9198424e00dfd5282026a93996a165fc4079d382169Jon Mason		((u64 *)product_desc)[j++] = be64_to_cpu(data0);
9208424e00dfd5282026a93996a165fc4079d382169Jon Mason		((u64 *)product_desc)[j++] = be64_to_cpu(data1);
9218424e00dfd5282026a93996a165fc4079d382169Jon Mason	}
9228424e00dfd5282026a93996a165fc4079d382169Jon Mason
9238424e00dfd5282026a93996a165fc4079d382169Jon Mason	return status;
9248424e00dfd5282026a93996a165fc4079d382169Jon Mason}
9258424e00dfd5282026a93996a165fc4079d382169Jon Mason
9268424e00dfd5282026a93996a165fc4079d382169Jon Mason/*
9278424e00dfd5282026a93996a165fc4079d382169Jon Mason * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode
9288424e00dfd5282026a93996a165fc4079d382169Jon Mason * Returns pci function mode
9298424e00dfd5282026a93996a165fc4079d382169Jon Mason */
930c3150eac9f2e5f770b09d371f7716540219a46f6Jon Masonstatic enum vxge_hw_status
931c3150eac9f2e5f770b09d371f7716540219a46f6Jon Mason__vxge_hw_vpath_pci_func_mode_get(struct __vxge_hw_virtualpath *vpath,
932c3150eac9f2e5f770b09d371f7716540219a46f6Jon Mason				  struct vxge_hw_device_hw_info *hw_info)
9338424e00dfd5282026a93996a165fc4079d382169Jon Mason{
9348424e00dfd5282026a93996a165fc4079d382169Jon Mason	u64 data0, data1 = 0, steer_ctrl = 0;
9358424e00dfd5282026a93996a165fc4079d382169Jon Mason	enum vxge_hw_status status;
9368424e00dfd5282026a93996a165fc4079d382169Jon Mason
937ca3e3b8fae982400dacbbf19f3112cc84e51d46aJon Mason	data0 = 0;
9388424e00dfd5282026a93996a165fc4079d382169Jon Mason
9398424e00dfd5282026a93996a165fc4079d382169Jon Mason	status = vxge_hw_vpath_fw_api(vpath,
940ca3e3b8fae982400dacbbf19f3112cc84e51d46aJon Mason			VXGE_HW_FW_API_GET_FUNC_MODE,
9418424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
9428424e00dfd5282026a93996a165fc4079d382169Jon Mason			0, &data0, &data1, &steer_ctrl);
943c3150eac9f2e5f770b09d371f7716540219a46f6Jon Mason	if (status != VXGE_HW_OK)
944c3150eac9f2e5f770b09d371f7716540219a46f6Jon Mason		return status;
9458424e00dfd5282026a93996a165fc4079d382169Jon Mason
946ca3e3b8fae982400dacbbf19f3112cc84e51d46aJon Mason	hw_info->function_mode = VXGE_HW_GET_FUNC_MODE_VAL(data0);
947c3150eac9f2e5f770b09d371f7716540219a46f6Jon Mason	return status;
9488424e00dfd5282026a93996a165fc4079d382169Jon Mason}
9498424e00dfd5282026a93996a165fc4079d382169Jon Mason
9508424e00dfd5282026a93996a165fc4079d382169Jon Mason/*
9518424e00dfd5282026a93996a165fc4079d382169Jon Mason * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath
9528424e00dfd5282026a93996a165fc4079d382169Jon Mason *               from MAC address table.
9538424e00dfd5282026a93996a165fc4079d382169Jon Mason */
9548424e00dfd5282026a93996a165fc4079d382169Jon Masonstatic enum vxge_hw_status
9558424e00dfd5282026a93996a165fc4079d382169Jon Mason__vxge_hw_vpath_addr_get(struct __vxge_hw_virtualpath *vpath,
9568424e00dfd5282026a93996a165fc4079d382169Jon Mason			 u8 *macaddr, u8 *macaddr_mask)
9578424e00dfd5282026a93996a165fc4079d382169Jon Mason{
9588424e00dfd5282026a93996a165fc4079d382169Jon Mason	u64 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY,
9598424e00dfd5282026a93996a165fc4079d382169Jon Mason	    data0 = 0, data1 = 0, steer_ctrl = 0;
9608424e00dfd5282026a93996a165fc4079d382169Jon Mason	enum vxge_hw_status status;
9618424e00dfd5282026a93996a165fc4079d382169Jon Mason	int i;
9628424e00dfd5282026a93996a165fc4079d382169Jon Mason
9638424e00dfd5282026a93996a165fc4079d382169Jon Mason	do {
9648424e00dfd5282026a93996a165fc4079d382169Jon Mason		status = vxge_hw_vpath_fw_api(vpath, action,
9658424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA,
9668424e00dfd5282026a93996a165fc4079d382169Jon Mason			0, &data0, &data1, &steer_ctrl);
9678424e00dfd5282026a93996a165fc4079d382169Jon Mason		if (status != VXGE_HW_OK)
9688424e00dfd5282026a93996a165fc4079d382169Jon Mason			goto exit;
9698424e00dfd5282026a93996a165fc4079d382169Jon Mason
9708424e00dfd5282026a93996a165fc4079d382169Jon Mason		data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data0);
9718424e00dfd5282026a93996a165fc4079d382169Jon Mason		data1 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(
9728424e00dfd5282026a93996a165fc4079d382169Jon Mason									data1);
9738424e00dfd5282026a93996a165fc4079d382169Jon Mason
9748424e00dfd5282026a93996a165fc4079d382169Jon Mason		for (i = ETH_ALEN; i > 0; i--) {
9758424e00dfd5282026a93996a165fc4079d382169Jon Mason			macaddr[i - 1] = (u8) (data0 & 0xFF);
9768424e00dfd5282026a93996a165fc4079d382169Jon Mason			data0 >>= 8;
9778424e00dfd5282026a93996a165fc4079d382169Jon Mason
9788424e00dfd5282026a93996a165fc4079d382169Jon Mason			macaddr_mask[i - 1] = (u8) (data1 & 0xFF);
9798424e00dfd5282026a93996a165fc4079d382169Jon Mason			data1 >>= 8;
9808424e00dfd5282026a93996a165fc4079d382169Jon Mason		}
9818424e00dfd5282026a93996a165fc4079d382169Jon Mason
9828424e00dfd5282026a93996a165fc4079d382169Jon Mason		action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY;
9838424e00dfd5282026a93996a165fc4079d382169Jon Mason		data0 = 0, data1 = 0, steer_ctrl = 0;
9848424e00dfd5282026a93996a165fc4079d382169Jon Mason
9858424e00dfd5282026a93996a165fc4079d382169Jon Mason	} while (!is_valid_ether_addr(macaddr));
9868424e00dfd5282026a93996a165fc4079d382169Jon Masonexit:
9878424e00dfd5282026a93996a165fc4079d382169Jon Mason	return status;
9888424e00dfd5282026a93996a165fc4079d382169Jon Mason}
9898424e00dfd5282026a93996a165fc4079d382169Jon Mason
99040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/**
99140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_hw_info_get - Get the hw information
99240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Returns the vpath mask that has the bits set for each vpath allocated
9939f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason * for the driver, FW version information, and the first mac address for
99440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * each vpath
99540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
99640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status __devinit
99740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_device_hw_info_get(void __iomem *bar0,
99840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			   struct vxge_hw_device_hw_info *hw_info)
99940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
100040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i;
100140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
100240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_toc_reg __iomem *toc;
100340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_mrpcim_reg __iomem *mrpcim_reg;
100440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_common_reg __iomem *common_reg;
100540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg;
100640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status;
10078424e00dfd5282026a93996a165fc4079d382169Jon Mason	struct __vxge_hw_virtualpath vpath;
100840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
100940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	memset(hw_info, 0, sizeof(struct vxge_hw_device_hw_info));
101040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
101140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	toc = __vxge_hw_device_toc_get(bar0);
101240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (toc == NULL) {
101340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_CRITICAL;
101440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
101540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
101640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
101740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&toc->toc_common_pointer);
101843d620c82985b19008d87a437b4cf83f356264f7Joe Perches	common_reg = bar0 + val64;
101940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
102040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_device_vpath_reset_in_prog_check(
102140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		(u64 __iomem *)&common_reg->vpath_rst_in_prog);
102240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
102340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
102440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
102540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hw_info->vpath_mask = readq(&common_reg->vpath_assignments);
102640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
102740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&common_reg->host_type_assignments);
102840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
102940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hw_info->host_type =
103040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	   (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
103140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
103240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
103340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
103440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			continue;
103540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
103640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&toc->toc_vpmgmt_pointer[i]);
103740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
103843d620c82985b19008d87a437b4cf83f356264f7Joe Perches		vpmgmt_reg = bar0 + val64;
103940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
10408424e00dfd5282026a93996a165fc4079d382169Jon Mason		hw_info->func_id = __vxge_hw_vpath_func_id_get(vpmgmt_reg);
104140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (__vxge_hw_device_access_rights_get(hw_info->host_type,
104240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			hw_info->func_id) &
104340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM) {
104440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
104540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 = readq(&toc->toc_mrpcim_pointer);
104640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
104743d620c82985b19008d87a437b4cf83f356264f7Joe Perches			mrpcim_reg = bar0 + val64;
104840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
104940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			writeq(0, &mrpcim_reg->xgmac_gen_fw_memo_mask);
105040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			wmb();
105140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
105240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
105340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&toc->toc_vpath_pointer[i]);
105440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
10559f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason		spin_lock_init(&vpath.lock);
105643d620c82985b19008d87a437b4cf83f356264f7Joe Perches		vpath.vp_reg = bar0 + val64;
10579f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason		vpath.vp_open = VXGE_HW_VP_NOT_OPEN;
105840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
1059c3150eac9f2e5f770b09d371f7716540219a46f6Jon Mason		status = __vxge_hw_vpath_pci_func_mode_get(&vpath, hw_info);
1060c3150eac9f2e5f770b09d371f7716540219a46f6Jon Mason		if (status != VXGE_HW_OK)
1061c3150eac9f2e5f770b09d371f7716540219a46f6Jon Mason			goto exit;
106240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
10638424e00dfd5282026a93996a165fc4079d382169Jon Mason		status = __vxge_hw_vpath_fw_ver_get(&vpath, hw_info);
106440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (status != VXGE_HW_OK)
106540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
106640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
10678424e00dfd5282026a93996a165fc4079d382169Jon Mason		status = __vxge_hw_vpath_card_info_get(&vpath, hw_info);
106840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (status != VXGE_HW_OK)
106940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
107040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
107140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
107240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
107340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
107440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
107540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
107640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			continue;
107740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
107840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&toc->toc_vpath_pointer[i]);
107943d620c82985b19008d87a437b4cf83f356264f7Joe Perches		vpath.vp_reg = bar0 + val64;
10809f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason		vpath.vp_open = VXGE_HW_VP_NOT_OPEN;
108140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
10828424e00dfd5282026a93996a165fc4079d382169Jon Mason		status =  __vxge_hw_vpath_addr_get(&vpath,
108340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				hw_info->mac_addrs[i],
108440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				hw_info->mac_addr_masks[i]);
108540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (status != VXGE_HW_OK)
108640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
108740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
108840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
108940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
109040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
109140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
109240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
1093528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_blockpool_destroy - Deallocates the block pool
1094528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
1095528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool)
1096528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
1097528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_device *hldev;
1098528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct list_head *p, *n;
1099528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u16 ret;
1100528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1101528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (blockpool == NULL) {
1102528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		ret = 1;
1103528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
1104528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1105528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1106528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hldev = blockpool->hldev;
1107528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1108528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	list_for_each_safe(p, n, &blockpool->free_block_list) {
1109528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		pci_unmap_single(hldev->pdev,
1110528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
1111528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			((struct __vxge_hw_blockpool_entry *)p)->length,
1112528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			PCI_DMA_BIDIRECTIONAL);
1113528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1114528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_os_dma_free(hldev->pdev,
1115528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			((struct __vxge_hw_blockpool_entry *)p)->memblock,
1116528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&((struct __vxge_hw_blockpool_entry *)p)->acc_handle);
1117528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1118528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
1119528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		kfree(p);
1120528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		blockpool->pool_size--;
1121528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1122528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1123528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	list_for_each_safe(p, n, &blockpool->free_entry_list) {
1124528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
1125528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		kfree((void *)p);
1126528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1127528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ret = 0;
1128528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
1129528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return;
1130528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
1131528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1132528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
1133528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_blockpool_create - Create block pool
1134528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
1135528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
1136528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev,
1137528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			   struct __vxge_hw_blockpool *blockpool,
1138528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			   u32 pool_size,
1139528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			   u32 pool_max)
1140528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
1141528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 i;
1142528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_blockpool_entry *entry = NULL;
1143528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	void *memblock;
1144528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	dma_addr_t dma_addr;
1145528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct pci_dev *dma_handle;
1146528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct pci_dev *acc_handle;
1147528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
1148528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1149528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (blockpool == NULL) {
1150528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_FAIL;
1151528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto blockpool_create_exit;
1152528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1153528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1154528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool->hldev = hldev;
1155528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool->block_size = VXGE_HW_BLOCK_SIZE;
1156528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool->pool_size = 0;
1157528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool->pool_max = pool_max;
1158528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool->req_out = 0;
1159528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1160528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	INIT_LIST_HEAD(&blockpool->free_block_list);
1161528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	INIT_LIST_HEAD(&blockpool->free_entry_list);
1162528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1163528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	for (i = 0; i < pool_size + pool_max; i++) {
1164528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		entry = kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
1165528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				GFP_KERNEL);
1166528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (entry == NULL) {
1167528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			__vxge_hw_blockpool_destroy(blockpool);
1168528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			status = VXGE_HW_ERR_OUT_OF_MEMORY;
1169528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto blockpool_create_exit;
1170528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
1171528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		list_add(&entry->item, &blockpool->free_entry_list);
1172528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1173528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1174528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	for (i = 0; i < pool_size; i++) {
1175528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		memblock = vxge_os_dma_malloc(
1176528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				hldev->pdev,
1177528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				VXGE_HW_BLOCK_SIZE,
1178528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				&dma_handle,
1179528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				&acc_handle);
1180528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (memblock == NULL) {
1181528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			__vxge_hw_blockpool_destroy(blockpool);
1182528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			status = VXGE_HW_ERR_OUT_OF_MEMORY;
1183528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto blockpool_create_exit;
1184528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
1185528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1186528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		dma_addr = pci_map_single(hldev->pdev, memblock,
1187528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				VXGE_HW_BLOCK_SIZE, PCI_DMA_BIDIRECTIONAL);
1188528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (unlikely(pci_dma_mapping_error(hldev->pdev,
1189528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				dma_addr))) {
1190528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			vxge_os_dma_free(hldev->pdev, memblock, &acc_handle);
1191528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			__vxge_hw_blockpool_destroy(blockpool);
1192528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			status = VXGE_HW_ERR_OUT_OF_MEMORY;
1193528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto blockpool_create_exit;
1194528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
1195528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1196528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (!list_empty(&blockpool->free_entry_list))
1197528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry = (struct __vxge_hw_blockpool_entry *)
1198528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				list_first_entry(&blockpool->free_entry_list,
1199528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					struct __vxge_hw_blockpool_entry,
1200528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					item);
1201528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1202528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (entry == NULL)
1203528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry =
1204528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			    kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
1205528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					GFP_KERNEL);
1206528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (entry != NULL) {
1207528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			list_del(&entry->item);
1208528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry->length = VXGE_HW_BLOCK_SIZE;
1209528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry->memblock = memblock;
1210528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry->dma_addr = dma_addr;
1211528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry->acc_handle = acc_handle;
1212528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry->dma_handle = dma_handle;
1213528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			list_add(&entry->item,
1214528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					  &blockpool->free_block_list);
1215528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			blockpool->pool_size++;
1216528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		} else {
1217528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			__vxge_hw_blockpool_destroy(blockpool);
1218528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			status = VXGE_HW_ERR_OUT_OF_MEMORY;
1219528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto blockpool_create_exit;
1220528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
1221528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1222528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1223528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonblockpool_create_exit:
1224528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
1225528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
1226528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1227528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
1228528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_device_fifo_config_check - Check fifo configuration.
1229528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Check the fifo configuration
1230528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
1231528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
1232528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config)
1233528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
1234528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) ||
1235528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	    (fifo_config->fifo_blocks > VXGE_HW_MAX_FIFO_BLOCKS))
1236528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		return VXGE_HW_BADCFG_FIFO_BLOCKS;
1237528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1238528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return VXGE_HW_OK;
1239528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
1240528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1241528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
1242528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_device_vpath_config_check - Check vpath configuration.
1243528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Check the vpath configuration
1244528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
1245528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
1246528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config)
1247528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
1248528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status;
1249528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1250528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if ((vp_config->min_bandwidth < VXGE_HW_VPATH_BANDWIDTH_MIN) ||
1251528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	    (vp_config->min_bandwidth >	VXGE_HW_VPATH_BANDWIDTH_MAX))
1252528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		return VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH;
1253528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1254528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_device_fifo_config_check(&vp_config->fifo);
1255528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
1256528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		return status;
1257528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1258528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if ((vp_config->mtu != VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) &&
1259528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		((vp_config->mtu < VXGE_HW_VPATH_MIN_INITIAL_MTU) ||
1260528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(vp_config->mtu > VXGE_HW_VPATH_MAX_INITIAL_MTU)))
1261528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		return VXGE_HW_BADCFG_VPATH_MTU;
1262528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1263528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if ((vp_config->rpa_strip_vlan_tag !=
1264528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) &&
1265528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(vp_config->rpa_strip_vlan_tag !=
1266528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) &&
1267528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(vp_config->rpa_strip_vlan_tag !=
1268528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE))
1269528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		return VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG;
1270528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1271528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return VXGE_HW_OK;
1272528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
1273528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1274528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
1275528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_device_config_check - Check device configuration.
1276528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Check the device configuration
1277528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
1278528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
1279528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config)
1280528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
1281528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 i;
1282528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status;
1283528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1284528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if ((new_config->intr_mode != VXGE_HW_INTR_MODE_IRQLINE) &&
1285528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	    (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX) &&
1286528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	    (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) &&
1287528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	    (new_config->intr_mode != VXGE_HW_INTR_MODE_DEF))
1288528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		return VXGE_HW_BADCFG_INTR_MODE;
1289528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1290528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if ((new_config->rts_mac_en != VXGE_HW_RTS_MAC_DISABLE) &&
1291528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	    (new_config->rts_mac_en != VXGE_HW_RTS_MAC_ENABLE))
1292528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		return VXGE_HW_BADCFG_RTS_MAC_EN;
1293528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1294528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
1295528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = __vxge_hw_device_vpath_config_check(
1296528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				&new_config->vp_config[i]);
1297528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (status != VXGE_HW_OK)
1298528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			return status;
1299528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1300528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1301528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return VXGE_HW_OK;
1302528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
1303528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1304528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
1305528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_device_initialize - Initialize Titan device.
1306528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Initialize Titan device. Note that all the arguments of this public API
1307528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * are 'IN', including @hldev. Driver cooperates with
130840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * OS to find new Titan device, locate its PCI and memory spaces.
130940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa *
131040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * When done, the driver allocates sizeof(struct __vxge_hw_device) bytes for HW
131140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * to enable the latter to perform Titan hardware initialization.
131240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
131340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status __devinit
131440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_device_initialize(
131540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_device **devh,
131640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_device_attr *attr,
131740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_device_config *device_config)
131840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
131940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i;
132040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 nblocks = 0;
132140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_device *hldev = NULL;
132240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
132340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
132440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_device_config_check(device_config);
132540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
132640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
132740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
1328e80be0b0ee307a2801e57cf36333d3d659e4bcc6Joe Perches	hldev = vzalloc(sizeof(struct __vxge_hw_device));
132940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hldev == NULL) {
133040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
133140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
133240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
133340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
133440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->magic = VXGE_HW_DEVICE_MAGIC;
133540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
133640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_ALL);
133740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
133840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* apply config */
133940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	memcpy(&hldev->config, device_config,
134040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		sizeof(struct vxge_hw_device_config));
134140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
134240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->bar0 = attr->bar0;
134340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->pdev = attr->pdev;
134440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
1345956a206620fa048afdcd8ab714ac3cf6a9e884b7stephen hemminger	hldev->uld_callbacks = attr->uld_callbacks;
134640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
134740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	__vxge_hw_device_pci_e_init(hldev);
134840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
134940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_device_reg_addr_get(hldev);
1350aaffbd9f7734721bf42d246eb31fc79d7adb2cb9Sreenivasa Honnur	if (status != VXGE_HW_OK) {
1351aaffbd9f7734721bf42d246eb31fc79d7adb2cb9Sreenivasa Honnur		vfree(hldev);
135240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
1353aaffbd9f7734721bf42d246eb31fc79d7adb2cb9Sreenivasa Honnur	}
135440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
135540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	__vxge_hw_device_host_info_get(hldev);
135640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
135740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* Incrementing for stats blocks */
135840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	nblocks++;
135940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
136040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
136140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (!(hldev->vpath_assignments & vxge_mBIT(i)))
136240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			continue;
136340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
136440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (device_config->vp_config[i].ring.enable ==
136540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RING_ENABLE)
136640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			nblocks += device_config->vp_config[i].ring.ring_blocks;
136740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
136840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (device_config->vp_config[i].fifo.enable ==
136940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_FIFO_ENABLE)
137040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			nblocks += device_config->vp_config[i].fifo.fifo_blocks;
137140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		nblocks++;
137240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
137340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
137440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (__vxge_hw_blockpool_create(hldev,
137540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		&hldev->block_pool,
137640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->dma_blockpool_initial + nblocks,
137740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->dma_blockpool_max + nblocks) != VXGE_HW_OK) {
137840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
137940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		vxge_hw_device_terminate(hldev);
138040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
138140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
138240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
138340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
138440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_device_initialize(hldev);
138540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK) {
138640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		vxge_hw_device_terminate(hldev);
138740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
138840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
138940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
139040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	*devh = hldev;
139140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
139240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
139340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
139440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
139540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
139640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_terminate - Terminate Titan device.
139740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Terminate HW device.
139840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
139940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavoid
140040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_device_terminate(struct __vxge_hw_device *hldev)
140140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
140240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vxge_assert(hldev->magic == VXGE_HW_DEVICE_MAGIC);
140340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
140440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->magic = VXGE_HW_DEVICE_DEAD;
140540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	__vxge_hw_blockpool_destroy(&hldev->block_pool);
140640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vfree(hldev);
140740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
140840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
140940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
1410528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_vpath_stats_access - Get the statistics from the given location
1411528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason *                           and offset and perform an operation
141240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
1413528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
1414528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath,
1415528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			     u32 operation, u32 offset, u64 *stat)
141640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
1417528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u64 val64;
141840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
1419528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct vxge_hw_vpath_reg __iomem *vp_reg;
142040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
1421528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
1422528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
1423528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto vpath_stats_access_exit;
1424528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
142540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
1426528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp_reg = vpath->vp_reg;
142740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
1428528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 =  VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(operation) |
1429528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		 VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE |
1430528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		 VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(offset);
143140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
1432528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_pio_mem_write64(val64,
1433528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				&vp_reg->xmac_stats_access_cmd,
1434528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE,
1435528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				vpath->hldev->config.device_poll_millis);
1436528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ))
1437528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		*stat = readq(&vp_reg->xmac_stats_access_data);
1438528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	else
1439528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		*stat = 0;
144040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
1441528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvpath_stats_access_exit:
144240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
144340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
144440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
144540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
1446528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_vpath_xmac_tx_stats_get - Get the TX Statistics of a vpath
1447528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
1448528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
1449528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_vpath_xmac_tx_stats_get(struct __vxge_hw_virtualpath *vpath,
1450528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats)
1451528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
1452528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u64 *val64;
1453528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	int i;
1454528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 offset = VXGE_HW_STATS_VPATH_TX_OFFSET;
1455528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
1456528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1457528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = (u64 *)vpath_tx_stats;
1458528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1459528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
1460528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
1461528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
1462528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1463528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1464528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_tx_stats) / 8; i++) {
1465528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = __vxge_hw_vpath_stats_access(vpath,
1466528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					VXGE_HW_STATS_OP_READ,
1467528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					offset, val64);
1468528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (status != VXGE_HW_OK)
1469528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto exit;
1470528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		offset++;
1471528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64++;
1472528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1473528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
1474528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
1475528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
1476528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1477528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
1478528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_vpath_xmac_rx_stats_get - Get the RX Statistics of a vpath
1479528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
1480528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
1481528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath,
1482528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats)
1483528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
1484528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u64 *val64;
1485528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
1486528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	int i;
1487528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 offset = VXGE_HW_STATS_VPATH_RX_OFFSET;
1488528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = (u64 *) vpath_rx_stats;
1489528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1490528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
1491528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
1492528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
1493528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1494528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_rx_stats) / 8; i++) {
1495528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = __vxge_hw_vpath_stats_access(vpath,
1496528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					VXGE_HW_STATS_OP_READ,
1497528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					offset >> 3, val64);
1498528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (status != VXGE_HW_OK)
1499528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto exit;
1500528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1501528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		offset += 8;
1502528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64++;
1503528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1504528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
1505528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
1506528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
1507528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1508528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
1509528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_vpath_stats_get - Get the vpath hw statistics.
1510528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
1511528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
1512528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_vpath_stats_get(struct __vxge_hw_virtualpath *vpath,
1513528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			  struct vxge_hw_vpath_stats_hw_info *hw_stats)
1514528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
1515528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u64 val64;
1516528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
1517528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct vxge_hw_vpath_reg __iomem *vp_reg;
1518528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1519528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
1520528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
1521528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
1522528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1523528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp_reg = vpath->vp_reg;
1524528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1525528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_debug_stats0);
1526528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->ini_num_mwr_sent =
1527528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u32)VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(val64);
1528528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1529528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_debug_stats1);
1530528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->ini_num_mrd_sent =
1531528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u32)VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(val64);
1532528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1533528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_debug_stats2);
1534528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->ini_num_cpl_rcvd =
1535528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u32)VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(val64);
1536528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1537528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_debug_stats3);
1538528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->ini_num_mwr_byte_sent =
1539528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(val64);
1540528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1541528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_debug_stats4);
1542528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->ini_num_cpl_byte_rcvd =
1543528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(val64);
1544528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1545528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_debug_stats5);
1546528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->wrcrdtarb_xoff =
1547528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u32)VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(val64);
1548528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1549528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_debug_stats6);
1550528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->rdcrdtarb_xoff =
1551528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u32)VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(val64);
1552528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1553528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_genstats_count01);
1554528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->vpath_genstats_count0 =
1555528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	(u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0(
1556528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64);
1557528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1558528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_genstats_count01);
1559528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->vpath_genstats_count1 =
1560528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	(u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1(
1561528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64);
1562528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1563528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_genstats_count23);
1564528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->vpath_genstats_count2 =
1565528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	(u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2(
1566528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64);
1567528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1568528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_genstats_count01);
1569528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->vpath_genstats_count3 =
1570528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	(u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3(
1571528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64);
1572528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1573528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_genstats_count4);
1574528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->vpath_genstats_count4 =
1575528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	(u32)VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4(
1576528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64);
1577528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1578528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->vpath_genstats_count5);
1579528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->vpath_genstats_count5 =
1580528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	(u32)VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5(
1581528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64);
1582528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1583528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_xmac_tx_stats_get(vpath, &hw_stats->tx_stats);
1584528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
1585528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
1586528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1587528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_xmac_rx_stats_get(vpath, &hw_stats->rx_stats);
1588528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
1589528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
1590528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1591528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	VXGE_HW_VPATH_STATS_PIO_READ(
1592528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET);
1593528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1594528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->prog_event_vnum0 =
1595528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			(u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(val64);
1596528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1597528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->prog_event_vnum1 =
1598528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			(u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(val64);
1599528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1600528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	VXGE_HW_VPATH_STATS_PIO_READ(
1601528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET);
1602528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1603528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->prog_event_vnum2 =
1604528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			(u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(val64);
1605528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1606528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->prog_event_vnum3 =
1607528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			(u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(val64);
1608528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1609528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->rx_multi_cast_stats);
1610528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->rx_multi_cast_frame_discard =
1611528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u16)VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(val64);
1612528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1613528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->rx_frm_transferred);
1614528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->rx_frm_transferred =
1615528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u32)VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(val64);
1616528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1617528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->rxd_returned);
1618528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->rxd_returned =
1619528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u16)VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(val64);
1620528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1621528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->dbg_stats_rx_mpa);
1622528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->rx_mpa_len_fail_frms =
1623528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u16)VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(val64);
1624528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->rx_mpa_mrk_fail_frms =
1625528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u16)VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(val64);
1626528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->rx_mpa_crc_fail_frms =
1627528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u16)VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(val64);
1628528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1629528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->dbg_stats_rx_fau);
1630528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->rx_permitted_frms =
1631528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(val64);
1632528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->rx_vp_reset_discarded_frms =
1633528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	(u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val64);
1634528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->rx_wol_frms =
1635528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(val64);
1636528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1637528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->tx_vp_reset_discarded_frms);
1638528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hw_stats->tx_vp_reset_discarded_frms =
1639528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	(u16)VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS(
1640528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64);
1641528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
1642528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
1643528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
1644528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1645528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
1646528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_device_stats_get - Get the device hw statistics.
1647528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Returns the vpath h/w stats for the device.
1648528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
1649528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonenum vxge_hw_status
1650528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvxge_hw_device_stats_get(struct __vxge_hw_device *hldev,
1651528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			struct vxge_hw_device_stats_hw_info *hw_stats)
1652528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
1653528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 i;
1654528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
1655528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1656528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
1657528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (!(hldev->vpaths_deployed & vxge_mBIT(i)) ||
1658528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			(hldev->virtual_paths[i].vp_open ==
1659528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				VXGE_HW_VP_NOT_OPEN))
1660528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			continue;
1661528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1662528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		memcpy(hldev->virtual_paths[i].hw_stats_sav,
1663528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				hldev->virtual_paths[i].hw_stats,
1664528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				sizeof(struct vxge_hw_vpath_stats_hw_info));
1665528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1666528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = __vxge_hw_vpath_stats_get(
1667528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&hldev->virtual_paths[i],
1668528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			hldev->virtual_paths[i].hw_stats);
1669528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
1670528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1671528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	memcpy(hw_stats, &hldev->stats.hw_dev_info_stats,
1672528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			sizeof(struct vxge_hw_device_stats_hw_info));
1673528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1674528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
1675528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
1676528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
1677528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
1678528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_driver_stats_get - Get the device sw statistics.
1679528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Returns the vpath s/w stats for the device.
168040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
168140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status vxge_hw_driver_stats_get(
168240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			struct __vxge_hw_device *hldev,
168340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			struct vxge_hw_device_stats_sw_info *sw_stats)
168440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
168540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
168640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
168740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	memcpy(sw_stats, &hldev->stats.sw_dev_info_stats,
168840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		sizeof(struct vxge_hw_device_stats_sw_info));
168940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
169040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
169140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
169240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
169340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
169440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_mrpcim_stats_access - Access the statistics from the given location
169540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa *                           and offset and perform an operation
169640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Get the statistics from the given location and offset.
169740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
169840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status
169940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_mrpcim_stats_access(struct __vxge_hw_device *hldev,
170040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			    u32 operation, u32 location, u32 offset, u64 *stat)
170140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
170240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
170340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
170440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
170592cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur	status = __vxge_hw_device_is_privilaged(hldev->host_type,
170692cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur			hldev->func_id);
170740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
170840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
170940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
171040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = VXGE_HW_XMAC_STATS_SYS_CMD_OP(operation) |
171140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		VXGE_HW_XMAC_STATS_SYS_CMD_STROBE |
171240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		VXGE_HW_XMAC_STATS_SYS_CMD_LOC_SEL(location) |
171340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		VXGE_HW_XMAC_STATS_SYS_CMD_OFFSET_SEL(offset);
171440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
171540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_pio_mem_write64(val64,
171640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				&hldev->mrpcim_reg->xmac_stats_sys_cmd,
171740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_XMAC_STATS_SYS_CMD_STROBE,
171840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				hldev->config.device_poll_millis);
171940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
172040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ))
172140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*stat = readq(&hldev->mrpcim_reg->xmac_stats_sys_data);
172240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	else
172340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*stat = 0;
172440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
172540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
172640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
172740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
172840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
172940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_xmac_aggr_stats_get - Get the Statistics on aggregate port
173040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Get the Statistics on aggregate port
173140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
173242821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
173340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_device_xmac_aggr_stats_get(struct __vxge_hw_device *hldev, u32 port,
173440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				   struct vxge_hw_xmac_aggr_stats *aggr_stats)
173540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
173640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 *val64;
173740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	int i;
173840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 offset = VXGE_HW_STATS_AGGRn_OFFSET;
173940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
174040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
174140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = (u64 *)aggr_stats;
174240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
174392cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur	status = __vxge_hw_device_is_privilaged(hldev->host_type,
174492cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur			hldev->func_id);
174540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
174640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
174740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
174840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < sizeof(struct vxge_hw_xmac_aggr_stats) / 8; i++) {
174940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = vxge_hw_mrpcim_stats_access(hldev,
175040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					VXGE_HW_STATS_OP_READ,
175140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					VXGE_HW_STATS_LOC_AGGR,
175240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					((offset + (104 * port)) >> 3), val64);
175340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (status != VXGE_HW_OK)
175440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
175540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
175640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		offset += 8;
175740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64++;
175840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
175940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
176040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
176140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
176240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
176340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
176440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_xmac_port_stats_get - Get the Statistics on a port
176540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Get the Statistics on port
176640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
176742821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
176840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_device_xmac_port_stats_get(struct __vxge_hw_device *hldev, u32 port,
176940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				   struct vxge_hw_xmac_port_stats *port_stats)
177040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
177140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 *val64;
177240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
177340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	int i;
177440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 offset = 0x0;
177540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = (u64 *) port_stats;
177640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
177792cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur	status = __vxge_hw_device_is_privilaged(hldev->host_type,
177892cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur			hldev->func_id);
177940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
178040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
178140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
178240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < sizeof(struct vxge_hw_xmac_port_stats) / 8; i++) {
178340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = vxge_hw_mrpcim_stats_access(hldev,
178440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					VXGE_HW_STATS_OP_READ,
178540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					VXGE_HW_STATS_LOC_AGGR,
178640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					((offset + (608 * port)) >> 3), val64);
178740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (status != VXGE_HW_OK)
178840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
178940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
179040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		offset += 8;
179140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64++;
179240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
179340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
179440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
179540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
179640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
179740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
179840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
179940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_xmac_stats_get - Get the XMAC Statistics
180040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Get the XMAC Statistics
180140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
180240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status
180340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_device_xmac_stats_get(struct __vxge_hw_device *hldev,
180440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			      struct vxge_hw_xmac_stats *xmac_stats)
180540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
180640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
180740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i;
180840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
180940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = vxge_hw_device_xmac_aggr_stats_get(hldev,
181040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					0, &xmac_stats->aggr_stats[0]);
181140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
181240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
181340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
181440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = vxge_hw_device_xmac_aggr_stats_get(hldev,
181540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				1, &xmac_stats->aggr_stats[1]);
181640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
181740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
181840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
181940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i <= VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) {
182040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
182140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = vxge_hw_device_xmac_port_stats_get(hldev,
182240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					i, &xmac_stats->port_stats[i]);
182340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (status != VXGE_HW_OK)
182440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
182540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
182640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
182740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
182840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
182940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
183040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			continue;
183140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
183240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = __vxge_hw_vpath_xmac_tx_stats_get(
183340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					&hldev->virtual_paths[i],
183440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					&xmac_stats->vpath_tx_stats[i]);
183540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (status != VXGE_HW_OK)
183640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
183740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
183840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = __vxge_hw_vpath_xmac_rx_stats_get(
183940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					&hldev->virtual_paths[i],
184040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					&xmac_stats->vpath_rx_stats[i]);
184140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (status != VXGE_HW_OK)
184240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
184340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
184440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
184540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
184640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
184740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
184840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
184940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_debug_set - Set the debug module, level and timestamp
185040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine is used to dynamically change the debug output
185140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
185240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavoid vxge_hw_device_debug_set(struct __vxge_hw_device *hldev,
185340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			      enum vxge_debug_level level, u32 mask)
185440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
185540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hldev == NULL)
185640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		return;
185740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
185840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#if defined(VXGE_DEBUG_TRACE_MASK) || \
185940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	defined(VXGE_DEBUG_ERR_MASK)
186040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->debug_module_mask = mask;
186140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->debug_level = level;
186240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#endif
186340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
186440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#if defined(VXGE_DEBUG_ERR_MASK)
186540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->level_err = level & VXGE_ERR;
186640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#endif
186740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
186840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#if defined(VXGE_DEBUG_TRACE_MASK)
186940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	hldev->level_trace = level & VXGE_TRACE;
187040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#endif
187140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
187240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
187340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
187440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_error_level_get - Get the error level
187540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine returns the current error level set
187640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
187740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepau32 vxge_hw_device_error_level_get(struct __vxge_hw_device *hldev)
187840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
187940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#if defined(VXGE_DEBUG_ERR_MASK)
188040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hldev == NULL)
188140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		return VXGE_ERR;
188240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	else
188340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		return hldev->level_err;
188440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#else
188540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return 0;
188640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#endif
188740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
188840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
188940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
189040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_trace_level_get - Get the trace level
189140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine returns the current trace level set
189240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
189340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepau32 vxge_hw_device_trace_level_get(struct __vxge_hw_device *hldev)
189440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
189540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#if defined(VXGE_DEBUG_TRACE_MASK)
189640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hldev == NULL)
189740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		return VXGE_TRACE;
189840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	else
189940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		return hldev->level_trace;
190040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#else
190140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return 0;
190240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#endif
190340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
190440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
190540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
190640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_getpause_data -Pause frame frame generation and reception.
190740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Returns the Pause frame generation and reception capability of the NIC.
190840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
190940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status vxge_hw_device_getpause_data(struct __vxge_hw_device *hldev,
191040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						 u32 port, u32 *tx, u32 *rx)
191140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
191240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
191340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
191440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
191540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
191640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_DEVICE;
191740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
191840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
191940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
192040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (port > VXGE_HW_MAC_MAX_MAC_PORT_ID) {
192140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_PORT;
192240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
192340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
192440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
192540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (!(hldev->access_rights & VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
192640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
192740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
192840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
192940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
193040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
193140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (val64 & VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN)
193240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*tx = 1;
193340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (val64 & VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN)
193440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*rx = 1;
193540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
193640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
193740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
193840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
193940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
194040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_setpause_data -  set/reset pause frame generation.
194140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * It can be used to set or reset Pause frame generation or reception
194240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * support of the NIC.
194340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
194440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev,
194540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						 u32 port, u32 tx, u32 rx)
194640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
194740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
194840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
194940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
195040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
195140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_DEVICE;
195240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
195340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
195440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
195540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (port > VXGE_HW_MAC_MAX_MAC_PORT_ID) {
195640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_PORT;
195740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
195840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
195940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
196092cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur	status = __vxge_hw_device_is_privilaged(hldev->host_type,
196192cdd7c377c893c72d6968537076a18a510ae5ccSreenivasa Honnur			hldev->func_id);
196240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
196340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
196440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
196540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
196640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (tx)
196740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 |= VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN;
196840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	else
196940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 &= ~VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN;
197040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (rx)
197140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 |= VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN;
197240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	else
197340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 &= ~VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN;
197440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
197540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(val64, &hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
197640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
197740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
197840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
197940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
198040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepau16 vxge_hw_device_link_width_get(struct __vxge_hw_device *hldev)
198140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
198295cab7386bef62f8c7535d4726573ce230778e7bJon Mason	struct pci_dev *dev = hldev->pdev;
198340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u16 lnk;
198440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
198595cab7386bef62f8c7535d4726573ce230778e7bJon Mason	pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk);
198695cab7386bef62f8c7535d4726573ce230778e7bJon Mason	return (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4;
198740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
198840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
198940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
199040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_ring_block_memblock_idx - Return the memblock index
199140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This function returns the index of memory block
199240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
199340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepastatic inline u32
199440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_ring_block_memblock_idx(u8 *block)
199540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
199640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return (u32)*((u64 *)(block + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET));
199740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
199840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
199940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
200040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_ring_block_memblock_idx_set - Sets the memblock index
200140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This function sets index to a memory block
200240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
200340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepastatic inline void
200440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_ring_block_memblock_idx_set(u8 *block, u32 memblock_idx)
200540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
200640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	*((u64 *)(block + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET)) = memblock_idx;
200740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
200840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
200940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
201040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_ring_block_next_pointer_set - Sets the next block pointer
201140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * in RxD block
201240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Sets the next block pointer in RxD block
201340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
201440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepastatic inline void
201540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_ring_block_next_pointer_set(u8 *block, dma_addr_t dma_next)
201640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
201740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	*((u64 *)(block + VXGE_HW_RING_NEXT_BLOCK_POINTER_OFFSET)) = dma_next;
201840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
201940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
202040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
202140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_ring_first_block_address_get - Returns the dma address of the
202240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa *             first block
202340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Returns the dma address of the first RxD block
202440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
202542821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic u64 __vxge_hw_ring_first_block_address_get(struct __vxge_hw_ring *ring)
202640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
202740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_mempool_dma *dma_object;
202840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
202940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	dma_object = ring->mempool->memblocks_dma_arr;
203040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vxge_assert(dma_object != NULL);
203140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
203240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return dma_object->addr;
203340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
203440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
203540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
203640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_ring_item_dma_addr - Return the dma address of an item
203740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This function returns the dma address of a given item
203840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
203940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepastatic dma_addr_t __vxge_hw_ring_item_dma_addr(struct vxge_hw_mempool *mempoolh,
204040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					       void *item)
204140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
204240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 memblock_idx;
204340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	void *memblock;
204440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_mempool_dma *memblock_dma_object;
204540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	ptrdiff_t dma_item_offset;
204640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
204740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* get owner memblock index */
204840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	memblock_idx = __vxge_hw_ring_block_memblock_idx(item);
204940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
205040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* get owner memblock by memblock index */
205140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	memblock = mempoolh->memblocks_arr[memblock_idx];
205240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
205340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* get memblock DMA object by memblock index */
205440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	memblock_dma_object = mempoolh->memblocks_dma_arr + memblock_idx;
205540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
205640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* calculate offset in the memblock of this item */
205740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	dma_item_offset = (u8 *)item - (u8 *)memblock;
205840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
205940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return memblock_dma_object->addr + dma_item_offset;
206040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
206140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
206240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
206340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_ring_rxdblock_link - Link the RxD blocks
206440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This function returns the dma address of a given item
206540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
206640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepastatic void __vxge_hw_ring_rxdblock_link(struct vxge_hw_mempool *mempoolh,
206740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					 struct __vxge_hw_ring *ring, u32 from,
206840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					 u32 to)
206940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
207040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u8 *to_item , *from_item;
207140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	dma_addr_t to_dma;
207240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
207340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* get "from" RxD block */
207440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	from_item = mempoolh->items_arr[from];
207540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vxge_assert(from_item);
207640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
207740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* get "to" RxD block */
207840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	to_item = mempoolh->items_arr[to];
207940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vxge_assert(to_item);
208040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
208140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* return address of the beginning of previous RxD block */
208240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	to_dma = __vxge_hw_ring_item_dma_addr(mempoolh, to_item);
208340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
208440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* set next pointer for this RxD block to point on
208540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 * previous item's DMA start address */
208640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	__vxge_hw_ring_block_next_pointer_set(from_item, to_dma);
208740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
208840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
208940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
209040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_ring_mempool_item_alloc - Allocate List blocks for RxD
209140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * block callback
209240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This function is callback passed to __vxge_hw_mempool_create to create memory
209340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * pool for RxD block
209440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
209540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepastatic void
209640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_ring_mempool_item_alloc(struct vxge_hw_mempool *mempoolh,
209740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				  u32 memblock_index,
209840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				  struct vxge_hw_mempool_dma *dma_object,
209940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				  u32 index, u32 is_last)
210040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
210140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i;
210240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	void *item = mempoolh->items_arr[index];
210340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_ring *ring =
210440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		(struct __vxge_hw_ring *)mempoolh->userdata;
210540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
210640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* format rxds array */
210740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < ring->rxds_per_block; i++) {
210840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		void *rxdblock_priv;
210940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		void *uld_priv;
211040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		struct vxge_hw_ring_rxd_1 *rxdp;
211140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
211240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		u32 reserve_index = ring->channel.reserve_ptr -
211340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				(index * ring->rxds_per_block + i + 1);
211440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		u32 memblock_item_idx;
211540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
211640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		ring->channel.reserve_arr[reserve_index] = ((u8 *)item) +
211740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						i * ring->rxd_size;
211840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
211940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		/* Note: memblock_item_idx is index of the item within
212040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		 *       the memblock. For instance, in case of three RxD-blocks
212140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		 *       per memblock this value can be 0, 1 or 2. */
212240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		rxdblock_priv = __vxge_hw_mempool_item_priv(mempoolh,
212340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					memblock_index, item,
212440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					&memblock_item_idx);
212540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
212643d620c82985b19008d87a437b4cf83f356264f7Joe Perches		rxdp = ring->channel.reserve_arr[reserve_index];
212740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
212840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		uld_priv = ((u8 *)rxdblock_priv + ring->rxd_priv_size * i);
212940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
213040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		/* pre-format Host_Control */
213140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		rxdp->host_control = (u64)(size_t)uld_priv;
213240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
213340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
213440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	__vxge_hw_ring_block_memblock_idx_set(item, memblock_index);
213540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
213640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (is_last) {
213740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		/* link last one with first one */
213840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_ring_rxdblock_link(mempoolh, ring, index, 0);
213940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
214040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
214140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (index > 0) {
214240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		/* link this RxD block with previous one */
214340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_ring_rxdblock_link(mempoolh, ring, index - 1, index);
214440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
214540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
214640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
214740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
21483363276f1c420b7de92169ddabd2bb88aa26a7d6Sreenivasa Honnur * __vxge_hw_ring_replenish - Initial replenish of RxDs
214940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This function replenishes the RxDs from reserve array to work array
215040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
215140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status
21523363276f1c420b7de92169ddabd2bb88aa26a7d6Sreenivasa Honnurvxge_hw_ring_replenish(struct __vxge_hw_ring *ring)
215340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
215440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	void *rxd;
215540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_channel *channel;
215640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
215740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
215840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	channel = &ring->channel;
215940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
216040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	while (vxge_hw_channel_dtr_count(channel) > 0) {
216140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
216240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = vxge_hw_ring_rxd_reserve(ring, &rxd);
216340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
216440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		vxge_assert(status == VXGE_HW_OK);
216540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
216640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (ring->rxd_init) {
216740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = ring->rxd_init(rxd, channel->userdata);
216840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			if (status != VXGE_HW_OK) {
216940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				vxge_hw_ring_rxd_free(ring, rxd);
217040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				goto exit;
217140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			}
217240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
217340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
217440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		vxge_hw_ring_rxd_post(ring, rxd);
217540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
217640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = VXGE_HW_OK;
217740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
217840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
217940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
218040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
218140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
2182528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_channel_allocate - Allocate memory for channel
2183528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function allocates required memory for the channel and various arrays
2184528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * in the channel
218540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
2186528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic struct __vxge_hw_channel *
2187528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph,
2188528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			   enum __vxge_hw_channel_type type,
2189528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			   u32 length, u32 per_dtr_space,
2190528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			   void *userdata)
219140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
2192528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_channel *channel;
219340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_device *hldev;
2194528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	int size = 0;
219540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 vp_id;
219640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2197528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hldev = vph->vpath->hldev;
2198528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp_id = vph->vpath->vp_id;
219940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2200528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	switch (type) {
2201528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	case VXGE_HW_CHANNEL_TYPE_FIFO:
2202528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		size = sizeof(struct __vxge_hw_fifo);
2203528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		break;
2204528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	case VXGE_HW_CHANNEL_TYPE_RING:
2205528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		size = sizeof(struct __vxge_hw_ring);
2206528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		break;
2207528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	default:
2208528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		break;
220940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
221040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2211528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel = kzalloc(size, GFP_KERNEL);
2212528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (channel == NULL)
2213528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit0;
2214528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	INIT_LIST_HEAD(&channel->item);
221540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2216528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->common_reg = hldev->common_reg;
2217528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->first_vp_id = hldev->first_vp_id;
2218528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->type = type;
2219528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->devh = hldev;
2220528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->vph = vph;
2221528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->userdata = userdata;
2222528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->per_dtr_space = per_dtr_space;
2223528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->length = length;
2224528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->vp_id = vp_id;
222540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2226528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->work_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
2227528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (channel->work_arr == NULL)
2228528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit1;
222940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2230528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->free_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
2231528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (channel->free_arr == NULL)
2232528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit1;
2233528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->free_ptr = length;
223440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2235528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->reserve_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
2236528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (channel->reserve_arr == NULL)
2237528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit1;
2238528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->reserve_ptr = length;
2239528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->reserve_top = 0;
224040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2241528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel->orig_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
2242528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (channel->orig_arr == NULL)
2243528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit1;
224440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2245528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return channel;
2246528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit1:
2247528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_channel_free(channel);
224840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2249528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit0:
2250528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return NULL;
225140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
225240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
225340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
2254528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_blockpool_block_add - callback for vxge_os_dma_malloc_async
2255528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Adds a block to block pool
225640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
2257528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh,
2258528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					void *block_addr,
2259528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					u32 length,
2260528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					struct pci_dev *dma_h,
2261528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					struct pci_dev *acc_handle)
226240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
2263528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_blockpool *blockpool;
2264528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_blockpool_entry *entry = NULL;
2265528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	dma_addr_t dma_addr;
2266528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
2267528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 req_out;
226840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2269528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool = &devh->block_pool;
227040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2271528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (block_addr == NULL) {
2272528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		blockpool->req_out--;
2273528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_FAIL;
2274528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
2275528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
227640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2277528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	dma_addr = pci_map_single(devh->pdev, block_addr, length,
2278528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				PCI_DMA_BIDIRECTIONAL);
227940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2280528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (unlikely(pci_dma_mapping_error(devh->pdev, dma_addr))) {
2281528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_os_dma_free(devh->pdev, block_addr, &acc_handle);
2282528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		blockpool->req_out--;
2283528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_FAIL;
2284528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
2285528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
228640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2287528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (!list_empty(&blockpool->free_entry_list))
2288528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		entry = (struct __vxge_hw_blockpool_entry *)
2289528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			list_first_entry(&blockpool->free_entry_list,
2290528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				struct __vxge_hw_blockpool_entry,
2291528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				item);
229240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2293528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (entry == NULL)
2294528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		entry =	vmalloc(sizeof(struct __vxge_hw_blockpool_entry));
2295528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	else
2296528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		list_del(&entry->item);
229740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2298528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (entry != NULL) {
2299528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		entry->length = length;
2300528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		entry->memblock = block_addr;
2301528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		entry->dma_addr = dma_addr;
2302528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		entry->acc_handle = acc_handle;
2303528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		entry->dma_handle = dma_h;
2304528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		list_add(&entry->item, &blockpool->free_block_list);
2305528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		blockpool->pool_size++;
2306528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_OK;
2307528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	} else
2308528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_OUT_OF_MEMORY;
230940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2310528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool->req_out--;
231140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2312528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	req_out = blockpool->req_out;
2313528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
2314528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return;
2315528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
231640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2317528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic inline void
2318528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvxge_os_dma_malloc_async(struct pci_dev *pdev, void *devh, unsigned long size)
2319528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
2320528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	gfp_t flags;
2321528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	void *vaddr;
232240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2323528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (in_interrupt())
2324528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		flags = GFP_ATOMIC | GFP_DMA;
2325528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	else
2326528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		flags = GFP_KERNEL | GFP_DMA;
232740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2328528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vaddr = kmalloc((size), flags);
232940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2330528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vxge_hw_blockpool_block_add(devh, vaddr, size, pdev, pdev);
233140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
233240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
233340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
2334528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_blockpool_blocks_add - Request additional blocks
233540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
2336528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic
2337528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvoid __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool)
233840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
2339528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 nreq = 0, i;
234040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2341528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if ((blockpool->pool_size  +  blockpool->req_out) <
2342528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE) {
2343528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		nreq = VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE;
2344528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		blockpool->req_out += nreq;
2345528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
234640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2347528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	for (i = 0; i < nreq; i++)
2348528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_os_dma_malloc_async(
2349528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			((struct __vxge_hw_device *)blockpool->hldev)->pdev,
2350528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			blockpool->hldev, VXGE_HW_BLOCK_SIZE);
235140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
235240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
235340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
2354528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_blockpool_malloc - Allocate a memory block from pool
2355528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Allocates a block of memory of given size, either from block pool
2356528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * or by calling vxge_os_dma_malloc()
235740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
2358528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic void *__vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size,
2359528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					struct vxge_hw_mempool_dma *dma_object)
236040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
2361528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_blockpool_entry *entry = NULL;
2362528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_blockpool  *blockpool;
2363528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	void *memblock = NULL;
236440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
236540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2366528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool = &devh->block_pool;
2367528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2368528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (size != blockpool->block_size) {
2369528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2370528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		memblock = vxge_os_dma_malloc(devh->pdev, size,
2371528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						&dma_object->handle,
2372528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						&dma_object->acc_handle);
2373528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2374528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (memblock == NULL) {
2375528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			status = VXGE_HW_ERR_OUT_OF_MEMORY;
2376528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto exit;
2377528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
2378528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2379528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		dma_object->addr = pci_map_single(devh->pdev, memblock, size,
2380528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					PCI_DMA_BIDIRECTIONAL);
2381528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2382528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (unlikely(pci_dma_mapping_error(devh->pdev,
2383528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				dma_object->addr))) {
2384528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			vxge_os_dma_free(devh->pdev, memblock,
2385528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				&dma_object->acc_handle);
2386528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			status = VXGE_HW_ERR_OUT_OF_MEMORY;
2387528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto exit;
2388528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
2389528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2390528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	} else {
2391528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2392528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (!list_empty(&blockpool->free_block_list))
2393528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry = (struct __vxge_hw_blockpool_entry *)
2394528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				list_first_entry(&blockpool->free_block_list,
2395528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					struct __vxge_hw_blockpool_entry,
2396528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					item);
2397528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2398528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (entry != NULL) {
2399528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			list_del(&entry->item);
2400528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			dma_object->addr = entry->dma_addr;
2401528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			dma_object->handle = entry->dma_handle;
2402528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			dma_object->acc_handle = entry->acc_handle;
2403528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			memblock = entry->memblock;
2404528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2405528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			list_add(&entry->item,
2406528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				&blockpool->free_entry_list);
2407528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			blockpool->pool_size--;
2408528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
2409528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2410528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (memblock != NULL)
2411528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			__vxge_hw_blockpool_blocks_add(blockpool);
2412528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
2413528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
2414528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return memblock;
2415528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
2416528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2417528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
2418528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_blockpool_blocks_remove - Free additional blocks
2419528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
2420528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic void
2421528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool)
2422528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
2423528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct list_head *p, *n;
2424528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2425528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	list_for_each_safe(p, n, &blockpool->free_block_list) {
2426528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2427528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (blockpool->pool_size < blockpool->pool_max)
2428528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			break;
2429528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2430528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		pci_unmap_single(
2431528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			((struct __vxge_hw_device *)blockpool->hldev)->pdev,
2432528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
2433528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			((struct __vxge_hw_blockpool_entry *)p)->length,
2434528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			PCI_DMA_BIDIRECTIONAL);
2435528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2436528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_os_dma_free(
2437528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			((struct __vxge_hw_device *)blockpool->hldev)->pdev,
2438528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			((struct __vxge_hw_blockpool_entry *)p)->memblock,
2439528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&((struct __vxge_hw_blockpool_entry *)p)->acc_handle);
2440528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2441528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
2442528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2443528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		list_add(p, &blockpool->free_entry_list);
2444528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2445528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		blockpool->pool_size--;
2446528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2447528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
2448528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
2449528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2450528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
2451528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_blockpool_free - Frees the memory allcoated with
2452528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason *				__vxge_hw_blockpool_malloc
2453528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
2454528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic void __vxge_hw_blockpool_free(struct __vxge_hw_device *devh,
2455528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				     void *memblock, u32 size,
2456528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				     struct vxge_hw_mempool_dma *dma_object)
2457528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
2458528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_blockpool_entry *entry = NULL;
2459528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_blockpool  *blockpool;
2460528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
2461528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2462528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool = &devh->block_pool;
2463528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2464528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (size != blockpool->block_size) {
2465528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		pci_unmap_single(devh->pdev, dma_object->addr, size,
2466528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			PCI_DMA_BIDIRECTIONAL);
2467528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_os_dma_free(devh->pdev, memblock, &dma_object->acc_handle);
2468528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	} else {
2469528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2470528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (!list_empty(&blockpool->free_entry_list))
2471528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry = (struct __vxge_hw_blockpool_entry *)
2472528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				list_first_entry(&blockpool->free_entry_list,
2473528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					struct __vxge_hw_blockpool_entry,
2474528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					item);
2475528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2476528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (entry == NULL)
2477528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry =	vmalloc(sizeof(
2478528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					struct __vxge_hw_blockpool_entry));
2479528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		else
2480528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			list_del(&entry->item);
2481528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2482528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (entry != NULL) {
2483528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry->length = size;
2484528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry->memblock = memblock;
2485528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry->dma_addr = dma_object->addr;
2486528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry->acc_handle = dma_object->acc_handle;
2487528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			entry->dma_handle = dma_object->handle;
2488528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			list_add(&entry->item,
2489528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					&blockpool->free_block_list);
2490528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			blockpool->pool_size++;
2491528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			status = VXGE_HW_OK;
2492528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		} else
2493528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			status = VXGE_HW_ERR_OUT_OF_MEMORY;
2494528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2495528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (status == VXGE_HW_OK)
2496528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			__vxge_hw_blockpool_blocks_remove(blockpool);
2497528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
2498528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
2499528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2500528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
2501528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_mempool_destroy
2502528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
2503528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool)
2504528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
2505528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 i, j;
2506528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_device *devh = mempool->devh;
2507528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2508528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	for (i = 0; i < mempool->memblocks_allocated; i++) {
2509528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		struct vxge_hw_mempool_dma *dma_object;
2510528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2511528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_assert(mempool->memblocks_arr[i]);
2512528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_assert(mempool->memblocks_dma_arr + i);
2513528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2514528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		dma_object = mempool->memblocks_dma_arr + i;
2515528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2516528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		for (j = 0; j < mempool->items_per_memblock; j++) {
2517528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			u32 index = i * mempool->items_per_memblock + j;
2518528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2519528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			/* to skip last partially filled(if any) memblock */
2520528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			if (index >= mempool->items_current)
2521528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				break;
2522528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
2523528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2524528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vfree(mempool->memblocks_priv_arr[i]);
2525528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2526528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_blockpool_free(devh, mempool->memblocks_arr[i],
2527528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				mempool->memblock_size, dma_object);
2528528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
2529528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2530528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vfree(mempool->items_arr);
2531528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vfree(mempool->memblocks_dma_arr);
2532528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vfree(mempool->memblocks_priv_arr);
2533528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vfree(mempool->memblocks_arr);
2534528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vfree(mempool);
2535528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
2536528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2537528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
2538528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_mempool_grow
2539528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Will resize mempool up to %num_allocate value.
2540528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
2541528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
2542528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate,
2543528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		       u32 *num_allocated)
2544528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
2545528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 i, first_time = mempool->memblocks_allocated == 0 ? 1 : 0;
2546528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 n_items = mempool->items_per_memblock;
2547528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 start_block_idx = mempool->memblocks_allocated;
2548528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 end_block_idx = mempool->memblocks_allocated + num_allocate;
2549528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
2550528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2551528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	*num_allocated = 0;
255240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
255340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (end_block_idx > mempool->memblocks_max) {
255440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
255540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
255640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
255740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
255840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = start_block_idx; i < end_block_idx; i++) {
255940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		u32 j;
256040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		u32 is_last = ((end_block_idx - 1) == i);
256140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		struct vxge_hw_mempool_dma *dma_object =
256240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			mempool->memblocks_dma_arr + i;
256340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		void *the_memblock;
256440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
256540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		/* allocate memblock's private part. Each DMA memblock
256640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		 * has a space allocated for item's private usage upon
256740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		 * mempool's user request. Each time mempool grows, it will
256840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		 * allocate new memblock and its private part at once.
256940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		 * This helps to minimize memory usage a lot. */
257040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		mempool->memblocks_priv_arr[i] =
257189bf67f1f080c947c92f8773482d9e57767ca292Eric Dumazet				vzalloc(mempool->items_priv_size * n_items);
257240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (mempool->memblocks_priv_arr[i] == NULL) {
257340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_OUT_OF_MEMORY;
257440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
257540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
257640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
257740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		/* allocate DMA-capable memblock */
257840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		mempool->memblocks_arr[i] =
257940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			__vxge_hw_blockpool_malloc(mempool->devh,
258040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				mempool->memblock_size, dma_object);
258140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (mempool->memblocks_arr[i] == NULL) {
258240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			vfree(mempool->memblocks_priv_arr[i]);
258340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_OUT_OF_MEMORY;
258440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
258540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
258640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
258740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		(*num_allocated)++;
258840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		mempool->memblocks_allocated++;
258940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
259040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		memset(mempool->memblocks_arr[i], 0, mempool->memblock_size);
259140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
259240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		the_memblock = mempool->memblocks_arr[i];
259340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
259440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		/* fill the items hash array */
259540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		for (j = 0; j < n_items; j++) {
259640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			u32 index = i * n_items + j;
259740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
259840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			if (first_time && index >= mempool->items_initial)
259940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				break;
260040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
260140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			mempool->items_arr[index] =
260240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				((char *)the_memblock + j*mempool->item_size);
260340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
260440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			/* let caller to do more job on each item */
260540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			if (mempool->item_func_alloc != NULL)
260640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				mempool->item_func_alloc(mempool, i,
260740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					dma_object, index, is_last);
260840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
260940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			mempool->items_current = index + 1;
261040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
261140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
261240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (first_time && mempool->items_current ==
261340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					mempool->items_initial)
261440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
261540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
261640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
261740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
261840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
261940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
262040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
262140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_mempool_create
262240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This function will create memory pool object. Pool may grow but will
262340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * never shrink. Pool consists of number of dynamically allocated blocks
262440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * with size enough to hold %items_initial number of items. Memory is
262540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * DMA-able but client must map/unmap before interoperating with the device.
262640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
2627528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic struct vxge_hw_mempool *
2628528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_mempool_create(struct __vxge_hw_device *devh,
2629528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			 u32 memblock_size,
2630528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			 u32 item_size,
2631528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			 u32 items_priv_size,
2632528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			 u32 items_initial,
2633528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			 u32 items_max,
2634956a206620fa048afdcd8ab714ac3cf6a9e884b7stephen hemminger			 const struct vxge_hw_mempool_cbs *mp_callback,
2635528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			 void *userdata)
263640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
263740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
263840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 memblocks_to_allocate;
263940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_mempool *mempool = NULL;
264040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 allocated;
264140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
264240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (memblock_size < item_size) {
264340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_FAIL;
264440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
264540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
264640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2647e80be0b0ee307a2801e57cf36333d3d659e4bcc6Joe Perches	mempool = vzalloc(sizeof(struct vxge_hw_mempool));
264840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (mempool == NULL) {
264940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
265040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
265140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
265240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
265340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->devh			= devh;
265440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->memblock_size		= memblock_size;
265540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->items_max		= items_max;
265640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->items_initial		= items_initial;
265740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->item_size		= item_size;
265840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->items_priv_size	= items_priv_size;
265940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->item_func_alloc	= mp_callback->item_func_alloc;
266040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->userdata		= userdata;
266140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
266240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->memblocks_allocated = 0;
266340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
266440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->items_per_memblock = memblock_size / item_size;
266540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
266640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->memblocks_max = (items_max + mempool->items_per_memblock - 1) /
266740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					mempool->items_per_memblock;
266840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
266940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* allocate array of memblocks */
267040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->memblocks_arr =
2671e80be0b0ee307a2801e57cf36333d3d659e4bcc6Joe Perches		vzalloc(sizeof(void *) * mempool->memblocks_max);
267240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (mempool->memblocks_arr == NULL) {
267340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_mempool_destroy(mempool);
267440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
267540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		mempool = NULL;
267640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
267740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
267840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
267940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* allocate array of private parts of items per memblocks */
268040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	mempool->memblocks_priv_arr =
2681e80be0b0ee307a2801e57cf36333d3d659e4bcc6Joe Perches		vzalloc(sizeof(void *) * mempool->memblocks_max);
268240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (mempool->memblocks_priv_arr == NULL) {
268340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_mempool_destroy(mempool);
268440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
268540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		mempool = NULL;
268640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
268740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
268840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
268940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* allocate array of memblocks DMA objects */
2690e80be0b0ee307a2801e57cf36333d3d659e4bcc6Joe Perches	mempool->memblocks_dma_arr =
269189bf67f1f080c947c92f8773482d9e57767ca292Eric Dumazet		vzalloc(sizeof(struct vxge_hw_mempool_dma) *
269240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			mempool->memblocks_max);
269340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (mempool->memblocks_dma_arr == NULL) {
269440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_mempool_destroy(mempool);
269540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
269640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		mempool = NULL;
269740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
269840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
269940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
270040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* allocate hash array of items */
2701e80be0b0ee307a2801e57cf36333d3d659e4bcc6Joe Perches	mempool->items_arr = vzalloc(sizeof(void *) * mempool->items_max);
270240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (mempool->items_arr == NULL) {
270340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_mempool_destroy(mempool);
270440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
270540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		mempool = NULL;
270640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
270740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
270840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
270940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* calculate initial number of memblocks */
271040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	memblocks_to_allocate = (mempool->items_initial +
271140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				 mempool->items_per_memblock - 1) /
271240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						mempool->items_per_memblock;
271340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
271440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* pre-allocate the mempool */
271540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_mempool_grow(mempool, memblocks_to_allocate,
271640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					&allocated);
271740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK) {
271840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_mempool_destroy(mempool);
271940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
272040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		mempool = NULL;
272140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
272240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
272340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
272440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
272540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return mempool;
272640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
272740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
272840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
2729528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_ring_abort - Returns the RxD
2730528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function terminates the RxDs of ring
273140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
2732528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status __vxge_hw_ring_abort(struct __vxge_hw_ring *ring)
273340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
2734528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	void *rxdh;
2735528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_channel *channel;
273640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2737528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel = &ring->channel;
273840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2739528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	for (;;) {
2740528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_hw_channel_dtr_try_complete(channel, &rxdh);
274140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2742528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (rxdh == NULL)
2743528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			break;
274440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2745528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_hw_channel_dtr_complete(channel);
274640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2747528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (ring->rxd_term)
2748528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			ring->rxd_term(rxdh, VXGE_HW_RXD_STATE_POSTED,
2749528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				channel->userdata);
275040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2751528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_hw_channel_dtr_free(channel, rxdh);
275240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
275340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2754528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return VXGE_HW_OK;
2755528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
275640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2757528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
2758528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_ring_reset - Resets the ring
2759528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function resets the ring during vpath reset operation
2760528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
2761528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status __vxge_hw_ring_reset(struct __vxge_hw_ring *ring)
2762528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
2763528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
2764528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_channel *channel;
276540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2766528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	channel = &ring->channel;
276740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2768528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_ring_abort(ring);
276940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2770528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_channel_reset(channel);
2771528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2772528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
2773528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
2774528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2775528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (ring->rxd_init) {
2776528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = vxge_hw_ring_replenish(ring);
2777528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (status != VXGE_HW_OK)
2778528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto exit;
2779528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
2780528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
2781528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
278240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
278340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
278440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
2785528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_ring_delete - Removes the ring
2786528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function freeup the memory pool and removes the ring
278740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
27882c91308f449c6705b81bd3370a0ec647e370f35cJon Masonstatic enum vxge_hw_status
2789528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp)
279040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
2791528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_ring *ring = vp->vpath->ringh;
279240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2793528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_ring_abort(ring);
279440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2795528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (ring->mempool)
2796528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_mempool_destroy(ring->mempool);
279740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2798528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp->vpath->ringh = NULL;
2799528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_channel_free(&ring->channel);
280040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
280140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return VXGE_HW_OK;
280240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
280340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
280440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
2805528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_ring_create - Create a Ring
2806528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function creates Ring and initializes it.
280740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
28082c91308f449c6705b81bd3370a0ec647e370f35cJon Masonstatic enum vxge_hw_status
2809528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp,
2810528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		      struct vxge_hw_ring_attr *attr)
281140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
2812528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
2813528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_ring *ring;
2814528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 ring_length;
2815528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct vxge_hw_ring_config *config;
2816528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_device *hldev;
2817528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 vp_id;
2818956a206620fa048afdcd8ab714ac3cf6a9e884b7stephen hemminger	static const struct vxge_hw_mempool_cbs ring_mp_callback = {
2819956a206620fa048afdcd8ab714ac3cf6a9e884b7stephen hemminger		.item_func_alloc = __vxge_hw_ring_mempool_item_alloc,
2820956a206620fa048afdcd8ab714ac3cf6a9e884b7stephen hemminger	};
282140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2822528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if ((vp == NULL) || (attr == NULL)) {
2823528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_FAIL;
2824528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
2825528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
282640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2827528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hldev = vp->vpath->hldev;
2828528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp_id = vp->vpath->vp_id;
282940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2830528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	config = &hldev->config.vp_config[vp_id].ring;
2831528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2832528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring_length = config->ring_blocks *
2833528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
2834528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2835528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring = (struct __vxge_hw_ring *)__vxge_hw_channel_allocate(vp,
2836528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						VXGE_HW_CHANNEL_TYPE_RING,
2837528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						ring_length,
2838528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						attr->per_rxd_space,
2839528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						attr->userdata);
2840528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (ring == NULL) {
2841528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_OUT_OF_MEMORY;
2842528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
284340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
284440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
2845528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp->vpath->ringh = ring;
2846528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->vp_id = vp_id;
2847528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->vp_reg = vp->vpath->vp_reg;
2848528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->common_reg = hldev->common_reg;
2849528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->stats = &vp->vpath->sw_stats->ring_stats;
2850528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->config = config;
2851528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->callback = attr->callback;
2852528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->rxd_init = attr->rxd_init;
2853528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->rxd_term = attr->rxd_term;
2854528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->buffer_mode = config->buffer_mode;
285516fded7da2cefc619ece0d44f8df76b533c43fd2Jon Mason	ring->tim_rti_cfg1_saved = vp->vpath->tim_rti_cfg1_saved;
285616fded7da2cefc619ece0d44f8df76b533c43fd2Jon Mason	ring->tim_rti_cfg3_saved = vp->vpath->tim_rti_cfg3_saved;
2857528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->rxds_limit = config->rxds_limit;
2858528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2859528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->rxd_size = vxge_hw_ring_rxd_size_get(config->buffer_mode);
2860528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->rxd_priv_size =
2861528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		sizeof(struct __vxge_hw_ring_rxd_priv) + attr->per_rxd_space;
2862528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->per_rxd_space = attr->per_rxd_space;
2863528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2864528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->rxd_priv_size =
2865528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		((ring->rxd_priv_size + VXGE_CACHE_LINE_SIZE - 1) /
2866528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE;
2867528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2868528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	/* how many RxDs can fit into one block. Depends on configured
2869528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	 * buffer_mode. */
2870528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->rxds_per_block =
2871528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
2872528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2873528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	/* calculate actual RxD block private size */
2874528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->rxdblock_priv_size = ring->rxd_priv_size * ring->rxds_per_block;
2875528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->mempool = __vxge_hw_mempool_create(hldev,
2876528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				VXGE_HW_BLOCK_SIZE,
2877528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				VXGE_HW_BLOCK_SIZE,
2878528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				ring->rxdblock_priv_size,
2879528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				ring->config->ring_blocks,
2880528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				ring->config->ring_blocks,
2881528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				&ring_mp_callback,
2882528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				ring);
2883528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (ring->mempool == NULL) {
2884528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_ring_delete(vp);
2885528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		return VXGE_HW_ERR_OUT_OF_MEMORY;
2886528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
2887528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2888528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_channel_initialize(&ring->channel);
2889528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK) {
2890528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_ring_delete(vp);
2891528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
2892528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
2893528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2894528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	/* Note:
2895528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	 * Specifying rxd_init callback means two things:
2896528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	 * 1) rxds need to be initialized by driver at channel-open time;
2897528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	 * 2) rxds need to be posted at channel-open time
2898528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	 *    (that's what the initial_replenish() below does)
2899528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	 * Currently we don't have a case when the 1) is done without the 2).
2900528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	 */
2901528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (ring->rxd_init) {
2902528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = vxge_hw_ring_replenish(ring);
2903528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (status != VXGE_HW_OK) {
2904528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			__vxge_hw_ring_delete(vp);
2905528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto exit;
2906528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
2907528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
2908528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
2909528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	/* initial replenish will increment the counter in its post() routine,
2910528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	 * we have to reset it */
2911528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->stats->common_stats.usage_cnt = 0;
2912528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
2913528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
291440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
291540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
291640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
291740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_config_default_get - Initialize device config with defaults.
291840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Initialize Titan device config with default values.
291940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
292040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status __devinit
292140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_device_config_default_get(struct vxge_hw_device_config *device_config)
292240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
292340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i;
292440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
292540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	device_config->dma_blockpool_initial =
292640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE;
292740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	device_config->dma_blockpool_max = VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE;
292840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	device_config->intr_mode = VXGE_HW_INTR_MODE_DEF;
292940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	device_config->rth_en = VXGE_HW_RTH_DEFAULT;
293040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	device_config->rth_it_type = VXGE_HW_RTH_IT_TYPE_DEFAULT;
293140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	device_config->device_poll_millis =  VXGE_HW_DEF_DEVICE_POLL_MILLIS;
293240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	device_config->rts_mac_en =  VXGE_HW_RTS_MAC_DEFAULT;
293340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
293440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
293540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].vp_id = i;
293640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
293740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].min_bandwidth =
293840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_VPATH_BANDWIDTH_DEFAULT;
293940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
294040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].ring.enable = VXGE_HW_RING_DEFAULT;
294140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
294240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].ring.ring_blocks =
294340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_DEF_RING_BLOCKS;
294440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
294540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].ring.buffer_mode =
294640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_RING_RXD_BUFFER_MODE_DEFAULT;
294740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
294840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].ring.scatter_mode =
294940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT;
295040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
295140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].ring.rxds_limit =
295240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_DEF_RING_RXDS_LIMIT;
295340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
295440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].fifo.enable = VXGE_HW_FIFO_ENABLE;
295540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
295640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].fifo.fifo_blocks =
295740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_MIN_FIFO_BLOCKS;
295840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
295940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].fifo.max_frags =
296040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_MAX_FIFO_FRAGS;
296140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
296240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].fifo.memblock_size =
296340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_DEF_FIFO_MEMBLOCK_SIZE;
296440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
296540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].fifo.alignment_size =
296640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_DEF_FIFO_ALIGNMENT_SIZE;
296740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
296840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].fifo.intr =
296940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_FIFO_QUEUE_INTR_DEFAULT;
297040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
297140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].fifo.no_snoop_bits =
297240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_FIFO_NO_SNOOP_DEFAULT;
297340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.intr_enable =
297440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_TIM_INTR_DEFAULT;
297540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
297640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.btimer_val =
297740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
297840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
297940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.timer_ac_en =
298040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
298140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
298240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.timer_ci_en =
298340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
298440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
298540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.timer_ri_en =
298640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
298740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
298840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.rtimer_val =
298940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
299040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
299140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.util_sel =
299240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
299340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
299440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.ltimer_val =
299540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
299640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
299740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.urange_a =
299840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
299940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
300040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.uec_a =
300140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
300240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
300340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.urange_b =
300440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
300540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
300640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.uec_b =
300740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
300840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
300940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.urange_c =
301040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
301140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
301240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.uec_c =
301340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
301440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
301540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].tti.uec_d =
301640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
301740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
301840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.intr_enable =
301940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_TIM_INTR_DEFAULT;
302040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
302140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.btimer_val =
302240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
302340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
302440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.timer_ac_en =
302540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
302640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
302740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.timer_ci_en =
302840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
302940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
303040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.timer_ri_en =
303140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
303240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
303340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.rtimer_val =
303440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
303540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
303640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.util_sel =
303740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
303840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
303940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.ltimer_val =
304040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
304140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
304240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.urange_a =
304340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
304440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
304540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.uec_a =
304640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
304740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
304840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.urange_b =
304940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
305040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
305140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.uec_b =
305240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
305340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
305440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.urange_c =
305540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
305640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
305740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.uec_c =
305840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
305940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
306040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rti.uec_d =
306140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_USE_FLASH_DEFAULT;
306240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
306340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].mtu =
306440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU;
306540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
306640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		device_config->vp_config[i].rpa_strip_vlan_tag =
306740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT;
306840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
306940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
307040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return VXGE_HW_OK;
307140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
307240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
307340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
307440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_swapper_set - Set the swapper bits for the vpath.
307540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Set the swapper bits appropriately for the vpath.
307640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
307742821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
307840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_vpath_swapper_set(struct vxge_hw_vpath_reg __iomem *vpath_reg)
307940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
308040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#ifndef __BIG_ENDIAN
308140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
308240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
308340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vpath_reg->vpath_general_cfg1);
308440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	wmb();
308540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 |= VXGE_HW_VPATH_GENERAL_CFG1_CTL_BYTE_SWAPEN;
308640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(val64, &vpath_reg->vpath_general_cfg1);
308740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	wmb();
308840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#endif
308940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return VXGE_HW_OK;
309040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
309140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
309240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
309340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_kdfc_swapper_set - Set the swapper bits for the kdfc.
309440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Set the swapper bits appropriately for the vpath.
309540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
309642821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
3097528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_kdfc_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg,
3098528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			   struct vxge_hw_vpath_reg __iomem *vpath_reg)
309940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
310040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
310140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
310240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&legacy_reg->pifm_wr_swap_en);
310340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
310440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (val64 == VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE) {
310540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&vpath_reg->kdfcctl_cfg0);
310640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		wmb();
310740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
310840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 |= VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO0	|
310940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO1	|
311040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO2;
311140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
311240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(val64, &vpath_reg->kdfcctl_cfg0);
311340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		wmb();
311440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
311540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
311640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return VXGE_HW_OK;
311740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
311840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
311940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
312040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_mgmt_reg_read - Read Titan register.
312140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
312240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status
312340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_mgmt_reg_read(struct __vxge_hw_device *hldev,
312440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		      enum vxge_hw_mgmt_reg_type type,
312540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		      u32 index, u32 offset, u64 *value)
312640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
312740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
312840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
312940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
313040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_DEVICE;
313140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
313240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
313340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
313440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	switch (type) {
313540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_legacy:
313640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_legacy_reg) - 8) {
313740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
313840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
313940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
314040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*value = readq((void __iomem *)hldev->legacy_reg + offset);
314140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
314240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_toc:
314340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_toc_reg) - 8) {
314440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
314540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
314640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
314740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*value = readq((void __iomem *)hldev->toc_reg + offset);
314840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
314940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_common:
315040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_common_reg) - 8) {
315140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
315240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
315340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
315440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*value = readq((void __iomem *)hldev->common_reg + offset);
315540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
315640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_mrpcim:
315740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (!(hldev->access_rights &
315840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
315940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
316040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
316140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
316240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_mrpcim_reg) - 8) {
316340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
316440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
316540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
316640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*value = readq((void __iomem *)hldev->mrpcim_reg + offset);
316740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
316840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_srpcim:
316940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (!(hldev->access_rights &
317040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM)) {
317140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
317240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
317340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
317440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (index > VXGE_HW_TITAN_SRPCIM_REG_SPACES - 1) {
317540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_INDEX;
317640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
317740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
317840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_srpcim_reg) - 8) {
317940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
318040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
318140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
318240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*value = readq((void __iomem *)hldev->srpcim_reg[index] +
318340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				offset);
318440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
318540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_vpmgmt:
318640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if ((index > VXGE_HW_TITAN_VPMGMT_REG_SPACES - 1) ||
318740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(!(hldev->vpath_assignments & vxge_mBIT(index)))) {
318840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_INDEX;
318940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
319040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
319140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_vpmgmt_reg) - 8) {
319240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
319340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
319440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
319540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*value = readq((void __iomem *)hldev->vpmgmt_reg[index] +
319640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				offset);
319740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
319840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_vpath:
319940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if ((index > VXGE_HW_TITAN_VPATH_REG_SPACES - 1) ||
320040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(!(hldev->vpath_assignments & vxge_mBIT(index)))) {
320140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_INDEX;
320240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
320340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
320440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (index > VXGE_HW_TITAN_VPATH_REG_SPACES - 1) {
320540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_INDEX;
320640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
320740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
320840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_vpath_reg) - 8) {
320940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
321040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
321140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
321240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*value = readq((void __iomem *)hldev->vpath_reg[index] +
321340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				offset);
321440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
321540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	default:
321640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_TYPE;
321740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
321840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
321940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
322040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
322140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
322240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
322340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
322440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
3225fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur * vxge_hw_vpath_strip_fcs_check - Check for FCS strip.
3226fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur */
3227fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnurenum vxge_hw_status
3228fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnurvxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask)
3229fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur{
3230fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur	struct vxge_hw_vpmgmt_reg       __iomem *vpmgmt_reg;
3231fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur	enum vxge_hw_status status = VXGE_HW_OK;
3232fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur	int i = 0, j = 0;
3233fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur
3234fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
3235fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur		if (!((vpath_mask) & vxge_mBIT(i)))
3236fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur			continue;
3237fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur		vpmgmt_reg = hldev->vpmgmt_reg[i];
3238fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur		for (j = 0; j < VXGE_HW_MAC_MAX_MAC_PORT_ID; j++) {
3239fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur			if (readq(&vpmgmt_reg->rxmac_cfg0_port_vpmgmt_clone[j])
3240fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur			& VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_STRIP_FCS)
3241fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur				return VXGE_HW_FAIL;
3242fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur		}
3243fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur	}
3244fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur	return status;
3245fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur}
3246fa41fd10038ab575f043a62dace374e07e9193deSreenivasa Honnur/*
324740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_mgmt_reg_Write - Write Titan register.
324840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
324940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status
325040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_mgmt_reg_write(struct __vxge_hw_device *hldev,
325140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		      enum vxge_hw_mgmt_reg_type type,
325240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		      u32 index, u32 offset, u64 value)
325340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
325440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
325540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
325640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
325740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_DEVICE;
325840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
325940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
326040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
326140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	switch (type) {
326240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_legacy:
326340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_legacy_reg) - 8) {
326440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
326540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
326640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
326740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(value, (void __iomem *)hldev->legacy_reg + offset);
326840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
326940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_toc:
327040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_toc_reg) - 8) {
327140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
327240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
327340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
327440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(value, (void __iomem *)hldev->toc_reg + offset);
327540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
327640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_common:
327740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_common_reg) - 8) {
327840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
327940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
328040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
328140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(value, (void __iomem *)hldev->common_reg + offset);
328240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
328340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_mrpcim:
328440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (!(hldev->access_rights &
328540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
328640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
328740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
328840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
328940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_mrpcim_reg) - 8) {
329040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
329140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
329240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
329340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(value, (void __iomem *)hldev->mrpcim_reg + offset);
329440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
329540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_srpcim:
329640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (!(hldev->access_rights &
329740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM)) {
329840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
329940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
330040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
330140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (index > VXGE_HW_TITAN_SRPCIM_REG_SPACES - 1) {
330240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_INDEX;
330340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
330440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
330540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_srpcim_reg) - 8) {
330640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
330740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
330840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
330940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(value, (void __iomem *)hldev->srpcim_reg[index] +
331040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			offset);
331140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
331240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
331340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_vpmgmt:
331440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if ((index > VXGE_HW_TITAN_VPMGMT_REG_SPACES - 1) ||
331540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(!(hldev->vpath_assignments & vxge_mBIT(index)))) {
331640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_INDEX;
331740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
331840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
331940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_vpmgmt_reg) - 8) {
332040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
332140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
332240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
332340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(value, (void __iomem *)hldev->vpmgmt_reg[index] +
332440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			offset);
332540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
332640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case vxge_hw_mgmt_reg_type_vpath:
332740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if ((index > VXGE_HW_TITAN_VPATH_REG_SPACES-1) ||
332840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(!(hldev->vpath_assignments & vxge_mBIT(index)))) {
332940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_INDEX;
333040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
333140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
333240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (offset > sizeof(struct vxge_hw_vpath_reg) - 8) {
333340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = VXGE_HW_ERR_INVALID_OFFSET;
333440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
333540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
333640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(value, (void __iomem *)hldev->vpath_reg[index] +
333740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			offset);
333840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
333940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	default:
334040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_TYPE;
334140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		break;
334240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
334340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
334440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
334540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
334640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
334740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
3348528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_fifo_abort - Returns the TxD
3349528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function terminates the TxDs of fifo
335040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
3351528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo)
335240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
3353528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	void *txdlh;
335440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
3355528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	for (;;) {
3356528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh);
335740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
3358528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (txdlh == NULL)
3359528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			break;
336040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
3361528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_hw_channel_dtr_complete(&fifo->channel);
336240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
3363528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (fifo->txdl_term) {
3364528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			fifo->txdl_term(txdlh,
3365528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			VXGE_HW_TXDL_STATE_POSTED,
3366528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			fifo->channel.userdata);
3367528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
336840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
3369528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vxge_hw_channel_dtr_free(&fifo->channel, txdlh);
3370528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
337140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
3372528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return VXGE_HW_OK;
337340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
337440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
337540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
3376528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_fifo_reset - Resets the fifo
3377528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function resets the fifo during vpath reset operation
337840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
3379528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo)
338040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
338140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
3382528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3383528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_fifo_abort(fifo);
3384528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_channel_reset(&fifo->channel);
3385528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3386528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
3387528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
3388528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3389528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
3390528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_fifo_delete - Removes the FIFO
3391528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function freeup the memory pool and removes the FIFO
3392528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
3393528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
3394528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp)
3395528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
3396528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_fifo *fifo = vp->vpath->fifoh;
3397528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3398528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_fifo_abort(fifo);
3399528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3400528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (fifo->mempool)
3401528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_mempool_destroy(fifo->mempool);
3402528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3403528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp->vpath->fifoh = NULL;
3404528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3405528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_channel_free(&fifo->channel);
3406528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3407528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return VXGE_HW_OK;
3408528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
3409528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3410528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
3411528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_fifo_mempool_item_alloc - Allocate List blocks for TxD
3412528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * list callback
3413528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function is callback passed to __vxge_hw_mempool_create to create memory
3414528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * pool for TxD list
3415528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
3416528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic void
3417528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_fifo_mempool_item_alloc(
3418528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct vxge_hw_mempool *mempoolh,
3419528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 memblock_index, struct vxge_hw_mempool_dma *dma_object,
3420528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 index, u32 is_last)
3421528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
3422528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 memblock_item_idx;
3423528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_fifo_txdl_priv *txdl_priv;
3424528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct vxge_hw_fifo_txd *txdp =
3425528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(struct vxge_hw_fifo_txd *)mempoolh->items_arr[index];
3426528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_fifo *fifo =
3427528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			(struct __vxge_hw_fifo *)mempoolh->userdata;
3428528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	void *memblock = mempoolh->memblocks_arr[memblock_index];
3429528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3430528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vxge_assert(txdp);
3431528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3432528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	txdp->host_control = (u64) (size_t)
3433528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_mempool_item_priv(mempoolh, memblock_index, txdp,
3434528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					&memblock_item_idx);
3435528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3436528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdp);
3437528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3438528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vxge_assert(txdl_priv);
3439528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3440528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	fifo->channel.reserve_arr[fifo->channel.reserve_ptr - 1 - index] = txdp;
3441528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3442528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	/* pre-format HW's TxDL's private */
3443528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	txdl_priv->dma_offset = (char *)txdp - (char *)memblock;
3444528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	txdl_priv->dma_addr = dma_object->addr + txdl_priv->dma_offset;
3445528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	txdl_priv->dma_handle = dma_object->handle;
3446528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	txdl_priv->memblock   = memblock;
3447528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	txdl_priv->first_txdp = txdp;
3448528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	txdl_priv->next_txdl_priv = NULL;
3449528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	txdl_priv->alloc_frags = 0;
3450528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
3451528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
3452528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
3453528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_fifo_create - Create a FIFO
3454528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function creates FIFO and initializes it.
3455528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
3456528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
3457528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp,
3458528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		      struct vxge_hw_fifo_attr *attr)
3459528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
3460528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
3461528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_fifo *fifo;
346240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_fifo_config *config;
346340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 txdl_size, txdl_per_memblock;
346440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_mempool_cbs fifo_mp_callback;
346540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_virtualpath *vpath;
346640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
346740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if ((vp == NULL) || (attr == NULL)) {
346840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_HANDLE;
346940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
347040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
347140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath = vp->vpath;
347240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	config = &vpath->hldev->config.vp_config[vpath->vp_id].fifo;
347340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
347440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	txdl_size = config->max_frags * sizeof(struct vxge_hw_fifo_txd);
347540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
347640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	txdl_per_memblock = config->memblock_size / txdl_size;
347740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
347840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo = (struct __vxge_hw_fifo *)__vxge_hw_channel_allocate(vp,
347940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					VXGE_HW_CHANNEL_TYPE_FIFO,
348040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					config->fifo_blocks * txdl_per_memblock,
348140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					attr->per_txdl_space, attr->userdata);
348240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
348340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (fifo == NULL) {
348440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
348540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
348640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
348740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
348840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath->fifoh = fifo;
348940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->nofl_db = vpath->nofl_db;
349040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
349140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->vp_id = vpath->vp_id;
349240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->vp_reg = vpath->vp_reg;
349340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->stats = &vpath->sw_stats->fifo_stats;
349440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
349540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->config = config;
349640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
349740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* apply "interrupts per txdl" attribute */
349840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_UTILZ;
349916fded7da2cefc619ece0d44f8df76b533c43fd2Jon Mason	fifo->tim_tti_cfg1_saved = vpath->tim_tti_cfg1_saved;
350016fded7da2cefc619ece0d44f8df76b533c43fd2Jon Mason	fifo->tim_tti_cfg3_saved = vpath->tim_tti_cfg3_saved;
350140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
350240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (fifo->config->intr)
350340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_PER_LIST;
350440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
350540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->no_snoop_bits = config->no_snoop_bits;
350640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
350740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/*
350840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 * FIFO memory management strategy:
350940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 *
351040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 * TxDL split into three independent parts:
351140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 *	- set of TxD's
351240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 *	- TxD HW private part
351340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 *	- driver private part
351440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 *
351540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 * Adaptative memory allocation used. i.e. Memory allocated on
351640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 * demand with the size which will fit into one memory block.
351740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 * One memory block may contain more than one TxDL.
351840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 *
351940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 * During "reserve" operations more memory can be allocated on demand
352040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 * for example due to FIFO full condition.
352140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 *
352240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 * Pool of memory memblocks never shrinks except in __vxge_hw_fifo_close
352340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 * routine which will essentially stop the channel and free resources.
352440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	 */
352540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
352640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* TxDL common private size == TxDL private  +  driver private */
352740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->priv_size =
352840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		sizeof(struct __vxge_hw_fifo_txdl_priv) + attr->per_txdl_space;
352940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->priv_size = ((fifo->priv_size  +  VXGE_CACHE_LINE_SIZE - 1) /
353040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE;
353140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
353240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->per_txdl_space = attr->per_txdl_space;
353340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
353440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	/* recompute txdl size to be cacheline aligned */
353540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->txdl_size = txdl_size;
353640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->txdl_per_memblock = txdl_per_memblock;
353740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
353840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->txdl_term = attr->txdl_term;
353940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->callback = attr->callback;
354040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
354140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (fifo->txdl_per_memblock == 0) {
354240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_fifo_delete(vp);
354340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_BLOCK_SIZE;
354440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
354540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
354640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
354740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo_mp_callback.item_func_alloc = __vxge_hw_fifo_mempool_item_alloc;
354840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
354940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	fifo->mempool =
355040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_mempool_create(vpath->hldev,
355140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			fifo->config->memblock_size,
355240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			fifo->txdl_size,
355340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			fifo->priv_size,
355440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(fifo->config->fifo_blocks * fifo->txdl_per_memblock),
355540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(fifo->config->fifo_blocks * fifo->txdl_per_memblock),
355640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			&fifo_mp_callback,
355740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			fifo);
355840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
355940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (fifo->mempool == NULL) {
356040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_fifo_delete(vp);
356140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_OUT_OF_MEMORY;
356240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
356340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
356440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
356540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_channel_initialize(&fifo->channel);
356640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK) {
356740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		__vxge_hw_fifo_delete(vp);
356840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
356940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
357040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
357140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vxge_assert(fifo->channel.reserve_ptr);
357240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
357340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
357440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
357540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
357640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
357740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_pci_read - Read the content of given address
357840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa *                          in pci config space.
357940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Read from the vpath pci config space.
358040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
358142821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
358240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_vpath_pci_read(struct __vxge_hw_virtualpath *vpath,
358340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			 u32 phy_func_0, u32 offset, u32 *val)
358440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
358540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
358640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
358740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg;
358840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
358940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 =	VXGE_HW_PCI_CONFIG_ACCESS_CFG1_ADDRESS(offset);
359040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
359140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (phy_func_0)
359240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 |= VXGE_HW_PCI_CONFIG_ACCESS_CFG1_SEL_FUNC0;
359340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
359440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(val64, &vp_reg->pci_config_access_cfg1);
359540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	wmb();
359640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(VXGE_HW_PCI_CONFIG_ACCESS_CFG2_REQ,
359740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			&vp_reg->pci_config_access_cfg2);
359840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	wmb();
359940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
360040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_device_register_poll(
360140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			&vp_reg->pci_config_access_cfg2,
360240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_INTR_MASK_ALL, VXGE_HW_DEF_DEVICE_POLL_MILLIS);
360340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
360440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
360540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
360640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
360740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vp_reg->pci_config_access_status);
360840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
360940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (val64 & VXGE_HW_PCI_CONFIG_ACCESS_STATUS_ACCESS_ERR) {
361040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_FAIL;
361140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*val = 0;
361240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	} else
361340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*val = (u32)vxge_bVALn(val64, 32, 32);
361440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
361540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
361640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
361740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
361840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/**
361940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_device_flick_link_led - Flick (blink) link LED.
362040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * @hldev: HW device.
362140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * @on_off: TRUE if flickering to be on, FALSE to be off
362240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa *
362340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Flicker the link LED.
362440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
362540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status
36268424e00dfd5282026a93996a165fc4079d382169Jon Masonvxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev, u64 on_off)
362740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
36288424e00dfd5282026a93996a165fc4079d382169Jon Mason	struct __vxge_hw_virtualpath *vpath;
36298424e00dfd5282026a93996a165fc4079d382169Jon Mason	u64 data0, data1 = 0, steer_ctrl = 0;
36308424e00dfd5282026a93996a165fc4079d382169Jon Mason	enum vxge_hw_status status;
363140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
363240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hldev == NULL) {
363340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_DEVICE;
363440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
363540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
363640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
36378424e00dfd5282026a93996a165fc4079d382169Jon Mason	vpath = &hldev->virtual_paths[hldev->first_vp_id];
363840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
36398424e00dfd5282026a93996a165fc4079d382169Jon Mason	data0 = on_off;
36408424e00dfd5282026a93996a165fc4079d382169Jon Mason	status = vxge_hw_vpath_fw_api(vpath,
36418424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL,
36428424e00dfd5282026a93996a165fc4079d382169Jon Mason			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
36438424e00dfd5282026a93996a165fc4079d382169Jon Mason			0, &data0, &data1, &steer_ctrl);
364440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
364540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
364640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
364740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
364840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
364940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_rts_table_get - Get the entries from RTS access tables
365040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
365140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status
36528424e00dfd5282026a93996a165fc4079d382169Jon Mason__vxge_hw_vpath_rts_table_get(struct __vxge_hw_vpath_handle *vp,
36538424e00dfd5282026a93996a165fc4079d382169Jon Mason			      u32 action, u32 rts_table, u32 offset,
36548424e00dfd5282026a93996a165fc4079d382169Jon Mason			      u64 *data0, u64 *data1)
365540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
36568424e00dfd5282026a93996a165fc4079d382169Jon Mason	enum vxge_hw_status status;
36578424e00dfd5282026a93996a165fc4079d382169Jon Mason	u64 steer_ctrl = 0;
365840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
365940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vp == NULL) {
366040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_HANDLE;
366140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
366240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
366340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
366440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if ((rts_table ==
36658424e00dfd5282026a93996a165fc4079d382169Jon Mason	     VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) ||
366640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	    (rts_table ==
36678424e00dfd5282026a93996a165fc4079d382169Jon Mason	     VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) ||
366840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	    (rts_table ==
36698424e00dfd5282026a93996a165fc4079d382169Jon Mason	     VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) ||
367040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	    (rts_table ==
36718424e00dfd5282026a93996a165fc4079d382169Jon Mason	     VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) {
36728424e00dfd5282026a93996a165fc4079d382169Jon Mason		steer_ctrl = VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL;
367340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
367440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
36758424e00dfd5282026a93996a165fc4079d382169Jon Mason	status = vxge_hw_vpath_fw_api(vp->vpath, action, rts_table, offset,
36768424e00dfd5282026a93996a165fc4079d382169Jon Mason				      data0, data1, &steer_ctrl);
367740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
367840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
367940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
368048bc9a2ccec98de007117495123bba78a4bbdd9cStefan Weil	if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) &&
36818424e00dfd5282026a93996a165fc4079d382169Jon Mason	    (rts_table !=
36828424e00dfd5282026a93996a165fc4079d382169Jon Mason	     VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT))
36838424e00dfd5282026a93996a165fc4079d382169Jon Mason		*data1 = 0;
368440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
368540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
368640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
368740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
368840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
368940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_rts_table_set - Set the entries of RTS access tables
369040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
369140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status
36928424e00dfd5282026a93996a165fc4079d382169Jon Mason__vxge_hw_vpath_rts_table_set(struct __vxge_hw_vpath_handle *vp, u32 action,
36938424e00dfd5282026a93996a165fc4079d382169Jon Mason			      u32 rts_table, u32 offset, u64 steer_data0,
36948424e00dfd5282026a93996a165fc4079d382169Jon Mason			      u64 steer_data1)
369540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
36968424e00dfd5282026a93996a165fc4079d382169Jon Mason	u64 data0, data1 = 0, steer_ctrl = 0;
36978424e00dfd5282026a93996a165fc4079d382169Jon Mason	enum vxge_hw_status status;
369840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
369940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vp == NULL) {
370040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_HANDLE;
370140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
370240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
370340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
37048424e00dfd5282026a93996a165fc4079d382169Jon Mason	data0 = steer_data0;
370540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
370640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if ((rts_table == VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) ||
370740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	    (rts_table ==
37088424e00dfd5282026a93996a165fc4079d382169Jon Mason	     VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT))
37098424e00dfd5282026a93996a165fc4079d382169Jon Mason		data1 = steer_data1;
371040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
37118424e00dfd5282026a93996a165fc4079d382169Jon Mason	status = vxge_hw_vpath_fw_api(vp->vpath, action, rts_table, offset,
37128424e00dfd5282026a93996a165fc4079d382169Jon Mason				      &data0, &data1, &steer_ctrl);
371340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
371440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
371540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
371640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
371740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
371840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_vpath_rts_rth_set - Set/configure RTS hashing.
371940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
372040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status vxge_hw_vpath_rts_rth_set(
372140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			struct __vxge_hw_vpath_handle *vp,
372240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			enum vxge_hw_rth_algoritms algorithm,
372340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			struct vxge_hw_rth_hash_types *hash_type,
372440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			u16 bucket_size)
372540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
372640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 data0, data1;
372740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
372840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
372940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vp == NULL) {
373040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_HANDLE;
373140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
373240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
373340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
373440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_vpath_rts_table_get(vp,
373540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		     VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY,
373640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		     VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
373740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			0, &data0, &data1);
373847f01db44b2470d9517848f6b73c75883ef5fda0Jon Mason	if (status != VXGE_HW_OK)
373947f01db44b2470d9517848f6b73c75883ef5fda0Jon Mason		goto exit;
374040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
374140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) |
374240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3));
374340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
374440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_EN |
374540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(bucket_size) |
374640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(algorithm);
374740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
374840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hash_type->hash_type_tcpipv4_en)
374940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV4_EN;
375040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
375140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hash_type->hash_type_ipv4_en)
375240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV4_EN;
375340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
375440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hash_type->hash_type_tcpipv6_en)
375540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EN;
375640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
375740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hash_type->hash_type_ipv6_en)
375840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EN;
375940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
376040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hash_type->hash_type_tcpipv6ex_en)
376140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		data0 |=
376240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EX_EN;
376340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
376440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hash_type->hash_type_ipv6ex_en)
376540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EX_EN;
376640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
376740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_ACTIVE_TABLE(data0))
376840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		data0 &= ~VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE;
376940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	else
377040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE;
377140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
377240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_vpath_rts_table_set(vp,
377340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY,
377440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
377540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		0, data0, 0);
377640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
377740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
377840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
377940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
378040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepastatic void
378140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_rts_rth_data0_data1_get(u32 j, u64 *data0, u64 *data1,
378240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				u16 flag, u8 *itable)
378340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
378440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	switch (flag) {
378540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case 1:
378640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_NUM(j)|
378740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_ENTRY_EN |
378840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_DATA(
378940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			itable[j]);
379040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case 2:
379140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*data0 |=
379240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_NUM(j)|
379340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_ENTRY_EN |
379440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_DATA(
379540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			itable[j]);
379640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case 3:
379740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*data1 = VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_NUM(j)|
379840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_ENTRY_EN |
379940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_DATA(
380040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			itable[j]);
380140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	case 4:
380240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		*data1 |=
380340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_NUM(j)|
380440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_ENTRY_EN |
380540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_DATA(
380640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			itable[j]);
380740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	default:
380840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		return;
380940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
381040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
381140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
381240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_vpath_rts_rth_itable_set - Set/configure indirection table (IT).
381340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
381440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status vxge_hw_vpath_rts_rth_itable_set(
381540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			struct __vxge_hw_vpath_handle **vpath_handles,
381640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			u32 vpath_count,
381740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			u8 *mtable,
381840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			u8 *itable,
381940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			u32 itable_size)
382040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
382140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i, j, action, rts_table;
382240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 data0;
382340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 data1;
382440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 max_entries;
382540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
382640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_vpath_handle *vp = vpath_handles[0];
382740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
382840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vp == NULL) {
382940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_ERR_INVALID_HANDLE;
383040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
383140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
383240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
383340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	max_entries = (((u32)1) << itable_size);
383440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
383540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vp->vpath->hldev->config.rth_it_type
383640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				== VXGE_HW_RTH_IT_TYPE_SOLO_IT) {
383740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY;
383840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		rts_table =
383940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT;
384040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
384140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		for (j = 0; j < max_entries; j++) {
384240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
384340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			data1 = 0;
384440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
384540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			data0 =
384640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA(
384740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				itable[j]);
384840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
384940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = __vxge_hw_vpath_rts_table_set(vpath_handles[0],
385040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				action, rts_table, j, data0, data1);
385140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
385240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			if (status != VXGE_HW_OK)
385340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				goto exit;
385440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
385540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
385640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		for (j = 0; j < max_entries; j++) {
385740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
385840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			data1 = 0;
385940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
386040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			data0 =
386140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_ENTRY_EN |
386240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA(
386340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				itable[j]);
386440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
386540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			status = __vxge_hw_vpath_rts_table_set(
386640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				vpath_handles[mtable[itable[j]]], action,
386740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				rts_table, j, data0, data1);
386840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
386940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			if (status != VXGE_HW_OK)
387040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				goto exit;
387140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
387240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	} else {
387340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY;
387440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		rts_table =
387540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT;
387640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		for (i = 0; i < vpath_count; i++) {
387740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
387840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			for (j = 0; j < max_entries;) {
387940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
388040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				data0 = 0;
388140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				data1 = 0;
388240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
388340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				while (j < max_entries) {
388440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					if (mtable[itable[j]] != i) {
388540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						j++;
388640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						continue;
388740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					}
388840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					vxge_hw_rts_rth_data0_data1_get(j,
388940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						&data0, &data1, 1, itable);
389040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					j++;
389140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					break;
389240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				}
389340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
389440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				while (j < max_entries) {
389540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					if (mtable[itable[j]] != i) {
389640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						j++;
389740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						continue;
389840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					}
389940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					vxge_hw_rts_rth_data0_data1_get(j,
390040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						&data0, &data1, 2, itable);
390140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					j++;
390240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					break;
390340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				}
390440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
390540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				while (j < max_entries) {
390640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					if (mtable[itable[j]] != i) {
390740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						j++;
390840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						continue;
390940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					}
391040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					vxge_hw_rts_rth_data0_data1_get(j,
391140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						&data0, &data1, 3, itable);
391240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					j++;
391340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					break;
391440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				}
391540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
391640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				while (j < max_entries) {
391740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					if (mtable[itable[j]] != i) {
391840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						j++;
391940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						continue;
392040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					}
392140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					vxge_hw_rts_rth_data0_data1_get(j,
392240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						&data0, &data1, 4, itable);
392340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					j++;
392440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					break;
392540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				}
392640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
392740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				if (data0 != 0) {
392840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					status = __vxge_hw_vpath_rts_table_set(
392940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa							vpath_handles[i],
393040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa							action, rts_table,
393140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa							0, data0, data1);
393240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
393340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					if (status != VXGE_HW_OK)
393440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						goto exit;
393540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				}
393640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			}
393740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
393840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
393940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
394040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
394140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
394240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
394340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/**
394440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * vxge_hw_vpath_check_leak - Check for memory leak
394540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * @ringh: Handle to the ring object used for receive
394640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa *
394740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * If PRC_RXD_DOORBELL_VPn.NEW_QW_CNT is larger or equal to
394840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * PRC_CFG6_VPn.RXD_SPAT then a leak has occurred.
394940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * Returns: VXGE_HW_FAIL, if leak has occurred.
395040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa *
395140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
395240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaenum vxge_hw_status
395340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepavxge_hw_vpath_check_leak(struct __vxge_hw_ring *ring)
395440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
395540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
395640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 rxd_new_count, rxd_spat;
395740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
395840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (ring == NULL)
395940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		return status;
396040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
396140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	rxd_new_count = readl(&ring->vp_reg->prc_rxd_doorbell);
396240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	rxd_spat = readq(&ring->vp_reg->prc_cfg6);
396340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	rxd_spat = VXGE_HW_PRC_CFG6_RXD_SPAT(rxd_spat);
396440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
396540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (rxd_new_count >= rxd_spat)
396640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = VXGE_HW_FAIL;
396740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
396840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
396940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
397040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
397140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
397240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_mgmt_read
397340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine reads the vpath_mgmt registers
397440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
397540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepastatic enum vxge_hw_status
397640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_vpath_mgmt_read(
397740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_device *hldev,
397840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_virtualpath *vpath)
397940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
398040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u32 i, mtu = 0, max_pyld = 0;
398140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
398240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
398340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
398440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) {
398540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
398640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&vpath->vpmgmt_reg->
398740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				rxmac_cfg0_port_vpmgmt_clone[i]);
398840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		max_pyld =
398940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(u32)
399040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_GET_MAX_PYLD_LEN
399140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(val64);
399240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (mtu < max_pyld)
399340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			mtu = max_pyld;
399440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
399540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
399640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath->max_mtu = mtu + VXGE_HW_MAC_HEADER_MAX_SIZE;
399740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
399840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vpath->vpmgmt_reg->xmac_vsport_choices_vp);
399940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
400040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
400140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (val64 & vxge_mBIT(i))
400240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			vpath->vsport_number = i;
400340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
400440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
400540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vpath->vpmgmt_reg->xgmac_gen_status_vpmgmt_clone);
400640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
400740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (val64 & VXGE_HW_XGMAC_GEN_STATUS_VPMGMT_CLONE_XMACJ_NTWK_OK)
400840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_UP);
400940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	else
401040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_DOWN);
401140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
401240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
401340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
401440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
401540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
401640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_reset_check - Check if resetting the vpath completed
401740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine checks the vpath_rst_in_prog register to see if
401840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * adapter completed the reset process for the vpath
401940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
402042821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
402140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath)
402240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
402340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status;
402440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
402540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_device_register_poll(
402640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			&vpath->hldev->common_reg->vpath_rst_in_prog,
402740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(
402840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				1 << (16 - vpath->vp_id)),
402940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			vpath->hldev->config.device_poll_millis);
403040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
403140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
403240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
403340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
403440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
403540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_reset
403640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine resets the vpath on the device
403740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
403842821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
403940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_vpath_reset(struct __vxge_hw_device *hldev, u32 vp_id)
404040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
404140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
404240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
404340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
404440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = VXGE_HW_CMN_RSTHDLR_CFG0_SW_RESET_VPATH(1 << (16 - vp_id));
404540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
404640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
404740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				&hldev->common_reg->cmn_rsthdlr_cfg0);
404840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
404940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
405040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
405140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
405240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
405340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_sw_reset
405440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine resets the vpath structures
405540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
405642821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
405740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_vpath_sw_reset(struct __vxge_hw_device *hldev, u32 vp_id)
405840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
405940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
406040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_virtualpath *vpath;
406140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
406240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath = (struct __vxge_hw_virtualpath *)&hldev->virtual_paths[vp_id];
406340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
406440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vpath->ringh) {
406540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = __vxge_hw_ring_reset(vpath->ringh);
406640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (status != VXGE_HW_OK)
406740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			goto exit;
406840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
406940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
407040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vpath->fifoh)
407140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		status = __vxge_hw_fifo_reset(vpath->fifoh);
407240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
407340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
407440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
407540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
407640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
407740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_prc_configure
407840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine configures the prc registers of virtual path using the config
407940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * passed
408040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
408142821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic void
408240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_vpath_prc_configure(struct __vxge_hw_device *hldev, u32 vp_id)
408340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
408440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
408540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_virtualpath *vpath;
408640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_vp_config *vp_config;
408740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_vpath_reg __iomem *vp_reg;
408840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
408940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath = &hldev->virtual_paths[vp_id];
409040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vp_reg = vpath->vp_reg;
409140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vp_config = vpath->vp_config;
409240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
409340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vp_config->ring.enable == VXGE_HW_RING_DISABLE)
409440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		return;
409540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
409640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vp_reg->prc_cfg1);
409740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 |= VXGE_HW_PRC_CFG1_RTI_TINT_DISABLE;
409840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(val64, &vp_reg->prc_cfg1);
409940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
410040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vpath->vp_reg->prc_cfg6);
410140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 |= VXGE_HW_PRC_CFG6_DOORBELL_MODE_EN;
410240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(val64, &vpath->vp_reg->prc_cfg6);
410340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
410440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vp_reg->prc_cfg7);
410540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
410640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vpath->vp_config->ring.scatter_mode !=
410740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT) {
410840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
410940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 &= ~VXGE_HW_PRC_CFG7_SCATTER_MODE(0x3);
411040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
411140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		switch (vpath->vp_config->ring.scatter_mode) {
411240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		case VXGE_HW_RING_SCATTER_MODE_A:
411340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
411440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					VXGE_HW_PRC_CFG7_SCATTER_MODE_A);
411540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
411640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		case VXGE_HW_RING_SCATTER_MODE_B:
411740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
411840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					VXGE_HW_PRC_CFG7_SCATTER_MODE_B);
411940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
412040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		case VXGE_HW_RING_SCATTER_MODE_C:
412140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
412240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					VXGE_HW_PRC_CFG7_SCATTER_MODE_C);
412340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			break;
412440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
412540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
412640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
412740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(val64, &vp_reg->prc_cfg7);
412840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
412940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(VXGE_HW_PRC_CFG5_RXD0_ADD(
413040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				__vxge_hw_ring_first_block_address_get(
413140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					vpath->ringh) >> 3), &vp_reg->prc_cfg5);
413240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
413340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vp_reg->prc_cfg4);
413440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 |= VXGE_HW_PRC_CFG4_IN_SVC;
413540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 &= ~VXGE_HW_PRC_CFG4_RING_MODE(0x3);
413640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
413740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 |= VXGE_HW_PRC_CFG4_RING_MODE(
413840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_PRC_CFG4_RING_MODE_ONE_BUFFER);
413940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
414040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (hldev->config.rth_en == VXGE_HW_RTH_DISABLE)
414140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 |= VXGE_HW_PRC_CFG4_RTH_DISABLE;
414240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	else
414340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 &= ~VXGE_HW_PRC_CFG4_RTH_DISABLE;
414440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
414540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(val64, &vp_reg->prc_cfg4);
414640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
414740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
414840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
414940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_kdfc_configure
415040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine configures the kdfc registers of virtual path using the
415140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * config passed
415240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
415342821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
415440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_vpath_kdfc_configure(struct __vxge_hw_device *hldev, u32 vp_id)
415540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
415640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
415740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 vpath_stride;
415840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
415940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_virtualpath *vpath;
416040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_vpath_reg __iomem *vp_reg;
416140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
416240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath = &hldev->virtual_paths[vp_id];
416340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vp_reg = vpath->vp_reg;
416440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	status = __vxge_hw_kdfc_swapper_set(hldev->legacy_reg, vp_reg);
416540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
416640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (status != VXGE_HW_OK)
416740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
416840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
416940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vp_reg->kdfc_drbl_triplet_total);
417040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
417140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath->max_kdfc_db =
417240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		(u32)VXGE_HW_KDFC_DRBL_TRIPLET_TOTAL_GET_KDFC_MAX_SIZE(
417340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64+1)/2;
417440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
417540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
417640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
417740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		vpath->max_nofl_db = vpath->max_kdfc_db;
417840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
417940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (vpath->max_nofl_db <
418040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			((vpath->vp_config->fifo.memblock_size /
418140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(vpath->vp_config->fifo.max_frags *
418240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			sizeof(struct vxge_hw_fifo_txd))) *
418340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			vpath->vp_config->fifo.fifo_blocks)) {
418440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
418540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			return VXGE_HW_BADCFG_FIFO_BLOCKS;
418640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
418740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_0(
418840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				(vpath->max_nofl_db*2)-1);
418940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
419040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
419140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(val64, &vp_reg->kdfc_fifo_trpl_partition);
419240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
419340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(VXGE_HW_KDFC_FIFO_TRPL_CTRL_TRIPLET_ENABLE,
419440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		&vp_reg->kdfc_fifo_trpl_ctrl);
419540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
419640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vp_reg->kdfc_trpl_fifo_0_ctrl);
419740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
419840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 &= ~(VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(0x3) |
419940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		   VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0xFF));
420040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
420140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 |= VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(
420240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		 VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_NON_OFFLOAD_ONLY) |
420340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#ifndef __BIG_ENDIAN
420440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		 VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SWAP_EN |
420540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa#endif
420640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		 VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0);
420740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
420840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(val64, &vp_reg->kdfc_trpl_fifo_0_ctrl);
420940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq((u64)0, &vp_reg->kdfc_trpl_fifo_0_wb_address);
421040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	wmb();
421140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath_stride = readq(&hldev->toc_reg->toc_kdfc_vpath_stride);
421240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
421340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath->nofl_db =
421440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		(struct __vxge_hw_non_offload_db_wrapper __iomem *)
421540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		(hldev->kdfc + (vp_id *
421640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		VXGE_HW_TOC_KDFC_VPATH_STRIDE_GET_TOC_KDFC_VPATH_STRIDE(
421740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					vpath_stride)));
421840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
421940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
422040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
422140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
422240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
422340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_mac_configure
422440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine configures the mac of virtual path using the config passed
422540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
422642821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
422740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_vpath_mac_configure(struct __vxge_hw_device *hldev, u32 vp_id)
422840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
422940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
423040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
423140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_virtualpath *vpath;
423240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_vp_config *vp_config;
423340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_vpath_reg __iomem *vp_reg;
423440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
423540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath = &hldev->virtual_paths[vp_id];
423640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vp_reg = vpath->vp_reg;
423740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vp_config = vpath->vp_config;
423840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
423940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(VXGE_HW_XMAC_VSPORT_CHOICE_VSPORT_NUMBER(
424040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			vpath->vsport_number), &vp_reg->xmac_vsport_choice);
424140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
424240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (vp_config->ring.enable == VXGE_HW_RING_ENABLE) {
424340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
424440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&vp_reg->xmac_rpa_vcfg);
424540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
424640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (vp_config->rpa_strip_vlan_tag !=
424740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) {
424840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			if (vp_config->rpa_strip_vlan_tag)
424940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				val64 |= VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG;
425040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			else
425140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				val64 &= ~VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG;
425240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
425340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
425440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(val64, &vp_reg->xmac_rpa_vcfg);
425540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&vp_reg->rxmac_vcfg0);
425640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
425740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (vp_config->mtu !=
425840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) {
425940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
426040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			if ((vp_config->mtu  +
426140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_MAC_HEADER_MAX_SIZE) < vpath->max_mtu)
426240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(
426340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					vp_config->mtu  +
426440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					VXGE_HW_MAC_HEADER_MAX_SIZE);
426540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			else
426640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(
426740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					vpath->max_mtu);
426840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
426940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
427040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(val64, &vp_reg->rxmac_vcfg0);
427140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
427240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&vp_reg->rxmac_vcfg1);
427340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
427440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 &= ~(VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(0x3) |
427540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE);
427640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
427740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (hldev->config.rth_it_type ==
427840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_RTH_IT_TYPE_MULTI_IT) {
427940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(
428040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				0x2) |
428140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE;
428240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
428340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
428440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(val64, &vp_reg->rxmac_vcfg1);
428540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
428640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
428740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
428840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
428940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
429040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * __vxge_hw_vpath_tim_configure
429140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * This routine configures the tim registers of virtual path using the config
429240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa * passed
429340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
429442821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
429540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa__vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id)
429640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
429740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
429840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
429940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct __vxge_hw_virtualpath *vpath;
430040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_vpath_reg __iomem *vp_reg;
430140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_vp_config *config;
430240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
430340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vpath = &hldev->virtual_paths[vp_id];
430440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vp_reg = vpath->vp_reg;
430540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	config = vpath->vp_config;
430640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4307528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(0, &vp_reg->tim_dest_addr);
4308528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(0, &vp_reg->tim_vpath_map);
4309528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(0, &vp_reg->tim_bitmap);
4310528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(0, &vp_reg->tim_remap);
431140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
431240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (config->ring.enable == VXGE_HW_RING_ENABLE)
431340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(VXGE_HW_TIM_RING_ASSN_INT_NUM(
431440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			(vp_id * VXGE_HW_MAX_INTR_PER_VP) +
431540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			VXGE_HW_VPATH_INTR_RX), &vp_reg->tim_ring_assn);
431640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
431740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 = readq(&vp_reg->tim_pci_cfg);
431840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	val64 |= VXGE_HW_TIM_PCI_CFG_ADD_PAD;
431940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	writeq(val64, &vp_reg->tim_pci_cfg);
432040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
432140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	if (config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
432240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
432340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
432440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
432540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
432640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
432740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				0x3ffffff);
432840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
432940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					config->tti.btimer_val);
433040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
433140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
433240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN;
433340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
433440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) {
433540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			if (config->tti.timer_ac_en)
433640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
433740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			else
433840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
433940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
434040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
434140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) {
434240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			if (config->tti.timer_ci_en)
434340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
434440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			else
434540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
434640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
434740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
434840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) {
434940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f);
435040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(
435140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					config->tti.urange_a);
435240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
435340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
435440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) {
435540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f);
435640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(
435740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					config->tti.urange_b);
435840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
435940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
436040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) {
436140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f);
436240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(
436340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					config->tti.urange_c);
436440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
436540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
436640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
436716fded7da2cefc619ece0d44f8df76b533c43fd2Jon Mason		vpath->tim_tti_cfg1_saved = val64;
436816fded7da2cefc619ece0d44f8df76b533c43fd2Jon Mason
436940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]);
437040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
437140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) {
437240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff);
437340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(
437440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						config->tti.uec_a);
437540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
437640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
437740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) {
437840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff);
437940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(
438040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						config->tti.uec_b);
438140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
438240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
438340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) {
438440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff);
438540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(
438640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						config->tti.uec_c);
438740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
438840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
438940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) {
439040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff);
439140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(
439240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa						config->tti.uec_d);
439340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
439440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
439540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]);
439640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]);
439740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
439840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) {
439940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			if (config->tti.timer_ri_en)
440040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
440140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			else
440240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa				val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
440340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
440440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
440540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
440640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
440740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					0x3ffffff);
440840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
440940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					config->tti.rtimer_val);
441040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
441140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
441240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) {
441340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f);
4414b55e7b153f698bb027102759388d0c09542f68bdJon Mason			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(vp_id);
441540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
441640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
441740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (config->tti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
441840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
441940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					0x3ffffff);
442040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
442140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					config->tti.ltimer_val);
442240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
442340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4424528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]);
442516fded7da2cefc619ece0d44f8df76b533c43fd2Jon Mason		vpath->tim_tti_cfg3_saved = val64;
4426528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
442740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4428528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (config->ring.enable == VXGE_HW_RING_ENABLE) {
442940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4430528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]);
443140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4432528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
4433528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
4434528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					0x3ffffff);
4435528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
4436528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					config->rti.btimer_val);
4437528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
443840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4439528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN;
444040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4441528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) {
4442528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			if (config->rti.timer_ac_en)
4443528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
4444528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			else
4445528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
4446528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
444740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4448528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) {
4449528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			if (config->rti.timer_ci_en)
4450528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
4451528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			else
4452528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
4453528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
445440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4455528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) {
4456528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f);
4457528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(
4458528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					config->rti.urange_a);
4459528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
446040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4461528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) {
4462528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f);
4463528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(
4464528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					config->rti.urange_b);
4465528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
446640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4467528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) {
4468528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f);
4469528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(
4470528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					config->rti.urange_c);
4471528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
447240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4473528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]);
447416fded7da2cefc619ece0d44f8df76b533c43fd2Jon Mason		vpath->tim_rti_cfg1_saved = val64;
447516fded7da2cefc619ece0d44f8df76b533c43fd2Jon Mason
4476528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]);
447740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4478528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) {
4479528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff);
4480528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(
4481528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						config->rti.uec_a);
4482528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
448340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4484528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) {
4485528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff);
4486528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(
4487528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						config->rti.uec_b);
4488528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
448940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4490528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) {
4491528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff);
4492528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(
4493528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						config->rti.uec_c);
4494528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
449540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4496528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) {
4497528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff);
4498528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(
4499528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						config->rti.uec_d);
4500528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
450140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4502528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]);
4503528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]);
450440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4505528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) {
4506528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			if (config->rti.timer_ri_en)
4507528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
4508528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			else
4509528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
4510528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
451140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4512528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
4513528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
4514528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					0x3ffffff);
4515528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
4516528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					config->rti.rtimer_val);
4517528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
451840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4519528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) {
4520528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f);
4521b55e7b153f698bb027102759388d0c09542f68bdJon Mason			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(vp_id);
4522528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
452340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4524528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (config->rti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
4525528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
4526528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					0x3ffffff);
4527528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
4528528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason					config->rti.ltimer_val);
4529528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		}
453040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4531528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]);
453216fded7da2cefc619ece0d44f8df76b533c43fd2Jon Mason		vpath->tim_rti_cfg3_saved = val64;
453340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
453440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4535528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = 0;
4536528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_EINTA]);
4537528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_EINTA]);
4538528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_EINTA]);
4539528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_BMAP]);
4540528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_BMAP]);
4541528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_BMAP]);
4542528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
4543b55e7b153f698bb027102759388d0c09542f68bdJon Mason	val64 = VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_PRD(150);
4544b55e7b153f698bb027102759388d0c09542f68bdJon Mason	val64 |= VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_DIV(0);
4545b55e7b153f698bb027102759388d0c09542f68bdJon Mason	val64 |= VXGE_HW_TIM_WRKLD_CLC_CNT_RX_TX(3);
4546b55e7b153f698bb027102759388d0c09542f68bdJon Mason	writeq(val64, &vp_reg->tim_wrkld_clc);
4547b55e7b153f698bb027102759388d0c09542f68bdJon Mason
454840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
454940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
455040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
455140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
4552528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_vpath_initialize
4553528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This routine is the final phase of init which initializes the
4554528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * registers of the vpath using the configuration passed.
455540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
455642821a5b393e36f5c0b267473d59d375578df7ecstephen hemmingerstatic enum vxge_hw_status
4557528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_vpath_initialize(struct __vxge_hw_device *hldev, u32 vp_id)
455840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
455940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	u64 val64;
4560528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 val32;
456140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
4562528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_virtualpath *vpath;
456340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	struct vxge_hw_vpath_reg __iomem *vp_reg;
456440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4565528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath = &hldev->virtual_paths[vp_id];
4566528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
4567528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) {
4568528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE;
456940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
457040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
457140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	vp_reg = vpath->vp_reg;
457240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4573528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status =  __vxge_hw_vpath_swapper_set(vpath->vp_reg);
4574528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
4575528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
457640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4577528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status =  __vxge_hw_vpath_mac_configure(hldev, vp_id);
4578528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
4579528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
458040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4581528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status =  __vxge_hw_vpath_kdfc_configure(hldev, vp_id);
4582528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
4583528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
458440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4585528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_tim_configure(hldev, vp_id);
4586528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
4587528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
458840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4589528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vp_reg->rtdma_rd_optimization_ctrl);
459040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4591528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	/* Get MRRS value from device control */
4592528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status  = __vxge_hw_vpath_pci_read(vpath, 1, 0x78, &val32);
4593528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status == VXGE_HW_OK) {
4594528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val32 = (val32 & VXGE_HW_PCI_EXP_DEVCTL_READRQ) >> 12;
4595528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64 &=
4596528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		    ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(7));
4597528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64 |=
4598528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		    VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(val32);
459940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4600528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_WAIT_FOR_SPACE;
4601528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
460240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4603528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 &= ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(7));
4604528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 |=
4605528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	    VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(
4606528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		    VXGE_HW_MAX_PAYLOAD_SIZE_512);
460740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4608528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY_EN;
4609528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(val64, &vp_reg->rtdma_rd_optimization_ctrl);
461040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4611528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
4612528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
4613528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
461440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4615528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
4616528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_vp_terminate - Terminate Virtual Path structure
4617528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This routine closes all channels it opened and freeup memory
4618528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
4619528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic void __vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id)
4620528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
4621528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_virtualpath *vpath;
462240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4623528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath = &hldev->virtual_paths[vp_id];
462440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4625528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN)
462640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		goto exit;
462740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4628528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	VXGE_HW_DEVICE_TIM_INT_MASK_RESET(vpath->hldev->tim_int_mask0,
4629528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vpath->hldev->tim_int_mask1, vpath->vp_id);
4630528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL;
463140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
46329f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	/* If the whole struct __vxge_hw_virtualpath is zeroed, nothing will
46339f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	 * work after the interface is brought down.
46349f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	 */
46359f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	spin_lock(&vpath->lock);
46369f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->vp_open = VXGE_HW_VP_NOT_OPEN;
46379f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	spin_unlock(&vpath->lock);
46389f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason
46399f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->vpmgmt_reg = NULL;
46409f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->nofl_db = NULL;
46419f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->max_mtu = 0;
46429f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->vsport_number = 0;
46439f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->max_kdfc_db = 0;
46449f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->max_nofl_db = 0;
46459f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->ringh = NULL;
46469f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->fifoh = NULL;
46479f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	memset(&vpath->vpath_handles, 0, sizeof(struct list_head));
46489f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->stats_block = 0;
46499f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->hw_stats = NULL;
46509f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->hw_stats_sav = NULL;
46519f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	vpath->sw_stats = NULL;
46529f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason
4653528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
4654528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return;
4655528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
465640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4657528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
4658528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_vp_initialize - Initialize Virtual Path structure
4659528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This routine is the initial phase of init which resets the vpath and
4660528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * initializes the software support structures.
4661528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
4662528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic enum vxge_hw_status
4663528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id,
4664528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			struct vxge_hw_vp_config *config)
4665528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
4666528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_virtualpath *vpath;
4667528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
466840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4669528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) {
4670528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE;
4671528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
4672528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
467340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4674528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath = &hldev->virtual_paths[vp_id];
467540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
46769f9b16458134ba9f06ef6f15369513aa9eebc81cJon Mason	spin_lock_init(&vpath->lock);
4677528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->vp_id = vp_id;
4678528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->vp_open = VXGE_HW_VP_OPEN;
4679528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->hldev = hldev;
4680528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->vp_config = config;
4681528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->vp_reg = hldev->vpath_reg[vp_id];
4682528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->vpmgmt_reg = hldev->vpmgmt_reg[vp_id];
468340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4684528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_vpath_reset(hldev, vp_id);
468540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4686528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_reset_check(vpath);
4687528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK) {
4688528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
4689528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
4690528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
469140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4692528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_mgmt_read(hldev, vpath);
4693528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK) {
4694528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
4695528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
4696528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
469740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4698528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	INIT_LIST_HEAD(&vpath->vpath_handles);
469940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4700528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->sw_stats = &hldev->stats.sw_dev_info_stats.vpath_info[vp_id];
470140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4702528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	VXGE_HW_DEVICE_TIM_INT_MASK_SET(hldev->tim_int_mask0,
4703528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		hldev->tim_int_mask1, vp_id);
470440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4705528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_initialize(hldev, vp_id);
4706528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
4707528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_vp_terminate(hldev, vp_id);
470840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepaexit:
470940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	return status;
471040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
471140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4712528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
4713528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_vpath_mtu_set - Set MTU.
4714528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Set new MTU value. Example, to use jumbo frames:
4715528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_vpath_mtu_set(my_device, 9600);
4716528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
4717528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonenum vxge_hw_status
4718528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvxge_hw_vpath_mtu_set(struct __vxge_hw_vpath_handle *vp, u32 new_mtu)
471942821a5b393e36f5c0b267473d59d375578df7ecstephen hemminger{
4720528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u64 val64;
4721528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status = VXGE_HW_OK;
4722528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_virtualpath *vpath;
472342821a5b393e36f5c0b267473d59d375578df7ecstephen hemminger
4724528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vp == NULL) {
4725528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_INVALID_HANDLE;
4726528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
4727528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
4728528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath = vp->vpath;
472942821a5b393e36f5c0b267473d59d375578df7ecstephen hemminger
4730528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	new_mtu += VXGE_HW_MAC_HEADER_MAX_SIZE;
473142821a5b393e36f5c0b267473d59d375578df7ecstephen hemminger
4732528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if ((new_mtu < VXGE_HW_MIN_MTU) || (new_mtu > vpath->max_mtu))
4733528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_INVALID_MTU_SIZE;
473442821a5b393e36f5c0b267473d59d375578df7ecstephen hemminger
4735528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
4736528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
4737528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
4738528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(new_mtu);
4739528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
4740528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
4741528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
4742528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->vp_config->mtu = new_mtu - VXGE_HW_MAC_HEADER_MAX_SIZE;
4743528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
4744528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
4745528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
474642821a5b393e36f5c0b267473d59d375578df7ecstephen hemminger}
474742821a5b393e36f5c0b267473d59d375578df7ecstephen hemminger
474840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
4749528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_vpath_stats_enable - Enable vpath h/wstatistics.
4750528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * Enable the DMA vpath statistics. The function is to be called to re-enable
4751528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * the adapter to update stats into the host memory
475240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
47532c91308f449c6705b81bd3370a0ec647e370f35cJon Masonstatic enum vxge_hw_status
4754528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vp)
475540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
475640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
4757528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_virtualpath *vpath;
475840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4759528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath = vp->vpath;
476040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4761528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
4762528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
4763528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
476440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
476540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4766528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	memcpy(vpath->hw_stats_sav, vpath->hw_stats,
4767528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			sizeof(struct vxge_hw_vpath_stats_hw_info));
476840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4769528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_stats_get(vpath, vpath->hw_stats);
4770528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
4771528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
4772528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
477340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4774528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
4775528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool
4776528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function allocates a block from block pool or from the system
4777528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
4778528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic struct __vxge_hw_blockpool_entry *
4779528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size)
4780528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
4781528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_blockpool_entry *entry = NULL;
4782528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_blockpool  *blockpool;
478340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4784528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool = &devh->block_pool;
478540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4786528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (size == blockpool->block_size) {
478740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4788528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (!list_empty(&blockpool->free_block_list))
478940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			entry = (struct __vxge_hw_blockpool_entry *)
4790528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				list_first_entry(&blockpool->free_block_list,
479140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					struct __vxge_hw_blockpool_entry,
479240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa					item);
479340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
479440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		if (entry != NULL) {
479540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa			list_del(&entry->item);
4796528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			blockpool->pool_size--;
479740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		}
479840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
479940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4800528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (entry != NULL)
4801528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_blockpool_blocks_add(blockpool);
4802528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
4803528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return entry;
480440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
480540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
480640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
4807528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_vpath_open - Open a virtual path on a given adapter
4808528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function is used to open access to virtual path of an
4809528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * adapter for offload, GRO operations. This function returns
4810528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * synchronously.
481140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
4812528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonenum vxge_hw_status
4813528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvxge_hw_vpath_open(struct __vxge_hw_device *hldev,
4814528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		   struct vxge_hw_vpath_attr *attr,
4815528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		   struct __vxge_hw_vpath_handle **vpath_handle)
481640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
4817528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_virtualpath *vpath;
4818528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_vpath_handle *vp;
4819528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status;
482040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4821528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath = &hldev->virtual_paths[attr->vp_id];
482240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4823528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_open == VXGE_HW_VP_OPEN) {
4824528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_INVALID_STATE;
4825528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto vpath_open_exit1;
482640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
482740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4828528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vp_initialize(hldev, attr->vp_id,
4829528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			&hldev->config.vp_config[attr->vp_id]);
4830528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
4831528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto vpath_open_exit1;
483240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4833528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp = vzalloc(sizeof(struct __vxge_hw_vpath_handle));
4834528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vp == NULL) {
4835528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_OUT_OF_MEMORY;
4836528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto vpath_open_exit2;
4837528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
483840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4839528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp->vpath = vpath;
484040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4841528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
4842528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = __vxge_hw_fifo_create(vp, &attr->fifo_attr);
4843528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (status != VXGE_HW_OK)
4844528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto vpath_open_exit6;
484540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
484640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4847528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_config->ring.enable == VXGE_HW_RING_ENABLE) {
4848528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = __vxge_hw_ring_create(vp, &attr->ring_attr);
4849528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		if (status != VXGE_HW_OK)
4850528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			goto vpath_open_exit7;
4851528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
4852528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_vpath_prc_configure(hldev, attr->vp_id);
485340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
485440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4855528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->fifoh->tx_intr_num =
4856528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		(attr->vp_id * VXGE_HW_MAX_INTR_PER_VP)  +
4857528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			VXGE_HW_VPATH_INTR_TX;
485840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4859528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->stats_block = __vxge_hw_blockpool_block_allocate(hldev,
4860528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason				VXGE_HW_BLOCK_SIZE);
4861528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->stats_block == NULL) {
4862528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_OUT_OF_MEMORY;
4863528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto vpath_open_exit8;
486440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
486540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
486643d620c82985b19008d87a437b4cf83f356264f7Joe Perches	vpath->hw_stats = vpath->stats_block->memblock;
4867528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	memset(vpath->hw_stats, 0,
4868528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		sizeof(struct vxge_hw_vpath_stats_hw_info));
486940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4870528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hldev->stats.hw_dev_info_stats.vpath_info[attr->vp_id] =
4871528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason						vpath->hw_stats;
487240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4873528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath->hw_stats_sav =
4874528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		&hldev->stats.hw_dev_info_stats.vpath_info_sav[attr->vp_id];
4875528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	memset(vpath->hw_stats_sav, 0,
4876528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			sizeof(struct vxge_hw_vpath_stats_hw_info));
487740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4878528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(vpath->stats_block->dma_addr, &vpath->vp_reg->stats_cfg);
487940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4880528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = vxge_hw_vpath_stats_enable(vp);
4881528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
4882528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto vpath_open_exit8;
488340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4884528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	list_add(&vp->item, &vpath->vpath_handles);
488540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4886528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hldev->vpaths_deployed |= vxge_mBIT(vpath->vp_id);
488740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4888528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	*vpath_handle = vp;
488940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4890528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	attr->fifo_attr.userdata = vpath->fifoh;
4891528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	attr->ring_attr.userdata = vpath->ringh;
489240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4893528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return VXGE_HW_OK;
4894528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
4895528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvpath_open_exit8:
4896528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->ringh != NULL)
4897528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_ring_delete(vp);
4898528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvpath_open_exit7:
4899528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->fifoh != NULL)
4900528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_fifo_delete(vp);
4901528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvpath_open_exit6:
4902528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vfree(vp);
4903528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvpath_open_exit2:
4904528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_vp_terminate(hldev, attr->vp_id);
4905528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvpath_open_exit1:
4906528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
4907528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
490840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
490940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4910528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/**
4911528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_vpath_rx_doorbell_post - Close the handle got from previous vpath
4912528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * (vpath) open
4913528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * @vp: Handle got from previous vpath open
4914528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason *
4915528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function is used to close access to virtual path opened
4916528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * earlier.
491740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
4918528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvoid vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp)
491940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
4920528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_virtualpath *vpath = vp->vpath;
4921528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_ring *ring = vpath->ringh;
4922528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct vxgedev *vdev = netdev_priv(vpath->hldev->ndev);
4923528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u64 new_count, val64, val164;
492440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4925528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vdev->titan1) {
4926528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		new_count = readq(&vpath->vp_reg->rxdmem_size);
4927528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		new_count &= 0x1fff;
4928528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	} else
4929528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		new_count = ring->config->ring_blocks * VXGE_HW_BLOCK_SIZE / 8;
493040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4931528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val164 = VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count);
493240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4933528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val164),
4934528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		&vpath->vp_reg->prc_rxd_doorbell);
4935528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	readl(&vpath->vp_reg->prc_rxd_doorbell);
493640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4937528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val164 /= 2;
4938528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = readq(&vpath->vp_reg->prc_cfg6);
4939528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = VXGE_HW_PRC_CFG6_RXD_SPAT(val64);
4940528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 &= 0x1ff;
494140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4942528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	/*
4943528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	 * Each RxD is of 4 qwords
4944528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	 */
4945528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	new_count -= (val64 + 1);
4946528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = min(val164, new_count) / 4;
494740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4948528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	ring->rxds_limit = min(ring->rxds_limit, val64);
4949528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (ring->rxds_limit < 4)
4950528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		ring->rxds_limit = 4;
4951528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason}
495240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4953528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason/*
4954528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * __vxge_hw_blockpool_block_free - Frees a block from block pool
4955528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * @devh: Hal device
4956528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * @entry: Entry of block to be freed
4957528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason *
4958528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function frees a block from block pool
4959528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason */
4960528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonstatic void
4961528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason__vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh,
4962528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason			       struct __vxge_hw_blockpool_entry *entry)
4963528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason{
4964528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_blockpool  *blockpool;
496540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4966528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	blockpool = &devh->block_pool;
496740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4968528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (entry->length == blockpool->block_size) {
496940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		list_add(&entry->item, &blockpool->free_block_list);
497040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa		blockpool->pool_size++;
4971528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
497240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4973528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_blockpool_blocks_remove(blockpool);
497440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
497540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
497640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
4977528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_vpath_close - Close the handle got from previous vpath (vpath) open
4978528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function is used to close access to virtual path opened
4979528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * earlier.
498040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
4981528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonenum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp)
498240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
4983528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_virtualpath *vpath = NULL;
4984528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_device *devh = NULL;
4985528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 vp_id = vp->vpath->vp_id;
4986528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 is_empty = TRUE;
498740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	enum vxge_hw_status status = VXGE_HW_OK;
498840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4989528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath = vp->vpath;
4990528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	devh = vpath->hldev;
499140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4992528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
4993528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
4994528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto vpath_close_exit;
4995528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
499640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4997528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	list_del(&vp->item);
499840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
4999528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (!list_empty(&vpath->vpath_handles)) {
5000528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		list_add(&vp->item, &vpath->vpath_handles);
5001528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		is_empty = FALSE;
5002528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
500340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5004528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (!is_empty) {
5005528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_FAIL;
5006528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto vpath_close_exit;
5007528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
500840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5009528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	devh->vpaths_deployed &= ~vxge_mBIT(vp_id);
501040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5011528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->ringh != NULL)
5012528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_ring_delete(vp);
501340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5014528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->fifoh != NULL)
5015528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_fifo_delete(vp);
501640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5017528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->stats_block != NULL)
5018528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_blockpool_block_free(devh, vpath->stats_block);
501940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5020528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vfree(vp);
502140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5022528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_vp_terminate(devh, vp_id);
5023528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
5024528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvpath_close_exit:
5025528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
502640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
502740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
502840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
5029528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_vpath_reset - Resets vpath
5030528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function is used to request a reset of vpath
503140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
5032528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonenum vxge_hw_status vxge_hw_vpath_reset(struct __vxge_hw_vpath_handle *vp)
503340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
5034528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status;
5035528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 vp_id;
5036528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_virtualpath *vpath = vp->vpath;
503740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5038528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp_id = vpath->vp_id;
503940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5040528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
5041528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
5042528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
504340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa	}
5044528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
5045528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_reset(vpath->hldev, vp_id);
5046528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status == VXGE_HW_OK)
5047528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		vpath->sw_stats->soft_reset_cnt++;
5048528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
5049528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
505040a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
505140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
505240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
5053528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_vpath_recover_from_reset - Poll for reset complete and re-initialize.
5054528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This function poll's for the vpath reset completion and re initializes
5055528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * the vpath.
505640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
5057528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonenum vxge_hw_status
5058528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvxge_hw_vpath_recover_from_reset(struct __vxge_hw_vpath_handle *vp)
505940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
5060528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_virtualpath *vpath = NULL;
5061528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	enum vxge_hw_status status;
5062528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_device *hldev;
5063528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u32 vp_id;
506440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5065528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vp_id = vp->vpath->vp_id;
5066528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	vpath = vp->vpath;
5067528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hldev = vpath->hldev;
506840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5069528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
5070528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
5071528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
5072528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	}
507340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5074528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_reset_check(vpath);
5075528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
5076528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
507740a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5078528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_sw_reset(hldev, vp_id);
5079528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
5080528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
508140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5082528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = __vxge_hw_vpath_initialize(hldev, vp_id);
5083528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (status != VXGE_HW_OK)
5084528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		goto exit;
508540a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5086528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	if (vpath->ringh != NULL)
5087528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		__vxge_hw_vpath_prc_configure(hldev, vp_id);
5088528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
5089528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	memset(vpath->hw_stats, 0,
5090528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		sizeof(struct vxge_hw_vpath_stats_hw_info));
5091528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
5092528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	memset(vpath->hw_stats_sav, 0,
5093528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		sizeof(struct vxge_hw_vpath_stats_hw_info));
5094528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
5095528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	writeq(vpath->stats_block->dma_addr,
5096528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		&vpath->vp_reg->stats_cfg);
5097528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
5098528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	status = vxge_hw_vpath_stats_enable(vp);
5099528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason
5100528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonexit:
5101528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	return status;
510240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
510340a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
510440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa/*
5105528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * vxge_hw_vpath_enable - Enable vpath.
5106528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * This routine clears the vpath reset thereby enabling a vpath
5107528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason * to start forwarding frames and generating interrupts.
510840a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa */
5109528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvoid
5110528f727279ae840db8a06c94f5e82cdaeb00da6fJon Masonvxge_hw_vpath_enable(struct __vxge_hw_vpath_handle *vp)
511140a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa{
5112528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	struct __vxge_hw_device *hldev;
5113528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	u64 val64;
511440a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5115528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	hldev = vp->vpath->hldev;
511640a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5117528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	val64 = VXGE_HW_CMN_RSTHDLR_CFG1_CLR_VPATH_RESET(
5118528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		1 << (16 - vp->vpath->vp_id));
511940a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa
5120528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason	__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
5121528f727279ae840db8a06c94f5e82cdaeb00da6fJon Mason		&hldev->common_reg->cmn_rsthdlr_cfg1);
512240a3a9156dc66f23cc79758981886c1896887341Ramkrishna Vepa}
5123