mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	RDMA/irdma: Add irdma Kconfig/Makefile and remove i40iw
Add Kconfig and Makefile to build irdma driver. Remove i40iw driver and add an alias in irdma. Remove legacy exported symbols i40e_register_client and i40e_unregister_client from i40e as they are no longer used. irdma is the replacement driver that supports X722. Link: https://lore.kernel.org/r/20210602205138.889-16-shiraz.saleem@intel.com Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
		
							parent
							
								
									48d6b3336a
								
							
						
					
					
						commit
						fa0cf568fd
					
				
					 38 changed files with 41 additions and 28996 deletions
				
			
		| 
						 | 
					@ -731,26 +731,6 @@ Description:
 | 
				
			||||||
		is the irq number of "sdma3", and M is irq number of "sdma4" in
 | 
							is the irq number of "sdma3", and M is irq number of "sdma4" in
 | 
				
			||||||
		the /proc/interrupts file.
 | 
							the /proc/interrupts file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
sysfs interface for Intel(R) X722 iWARP i40iw driver
 | 
					 | 
				
			||||||
----------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
What:		/sys/class/infiniband/i40iwX/hw_rev
 | 
					 | 
				
			||||||
What:		/sys/class/infiniband/i40iwX/hca_type
 | 
					 | 
				
			||||||
What:		/sys/class/infiniband/i40iwX/board_id
 | 
					 | 
				
			||||||
Date:		Jan, 2016
 | 
					 | 
				
			||||||
KernelVersion:	v4.10
 | 
					 | 
				
			||||||
Contact:	linux-rdma@vger.kernel.org
 | 
					 | 
				
			||||||
Description:
 | 
					 | 
				
			||||||
		=============== ==== ========================
 | 
					 | 
				
			||||||
		hw_rev:		(RO) Hardware revision number
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		hca_type:	(RO) Show HCA type (I40IW)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		board_id:	(RO) I40IW board ID
 | 
					 | 
				
			||||||
		=============== ==== ========================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sysfs interface for QLogic qedr NIC Driver
 | 
					sysfs interface for QLogic qedr NIC Driver
 | 
				
			||||||
------------------------------------------
 | 
					------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9365,14 +9365,6 @@ L:	linux-pm@vger.kernel.org
 | 
				
			||||||
S:	Supported
 | 
					S:	Supported
 | 
				
			||||||
F:	drivers/cpufreq/intel_pstate.c
 | 
					F:	drivers/cpufreq/intel_pstate.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INTEL RDMA RNIC DRIVER
 | 
					 | 
				
			||||||
M:	Faisal Latif <faisal.latif@intel.com>
 | 
					 | 
				
			||||||
M:	Shiraz Saleem <shiraz.saleem@intel.com>
 | 
					 | 
				
			||||||
L:	linux-rdma@vger.kernel.org
 | 
					 | 
				
			||||||
S:	Supported
 | 
					 | 
				
			||||||
F:	drivers/infiniband/hw/i40iw/
 | 
					 | 
				
			||||||
F:	include/uapi/rdma/i40iw-abi.h
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
INTEL SCU DRIVERS
 | 
					INTEL SCU DRIVERS
 | 
				
			||||||
M:	Mika Westerberg <mika.westerberg@linux.intel.com>
 | 
					M:	Mika Westerberg <mika.westerberg@linux.intel.com>
 | 
				
			||||||
S:	Maintained
 | 
					S:	Maintained
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +82,7 @@ source "drivers/infiniband/hw/mthca/Kconfig"
 | 
				
			||||||
source "drivers/infiniband/hw/qib/Kconfig"
 | 
					source "drivers/infiniband/hw/qib/Kconfig"
 | 
				
			||||||
source "drivers/infiniband/hw/cxgb4/Kconfig"
 | 
					source "drivers/infiniband/hw/cxgb4/Kconfig"
 | 
				
			||||||
source "drivers/infiniband/hw/efa/Kconfig"
 | 
					source "drivers/infiniband/hw/efa/Kconfig"
 | 
				
			||||||
source "drivers/infiniband/hw/i40iw/Kconfig"
 | 
					source "drivers/infiniband/hw/irdma/Kconfig"
 | 
				
			||||||
source "drivers/infiniband/hw/mlx4/Kconfig"
 | 
					source "drivers/infiniband/hw/mlx4/Kconfig"
 | 
				
			||||||
source "drivers/infiniband/hw/mlx5/Kconfig"
 | 
					source "drivers/infiniband/hw/mlx5/Kconfig"
 | 
				
			||||||
source "drivers/infiniband/hw/ocrdma/Kconfig"
 | 
					source "drivers/infiniband/hw/ocrdma/Kconfig"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@ obj-$(CONFIG_INFINIBAND_MTHCA)		+= mthca/
 | 
				
			||||||
obj-$(CONFIG_INFINIBAND_QIB)		+= qib/
 | 
					obj-$(CONFIG_INFINIBAND_QIB)		+= qib/
 | 
				
			||||||
obj-$(CONFIG_INFINIBAND_CXGB4)		+= cxgb4/
 | 
					obj-$(CONFIG_INFINIBAND_CXGB4)		+= cxgb4/
 | 
				
			||||||
obj-$(CONFIG_INFINIBAND_EFA)		+= efa/
 | 
					obj-$(CONFIG_INFINIBAND_EFA)		+= efa/
 | 
				
			||||||
obj-$(CONFIG_INFINIBAND_I40IW)		+= i40iw/
 | 
					obj-$(CONFIG_INFINIBAND_IRDMA)		+= irdma/
 | 
				
			||||||
obj-$(CONFIG_MLX4_INFINIBAND)		+= mlx4/
 | 
					obj-$(CONFIG_MLX4_INFINIBAND)		+= mlx4/
 | 
				
			||||||
obj-$(CONFIG_MLX5_INFINIBAND)		+= mlx5/
 | 
					obj-$(CONFIG_MLX5_INFINIBAND)		+= mlx5/
 | 
				
			||||||
obj-$(CONFIG_INFINIBAND_OCRDMA)		+= ocrdma/
 | 
					obj-$(CONFIG_INFINIBAND_OCRDMA)		+= ocrdma/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +0,0 @@
 | 
				
			||||||
# SPDX-License-Identifier: GPL-2.0-only
 | 
					 | 
				
			||||||
config INFINIBAND_I40IW
 | 
					 | 
				
			||||||
	tristate "Intel(R) Ethernet X722 iWARP Driver"
 | 
					 | 
				
			||||||
	depends on INET && I40E
 | 
					 | 
				
			||||||
	depends on IPV6 || !IPV6
 | 
					 | 
				
			||||||
	depends on PCI
 | 
					 | 
				
			||||||
	select GENERIC_ALLOCATOR
 | 
					 | 
				
			||||||
	help
 | 
					 | 
				
			||||||
	Intel(R) Ethernet X722 iWARP Driver
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,9 +0,0 @@
 | 
				
			||||||
# SPDX-License-Identifier: GPL-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
obj-$(CONFIG_INFINIBAND_I40IW) += i40iw.o
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
i40iw-objs :=\
 | 
					 | 
				
			||||||
               i40iw_cm.o i40iw_ctrl.o \
 | 
					 | 
				
			||||||
               i40iw_hmc.o i40iw_hw.o i40iw_main.o  \
 | 
					 | 
				
			||||||
               i40iw_pble.o i40iw_puda.o i40iw_uk.o i40iw_utils.o \
 | 
					 | 
				
			||||||
               i40iw_verbs.o i40iw_virtchnl.o i40iw_vf.o
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,602 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_IW_H
 | 
					 | 
				
			||||||
#define I40IW_IW_H
 | 
					 | 
				
			||||||
#include <linux/netdevice.h>
 | 
					 | 
				
			||||||
#include <linux/inetdevice.h>
 | 
					 | 
				
			||||||
#include <linux/spinlock.h>
 | 
					 | 
				
			||||||
#include <linux/kernel.h>
 | 
					 | 
				
			||||||
#include <linux/delay.h>
 | 
					 | 
				
			||||||
#include <linux/pci.h>
 | 
					 | 
				
			||||||
#include <linux/dma-mapping.h>
 | 
					 | 
				
			||||||
#include <linux/workqueue.h>
 | 
					 | 
				
			||||||
#include <linux/slab.h>
 | 
					 | 
				
			||||||
#include <linux/io.h>
 | 
					 | 
				
			||||||
#include <linux/crc32c.h>
 | 
					 | 
				
			||||||
#include <linux/net/intel/i40e_client.h>
 | 
					 | 
				
			||||||
#include <rdma/ib_smi.h>
 | 
					 | 
				
			||||||
#include <rdma/ib_verbs.h>
 | 
					 | 
				
			||||||
#include <rdma/ib_pack.h>
 | 
					 | 
				
			||||||
#include <rdma/rdma_cm.h>
 | 
					 | 
				
			||||||
#include <rdma/iw_cm.h>
 | 
					 | 
				
			||||||
#include <crypto/hash.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "i40iw_status.h"
 | 
					 | 
				
			||||||
#include "i40iw_osdep.h"
 | 
					 | 
				
			||||||
#include "i40iw_d.h"
 | 
					 | 
				
			||||||
#include "i40iw_hmc.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "i40iw_type.h"
 | 
					 | 
				
			||||||
#include "i40iw_p.h"
 | 
					 | 
				
			||||||
#include <rdma/i40iw-abi.h>
 | 
					 | 
				
			||||||
#include "i40iw_pble.h"
 | 
					 | 
				
			||||||
#include "i40iw_verbs.h"
 | 
					 | 
				
			||||||
#include "i40iw_cm.h"
 | 
					 | 
				
			||||||
#include "i40iw_user.h"
 | 
					 | 
				
			||||||
#include "i40iw_puda.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_FW_VER_DEFAULT 2
 | 
					 | 
				
			||||||
#define I40IW_HW_VERSION  2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_ARP_ADD     1
 | 
					 | 
				
			||||||
#define I40IW_ARP_DELETE  2
 | 
					 | 
				
			||||||
#define I40IW_ARP_RESOLVE 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_MACIP_ADD     1
 | 
					 | 
				
			||||||
#define I40IW_MACIP_DELETE  2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define IW_CCQ_SIZE         (I40IW_CQP_SW_SQSIZE_2048 + 1)
 | 
					 | 
				
			||||||
#define IW_CEQ_SIZE         2048
 | 
					 | 
				
			||||||
#define IW_AEQ_SIZE         2048
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RX_BUF_SIZE            (1536 + 8)
 | 
					 | 
				
			||||||
#define IW_REG0_SIZE           (4 * 1024)
 | 
					 | 
				
			||||||
#define IW_TX_TIMEOUT          (6 * HZ)
 | 
					 | 
				
			||||||
#define IW_FIRST_QPN           1
 | 
					 | 
				
			||||||
#define IW_SW_CONTEXT_ALIGN    1024
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAX_DPC_ITERATIONS		128
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_EVENT_TIMEOUT		100000
 | 
					 | 
				
			||||||
#define I40IW_VCHNL_EVENT_TIMEOUT	100000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	I40IW_NO_VLAN			0xffff
 | 
					 | 
				
			||||||
#define	I40IW_NO_QSET			0xffff
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* access to mcast filter list */
 | 
					 | 
				
			||||||
#define IW_ADD_MCAST false
 | 
					 | 
				
			||||||
#define IW_DEL_MCAST true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_ENABLE_MPA_VER_0     0x00000001
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_DISABLE_MPA_CRC      0x00000002
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_DISABLE_FIRST_WRITE  0x00000004
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_DISABLE_INTF         0x00000008
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_ENABLE_MSI           0x00000010
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_DUAL_LOGICAL_PORT    0x00000020
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_NO_INLINE_DATA       0x00000080
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_DISABLE_INT_MOD      0x00000100
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_DISABLE_VIRT_WQ      0x00000200
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_ENABLE_PAU           0x00000400
 | 
					 | 
				
			||||||
#define I40IW_DRV_OPT_MCAST_LOGPORT_MAP    0x00000800
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define IW_HMC_OBJ_TYPE_NUM ARRAY_SIZE(iw_hmc_obj_types)
 | 
					 | 
				
			||||||
#define IW_CFG_FPM_QP_COUNT               32768
 | 
					 | 
				
			||||||
#define I40IW_MAX_PAGES_PER_FMR           512
 | 
					 | 
				
			||||||
#define I40IW_MIN_PAGES_PER_FMR           1
 | 
					 | 
				
			||||||
#define I40IW_CQP_COMPL_RQ_WQE_FLUSHED    2
 | 
					 | 
				
			||||||
#define I40IW_CQP_COMPL_SQ_WQE_FLUSHED    3
 | 
					 | 
				
			||||||
#define I40IW_CQP_COMPL_RQ_SQ_WQE_FLUSHED 4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cqp_compl_info {
 | 
					 | 
				
			||||||
	u32 op_ret_val;
 | 
					 | 
				
			||||||
	u16 maj_err_code;
 | 
					 | 
				
			||||||
	u16 min_err_code;
 | 
					 | 
				
			||||||
	bool error;
 | 
					 | 
				
			||||||
	u8 op_code;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define i40iw_pr_err(fmt, args ...) pr_err("%s: "fmt, __func__, ## args)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define i40iw_pr_info(fmt, args ...) pr_info("%s: " fmt, __func__, ## args)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define i40iw_pr_warn(fmt, args ...) pr_warn("%s: " fmt, __func__, ## args)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cqp_request {
 | 
					 | 
				
			||||||
	struct cqp_commands_info info;
 | 
					 | 
				
			||||||
	wait_queue_head_t waitq;
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
					 | 
				
			||||||
	atomic_t refcount;
 | 
					 | 
				
			||||||
	void (*callback_fcn)(struct i40iw_cqp_request*, u32);
 | 
					 | 
				
			||||||
	void *param;
 | 
					 | 
				
			||||||
	struct i40iw_cqp_compl_info compl_info;
 | 
					 | 
				
			||||||
	bool waiting;
 | 
					 | 
				
			||||||
	bool request_done;
 | 
					 | 
				
			||||||
	bool dynamic;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cqp {
 | 
					 | 
				
			||||||
	struct i40iw_sc_cqp sc_cqp;
 | 
					 | 
				
			||||||
	spinlock_t req_lock; /*cqp request list */
 | 
					 | 
				
			||||||
	wait_queue_head_t waitq;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem sq;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem host_ctx;
 | 
					 | 
				
			||||||
	u64 *scratch_array;
 | 
					 | 
				
			||||||
	struct i40iw_cqp_request *cqp_requests;
 | 
					 | 
				
			||||||
	struct list_head cqp_avail_reqs;
 | 
					 | 
				
			||||||
	struct list_head cqp_pending_reqs;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_device;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_ccq {
 | 
					 | 
				
			||||||
	struct i40iw_sc_cq sc_cq;
 | 
					 | 
				
			||||||
	spinlock_t lock; /* ccq control */
 | 
					 | 
				
			||||||
	wait_queue_head_t waitq;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem mem_cq;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem shadow_area;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_ceq {
 | 
					 | 
				
			||||||
	struct i40iw_sc_ceq sc_ceq;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem mem;
 | 
					 | 
				
			||||||
	u32 irq;
 | 
					 | 
				
			||||||
	u32 msix_idx;
 | 
					 | 
				
			||||||
	struct i40iw_device *iwdev;
 | 
					 | 
				
			||||||
	struct tasklet_struct dpc_tasklet;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_aeq {
 | 
					 | 
				
			||||||
	struct i40iw_sc_aeq sc_aeq;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem mem;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_arp_entry {
 | 
					 | 
				
			||||||
	u32 ip_addr[4];
 | 
					 | 
				
			||||||
	u8 mac_addr[ETH_ALEN];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum init_completion_state {
 | 
					 | 
				
			||||||
	INVALID_STATE = 0,
 | 
					 | 
				
			||||||
	INITIAL_STATE,
 | 
					 | 
				
			||||||
	CQP_CREATED,
 | 
					 | 
				
			||||||
	HMC_OBJS_CREATED,
 | 
					 | 
				
			||||||
	PBLE_CHUNK_MEM,
 | 
					 | 
				
			||||||
	CCQ_CREATED,
 | 
					 | 
				
			||||||
	AEQ_CREATED,
 | 
					 | 
				
			||||||
	CEQ_CREATED,
 | 
					 | 
				
			||||||
	ILQ_CREATED,
 | 
					 | 
				
			||||||
	IEQ_CREATED,
 | 
					 | 
				
			||||||
	IP_ADDR_REGISTERED,
 | 
					 | 
				
			||||||
	RDMA_DEV_REGISTERED
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_msix_vector {
 | 
					 | 
				
			||||||
	u32 idx;
 | 
					 | 
				
			||||||
	u32 irq;
 | 
					 | 
				
			||||||
	u32 cpu_affinity;
 | 
					 | 
				
			||||||
	u32 ceq_id;
 | 
					 | 
				
			||||||
	cpumask_t mask;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct l2params_work {
 | 
					 | 
				
			||||||
	struct work_struct work;
 | 
					 | 
				
			||||||
	struct i40iw_device *iwdev;
 | 
					 | 
				
			||||||
	struct i40iw_l2params l2params;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_MSIX_TABLE_SIZE   65
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct virtchnl_work {
 | 
					 | 
				
			||||||
	struct work_struct work;
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct i40iw_cqp_request *cqp_request;
 | 
					 | 
				
			||||||
		struct i40iw_virtchnl_work_info work_info;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40e_qvlist_info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_device {
 | 
					 | 
				
			||||||
	struct i40iw_ib_device *iwibdev;
 | 
					 | 
				
			||||||
	struct net_device *netdev;
 | 
					 | 
				
			||||||
	wait_queue_head_t vchnl_waitq;
 | 
					 | 
				
			||||||
	struct i40iw_sc_dev sc_dev;
 | 
					 | 
				
			||||||
	struct i40iw_sc_vsi vsi;
 | 
					 | 
				
			||||||
	struct i40iw_handler *hdl;
 | 
					 | 
				
			||||||
	struct i40e_info *ldev;
 | 
					 | 
				
			||||||
	struct i40e_client *client;
 | 
					 | 
				
			||||||
	struct i40iw_hw hw;
 | 
					 | 
				
			||||||
	struct i40iw_cm_core cm_core;
 | 
					 | 
				
			||||||
	u8 *mem_resources;
 | 
					 | 
				
			||||||
	unsigned long *allocated_qps;
 | 
					 | 
				
			||||||
	unsigned long *allocated_cqs;
 | 
					 | 
				
			||||||
	unsigned long *allocated_mrs;
 | 
					 | 
				
			||||||
	unsigned long *allocated_pds;
 | 
					 | 
				
			||||||
	unsigned long *allocated_arps;
 | 
					 | 
				
			||||||
	struct i40iw_qp **qp_table;
 | 
					 | 
				
			||||||
	bool msix_shared;
 | 
					 | 
				
			||||||
	u32 msix_count;
 | 
					 | 
				
			||||||
	struct i40iw_msix_vector *iw_msixtbl;
 | 
					 | 
				
			||||||
	struct i40e_qvlist_info *iw_qvlist;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pble_rsrc *pble_rsrc;
 | 
					 | 
				
			||||||
	struct i40iw_arp_entry *arp_table;
 | 
					 | 
				
			||||||
	struct i40iw_cqp cqp;
 | 
					 | 
				
			||||||
	struct i40iw_ccq ccq;
 | 
					 | 
				
			||||||
	u32 ceqs_count;
 | 
					 | 
				
			||||||
	struct i40iw_ceq *ceqlist;
 | 
					 | 
				
			||||||
	struct i40iw_aeq aeq;
 | 
					 | 
				
			||||||
	u32 arp_table_size;
 | 
					 | 
				
			||||||
	u32 next_arp_index;
 | 
					 | 
				
			||||||
	spinlock_t resource_lock; /* hw resource access */
 | 
					 | 
				
			||||||
	spinlock_t qptable_lock;
 | 
					 | 
				
			||||||
	u32 vendor_id;
 | 
					 | 
				
			||||||
	u32 vendor_part_id;
 | 
					 | 
				
			||||||
	u32 of_device_registered;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u32 device_cap_flags;
 | 
					 | 
				
			||||||
	unsigned long db_start;
 | 
					 | 
				
			||||||
	u8 resource_profile;
 | 
					 | 
				
			||||||
	u8 max_rdma_vfs;
 | 
					 | 
				
			||||||
	u8 max_enabled_vfs;
 | 
					 | 
				
			||||||
	u8 max_sge;
 | 
					 | 
				
			||||||
	u8 iw_status;
 | 
					 | 
				
			||||||
	u8 send_term_ok;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* x710 specific */
 | 
					 | 
				
			||||||
	struct mutex pbl_mutex;
 | 
					 | 
				
			||||||
	struct tasklet_struct dpc_tasklet;
 | 
					 | 
				
			||||||
	struct workqueue_struct *virtchnl_wq;
 | 
					 | 
				
			||||||
	struct virtchnl_work virtchnl_w[I40IW_MAX_PE_ENABLED_VF_COUNT];
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem obj_mem;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem obj_next;
 | 
					 | 
				
			||||||
	u8 *hmc_info_mem;
 | 
					 | 
				
			||||||
	u32 sd_type;
 | 
					 | 
				
			||||||
	struct workqueue_struct *param_wq;
 | 
					 | 
				
			||||||
	atomic_t params_busy;
 | 
					 | 
				
			||||||
	enum init_completion_state init_state;
 | 
					 | 
				
			||||||
	u16 mac_ip_table_idx;
 | 
					 | 
				
			||||||
	atomic_t vchnl_msgs;
 | 
					 | 
				
			||||||
	u32 max_mr;
 | 
					 | 
				
			||||||
	u32 max_qp;
 | 
					 | 
				
			||||||
	u32 max_cq;
 | 
					 | 
				
			||||||
	u32 max_pd;
 | 
					 | 
				
			||||||
	u32 next_qp;
 | 
					 | 
				
			||||||
	u32 next_cq;
 | 
					 | 
				
			||||||
	u32 next_pd;
 | 
					 | 
				
			||||||
	u32 max_mr_size;
 | 
					 | 
				
			||||||
	u32 max_qp_wr;
 | 
					 | 
				
			||||||
	u32 max_cqe;
 | 
					 | 
				
			||||||
	u32 mr_stagmask;
 | 
					 | 
				
			||||||
	u32 mpa_version;
 | 
					 | 
				
			||||||
	bool dcb;
 | 
					 | 
				
			||||||
	bool closing;
 | 
					 | 
				
			||||||
	bool reset;
 | 
					 | 
				
			||||||
	u32 used_pds;
 | 
					 | 
				
			||||||
	u32 used_cqs;
 | 
					 | 
				
			||||||
	u32 used_mrs;
 | 
					 | 
				
			||||||
	u32 used_qps;
 | 
					 | 
				
			||||||
	wait_queue_head_t close_wq;
 | 
					 | 
				
			||||||
	atomic64_t use_count;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_ib_device {
 | 
					 | 
				
			||||||
	struct ib_device ibdev;
 | 
					 | 
				
			||||||
	struct i40iw_device *iwdev;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_handler {
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
					 | 
				
			||||||
	struct i40e_client *client;
 | 
					 | 
				
			||||||
	struct i40iw_device device;
 | 
					 | 
				
			||||||
	struct i40e_info ldev;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_fw_major_ver - get firmware major version
 | 
					 | 
				
			||||||
 * @dev: iwarp device
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline u64 i40iw_fw_major_ver(struct i40iw_sc_dev *dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return RS_64(dev->feature_info[I40IW_FEATURE_FW_INFO],
 | 
					 | 
				
			||||||
		     I40IW_FW_VER_MAJOR);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_fw_minor_ver - get firmware minor version
 | 
					 | 
				
			||||||
 * @dev: iwarp device
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline u64 i40iw_fw_minor_ver(struct i40iw_sc_dev *dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return RS_64(dev->feature_info[I40IW_FEATURE_FW_INFO],
 | 
					 | 
				
			||||||
		     I40IW_FW_VER_MINOR);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * to_iwdev - get device
 | 
					 | 
				
			||||||
 * @ibdev: ib device
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline struct i40iw_device *to_iwdev(struct ib_device *ibdev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return container_of(ibdev, struct i40iw_ib_device, ibdev)->iwdev;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * to_ucontext - get user context
 | 
					 | 
				
			||||||
 * @ibucontext: ib user context
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline struct i40iw_ucontext *to_ucontext(struct ib_ucontext *ibucontext)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return container_of(ibucontext, struct i40iw_ucontext, ibucontext);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * to_iwpd - get protection domain
 | 
					 | 
				
			||||||
 * @ibpd: ib pd
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline struct i40iw_pd *to_iwpd(struct ib_pd *ibpd)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return container_of(ibpd, struct i40iw_pd, ibpd);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * to_iwmr - get device memory region
 | 
					 | 
				
			||||||
 * @ibdev: ib memory region
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline struct i40iw_mr *to_iwmr(struct ib_mr *ibmr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return container_of(ibmr, struct i40iw_mr, ibmr);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * to_iwmw - get device memory window
 | 
					 | 
				
			||||||
 * @ibmw: ib memory window
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline struct i40iw_mr *to_iwmw(struct ib_mw *ibmw)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return container_of(ibmw, struct i40iw_mr, ibmw);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * to_iwcq - get completion queue
 | 
					 | 
				
			||||||
 * @ibcq: ib cqdevice
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline struct i40iw_cq *to_iwcq(struct ib_cq *ibcq)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return container_of(ibcq, struct i40iw_cq, ibcq);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * to_iwqp - get device qp
 | 
					 | 
				
			||||||
 * @ibqp: ib qp
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline struct i40iw_qp *to_iwqp(struct ib_qp *ibqp)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return container_of(ibqp, struct i40iw_qp, ibqp);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* i40iw.c */
 | 
					 | 
				
			||||||
void i40iw_qp_add_ref(struct ib_qp *ibqp);
 | 
					 | 
				
			||||||
void i40iw_qp_rem_ref(struct ib_qp *ibqp);
 | 
					 | 
				
			||||||
struct ib_qp *i40iw_get_qp(struct ib_device *, int);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_flush_wqes(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
		      struct i40iw_qp *qp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_manage_arp_cache(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
			    unsigned char *mac_addr,
 | 
					 | 
				
			||||||
			    u32 *ip_addr,
 | 
					 | 
				
			||||||
			    bool ipv4,
 | 
					 | 
				
			||||||
			    u32 action);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int i40iw_manage_apbvt(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
		       u16 accel_local_port,
 | 
					 | 
				
			||||||
		       bool add_port);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cqp_request *i40iw_get_cqp_request(struct i40iw_cqp *cqp, bool wait);
 | 
					 | 
				
			||||||
void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp_request);
 | 
					 | 
				
			||||||
void i40iw_put_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp_request);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_alloc_resource - allocate a resource
 | 
					 | 
				
			||||||
 * @iwdev: device pointer
 | 
					 | 
				
			||||||
 * @resource_array: resource bit array:
 | 
					 | 
				
			||||||
 * @max_resources: maximum resource number
 | 
					 | 
				
			||||||
 * @req_resources_num: Allocated resource number
 | 
					 | 
				
			||||||
 * @next: next free id
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline int i40iw_alloc_resource(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
				       unsigned long *resource_array,
 | 
					 | 
				
			||||||
				       u32 max_resources,
 | 
					 | 
				
			||||||
				       u32 *req_resource_num,
 | 
					 | 
				
			||||||
				       u32 *next)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u32 resource_num;
 | 
					 | 
				
			||||||
	unsigned long flags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spin_lock_irqsave(&iwdev->resource_lock, flags);
 | 
					 | 
				
			||||||
	resource_num = find_next_zero_bit(resource_array, max_resources, *next);
 | 
					 | 
				
			||||||
	if (resource_num >= max_resources) {
 | 
					 | 
				
			||||||
		resource_num = find_first_zero_bit(resource_array, max_resources);
 | 
					 | 
				
			||||||
		if (resource_num >= max_resources) {
 | 
					 | 
				
			||||||
			spin_unlock_irqrestore(&iwdev->resource_lock, flags);
 | 
					 | 
				
			||||||
			return -EOVERFLOW;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	set_bit(resource_num, resource_array);
 | 
					 | 
				
			||||||
	*next = resource_num + 1;
 | 
					 | 
				
			||||||
	if (*next == max_resources)
 | 
					 | 
				
			||||||
		*next = 0;
 | 
					 | 
				
			||||||
	*req_resource_num = resource_num;
 | 
					 | 
				
			||||||
	spin_unlock_irqrestore(&iwdev->resource_lock, flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_is_resource_allocated - detrmine if resource is
 | 
					 | 
				
			||||||
 * allocated
 | 
					 | 
				
			||||||
 * @iwdev: device pointer
 | 
					 | 
				
			||||||
 * @resource_array: resource array for the resource_num
 | 
					 | 
				
			||||||
 * @resource_num: resource number to check
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline bool i40iw_is_resource_allocated(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
					       unsigned long *resource_array,
 | 
					 | 
				
			||||||
					       u32 resource_num)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	bool bit_is_set;
 | 
					 | 
				
			||||||
	unsigned long flags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spin_lock_irqsave(&iwdev->resource_lock, flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bit_is_set = test_bit(resource_num, resource_array);
 | 
					 | 
				
			||||||
	spin_unlock_irqrestore(&iwdev->resource_lock, flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return bit_is_set;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_free_resource - free a resource
 | 
					 | 
				
			||||||
 * @iwdev: device pointer
 | 
					 | 
				
			||||||
 * @resource_array: resource array for the resource_num
 | 
					 | 
				
			||||||
 * @resource_num: resource number to free
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline void i40iw_free_resource(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
				       unsigned long *resource_array,
 | 
					 | 
				
			||||||
				       u32 resource_num)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	unsigned long flags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spin_lock_irqsave(&iwdev->resource_lock, flags);
 | 
					 | 
				
			||||||
	clear_bit(resource_num, resource_array);
 | 
					 | 
				
			||||||
	spin_unlock_irqrestore(&iwdev->resource_lock, flags);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_handler *i40iw_find_netdev(struct net_device *netdev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * iw_init_resources -
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
u32 i40iw_initialize_hw_resources(struct i40iw_device *iwdev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int i40iw_register_rdma_device(struct i40iw_device *iwdev);
 | 
					 | 
				
			||||||
void i40iw_port_ibevent(struct i40iw_device *iwdev);
 | 
					 | 
				
			||||||
void i40iw_cm_disconn(struct i40iw_qp *iwqp);
 | 
					 | 
				
			||||||
void i40iw_cm_disconn_worker(void *);
 | 
					 | 
				
			||||||
int mini_cm_recv_pkt(struct i40iw_cm_core *, struct i40iw_device *,
 | 
					 | 
				
			||||||
		     struct sk_buff *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_handle_cqp_op(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
					   struct i40iw_cqp_request *cqp_request);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_add_mac_addr(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
					  u8 *mac_addr, u8 *mac_index);
 | 
					 | 
				
			||||||
int i40iw_modify_qp(struct ib_qp *, struct ib_qp_attr *, int, struct ib_udata *);
 | 
					 | 
				
			||||||
void i40iw_cq_wq_destroy(struct i40iw_device *iwdev, struct i40iw_sc_cq *cq);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_cleanup_pending_cqp_op(struct i40iw_device *iwdev);
 | 
					 | 
				
			||||||
void i40iw_rem_pdusecount(struct i40iw_pd *iwpd, struct i40iw_device *iwdev);
 | 
					 | 
				
			||||||
void i40iw_add_pdusecount(struct i40iw_pd *iwpd);
 | 
					 | 
				
			||||||
void i40iw_rem_devusecount(struct i40iw_device *iwdev);
 | 
					 | 
				
			||||||
void i40iw_add_devusecount(struct i40iw_device *iwdev);
 | 
					 | 
				
			||||||
void i40iw_hw_modify_qp(struct i40iw_device *iwdev, struct i40iw_qp *iwqp,
 | 
					 | 
				
			||||||
			struct i40iw_modify_qp_info *info, bool wait);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_qp_suspend_resume(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
			     struct i40iw_sc_qp *qp,
 | 
					 | 
				
			||||||
			     bool suspend);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_manage_qhash(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
					  struct i40iw_cm_info *cminfo,
 | 
					 | 
				
			||||||
					  enum i40iw_quad_entry_type etype,
 | 
					 | 
				
			||||||
					  enum i40iw_quad_hash_manage_type mtype,
 | 
					 | 
				
			||||||
					  void *cmnode,
 | 
					 | 
				
			||||||
					  bool wait);
 | 
					 | 
				
			||||||
void i40iw_receive_ilq(struct i40iw_sc_vsi *vsi, struct i40iw_puda_buf *rbuf);
 | 
					 | 
				
			||||||
void i40iw_free_sqbuf(struct i40iw_sc_vsi *vsi, void *bufp);
 | 
					 | 
				
			||||||
void i40iw_free_qp_resources(struct i40iw_qp *iwqp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_obj_aligned_mem(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
					     struct i40iw_dma_mem *memptr,
 | 
					 | 
				
			||||||
					     u32 size, u32 mask);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_request_reset(struct i40iw_device *iwdev);
 | 
					 | 
				
			||||||
void i40iw_destroy_rdma_device(struct i40iw_ib_device *iwibdev);
 | 
					 | 
				
			||||||
int i40iw_setup_cm_core(struct i40iw_device *iwdev);
 | 
					 | 
				
			||||||
void i40iw_cleanup_cm_core(struct i40iw_cm_core *cm_core);
 | 
					 | 
				
			||||||
void i40iw_process_ceq(struct i40iw_device *, struct i40iw_ceq *iwceq);
 | 
					 | 
				
			||||||
void i40iw_process_aeq(struct i40iw_device *);
 | 
					 | 
				
			||||||
void i40iw_next_iw_state(struct i40iw_qp *iwqp,
 | 
					 | 
				
			||||||
			 u8 state, u8 del_hash,
 | 
					 | 
				
			||||||
			 u8 term, u8 term_len);
 | 
					 | 
				
			||||||
int i40iw_send_syn(struct i40iw_cm_node *cm_node, u32 sendack);
 | 
					 | 
				
			||||||
int i40iw_send_reset(struct i40iw_cm_node *cm_node);
 | 
					 | 
				
			||||||
struct i40iw_cm_node *i40iw_find_node(struct i40iw_cm_core *cm_core,
 | 
					 | 
				
			||||||
				      u16 rem_port,
 | 
					 | 
				
			||||||
				      u32 *rem_addr,
 | 
					 | 
				
			||||||
				      u16 loc_port,
 | 
					 | 
				
			||||||
				      u32 *loc_addr,
 | 
					 | 
				
			||||||
				      bool add_refcnt,
 | 
					 | 
				
			||||||
				      bool accelerated_list);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_hw_flush_wqes(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
					   struct i40iw_sc_qp *qp,
 | 
					 | 
				
			||||||
					   struct i40iw_qp_flush_info *info,
 | 
					 | 
				
			||||||
					   bool wait);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_gen_ae(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
		  struct i40iw_sc_qp *qp,
 | 
					 | 
				
			||||||
		  struct i40iw_gen_ae_info *info,
 | 
					 | 
				
			||||||
		  bool wait);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_copy_ip_ntohl(u32 *dst, __be32 *src);
 | 
					 | 
				
			||||||
struct ib_mr *i40iw_reg_phys_mr(struct ib_pd *ib_pd,
 | 
					 | 
				
			||||||
				u64 addr,
 | 
					 | 
				
			||||||
				u64 size,
 | 
					 | 
				
			||||||
				int acc,
 | 
					 | 
				
			||||||
				u64 *iova_start);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int i40iw_inetaddr_event(struct notifier_block *notifier,
 | 
					 | 
				
			||||||
			 unsigned long event,
 | 
					 | 
				
			||||||
			 void *ptr);
 | 
					 | 
				
			||||||
int i40iw_inet6addr_event(struct notifier_block *notifier,
 | 
					 | 
				
			||||||
			  unsigned long event,
 | 
					 | 
				
			||||||
			  void *ptr);
 | 
					 | 
				
			||||||
int i40iw_net_event(struct notifier_block *notifier,
 | 
					 | 
				
			||||||
		    unsigned long event,
 | 
					 | 
				
			||||||
		    void *ptr);
 | 
					 | 
				
			||||||
int i40iw_netdevice_event(struct notifier_block *notifier,
 | 
					 | 
				
			||||||
			  unsigned long event,
 | 
					 | 
				
			||||||
			  void *ptr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,462 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_CM_H
 | 
					 | 
				
			||||||
#define I40IW_CM_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define QUEUE_EVENTS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_MANAGE_APBVT_DEL 0
 | 
					 | 
				
			||||||
#define I40IW_MANAGE_APBVT_ADD 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_MPA_REQUEST_ACCEPT  1
 | 
					 | 
				
			||||||
#define I40IW_MPA_REQUEST_REJECT  2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* IETF MPA -- defines, enums, structs */
 | 
					 | 
				
			||||||
#define IEFT_MPA_KEY_REQ  "MPA ID Req Frame"
 | 
					 | 
				
			||||||
#define IEFT_MPA_KEY_REP  "MPA ID Rep Frame"
 | 
					 | 
				
			||||||
#define IETF_MPA_KEY_SIZE 16
 | 
					 | 
				
			||||||
#define IETF_MPA_VERSION  1
 | 
					 | 
				
			||||||
#define IETF_MAX_PRIV_DATA_LEN 512
 | 
					 | 
				
			||||||
#define IETF_MPA_FRAME_SIZE    20
 | 
					 | 
				
			||||||
#define IETF_RTR_MSG_SIZE      4
 | 
					 | 
				
			||||||
#define IETF_MPA_V2_FLAG       0x10
 | 
					 | 
				
			||||||
#define SNDMARKER_SEQNMASK     0x000001FF
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_MAX_IETF_SIZE      32
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* IETF RTR MSG Fields               */
 | 
					 | 
				
			||||||
#define IETF_PEER_TO_PEER       0x8000
 | 
					 | 
				
			||||||
#define IETF_FLPDU_ZERO_LEN     0x4000
 | 
					 | 
				
			||||||
#define IETF_RDMA0_WRITE        0x8000
 | 
					 | 
				
			||||||
#define IETF_RDMA0_READ         0x4000
 | 
					 | 
				
			||||||
#define IETF_NO_IRD_ORD         0x3FFF
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* HW-supported IRD sizes*/
 | 
					 | 
				
			||||||
#define	I40IW_HW_IRD_SETTING_2	2
 | 
					 | 
				
			||||||
#define	I40IW_HW_IRD_SETTING_4	4
 | 
					 | 
				
			||||||
#define	I40IW_HW_IRD_SETTING_8	8
 | 
					 | 
				
			||||||
#define	I40IW_HW_IRD_SETTING_16	16
 | 
					 | 
				
			||||||
#define	I40IW_HW_IRD_SETTING_32	32
 | 
					 | 
				
			||||||
#define	I40IW_HW_IRD_SETTING_64	64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAX_PORTS		65536
 | 
					 | 
				
			||||||
#define I40IW_VLAN_PRIO_SHIFT   13
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum ietf_mpa_flags {
 | 
					 | 
				
			||||||
	IETF_MPA_FLAGS_MARKERS = 0x80,	/* receive Markers */
 | 
					 | 
				
			||||||
	IETF_MPA_FLAGS_CRC = 0x40,	/* receive Markers */
 | 
					 | 
				
			||||||
	IETF_MPA_FLAGS_REJECT = 0x20,	/* Reject */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct ietf_mpa_v1 {
 | 
					 | 
				
			||||||
	u8 key[IETF_MPA_KEY_SIZE];
 | 
					 | 
				
			||||||
	u8 flags;
 | 
					 | 
				
			||||||
	u8 rev;
 | 
					 | 
				
			||||||
	__be16 priv_data_len;
 | 
					 | 
				
			||||||
	u8 priv_data[];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ietf_mpa_req_resp_frame ietf_mpa_frame
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct ietf_rtr_msg {
 | 
					 | 
				
			||||||
	__be16 ctrl_ird;
 | 
					 | 
				
			||||||
	__be16 ctrl_ord;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct ietf_mpa_v2 {
 | 
					 | 
				
			||||||
	u8 key[IETF_MPA_KEY_SIZE];
 | 
					 | 
				
			||||||
	u8 flags;
 | 
					 | 
				
			||||||
	u8 rev;
 | 
					 | 
				
			||||||
	__be16 priv_data_len;
 | 
					 | 
				
			||||||
	struct ietf_rtr_msg rtr_msg;
 | 
					 | 
				
			||||||
	u8 priv_data[];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cm_node;
 | 
					 | 
				
			||||||
enum i40iw_timer_type {
 | 
					 | 
				
			||||||
	I40IW_TIMER_TYPE_SEND,
 | 
					 | 
				
			||||||
	I40IW_TIMER_TYPE_RECV,
 | 
					 | 
				
			||||||
	I40IW_TIMER_NODE_CLEANUP,
 | 
					 | 
				
			||||||
	I40IW_TIMER_TYPE_CLOSE,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_PASSIVE_STATE_INDICATED    0
 | 
					 | 
				
			||||||
#define I40IW_DO_NOT_SEND_RESET_EVENT    1
 | 
					 | 
				
			||||||
#define I40IW_SEND_RESET_EVENT           2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAX_I40IW_IFS 4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SET_ACK 0x1
 | 
					 | 
				
			||||||
#define SET_SYN 0x2
 | 
					 | 
				
			||||||
#define SET_FIN 0x4
 | 
					 | 
				
			||||||
#define SET_RST 0x8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TCP_OPTIONS_PADDING     3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct option_base {
 | 
					 | 
				
			||||||
	u8 optionnum;
 | 
					 | 
				
			||||||
	u8 length;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum option_numbers {
 | 
					 | 
				
			||||||
	OPTION_NUMBER_END,
 | 
					 | 
				
			||||||
	OPTION_NUMBER_NONE,
 | 
					 | 
				
			||||||
	OPTION_NUMBER_MSS,
 | 
					 | 
				
			||||||
	OPTION_NUMBER_WINDOW_SCALE,
 | 
					 | 
				
			||||||
	OPTION_NUMBER_SACK_PERM,
 | 
					 | 
				
			||||||
	OPTION_NUMBER_SACK,
 | 
					 | 
				
			||||||
	OPTION_NUMBER_WRITE0 = 0xbc
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct option_mss {
 | 
					 | 
				
			||||||
	u8 optionnum;
 | 
					 | 
				
			||||||
	u8 length;
 | 
					 | 
				
			||||||
	__be16 mss;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct option_windowscale {
 | 
					 | 
				
			||||||
	u8 optionnum;
 | 
					 | 
				
			||||||
	u8 length;
 | 
					 | 
				
			||||||
	u8 shiftcount;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
union all_known_options {
 | 
					 | 
				
			||||||
	char as_end;
 | 
					 | 
				
			||||||
	struct option_base as_base;
 | 
					 | 
				
			||||||
	struct option_mss as_mss;
 | 
					 | 
				
			||||||
	struct option_windowscale as_windowscale;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_timer_entry {
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
					 | 
				
			||||||
	unsigned long timetosend;	/* jiffies */
 | 
					 | 
				
			||||||
	struct i40iw_puda_buf *sqbuf;
 | 
					 | 
				
			||||||
	u32 type;
 | 
					 | 
				
			||||||
	u32 retrycount;
 | 
					 | 
				
			||||||
	u32 retranscount;
 | 
					 | 
				
			||||||
	u32 context;
 | 
					 | 
				
			||||||
	u32 send_retrans;
 | 
					 | 
				
			||||||
	int close_when_complete;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_DEFAULT_RETRYS	64
 | 
					 | 
				
			||||||
#define I40IW_DEFAULT_RETRANS	8
 | 
					 | 
				
			||||||
#define I40IW_DEFAULT_TTL	0x40
 | 
					 | 
				
			||||||
#define I40IW_DEFAULT_RTT_VAR	0x6
 | 
					 | 
				
			||||||
#define I40IW_DEFAULT_SS_THRESH 0x3FFFFFFF
 | 
					 | 
				
			||||||
#define I40IW_DEFAULT_REXMIT_THRESH 8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_RETRY_TIMEOUT   HZ
 | 
					 | 
				
			||||||
#define I40IW_SHORT_TIME      10
 | 
					 | 
				
			||||||
#define I40IW_LONG_TIME       (2 * HZ)
 | 
					 | 
				
			||||||
#define I40IW_MAX_TIMEOUT     ((unsigned long)(12 * HZ))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_CM_HASHTABLE_SIZE         1024
 | 
					 | 
				
			||||||
#define I40IW_CM_TCP_TIMER_INTERVAL     3000
 | 
					 | 
				
			||||||
#define I40IW_CM_DEFAULT_MTU            1540
 | 
					 | 
				
			||||||
#define I40IW_CM_DEFAULT_FRAME_CNT      10
 | 
					 | 
				
			||||||
#define I40IW_CM_THREAD_STACK_SIZE      256
 | 
					 | 
				
			||||||
#define I40IW_CM_DEFAULT_RCV_WND        64240
 | 
					 | 
				
			||||||
#define I40IW_CM_DEFAULT_RCV_WND_SCALED 0x3fffc
 | 
					 | 
				
			||||||
#define I40IW_CM_DEFAULT_RCV_WND_SCALE  2
 | 
					 | 
				
			||||||
#define I40IW_CM_DEFAULT_FREE_PKTS      0x000A
 | 
					 | 
				
			||||||
#define I40IW_CM_FREE_PKT_LO_WATERMARK  2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_CM_DEFAULT_MSS   536
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_CM_DEF_SEQ       0x159bf75f
 | 
					 | 
				
			||||||
#define I40IW_CM_DEF_LOCAL_ID  0x3b47
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_CM_DEF_SEQ2      0x18ed5740
 | 
					 | 
				
			||||||
#define I40IW_CM_DEF_LOCAL_ID2 0xb807
 | 
					 | 
				
			||||||
#define MAX_CM_BUFFER   (I40IW_MAX_IETF_SIZE + IETF_MAX_PRIV_DATA_LEN)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef u32 i40iw_addr_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define i40iw_cm_tsa_context i40iw_qp_context
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_qp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* cm node transition states */
 | 
					 | 
				
			||||||
enum i40iw_cm_node_state {
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_UNKNOWN,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_INITED,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_LISTENING,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_SYN_RCVD,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_SYN_SENT,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_ONE_SIDE_ESTABLISHED,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_ESTABLISHED,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_ACCEPTING,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_MPAREQ_SENT,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_MPAREQ_RCVD,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_MPAREJ_RCVD,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_OFFLOADED,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_FIN_WAIT1,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_FIN_WAIT2,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_CLOSE_WAIT,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_TIME_WAIT,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_LAST_ACK,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_CLOSING,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_LISTENER_DESTROYED,
 | 
					 | 
				
			||||||
	I40IW_CM_STATE_CLOSED
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum mpa_frame_version {
 | 
					 | 
				
			||||||
	IETF_MPA_V1 = 1,
 | 
					 | 
				
			||||||
	IETF_MPA_V2 = 2
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum mpa_frame_key {
 | 
					 | 
				
			||||||
	MPA_KEY_REQUEST,
 | 
					 | 
				
			||||||
	MPA_KEY_REPLY
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum send_rdma0 {
 | 
					 | 
				
			||||||
	SEND_RDMA_READ_ZERO = 1,
 | 
					 | 
				
			||||||
	SEND_RDMA_WRITE_ZERO = 2
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_tcpip_pkt_type {
 | 
					 | 
				
			||||||
	I40IW_PKT_TYPE_UNKNOWN,
 | 
					 | 
				
			||||||
	I40IW_PKT_TYPE_SYN,
 | 
					 | 
				
			||||||
	I40IW_PKT_TYPE_SYNACK,
 | 
					 | 
				
			||||||
	I40IW_PKT_TYPE_ACK,
 | 
					 | 
				
			||||||
	I40IW_PKT_TYPE_FIN,
 | 
					 | 
				
			||||||
	I40IW_PKT_TYPE_RST
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* CM context params */
 | 
					 | 
				
			||||||
struct i40iw_cm_tcp_context {
 | 
					 | 
				
			||||||
	u8 client;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u32 loc_seq_num;
 | 
					 | 
				
			||||||
	u32 loc_ack_num;
 | 
					 | 
				
			||||||
	u32 rem_ack_num;
 | 
					 | 
				
			||||||
	u32 rcv_nxt;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u32 loc_id;
 | 
					 | 
				
			||||||
	u32 rem_id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u32 snd_wnd;
 | 
					 | 
				
			||||||
	u32 max_snd_wnd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u32 rcv_wnd;
 | 
					 | 
				
			||||||
	u32 mss;
 | 
					 | 
				
			||||||
	u8 snd_wscale;
 | 
					 | 
				
			||||||
	u8 rcv_wscale;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_cm_listener_state {
 | 
					 | 
				
			||||||
	I40IW_CM_LISTENER_PASSIVE_STATE = 1,
 | 
					 | 
				
			||||||
	I40IW_CM_LISTENER_ACTIVE_STATE = 2,
 | 
					 | 
				
			||||||
	I40IW_CM_LISTENER_EITHER_STATE = 3
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cm_listener {
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
					 | 
				
			||||||
	struct i40iw_cm_core *cm_core;
 | 
					 | 
				
			||||||
	u8 loc_mac[ETH_ALEN];
 | 
					 | 
				
			||||||
	u32 loc_addr[4];
 | 
					 | 
				
			||||||
	u16 loc_port;
 | 
					 | 
				
			||||||
	struct iw_cm_id *cm_id;
 | 
					 | 
				
			||||||
	atomic_t ref_count;
 | 
					 | 
				
			||||||
	struct i40iw_device *iwdev;
 | 
					 | 
				
			||||||
	atomic_t pend_accepts_cnt;
 | 
					 | 
				
			||||||
	int backlog;
 | 
					 | 
				
			||||||
	enum i40iw_cm_listener_state listener_state;
 | 
					 | 
				
			||||||
	u32 reused_node;
 | 
					 | 
				
			||||||
	u8 user_pri;
 | 
					 | 
				
			||||||
	u8 tos;
 | 
					 | 
				
			||||||
	u16 vlan_id;
 | 
					 | 
				
			||||||
	bool qhash_set;
 | 
					 | 
				
			||||||
	bool ipv4;
 | 
					 | 
				
			||||||
	struct list_head child_listen_list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_kmem_info {
 | 
					 | 
				
			||||||
	void *addr;
 | 
					 | 
				
			||||||
	u32 size;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* per connection node and node state information */
 | 
					 | 
				
			||||||
struct i40iw_cm_node {
 | 
					 | 
				
			||||||
	u32 loc_addr[4], rem_addr[4];
 | 
					 | 
				
			||||||
	u16 loc_port, rem_port;
 | 
					 | 
				
			||||||
	u16 vlan_id;
 | 
					 | 
				
			||||||
	enum i40iw_cm_node_state state;
 | 
					 | 
				
			||||||
	u8 loc_mac[ETH_ALEN];
 | 
					 | 
				
			||||||
	u8 rem_mac[ETH_ALEN];
 | 
					 | 
				
			||||||
	atomic_t ref_count;
 | 
					 | 
				
			||||||
	struct i40iw_qp *iwqp;
 | 
					 | 
				
			||||||
	struct i40iw_device *iwdev;
 | 
					 | 
				
			||||||
	struct i40iw_sc_dev *dev;
 | 
					 | 
				
			||||||
	struct i40iw_cm_tcp_context tcp_cntxt;
 | 
					 | 
				
			||||||
	struct i40iw_cm_core *cm_core;
 | 
					 | 
				
			||||||
	struct i40iw_cm_node *loopbackpartner;
 | 
					 | 
				
			||||||
	struct i40iw_timer_entry *send_entry;
 | 
					 | 
				
			||||||
	struct i40iw_timer_entry *close_entry;
 | 
					 | 
				
			||||||
	spinlock_t retrans_list_lock; /* cm transmit packet */
 | 
					 | 
				
			||||||
	enum send_rdma0 send_rdma0_op;
 | 
					 | 
				
			||||||
	u16 ird_size;
 | 
					 | 
				
			||||||
	u16 ord_size;
 | 
					 | 
				
			||||||
	u16     mpav2_ird_ord;
 | 
					 | 
				
			||||||
	struct iw_cm_id *cm_id;
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
					 | 
				
			||||||
	bool accelerated;
 | 
					 | 
				
			||||||
	struct i40iw_cm_listener *listener;
 | 
					 | 
				
			||||||
	int apbvt_set;
 | 
					 | 
				
			||||||
	int accept_pend;
 | 
					 | 
				
			||||||
	struct list_head timer_entry;
 | 
					 | 
				
			||||||
	struct list_head reset_entry;
 | 
					 | 
				
			||||||
	struct list_head teardown_entry;
 | 
					 | 
				
			||||||
	atomic_t passive_state;
 | 
					 | 
				
			||||||
	bool qhash_set;
 | 
					 | 
				
			||||||
	u8 user_pri;
 | 
					 | 
				
			||||||
	u8 tos;
 | 
					 | 
				
			||||||
	bool ipv4;
 | 
					 | 
				
			||||||
	bool snd_mark_en;
 | 
					 | 
				
			||||||
	u16 lsmm_size;
 | 
					 | 
				
			||||||
	enum mpa_frame_version mpa_frame_rev;
 | 
					 | 
				
			||||||
	struct i40iw_kmem_info pdata;
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct ietf_mpa_v1 mpa_frame;
 | 
					 | 
				
			||||||
		struct ietf_mpa_v2 mpa_v2_frame;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u8 pdata_buf[IETF_MAX_PRIV_DATA_LEN];
 | 
					 | 
				
			||||||
	struct i40iw_kmem_info mpa_hdr;
 | 
					 | 
				
			||||||
	bool ack_rcvd;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* structure for client or CM to fill when making CM api calls. */
 | 
					 | 
				
			||||||
/*	- only need to set relevant data, based on op. */
 | 
					 | 
				
			||||||
struct i40iw_cm_info {
 | 
					 | 
				
			||||||
	struct iw_cm_id *cm_id;
 | 
					 | 
				
			||||||
	u16 loc_port;
 | 
					 | 
				
			||||||
	u16 rem_port;
 | 
					 | 
				
			||||||
	u32 loc_addr[4];
 | 
					 | 
				
			||||||
	u32 rem_addr[4];
 | 
					 | 
				
			||||||
	u16 vlan_id;
 | 
					 | 
				
			||||||
	int backlog;
 | 
					 | 
				
			||||||
	u8 user_pri;
 | 
					 | 
				
			||||||
	u8 tos;
 | 
					 | 
				
			||||||
	bool ipv4;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* CM event codes */
 | 
					 | 
				
			||||||
enum i40iw_cm_event_type {
 | 
					 | 
				
			||||||
	I40IW_CM_EVENT_UNKNOWN,
 | 
					 | 
				
			||||||
	I40IW_CM_EVENT_ESTABLISHED,
 | 
					 | 
				
			||||||
	I40IW_CM_EVENT_MPA_REQ,
 | 
					 | 
				
			||||||
	I40IW_CM_EVENT_MPA_CONNECT,
 | 
					 | 
				
			||||||
	I40IW_CM_EVENT_MPA_ACCEPT,
 | 
					 | 
				
			||||||
	I40IW_CM_EVENT_MPA_REJECT,
 | 
					 | 
				
			||||||
	I40IW_CM_EVENT_MPA_ESTABLISHED,
 | 
					 | 
				
			||||||
	I40IW_CM_EVENT_CONNECTED,
 | 
					 | 
				
			||||||
	I40IW_CM_EVENT_RESET,
 | 
					 | 
				
			||||||
	I40IW_CM_EVENT_ABORTED
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* event to post to CM event handler */
 | 
					 | 
				
			||||||
struct i40iw_cm_event {
 | 
					 | 
				
			||||||
	enum i40iw_cm_event_type type;
 | 
					 | 
				
			||||||
	struct i40iw_cm_info cm_info;
 | 
					 | 
				
			||||||
	struct work_struct event_work;
 | 
					 | 
				
			||||||
	struct i40iw_cm_node *cm_node;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cm_core {
 | 
					 | 
				
			||||||
	struct i40iw_device *iwdev;
 | 
					 | 
				
			||||||
	struct i40iw_sc_dev *dev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct list_head listen_nodes;
 | 
					 | 
				
			||||||
	struct list_head accelerated_list;
 | 
					 | 
				
			||||||
	struct list_head non_accelerated_list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct timer_list tcp_timer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct workqueue_struct *event_wq;
 | 
					 | 
				
			||||||
	struct workqueue_struct *disconn_wq;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spinlock_t ht_lock; /* manage hash table */
 | 
					 | 
				
			||||||
	spinlock_t listen_list_lock; /* listen list */
 | 
					 | 
				
			||||||
	spinlock_t apbvt_lock; /*manage apbvt entries*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	unsigned long ports_in_use[BITS_TO_LONGS(MAX_PORTS)];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u64	stats_nodes_created;
 | 
					 | 
				
			||||||
	u64	stats_nodes_destroyed;
 | 
					 | 
				
			||||||
	u64	stats_listen_created;
 | 
					 | 
				
			||||||
	u64	stats_listen_destroyed;
 | 
					 | 
				
			||||||
	u64	stats_listen_nodes_created;
 | 
					 | 
				
			||||||
	u64	stats_listen_nodes_destroyed;
 | 
					 | 
				
			||||||
	u64	stats_loopbacks;
 | 
					 | 
				
			||||||
	u64	stats_accepts;
 | 
					 | 
				
			||||||
	u64	stats_rejects;
 | 
					 | 
				
			||||||
	u64	stats_connect_errs;
 | 
					 | 
				
			||||||
	u64	stats_passive_errs;
 | 
					 | 
				
			||||||
	u64	stats_pkt_retrans;
 | 
					 | 
				
			||||||
	u64	stats_backlog_drops;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int i40iw_schedule_cm_timer(struct i40iw_cm_node *cm_node,
 | 
					 | 
				
			||||||
			    struct i40iw_puda_buf *sqbuf,
 | 
					 | 
				
			||||||
			    enum i40iw_timer_type type,
 | 
					 | 
				
			||||||
			    int send_retrans,
 | 
					 | 
				
			||||||
			    int close_when_complete);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int i40iw_accept(struct iw_cm_id *, struct iw_cm_conn_param *);
 | 
					 | 
				
			||||||
int i40iw_reject(struct iw_cm_id *, const void *, u8);
 | 
					 | 
				
			||||||
int i40iw_connect(struct iw_cm_id *, struct iw_cm_conn_param *);
 | 
					 | 
				
			||||||
int i40iw_create_listen(struct iw_cm_id *, int);
 | 
					 | 
				
			||||||
int i40iw_destroy_listen(struct iw_cm_id *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int i40iw_cm_start(struct i40iw_device *);
 | 
					 | 
				
			||||||
int i40iw_cm_stop(struct i40iw_device *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int i40iw_arp_table(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
		    u32 *ip_addr,
 | 
					 | 
				
			||||||
		    bool ipv4,
 | 
					 | 
				
			||||||
		    u8 *mac_addr,
 | 
					 | 
				
			||||||
		    u32 action);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_if_notify(struct i40iw_device *iwdev, struct net_device *netdev,
 | 
					 | 
				
			||||||
		     u32 *ipaddr, bool ipv4, bool ifup);
 | 
					 | 
				
			||||||
void i40iw_cm_teardown_connections(struct i40iw_device *iwdev, u32 *ipaddr,
 | 
					 | 
				
			||||||
				   struct i40iw_cm_info *nfo,
 | 
					 | 
				
			||||||
				   bool disconnect_all);
 | 
					 | 
				
			||||||
bool i40iw_port_in_use(struct i40iw_cm_core *cm_core, u16 port);
 | 
					 | 
				
			||||||
#endif /* I40IW_CM_H */
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,821 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "i40iw_osdep.h"
 | 
					 | 
				
			||||||
#include "i40iw_register.h"
 | 
					 | 
				
			||||||
#include "i40iw_status.h"
 | 
					 | 
				
			||||||
#include "i40iw_hmc.h"
 | 
					 | 
				
			||||||
#include "i40iw_d.h"
 | 
					 | 
				
			||||||
#include "i40iw_type.h"
 | 
					 | 
				
			||||||
#include "i40iw_p.h"
 | 
					 | 
				
			||||||
#include "i40iw_vf.h"
 | 
					 | 
				
			||||||
#include "i40iw_virtchnl.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_find_sd_index_limit - finds segment descriptor index limit
 | 
					 | 
				
			||||||
 * @hmc_info: pointer to the HMC configuration information structure
 | 
					 | 
				
			||||||
 * @type: type of HMC resources we're searching
 | 
					 | 
				
			||||||
 * @idx: starting index for the object
 | 
					 | 
				
			||||||
 * @cnt: number of objects we're trying to create
 | 
					 | 
				
			||||||
 * @sd_idx: pointer to return index of the segment descriptor in question
 | 
					 | 
				
			||||||
 * @sd_limit: pointer to return the maximum number of segment descriptors
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This function calculates the segment descriptor index and index limit
 | 
					 | 
				
			||||||
 * for the resource defined by i40iw_hmc_rsrc_type.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void i40iw_find_sd_index_limit(struct i40iw_hmc_info *hmc_info,
 | 
					 | 
				
			||||||
					     u32 type,
 | 
					 | 
				
			||||||
					     u32 idx,
 | 
					 | 
				
			||||||
					     u32 cnt,
 | 
					 | 
				
			||||||
					     u32 *sd_idx,
 | 
					 | 
				
			||||||
					     u32 *sd_limit)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u64 fpm_addr, fpm_limit;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fpm_addr = hmc_info->hmc_obj[(type)].base +
 | 
					 | 
				
			||||||
			hmc_info->hmc_obj[type].size * idx;
 | 
					 | 
				
			||||||
	fpm_limit = fpm_addr + hmc_info->hmc_obj[type].size * cnt;
 | 
					 | 
				
			||||||
	*sd_idx = (u32)(fpm_addr / I40IW_HMC_DIRECT_BP_SIZE);
 | 
					 | 
				
			||||||
	*sd_limit = (u32)((fpm_limit - 1) / I40IW_HMC_DIRECT_BP_SIZE);
 | 
					 | 
				
			||||||
	*sd_limit += 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_find_pd_index_limit - finds page descriptor index limit
 | 
					 | 
				
			||||||
 * @hmc_info: pointer to the HMC configuration information struct
 | 
					 | 
				
			||||||
 * @type: HMC resource type we're examining
 | 
					 | 
				
			||||||
 * @idx: starting index for the object
 | 
					 | 
				
			||||||
 * @cnt: number of objects we're trying to create
 | 
					 | 
				
			||||||
 * @pd_idx: pointer to return page descriptor index
 | 
					 | 
				
			||||||
 * @pd_limit: pointer to return page descriptor index limit
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Calculates the page descriptor index and index limit for the resource
 | 
					 | 
				
			||||||
 * defined by i40iw_hmc_rsrc_type.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void i40iw_find_pd_index_limit(struct i40iw_hmc_info *hmc_info,
 | 
					 | 
				
			||||||
					     u32 type,
 | 
					 | 
				
			||||||
					     u32 idx,
 | 
					 | 
				
			||||||
					     u32 cnt,
 | 
					 | 
				
			||||||
					     u32 *pd_idx,
 | 
					 | 
				
			||||||
					     u32 *pd_limit)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u64 fpm_adr, fpm_limit;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fpm_adr = hmc_info->hmc_obj[type].base +
 | 
					 | 
				
			||||||
			hmc_info->hmc_obj[type].size * idx;
 | 
					 | 
				
			||||||
	fpm_limit = fpm_adr + (hmc_info)->hmc_obj[(type)].size * (cnt);
 | 
					 | 
				
			||||||
	*(pd_idx) = (u32)(fpm_adr / I40IW_HMC_PAGED_BP_SIZE);
 | 
					 | 
				
			||||||
	*(pd_limit) = (u32)((fpm_limit - 1) / I40IW_HMC_PAGED_BP_SIZE);
 | 
					 | 
				
			||||||
	*(pd_limit) += 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_set_sd_entry - setup entry for sd programming
 | 
					 | 
				
			||||||
 * @pa: physical addr
 | 
					 | 
				
			||||||
 * @idx: sd index
 | 
					 | 
				
			||||||
 * @type: paged or direct sd
 | 
					 | 
				
			||||||
 * @entry: sd entry ptr
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void i40iw_set_sd_entry(u64 pa,
 | 
					 | 
				
			||||||
				      u32 idx,
 | 
					 | 
				
			||||||
				      enum i40iw_sd_entry_type type,
 | 
					 | 
				
			||||||
				      struct update_sd_entry *entry)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	entry->data = pa | (I40IW_HMC_MAX_BP_COUNT << I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) |
 | 
					 | 
				
			||||||
			(((type == I40IW_SD_TYPE_PAGED) ? 0 : 1) <<
 | 
					 | 
				
			||||||
				I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT) |
 | 
					 | 
				
			||||||
			(1 << I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT);
 | 
					 | 
				
			||||||
	entry->cmd = (idx | (1 << I40E_PFHMC_SDCMD_PMSDWR_SHIFT) | (1 << 15));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_clr_sd_entry - setup entry for sd clear
 | 
					 | 
				
			||||||
 * @idx: sd index
 | 
					 | 
				
			||||||
 * @type: paged or direct sd
 | 
					 | 
				
			||||||
 * @entry: sd entry ptr
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void i40iw_clr_sd_entry(u32 idx, enum i40iw_sd_entry_type type,
 | 
					 | 
				
			||||||
				      struct update_sd_entry *entry)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	entry->data = (I40IW_HMC_MAX_BP_COUNT <<
 | 
					 | 
				
			||||||
			I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) |
 | 
					 | 
				
			||||||
			(((type == I40IW_SD_TYPE_PAGED) ? 0 : 1) <<
 | 
					 | 
				
			||||||
				I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT);
 | 
					 | 
				
			||||||
	entry->cmd = (idx | (1 << I40E_PFHMC_SDCMD_PMSDWR_SHIFT) | (1 << 15));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_hmc_sd_one - setup 1 sd entry for cqp
 | 
					 | 
				
			||||||
 * @dev: pointer to the device structure
 | 
					 | 
				
			||||||
 * @hmc_fn_id: hmc's function id
 | 
					 | 
				
			||||||
 * @pa: physical addr
 | 
					 | 
				
			||||||
 * @sd_idx: sd index
 | 
					 | 
				
			||||||
 * @type: paged or direct sd
 | 
					 | 
				
			||||||
 * @setsd: flag to set or clear sd
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_hmc_sd_one(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					u8 hmc_fn_id,
 | 
					 | 
				
			||||||
					u64 pa, u32 sd_idx,
 | 
					 | 
				
			||||||
					enum i40iw_sd_entry_type type,
 | 
					 | 
				
			||||||
					bool setsd)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_update_sds_info sdinfo;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sdinfo.cnt = 1;
 | 
					 | 
				
			||||||
	sdinfo.hmc_fn_id = hmc_fn_id;
 | 
					 | 
				
			||||||
	if (setsd)
 | 
					 | 
				
			||||||
		i40iw_set_sd_entry(pa, sd_idx, type, sdinfo.entry);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		i40iw_clr_sd_entry(sd_idx, type, sdinfo.entry);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return dev->cqp->process_cqp_sds(dev, &sdinfo);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_hmc_sd_grp - setup group od sd entries for cqp
 | 
					 | 
				
			||||||
 * @dev: pointer to the device structure
 | 
					 | 
				
			||||||
 * @hmc_info: pointer to the HMC configuration information struct
 | 
					 | 
				
			||||||
 * @sd_index: sd index
 | 
					 | 
				
			||||||
 * @sd_cnt: number of sd entries
 | 
					 | 
				
			||||||
 * @setsd: flag to set or clear sd
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code i40iw_hmc_sd_grp(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					       struct i40iw_hmc_info *hmc_info,
 | 
					 | 
				
			||||||
					       u32 sd_index,
 | 
					 | 
				
			||||||
					       u32 sd_cnt,
 | 
					 | 
				
			||||||
					       bool setsd)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry;
 | 
					 | 
				
			||||||
	struct i40iw_update_sds_info sdinfo;
 | 
					 | 
				
			||||||
	u64 pa;
 | 
					 | 
				
			||||||
	u32 i;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(&sdinfo, 0, sizeof(sdinfo));
 | 
					 | 
				
			||||||
	sdinfo.hmc_fn_id = hmc_info->hmc_fn_id;
 | 
					 | 
				
			||||||
	for (i = sd_index; i < sd_index + sd_cnt; i++) {
 | 
					 | 
				
			||||||
		sd_entry = &hmc_info->sd_table.sd_entry[i];
 | 
					 | 
				
			||||||
		if (!sd_entry ||
 | 
					 | 
				
			||||||
		    (!sd_entry->valid && setsd) ||
 | 
					 | 
				
			||||||
		    (sd_entry->valid && !setsd))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		if (setsd) {
 | 
					 | 
				
			||||||
			pa = (sd_entry->entry_type == I40IW_SD_TYPE_PAGED) ?
 | 
					 | 
				
			||||||
			    sd_entry->u.pd_table.pd_page_addr.pa :
 | 
					 | 
				
			||||||
			    sd_entry->u.bp.addr.pa;
 | 
					 | 
				
			||||||
			i40iw_set_sd_entry(pa, i, sd_entry->entry_type,
 | 
					 | 
				
			||||||
					   &sdinfo.entry[sdinfo.cnt]);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			i40iw_clr_sd_entry(i, sd_entry->entry_type,
 | 
					 | 
				
			||||||
					   &sdinfo.entry[sdinfo.cnt]);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		sdinfo.cnt++;
 | 
					 | 
				
			||||||
		if (sdinfo.cnt == I40IW_MAX_SD_ENTRIES) {
 | 
					 | 
				
			||||||
			ret_code = dev->cqp->process_cqp_sds(dev, &sdinfo);
 | 
					 | 
				
			||||||
			if (ret_code) {
 | 
					 | 
				
			||||||
				i40iw_debug(dev, I40IW_DEBUG_HMC,
 | 
					 | 
				
			||||||
					    "i40iw_hmc_sd_grp: sd_programming failed err=%d\n",
 | 
					 | 
				
			||||||
					    ret_code);
 | 
					 | 
				
			||||||
				return ret_code;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			sdinfo.cnt = 0;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (sdinfo.cnt)
 | 
					 | 
				
			||||||
		ret_code = dev->cqp->process_cqp_sds(dev, &sdinfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_vfdev_from_fpm - return vf dev ptr for hmc function id
 | 
					 | 
				
			||||||
 * @dev: pointer to the device structure
 | 
					 | 
				
			||||||
 * @hmc_fn_id: hmc's function id
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct i40iw_vfdev *i40iw_vfdev_from_fpm(struct i40iw_sc_dev *dev, u8 hmc_fn_id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_vfdev *vf_dev = NULL;
 | 
					 | 
				
			||||||
	u16 idx;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (idx = 0; idx < I40IW_MAX_PE_ENABLED_VF_COUNT; idx++) {
 | 
					 | 
				
			||||||
		if (dev->vf_dev[idx] &&
 | 
					 | 
				
			||||||
		    ((u8)dev->vf_dev[idx]->pmf_index == hmc_fn_id)) {
 | 
					 | 
				
			||||||
			vf_dev = dev->vf_dev[idx];
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return vf_dev;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_vf_hmcinfo_from_fpm - get ptr to hmc for func_id
 | 
					 | 
				
			||||||
 * @dev: pointer to the device structure
 | 
					 | 
				
			||||||
 * @hmc_fn_id: hmc's function id
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct i40iw_hmc_info *i40iw_vf_hmcinfo_from_fpm(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						 u8 hmc_fn_id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info = NULL;
 | 
					 | 
				
			||||||
	u16 idx;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (idx = 0; idx < I40IW_MAX_PE_ENABLED_VF_COUNT; idx++) {
 | 
					 | 
				
			||||||
		if (dev->vf_dev[idx] &&
 | 
					 | 
				
			||||||
		    ((u8)dev->vf_dev[idx]->pmf_index == hmc_fn_id)) {
 | 
					 | 
				
			||||||
			hmc_info = &dev->vf_dev[idx]->hmc_info;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return hmc_info;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_hmc_finish_add_sd_reg - program sd entries for objects
 | 
					 | 
				
			||||||
 * @dev: pointer to the device structure
 | 
					 | 
				
			||||||
 * @info: create obj info
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code i40iw_hmc_finish_add_sd_reg(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
							  struct i40iw_hmc_create_obj_info *info)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt)
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_HMC_OBJ_INDEX;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((info->start_idx + info->count) >
 | 
					 | 
				
			||||||
			info->hmc_info->hmc_obj[info->rsrc_type].cnt)
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_HMC_OBJ_COUNT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!info->add_sd_cnt)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return i40iw_hmc_sd_grp(dev, info->hmc_info,
 | 
					 | 
				
			||||||
				info->hmc_info->sd_indexes[0],
 | 
					 | 
				
			||||||
				info->add_sd_cnt, true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_sc_create_hmc_obj - allocate backing store for hmc objects
 | 
					 | 
				
			||||||
 * @dev: pointer to the device structure
 | 
					 | 
				
			||||||
 * @info: pointer to i40iw_hmc_iw_create_obj_info struct
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This will allocate memory for PDs and backing pages and populate
 | 
					 | 
				
			||||||
 * the sd and pd entries.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_sc_create_hmc_obj(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					       struct i40iw_hmc_create_obj_info *info)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry;
 | 
					 | 
				
			||||||
	u32 sd_idx, sd_lmt;
 | 
					 | 
				
			||||||
	u32 pd_idx = 0, pd_lmt = 0;
 | 
					 | 
				
			||||||
	u32 pd_idx1 = 0, pd_lmt1 = 0;
 | 
					 | 
				
			||||||
	u32 i, j;
 | 
					 | 
				
			||||||
	bool pd_error = false;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt)
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_HMC_OBJ_INDEX;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((info->start_idx + info->count) >
 | 
					 | 
				
			||||||
	    info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_HMC,
 | 
					 | 
				
			||||||
			    "%s: error type %u, start = %u, req cnt %u, cnt = %u\n",
 | 
					 | 
				
			||||||
			    __func__, info->rsrc_type, info->start_idx, info->count,
 | 
					 | 
				
			||||||
			    info->hmc_info->hmc_obj[info->rsrc_type].cnt);
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_HMC_OBJ_COUNT;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!dev->is_pf)
 | 
					 | 
				
			||||||
		return i40iw_vchnl_vf_add_hmc_objs(dev, info->rsrc_type, 0, info->count);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i40iw_find_sd_index_limit(info->hmc_info, info->rsrc_type,
 | 
					 | 
				
			||||||
				  info->start_idx, info->count,
 | 
					 | 
				
			||||||
				  &sd_idx, &sd_lmt);
 | 
					 | 
				
			||||||
	if (sd_idx >= info->hmc_info->sd_table.sd_cnt ||
 | 
					 | 
				
			||||||
	    sd_lmt > info->hmc_info->sd_table.sd_cnt) {
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_SD_INDEX;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	i40iw_find_pd_index_limit(info->hmc_info, info->rsrc_type,
 | 
					 | 
				
			||||||
				  info->start_idx, info->count, &pd_idx, &pd_lmt);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (j = sd_idx; j < sd_lmt; j++) {
 | 
					 | 
				
			||||||
		ret_code = i40iw_add_sd_table_entry(dev->hw, info->hmc_info,
 | 
					 | 
				
			||||||
						    j,
 | 
					 | 
				
			||||||
						    info->entry_type,
 | 
					 | 
				
			||||||
						    I40IW_HMC_DIRECT_BP_SIZE);
 | 
					 | 
				
			||||||
		if (ret_code)
 | 
					 | 
				
			||||||
			goto exit_sd_error;
 | 
					 | 
				
			||||||
		sd_entry = &info->hmc_info->sd_table.sd_entry[j];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if ((sd_entry->entry_type == I40IW_SD_TYPE_PAGED) &&
 | 
					 | 
				
			||||||
		    ((dev->hmc_info == info->hmc_info) &&
 | 
					 | 
				
			||||||
		     (info->rsrc_type != I40IW_HMC_IW_PBLE))) {
 | 
					 | 
				
			||||||
			pd_idx1 = max(pd_idx, (j * I40IW_HMC_MAX_BP_COUNT));
 | 
					 | 
				
			||||||
			pd_lmt1 = min(pd_lmt,
 | 
					 | 
				
			||||||
				      (j + 1) * I40IW_HMC_MAX_BP_COUNT);
 | 
					 | 
				
			||||||
			for (i = pd_idx1; i < pd_lmt1; i++) {
 | 
					 | 
				
			||||||
				/* update the pd table entry */
 | 
					 | 
				
			||||||
				ret_code = i40iw_add_pd_table_entry(dev->hw, info->hmc_info,
 | 
					 | 
				
			||||||
								    i, NULL);
 | 
					 | 
				
			||||||
				if (ret_code) {
 | 
					 | 
				
			||||||
					pd_error = true;
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (pd_error) {
 | 
					 | 
				
			||||||
				while (i && (i > pd_idx1)) {
 | 
					 | 
				
			||||||
					i40iw_remove_pd_bp(dev->hw, info->hmc_info, (i - 1),
 | 
					 | 
				
			||||||
							   info->is_pf);
 | 
					 | 
				
			||||||
					i--;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (sd_entry->valid)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		info->hmc_info->sd_indexes[info->add_sd_cnt] = (u16)j;
 | 
					 | 
				
			||||||
		info->add_sd_cnt++;
 | 
					 | 
				
			||||||
		sd_entry->valid = true;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return i40iw_hmc_finish_add_sd_reg(dev, info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
exit_sd_error:
 | 
					 | 
				
			||||||
	while (j && (j > sd_idx)) {
 | 
					 | 
				
			||||||
		sd_entry = &info->hmc_info->sd_table.sd_entry[j - 1];
 | 
					 | 
				
			||||||
		switch (sd_entry->entry_type) {
 | 
					 | 
				
			||||||
		case I40IW_SD_TYPE_PAGED:
 | 
					 | 
				
			||||||
			pd_idx1 = max(pd_idx,
 | 
					 | 
				
			||||||
				      (j - 1) * I40IW_HMC_MAX_BP_COUNT);
 | 
					 | 
				
			||||||
			pd_lmt1 = min(pd_lmt, (j * I40IW_HMC_MAX_BP_COUNT));
 | 
					 | 
				
			||||||
			for (i = pd_idx1; i < pd_lmt1; i++)
 | 
					 | 
				
			||||||
				i40iw_prep_remove_pd_page(info->hmc_info, i);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_SD_TYPE_DIRECT:
 | 
					 | 
				
			||||||
			i40iw_prep_remove_pd_page(info->hmc_info, (j - 1));
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			ret_code = I40IW_ERR_INVALID_SD_TYPE;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		j--;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_finish_del_sd_reg - delete sd entries for objects
 | 
					 | 
				
			||||||
 * @dev: pointer to the device structure
 | 
					 | 
				
			||||||
 * @info: dele obj info
 | 
					 | 
				
			||||||
 * @reset: true if called before reset
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code i40iw_finish_del_sd_reg(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						      struct i40iw_hmc_del_obj_info *info,
 | 
					 | 
				
			||||||
						      bool reset)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = 0;
 | 
					 | 
				
			||||||
	u32 i, sd_idx;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem *mem;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (dev->is_pf && !reset)
 | 
					 | 
				
			||||||
		ret_code = i40iw_hmc_sd_grp(dev, info->hmc_info,
 | 
					 | 
				
			||||||
					    info->hmc_info->sd_indexes[0],
 | 
					 | 
				
			||||||
					    info->del_sd_cnt, false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_HMC, "%s: error cqp sd sd_grp\n", __func__);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i = 0; i < info->del_sd_cnt; i++) {
 | 
					 | 
				
			||||||
		sd_idx = info->hmc_info->sd_indexes[i];
 | 
					 | 
				
			||||||
		sd_entry = &info->hmc_info->sd_table.sd_entry[sd_idx];
 | 
					 | 
				
			||||||
		if (!sd_entry)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		mem = (sd_entry->entry_type == I40IW_SD_TYPE_PAGED) ?
 | 
					 | 
				
			||||||
			&sd_entry->u.pd_table.pd_page_addr :
 | 
					 | 
				
			||||||
			&sd_entry->u.bp.addr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!mem || !mem->va)
 | 
					 | 
				
			||||||
			i40iw_debug(dev, I40IW_DEBUG_HMC, "%s: error cqp sd mem\n", __func__);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			i40iw_free_dma_mem(dev->hw, mem);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_sc_del_hmc_obj - remove pe hmc objects
 | 
					 | 
				
			||||||
 * @dev: pointer to the device structure
 | 
					 | 
				
			||||||
 * @info: pointer to i40iw_hmc_del_obj_info struct
 | 
					 | 
				
			||||||
 * @reset: true if called before reset
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This will de-populate the SDs and PDs.  It frees
 | 
					 | 
				
			||||||
 * the memory for PDS and backing storage.  After this function is returned,
 | 
					 | 
				
			||||||
 * caller should deallocate memory allocated previously for
 | 
					 | 
				
			||||||
 * book-keeping information about PDs and backing storage.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_sc_del_hmc_obj(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					    struct i40iw_hmc_del_obj_info *info,
 | 
					 | 
				
			||||||
					    bool reset)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pd_table *pd_table;
 | 
					 | 
				
			||||||
	u32 sd_idx, sd_lmt;
 | 
					 | 
				
			||||||
	u32 pd_idx, pd_lmt, rel_pd_idx;
 | 
					 | 
				
			||||||
	u32 i, j;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_HMC,
 | 
					 | 
				
			||||||
			    "%s: error start_idx[%04d]  >= [type %04d].cnt[%04d]\n",
 | 
					 | 
				
			||||||
			    __func__, info->start_idx, info->rsrc_type,
 | 
					 | 
				
			||||||
			    info->hmc_info->hmc_obj[info->rsrc_type].cnt);
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_HMC_OBJ_INDEX;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((info->start_idx + info->count) >
 | 
					 | 
				
			||||||
	    info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_HMC,
 | 
					 | 
				
			||||||
			    "%s: error start_idx[%04d] + count %04d  >= [type %04d].cnt[%04d]\n",
 | 
					 | 
				
			||||||
			    __func__, info->start_idx, info->count,
 | 
					 | 
				
			||||||
			    info->rsrc_type,
 | 
					 | 
				
			||||||
			    info->hmc_info->hmc_obj[info->rsrc_type].cnt);
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_HMC_OBJ_COUNT;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!dev->is_pf) {
 | 
					 | 
				
			||||||
		ret_code = i40iw_vchnl_vf_del_hmc_obj(dev, info->rsrc_type, 0,
 | 
					 | 
				
			||||||
						      info->count);
 | 
					 | 
				
			||||||
		if (info->rsrc_type != I40IW_HMC_IW_PBLE)
 | 
					 | 
				
			||||||
			return ret_code;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i40iw_find_pd_index_limit(info->hmc_info, info->rsrc_type,
 | 
					 | 
				
			||||||
				  info->start_idx, info->count, &pd_idx, &pd_lmt);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (j = pd_idx; j < pd_lmt; j++) {
 | 
					 | 
				
			||||||
		sd_idx = j / I40IW_HMC_PD_CNT_IN_SD;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (info->hmc_info->sd_table.sd_entry[sd_idx].entry_type !=
 | 
					 | 
				
			||||||
		    I40IW_SD_TYPE_PAGED)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		rel_pd_idx = j % I40IW_HMC_PD_CNT_IN_SD;
 | 
					 | 
				
			||||||
		pd_table = &info->hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
 | 
					 | 
				
			||||||
		if (pd_table->pd_entry[rel_pd_idx].valid) {
 | 
					 | 
				
			||||||
			ret_code = i40iw_remove_pd_bp(dev->hw, info->hmc_info, j,
 | 
					 | 
				
			||||||
						      info->is_pf);
 | 
					 | 
				
			||||||
			if (ret_code) {
 | 
					 | 
				
			||||||
				i40iw_debug(dev, I40IW_DEBUG_HMC, "%s: error\n", __func__);
 | 
					 | 
				
			||||||
				return ret_code;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i40iw_find_sd_index_limit(info->hmc_info, info->rsrc_type,
 | 
					 | 
				
			||||||
				  info->start_idx, info->count, &sd_idx, &sd_lmt);
 | 
					 | 
				
			||||||
	if (sd_idx >= info->hmc_info->sd_table.sd_cnt ||
 | 
					 | 
				
			||||||
	    sd_lmt > info->hmc_info->sd_table.sd_cnt) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_HMC, "%s: error invalid sd_idx\n", __func__);
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_SD_INDEX;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i = sd_idx; i < sd_lmt; i++) {
 | 
					 | 
				
			||||||
		if (!info->hmc_info->sd_table.sd_entry[i].valid)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		switch (info->hmc_info->sd_table.sd_entry[i].entry_type) {
 | 
					 | 
				
			||||||
		case I40IW_SD_TYPE_DIRECT:
 | 
					 | 
				
			||||||
			ret_code = i40iw_prep_remove_sd_bp(info->hmc_info, i);
 | 
					 | 
				
			||||||
			if (!ret_code) {
 | 
					 | 
				
			||||||
				info->hmc_info->sd_indexes[info->del_sd_cnt] = (u16)i;
 | 
					 | 
				
			||||||
				info->del_sd_cnt++;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_SD_TYPE_PAGED:
 | 
					 | 
				
			||||||
			ret_code = i40iw_prep_remove_pd_page(info->hmc_info, i);
 | 
					 | 
				
			||||||
			if (!ret_code) {
 | 
					 | 
				
			||||||
				info->hmc_info->sd_indexes[info->del_sd_cnt] = (u16)i;
 | 
					 | 
				
			||||||
				info->del_sd_cnt++;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return i40iw_finish_del_sd_reg(dev, info, reset);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_add_sd_table_entry - Adds a segment descriptor to the table
 | 
					 | 
				
			||||||
 * @hw: pointer to our hw struct
 | 
					 | 
				
			||||||
 * @hmc_info: pointer to the HMC configuration information struct
 | 
					 | 
				
			||||||
 * @sd_index: segment descriptor index to manipulate
 | 
					 | 
				
			||||||
 * @type: what type of segment descriptor we're manipulating
 | 
					 | 
				
			||||||
 * @direct_mode_sz: size to alloc in direct mode
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_add_sd_table_entry(struct i40iw_hw *hw,
 | 
					 | 
				
			||||||
						struct i40iw_hmc_info *hmc_info,
 | 
					 | 
				
			||||||
						u32 sd_index,
 | 
					 | 
				
			||||||
						enum i40iw_sd_entry_type type,
 | 
					 | 
				
			||||||
						u64 direct_mode_sz)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = 0;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry;
 | 
					 | 
				
			||||||
	bool dma_mem_alloc_done = false;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem mem;
 | 
					 | 
				
			||||||
	u64 alloc_len;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sd_entry = &hmc_info->sd_table.sd_entry[sd_index];
 | 
					 | 
				
			||||||
	if (!sd_entry->valid) {
 | 
					 | 
				
			||||||
		if (type == I40IW_SD_TYPE_PAGED)
 | 
					 | 
				
			||||||
			alloc_len = I40IW_HMC_PAGED_BP_SIZE;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			alloc_len = direct_mode_sz;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* allocate a 4K pd page or 2M backing page */
 | 
					 | 
				
			||||||
		ret_code = i40iw_allocate_dma_mem(hw, &mem, alloc_len,
 | 
					 | 
				
			||||||
						  I40IW_HMC_PD_BP_BUF_ALIGNMENT);
 | 
					 | 
				
			||||||
		if (ret_code)
 | 
					 | 
				
			||||||
			goto exit;
 | 
					 | 
				
			||||||
		dma_mem_alloc_done = true;
 | 
					 | 
				
			||||||
		if (type == I40IW_SD_TYPE_PAGED) {
 | 
					 | 
				
			||||||
			ret_code = i40iw_allocate_virt_mem(hw,
 | 
					 | 
				
			||||||
							   &sd_entry->u.pd_table.pd_entry_virt_mem,
 | 
					 | 
				
			||||||
							   sizeof(struct i40iw_hmc_pd_entry) * 512);
 | 
					 | 
				
			||||||
			if (ret_code)
 | 
					 | 
				
			||||||
				goto exit;
 | 
					 | 
				
			||||||
			sd_entry->u.pd_table.pd_entry = (struct i40iw_hmc_pd_entry *)
 | 
					 | 
				
			||||||
							 sd_entry->u.pd_table.pd_entry_virt_mem.va;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			memcpy(&sd_entry->u.pd_table.pd_page_addr, &mem, sizeof(struct i40iw_dma_mem));
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			memcpy(&sd_entry->u.bp.addr, &mem, sizeof(struct i40iw_dma_mem));
 | 
					 | 
				
			||||||
			sd_entry->u.bp.sd_pd_index = sd_index;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		hmc_info->sd_table.sd_entry[sd_index].entry_type = type;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		I40IW_INC_SD_REFCNT(&hmc_info->sd_table);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (sd_entry->entry_type == I40IW_SD_TYPE_DIRECT)
 | 
					 | 
				
			||||||
		I40IW_INC_BP_REFCNT(&sd_entry->u.bp);
 | 
					 | 
				
			||||||
exit:
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		if (dma_mem_alloc_done)
 | 
					 | 
				
			||||||
			i40iw_free_dma_mem(hw, &mem);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_add_pd_table_entry - Adds page descriptor to the specified table
 | 
					 | 
				
			||||||
 * @hw: pointer to our HW structure
 | 
					 | 
				
			||||||
 * @hmc_info: pointer to the HMC configuration information structure
 | 
					 | 
				
			||||||
 * @pd_index: which page descriptor index to manipulate
 | 
					 | 
				
			||||||
 * @rsrc_pg: if not NULL, use preallocated page instead of allocating new one.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This function:
 | 
					 | 
				
			||||||
 *	1. Initializes the pd entry
 | 
					 | 
				
			||||||
 *	2. Adds pd_entry in the pd_table
 | 
					 | 
				
			||||||
 *	3. Mark the entry valid in i40iw_hmc_pd_entry structure
 | 
					 | 
				
			||||||
 *	4. Initializes the pd_entry's ref count to 1
 | 
					 | 
				
			||||||
 * assumptions:
 | 
					 | 
				
			||||||
 *	1. The memory for pd should be pinned down, physically contiguous and
 | 
					 | 
				
			||||||
 *	   aligned on 4K boundary and zeroed memory.
 | 
					 | 
				
			||||||
 *	2. It should be 4K in size.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_add_pd_table_entry(struct i40iw_hw *hw,
 | 
					 | 
				
			||||||
						struct i40iw_hmc_info *hmc_info,
 | 
					 | 
				
			||||||
						u32 pd_index,
 | 
					 | 
				
			||||||
						struct i40iw_dma_mem *rsrc_pg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = 0;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pd_table *pd_table;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pd_entry *pd_entry;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem mem;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem *page = &mem;
 | 
					 | 
				
			||||||
	u32 sd_idx, rel_pd_idx;
 | 
					 | 
				
			||||||
	u64 *pd_addr;
 | 
					 | 
				
			||||||
	u64 page_desc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (pd_index / I40IW_HMC_PD_CNT_IN_SD >= hmc_info->sd_table.sd_cnt)
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_PAGE_DESC_INDEX;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sd_idx = (pd_index / I40IW_HMC_PD_CNT_IN_SD);
 | 
					 | 
				
			||||||
	if (hmc_info->sd_table.sd_entry[sd_idx].entry_type != I40IW_SD_TYPE_PAGED)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rel_pd_idx = (pd_index % I40IW_HMC_PD_CNT_IN_SD);
 | 
					 | 
				
			||||||
	pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
 | 
					 | 
				
			||||||
	pd_entry = &pd_table->pd_entry[rel_pd_idx];
 | 
					 | 
				
			||||||
	if (!pd_entry->valid) {
 | 
					 | 
				
			||||||
		if (rsrc_pg) {
 | 
					 | 
				
			||||||
			pd_entry->rsrc_pg = true;
 | 
					 | 
				
			||||||
			page = rsrc_pg;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			ret_code = i40iw_allocate_dma_mem(hw, page,
 | 
					 | 
				
			||||||
							  I40IW_HMC_PAGED_BP_SIZE,
 | 
					 | 
				
			||||||
							  I40IW_HMC_PD_BP_BUF_ALIGNMENT);
 | 
					 | 
				
			||||||
			if (ret_code)
 | 
					 | 
				
			||||||
				return ret_code;
 | 
					 | 
				
			||||||
			pd_entry->rsrc_pg = false;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		memcpy(&pd_entry->bp.addr, page, sizeof(struct i40iw_dma_mem));
 | 
					 | 
				
			||||||
		pd_entry->bp.sd_pd_index = pd_index;
 | 
					 | 
				
			||||||
		pd_entry->bp.entry_type = I40IW_SD_TYPE_PAGED;
 | 
					 | 
				
			||||||
		page_desc = page->pa | 0x1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		pd_addr = (u64 *)pd_table->pd_page_addr.va;
 | 
					 | 
				
			||||||
		pd_addr += rel_pd_idx;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		memcpy(pd_addr, &page_desc, sizeof(*pd_addr));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		pd_entry->sd_index = sd_idx;
 | 
					 | 
				
			||||||
		pd_entry->valid = true;
 | 
					 | 
				
			||||||
		I40IW_INC_PD_REFCNT(pd_table);
 | 
					 | 
				
			||||||
		if (hmc_info->hmc_fn_id < I40IW_FIRST_VF_FPM_ID)
 | 
					 | 
				
			||||||
			I40IW_INVALIDATE_PF_HMC_PD(hw, sd_idx, rel_pd_idx);
 | 
					 | 
				
			||||||
		else if (hw->hmc.hmc_fn_id != hmc_info->hmc_fn_id)
 | 
					 | 
				
			||||||
			I40IW_INVALIDATE_VF_HMC_PD(hw, sd_idx, rel_pd_idx,
 | 
					 | 
				
			||||||
						   hmc_info->hmc_fn_id);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	I40IW_INC_BP_REFCNT(&pd_entry->bp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_remove_pd_bp - remove a backing page from a page descriptor
 | 
					 | 
				
			||||||
 * @hw: pointer to our HW structure
 | 
					 | 
				
			||||||
 * @hmc_info: pointer to the HMC configuration information structure
 | 
					 | 
				
			||||||
 * @idx: the page index
 | 
					 | 
				
			||||||
 * @is_pf: distinguishes a VF from a PF
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This function:
 | 
					 | 
				
			||||||
 *	1. Marks the entry in pd table (for paged address mode) or in sd table
 | 
					 | 
				
			||||||
 *	   (for direct address mode) invalid.
 | 
					 | 
				
			||||||
 *	2. Write to register PMPDINV to invalidate the backing page in FV cache
 | 
					 | 
				
			||||||
 *	3. Decrement the ref count for the pd _entry
 | 
					 | 
				
			||||||
 * assumptions:
 | 
					 | 
				
			||||||
 *	1. Caller can deallocate the memory used by backing storage after this
 | 
					 | 
				
			||||||
 *	   function returns.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_remove_pd_bp(struct i40iw_hw *hw,
 | 
					 | 
				
			||||||
					  struct i40iw_hmc_info *hmc_info,
 | 
					 | 
				
			||||||
					  u32 idx,
 | 
					 | 
				
			||||||
					  bool is_pf)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pd_entry *pd_entry;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pd_table *pd_table;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry;
 | 
					 | 
				
			||||||
	u32 sd_idx, rel_pd_idx;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem *mem;
 | 
					 | 
				
			||||||
	u64 *pd_addr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sd_idx = idx / I40IW_HMC_PD_CNT_IN_SD;
 | 
					 | 
				
			||||||
	rel_pd_idx = idx % I40IW_HMC_PD_CNT_IN_SD;
 | 
					 | 
				
			||||||
	if (sd_idx >= hmc_info->sd_table.sd_cnt)
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_PAGE_DESC_INDEX;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sd_entry = &hmc_info->sd_table.sd_entry[sd_idx];
 | 
					 | 
				
			||||||
	if (sd_entry->entry_type != I40IW_SD_TYPE_PAGED)
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_SD_TYPE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
 | 
					 | 
				
			||||||
	pd_entry = &pd_table->pd_entry[rel_pd_idx];
 | 
					 | 
				
			||||||
	I40IW_DEC_BP_REFCNT(&pd_entry->bp);
 | 
					 | 
				
			||||||
	if (pd_entry->bp.ref_cnt)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pd_entry->valid = false;
 | 
					 | 
				
			||||||
	I40IW_DEC_PD_REFCNT(pd_table);
 | 
					 | 
				
			||||||
	pd_addr = (u64 *)pd_table->pd_page_addr.va;
 | 
					 | 
				
			||||||
	pd_addr += rel_pd_idx;
 | 
					 | 
				
			||||||
	memset(pd_addr, 0, sizeof(u64));
 | 
					 | 
				
			||||||
	if (is_pf)
 | 
					 | 
				
			||||||
		I40IW_INVALIDATE_PF_HMC_PD(hw, sd_idx, idx);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		I40IW_INVALIDATE_VF_HMC_PD(hw, sd_idx, idx,
 | 
					 | 
				
			||||||
					   hmc_info->hmc_fn_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!pd_entry->rsrc_pg) {
 | 
					 | 
				
			||||||
		mem = &pd_entry->bp.addr;
 | 
					 | 
				
			||||||
		if (!mem || !mem->va)
 | 
					 | 
				
			||||||
			return I40IW_ERR_PARAM;
 | 
					 | 
				
			||||||
		i40iw_free_dma_mem(hw, mem);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!pd_table->ref_cnt)
 | 
					 | 
				
			||||||
		i40iw_free_virt_mem(hw, &pd_table->pd_entry_virt_mem);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_prep_remove_sd_bp - Prepares to remove a backing page from a sd entry
 | 
					 | 
				
			||||||
 * @hmc_info: pointer to the HMC configuration information structure
 | 
					 | 
				
			||||||
 * @idx: the page index
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_prep_remove_sd_bp(struct i40iw_hmc_info *hmc_info, u32 idx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sd_entry = &hmc_info->sd_table.sd_entry[idx];
 | 
					 | 
				
			||||||
	I40IW_DEC_BP_REFCNT(&sd_entry->u.bp);
 | 
					 | 
				
			||||||
	if (sd_entry->u.bp.ref_cnt)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NOT_READY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	I40IW_DEC_SD_REFCNT(&hmc_info->sd_table);
 | 
					 | 
				
			||||||
	sd_entry->valid = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_prep_remove_pd_page - Prepares to remove a PD page from sd entry.
 | 
					 | 
				
			||||||
 * @hmc_info: pointer to the HMC configuration information structure
 | 
					 | 
				
			||||||
 * @idx: segment descriptor index to find the relevant page descriptor
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_prep_remove_pd_page(struct i40iw_hmc_info *hmc_info,
 | 
					 | 
				
			||||||
						 u32 idx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sd_entry = &hmc_info->sd_table.sd_entry[idx];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (sd_entry->u.pd_table.ref_cnt)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NOT_READY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sd_entry->valid = false;
 | 
					 | 
				
			||||||
	I40IW_DEC_SD_REFCNT(&hmc_info->sd_table);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_pf_init_vfhmc -
 | 
					 | 
				
			||||||
 * @vf_cnt_array: array of cnt values of iwarp hmc objects
 | 
					 | 
				
			||||||
 * @vf_hmc_fn_id: hmc function id ofr vf driver
 | 
					 | 
				
			||||||
 * @dev: pointer to i40iw_dev struct
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Called by pf driver to initialize hmc_info for vf driver instance.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_pf_init_vfhmc(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					   u8 vf_hmc_fn_id,
 | 
					 | 
				
			||||||
					   u32 *vf_cnt_array)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = 0;
 | 
					 | 
				
			||||||
	u32 i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((vf_hmc_fn_id < I40IW_FIRST_VF_FPM_ID) ||
 | 
					 | 
				
			||||||
	    (vf_hmc_fn_id >= I40IW_FIRST_VF_FPM_ID +
 | 
					 | 
				
			||||||
	     I40IW_MAX_PE_ENABLED_VF_COUNT)) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_HMC, "%s: invalid vf_hmc_fn_id  0x%x\n",
 | 
					 | 
				
			||||||
			    __func__, vf_hmc_fn_id);
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_HMCFN_ID;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret_code = i40iw_sc_init_iw_hmc(dev, vf_hmc_fn_id);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hmc_info = i40iw_vf_hmcinfo_from_fpm(dev, vf_hmc_fn_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i = I40IW_HMC_IW_QP; i < I40IW_HMC_IW_MAX; i++)
 | 
					 | 
				
			||||||
		if (vf_cnt_array)
 | 
					 | 
				
			||||||
			hmc_info->hmc_obj[i].cnt =
 | 
					 | 
				
			||||||
			    vf_cnt_array[i - I40IW_HMC_IW_QP];
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			hmc_info->hmc_obj[i].cnt = hmc_info->hmc_obj[i].max_cnt;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,241 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_HMC_H
 | 
					 | 
				
			||||||
#define I40IW_HMC_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "i40iw_d.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hw;
 | 
					 | 
				
			||||||
enum i40iw_status_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_HMC_MAX_BP_COUNT 512
 | 
					 | 
				
			||||||
#define I40IW_MAX_SD_ENTRIES 11
 | 
					 | 
				
			||||||
#define I40IW_HW_DBG_HMC_INVALID_BP_MARK     0xCA
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_HMC_INFO_SIGNATURE	0x484D5347
 | 
					 | 
				
			||||||
#define I40IW_HMC_PD_CNT_IN_SD		512
 | 
					 | 
				
			||||||
#define I40IW_HMC_DIRECT_BP_SIZE	0x200000
 | 
					 | 
				
			||||||
#define I40IW_HMC_MAX_SD_COUNT		4096
 | 
					 | 
				
			||||||
#define I40IW_HMC_PAGED_BP_SIZE		4096
 | 
					 | 
				
			||||||
#define I40IW_HMC_PD_BP_BUF_ALIGNMENT	4096
 | 
					 | 
				
			||||||
#define I40IW_FIRST_VF_FPM_ID		16
 | 
					 | 
				
			||||||
#define FPM_MULTIPLIER			1024
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_INC_SD_REFCNT(sd_table)   ((sd_table)->ref_cnt++)
 | 
					 | 
				
			||||||
#define I40IW_INC_PD_REFCNT(pd_table)   ((pd_table)->ref_cnt++)
 | 
					 | 
				
			||||||
#define I40IW_INC_BP_REFCNT(bp)         ((bp)->ref_cnt++)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_DEC_SD_REFCNT(sd_table)   ((sd_table)->ref_cnt--)
 | 
					 | 
				
			||||||
#define I40IW_DEC_PD_REFCNT(pd_table)   ((pd_table)->ref_cnt--)
 | 
					 | 
				
			||||||
#define I40IW_DEC_BP_REFCNT(bp)         ((bp)->ref_cnt--)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * I40IW_INVALIDATE_PF_HMC_PD - Invalidates the pd cache in the hardware
 | 
					 | 
				
			||||||
 * @hw: pointer to our hw struct
 | 
					 | 
				
			||||||
 * @sd_idx: segment descriptor index
 | 
					 | 
				
			||||||
 * @pd_idx: page descriptor index
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define I40IW_INVALIDATE_PF_HMC_PD(hw, sd_idx, pd_idx)                  \
 | 
					 | 
				
			||||||
	i40iw_wr32((hw), I40E_PFHMC_PDINV,                                    \
 | 
					 | 
				
			||||||
		(((sd_idx) << I40E_PFHMC_PDINV_PMSDIDX_SHIFT) |             \
 | 
					 | 
				
			||||||
		(0x1 << I40E_PFHMC_PDINV_PMSDPARTSEL_SHIFT) | \
 | 
					 | 
				
			||||||
		((pd_idx) << I40E_PFHMC_PDINV_PMPDIDX_SHIFT)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * I40IW_INVALIDATE_VF_HMC_PD - Invalidates the pd cache in the hardware
 | 
					 | 
				
			||||||
 * @hw: pointer to our hw struct
 | 
					 | 
				
			||||||
 * @sd_idx: segment descriptor index
 | 
					 | 
				
			||||||
 * @pd_idx: page descriptor index
 | 
					 | 
				
			||||||
 * @hmc_fn_id: VF's function id
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define I40IW_INVALIDATE_VF_HMC_PD(hw, sd_idx, pd_idx, hmc_fn_id)        \
 | 
					 | 
				
			||||||
	i40iw_wr32(hw, I40E_GLHMC_VFPDINV(hmc_fn_id - I40IW_FIRST_VF_FPM_ID),  \
 | 
					 | 
				
			||||||
	     ((sd_idx << I40E_PFHMC_PDINV_PMSDIDX_SHIFT) |              \
 | 
					 | 
				
			||||||
	      (pd_idx << I40E_PFHMC_PDINV_PMPDIDX_SHIFT)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_obj_info {
 | 
					 | 
				
			||||||
	u64 base;
 | 
					 | 
				
			||||||
	u32 max_cnt;
 | 
					 | 
				
			||||||
	u32 cnt;
 | 
					 | 
				
			||||||
	u64 size;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_sd_entry_type {
 | 
					 | 
				
			||||||
	I40IW_SD_TYPE_INVALID = 0,
 | 
					 | 
				
			||||||
	I40IW_SD_TYPE_PAGED = 1,
 | 
					 | 
				
			||||||
	I40IW_SD_TYPE_DIRECT = 2
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_bp {
 | 
					 | 
				
			||||||
	enum i40iw_sd_entry_type entry_type;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem addr;
 | 
					 | 
				
			||||||
	u32 sd_pd_index;
 | 
					 | 
				
			||||||
	u32 ref_cnt;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_pd_entry {
 | 
					 | 
				
			||||||
	struct i40iw_hmc_bp bp;
 | 
					 | 
				
			||||||
	u32 sd_index;
 | 
					 | 
				
			||||||
	bool rsrc_pg;
 | 
					 | 
				
			||||||
	bool valid;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_pd_table {
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem pd_page_addr;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pd_entry *pd_entry;
 | 
					 | 
				
			||||||
	struct i40iw_virt_mem pd_entry_virt_mem;
 | 
					 | 
				
			||||||
	u32 ref_cnt;
 | 
					 | 
				
			||||||
	u32 sd_index;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_sd_entry {
 | 
					 | 
				
			||||||
	enum i40iw_sd_entry_type entry_type;
 | 
					 | 
				
			||||||
	bool valid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct i40iw_hmc_pd_table pd_table;
 | 
					 | 
				
			||||||
		struct i40iw_hmc_bp bp;
 | 
					 | 
				
			||||||
	} u;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_sd_table {
 | 
					 | 
				
			||||||
	struct i40iw_virt_mem addr;
 | 
					 | 
				
			||||||
	u32 sd_cnt;
 | 
					 | 
				
			||||||
	u32 ref_cnt;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_info {
 | 
					 | 
				
			||||||
	u32 signature;
 | 
					 | 
				
			||||||
	u8 hmc_fn_id;
 | 
					 | 
				
			||||||
	u16 first_sd_index;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct i40iw_hmc_obj_info *hmc_obj;
 | 
					 | 
				
			||||||
	struct i40iw_virt_mem hmc_obj_virt_mem;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_table sd_table;
 | 
					 | 
				
			||||||
	u16 sd_indexes[I40IW_HMC_MAX_SD_COUNT];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct update_sd_entry {
 | 
					 | 
				
			||||||
	u64 cmd;
 | 
					 | 
				
			||||||
	u64 data;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_update_sds_info {
 | 
					 | 
				
			||||||
	u32 cnt;
 | 
					 | 
				
			||||||
	u8 hmc_fn_id;
 | 
					 | 
				
			||||||
	struct update_sd_entry entry[I40IW_MAX_SD_ENTRIES];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_ccq_cqe_info;
 | 
					 | 
				
			||||||
struct i40iw_hmc_fcn_info {
 | 
					 | 
				
			||||||
	void (*callback_fcn)(struct i40iw_sc_dev *, void *,
 | 
					 | 
				
			||||||
			     struct i40iw_ccq_cqe_info *);
 | 
					 | 
				
			||||||
	void *cqp_callback_param;
 | 
					 | 
				
			||||||
	u32 vf_id;
 | 
					 | 
				
			||||||
	u16 iw_vf_idx;
 | 
					 | 
				
			||||||
	bool free_fcn;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_hmc_rsrc_type {
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_QP = 0,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_CQ = 1,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_SRQ = 2,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_HTE = 3,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_ARP = 4,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_APBVT_ENTRY = 5,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_MR = 6,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_XF = 7,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_XFFL = 8,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_Q1 = 9,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_Q1FL = 10,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_TIMER = 11,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_FSIMC = 12,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_FSIAV = 13,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_PBLE = 14,
 | 
					 | 
				
			||||||
	I40IW_HMC_IW_MAX = 15,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_create_obj_info {
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info;
 | 
					 | 
				
			||||||
	struct i40iw_virt_mem add_sd_virt_mem;
 | 
					 | 
				
			||||||
	u32 rsrc_type;
 | 
					 | 
				
			||||||
	u32 start_idx;
 | 
					 | 
				
			||||||
	u32 count;
 | 
					 | 
				
			||||||
	u32 add_sd_cnt;
 | 
					 | 
				
			||||||
	enum i40iw_sd_entry_type entry_type;
 | 
					 | 
				
			||||||
	bool is_pf;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_del_obj_info {
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info;
 | 
					 | 
				
			||||||
	struct i40iw_virt_mem del_sd_virt_mem;
 | 
					 | 
				
			||||||
	u32 rsrc_type;
 | 
					 | 
				
			||||||
	u32 start_idx;
 | 
					 | 
				
			||||||
	u32 count;
 | 
					 | 
				
			||||||
	u32 del_sd_cnt;
 | 
					 | 
				
			||||||
	bool is_pf;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_copy_dma_mem(struct i40iw_hw *hw, void *dest_buf,
 | 
					 | 
				
			||||||
					  struct i40iw_dma_mem *src_mem, u64 src_offset, u64 size);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_sc_create_hmc_obj(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					       struct i40iw_hmc_create_obj_info *info);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_sc_del_hmc_obj(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					    struct i40iw_hmc_del_obj_info *info,
 | 
					 | 
				
			||||||
					    bool reset);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_hmc_sd_one(struct i40iw_sc_dev *dev, u8 hmc_fn_id,
 | 
					 | 
				
			||||||
					u64 pa, u32 sd_idx, enum i40iw_sd_entry_type type,
 | 
					 | 
				
			||||||
					bool setsd);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_update_sds_noccq(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					      struct i40iw_update_sds_info *info);
 | 
					 | 
				
			||||||
struct i40iw_vfdev *i40iw_vfdev_from_fpm(struct i40iw_sc_dev *dev, u8 hmc_fn_id);
 | 
					 | 
				
			||||||
struct i40iw_hmc_info *i40iw_vf_hmcinfo_from_fpm(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						 u8 hmc_fn_id);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_add_sd_table_entry(struct i40iw_hw *hw,
 | 
					 | 
				
			||||||
						struct i40iw_hmc_info *hmc_info, u32 sd_index,
 | 
					 | 
				
			||||||
						enum i40iw_sd_entry_type type, u64 direct_mode_sz);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_add_pd_table_entry(struct i40iw_hw *hw,
 | 
					 | 
				
			||||||
						struct i40iw_hmc_info *hmc_info, u32 pd_index,
 | 
					 | 
				
			||||||
						struct i40iw_dma_mem *rsrc_pg);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_remove_pd_bp(struct i40iw_hw *hw,
 | 
					 | 
				
			||||||
					  struct i40iw_hmc_info *hmc_info, u32 idx, bool is_pf);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_prep_remove_sd_bp(struct i40iw_hmc_info *hmc_info, u32 idx);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_prep_remove_pd_page(struct i40iw_hmc_info *hmc_info, u32 idx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define     ENTER_SHARED_FUNCTION()
 | 
					 | 
				
			||||||
#define     EXIT_SHARED_FUNCTION()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif				/* I40IW_HMC_H */
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,851 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <linux/module.h>
 | 
					 | 
				
			||||||
#include <linux/moduleparam.h>
 | 
					 | 
				
			||||||
#include <linux/netdevice.h>
 | 
					 | 
				
			||||||
#include <linux/etherdevice.h>
 | 
					 | 
				
			||||||
#include <linux/ip.h>
 | 
					 | 
				
			||||||
#include <linux/tcp.h>
 | 
					 | 
				
			||||||
#include <linux/if_vlan.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "i40iw.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_initialize_hw_resources - initialize hw resource during open
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
u32 i40iw_initialize_hw_resources(struct i40iw_device *iwdev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	unsigned long num_pds;
 | 
					 | 
				
			||||||
	u32 resources_size;
 | 
					 | 
				
			||||||
	u32 max_mr;
 | 
					 | 
				
			||||||
	u32 max_qp;
 | 
					 | 
				
			||||||
	u32 max_cq;
 | 
					 | 
				
			||||||
	u32 arp_table_size;
 | 
					 | 
				
			||||||
	u32 mrdrvbits;
 | 
					 | 
				
			||||||
	void *resource_ptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	max_qp = iwdev->sc_dev.hmc_info->hmc_obj[I40IW_HMC_IW_QP].cnt;
 | 
					 | 
				
			||||||
	max_cq = iwdev->sc_dev.hmc_info->hmc_obj[I40IW_HMC_IW_CQ].cnt;
 | 
					 | 
				
			||||||
	max_mr = iwdev->sc_dev.hmc_info->hmc_obj[I40IW_HMC_IW_MR].cnt;
 | 
					 | 
				
			||||||
	arp_table_size = iwdev->sc_dev.hmc_info->hmc_obj[I40IW_HMC_IW_ARP].cnt;
 | 
					 | 
				
			||||||
	iwdev->max_cqe = 0xFFFFF;
 | 
					 | 
				
			||||||
	num_pds = I40IW_MAX_PDS;
 | 
					 | 
				
			||||||
	resources_size = sizeof(struct i40iw_arp_entry) * arp_table_size;
 | 
					 | 
				
			||||||
	resources_size += sizeof(unsigned long) * BITS_TO_LONGS(max_qp);
 | 
					 | 
				
			||||||
	resources_size += sizeof(unsigned long) * BITS_TO_LONGS(max_mr);
 | 
					 | 
				
			||||||
	resources_size += sizeof(unsigned long) * BITS_TO_LONGS(max_cq);
 | 
					 | 
				
			||||||
	resources_size += sizeof(unsigned long) * BITS_TO_LONGS(num_pds);
 | 
					 | 
				
			||||||
	resources_size += sizeof(unsigned long) * BITS_TO_LONGS(arp_table_size);
 | 
					 | 
				
			||||||
	resources_size += sizeof(struct i40iw_qp **) * max_qp;
 | 
					 | 
				
			||||||
	iwdev->mem_resources = kzalloc(resources_size, GFP_KERNEL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!iwdev->mem_resources)
 | 
					 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	iwdev->max_qp = max_qp;
 | 
					 | 
				
			||||||
	iwdev->max_mr = max_mr;
 | 
					 | 
				
			||||||
	iwdev->max_cq = max_cq;
 | 
					 | 
				
			||||||
	iwdev->max_pd = num_pds;
 | 
					 | 
				
			||||||
	iwdev->arp_table_size = arp_table_size;
 | 
					 | 
				
			||||||
	iwdev->arp_table = (struct i40iw_arp_entry *)iwdev->mem_resources;
 | 
					 | 
				
			||||||
	resource_ptr = iwdev->mem_resources + (sizeof(struct i40iw_arp_entry) * arp_table_size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	iwdev->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY |
 | 
					 | 
				
			||||||
	    IB_DEVICE_MEM_WINDOW | IB_DEVICE_MEM_MGT_EXTENSIONS;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	iwdev->allocated_qps = resource_ptr;
 | 
					 | 
				
			||||||
	iwdev->allocated_cqs = &iwdev->allocated_qps[BITS_TO_LONGS(max_qp)];
 | 
					 | 
				
			||||||
	iwdev->allocated_mrs = &iwdev->allocated_cqs[BITS_TO_LONGS(max_cq)];
 | 
					 | 
				
			||||||
	iwdev->allocated_pds = &iwdev->allocated_mrs[BITS_TO_LONGS(max_mr)];
 | 
					 | 
				
			||||||
	iwdev->allocated_arps = &iwdev->allocated_pds[BITS_TO_LONGS(num_pds)];
 | 
					 | 
				
			||||||
	iwdev->qp_table = (struct i40iw_qp **)(&iwdev->allocated_arps[BITS_TO_LONGS(arp_table_size)]);
 | 
					 | 
				
			||||||
	set_bit(0, iwdev->allocated_mrs);
 | 
					 | 
				
			||||||
	set_bit(0, iwdev->allocated_qps);
 | 
					 | 
				
			||||||
	set_bit(0, iwdev->allocated_cqs);
 | 
					 | 
				
			||||||
	set_bit(0, iwdev->allocated_pds);
 | 
					 | 
				
			||||||
	set_bit(0, iwdev->allocated_arps);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Following for ILQ/IEQ */
 | 
					 | 
				
			||||||
	set_bit(1, iwdev->allocated_qps);
 | 
					 | 
				
			||||||
	set_bit(1, iwdev->allocated_cqs);
 | 
					 | 
				
			||||||
	set_bit(1, iwdev->allocated_pds);
 | 
					 | 
				
			||||||
	set_bit(2, iwdev->allocated_cqs);
 | 
					 | 
				
			||||||
	set_bit(2, iwdev->allocated_pds);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spin_lock_init(&iwdev->resource_lock);
 | 
					 | 
				
			||||||
	spin_lock_init(&iwdev->qptable_lock);
 | 
					 | 
				
			||||||
	/* stag index mask has a minimum of 14 bits */
 | 
					 | 
				
			||||||
	mrdrvbits = 24 - max(get_count_order(iwdev->max_mr), 14);
 | 
					 | 
				
			||||||
	iwdev->mr_stagmask = ~(((1 << mrdrvbits) - 1) << (32 - mrdrvbits));
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_cqp_ce_handler - handle cqp completions
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @arm: flag to arm after completions
 | 
					 | 
				
			||||||
 * @cq: cq for cqp completions
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void i40iw_cqp_ce_handler(struct i40iw_device *iwdev, struct i40iw_sc_cq *cq, bool arm)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_cqp_request *cqp_request;
 | 
					 | 
				
			||||||
	struct i40iw_sc_dev *dev = &iwdev->sc_dev;
 | 
					 | 
				
			||||||
	u32 cqe_count = 0;
 | 
					 | 
				
			||||||
	struct i40iw_ccq_cqe_info info;
 | 
					 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	do {
 | 
					 | 
				
			||||||
		memset(&info, 0, sizeof(info));
 | 
					 | 
				
			||||||
		ret = dev->ccq_ops->ccq_get_cqe_info(cq, &info);
 | 
					 | 
				
			||||||
		if (ret)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		cqp_request = (struct i40iw_cqp_request *)(unsigned long)info.scratch;
 | 
					 | 
				
			||||||
		if (info.error)
 | 
					 | 
				
			||||||
			i40iw_pr_err("opcode = 0x%x maj_err_code = 0x%x min_err_code = 0x%x\n",
 | 
					 | 
				
			||||||
				     info.op_code, info.maj_err_code, info.min_err_code);
 | 
					 | 
				
			||||||
		if (cqp_request) {
 | 
					 | 
				
			||||||
			cqp_request->compl_info.maj_err_code = info.maj_err_code;
 | 
					 | 
				
			||||||
			cqp_request->compl_info.min_err_code = info.min_err_code;
 | 
					 | 
				
			||||||
			cqp_request->compl_info.op_ret_val = info.op_ret_val;
 | 
					 | 
				
			||||||
			cqp_request->compl_info.error = info.error;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (cqp_request->waiting) {
 | 
					 | 
				
			||||||
				cqp_request->request_done = true;
 | 
					 | 
				
			||||||
				wake_up(&cqp_request->waitq);
 | 
					 | 
				
			||||||
				i40iw_put_cqp_request(&iwdev->cqp, cqp_request);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				if (cqp_request->callback_fcn)
 | 
					 | 
				
			||||||
					cqp_request->callback_fcn(cqp_request, 1);
 | 
					 | 
				
			||||||
				i40iw_put_cqp_request(&iwdev->cqp, cqp_request);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		cqe_count++;
 | 
					 | 
				
			||||||
	} while (1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (arm && cqe_count) {
 | 
					 | 
				
			||||||
		i40iw_process_bh(dev);
 | 
					 | 
				
			||||||
		dev->ccq_ops->ccq_arm(cq);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_iwarp_ce_handler - handle iwarp completions
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @iwcq: iwarp cq receiving event
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void i40iw_iwarp_ce_handler(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
				   struct i40iw_sc_cq *iwcq)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_cq *i40iwcq = iwcq->back_cq;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (i40iwcq->ibcq.comp_handler)
 | 
					 | 
				
			||||||
		i40iwcq->ibcq.comp_handler(&i40iwcq->ibcq,
 | 
					 | 
				
			||||||
					   i40iwcq->ibcq.cq_context);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_puda_ce_handler - handle puda completion events
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @cq: puda completion q for event
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void i40iw_puda_ce_handler(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
				  struct i40iw_sc_cq *cq)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_sc_dev *dev = (struct i40iw_sc_dev *)&iwdev->sc_dev;
 | 
					 | 
				
			||||||
	enum i40iw_status_code status;
 | 
					 | 
				
			||||||
	u32 compl_error;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	do {
 | 
					 | 
				
			||||||
		status = i40iw_puda_poll_completion(dev, cq, &compl_error);
 | 
					 | 
				
			||||||
		if (status == I40IW_ERR_QUEUE_EMPTY)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		if (status) {
 | 
					 | 
				
			||||||
			i40iw_pr_err("puda  status = %d\n", status);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (compl_error) {
 | 
					 | 
				
			||||||
			i40iw_pr_err("puda compl_err  =0x%x\n", compl_error);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} while (1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dev->ccq_ops->ccq_arm(cq);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_process_ceq - handle ceq for completions
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @ceq: ceq having cq for completion
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void i40iw_process_ceq(struct i40iw_device *iwdev, struct i40iw_ceq *ceq)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_sc_dev *dev = &iwdev->sc_dev;
 | 
					 | 
				
			||||||
	struct i40iw_sc_ceq *sc_ceq;
 | 
					 | 
				
			||||||
	struct i40iw_sc_cq *cq;
 | 
					 | 
				
			||||||
	bool arm = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sc_ceq = &ceq->sc_ceq;
 | 
					 | 
				
			||||||
	do {
 | 
					 | 
				
			||||||
		cq = dev->ceq_ops->process_ceq(dev, sc_ceq);
 | 
					 | 
				
			||||||
		if (!cq)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (cq->cq_type == I40IW_CQ_TYPE_CQP)
 | 
					 | 
				
			||||||
			i40iw_cqp_ce_handler(iwdev, cq, arm);
 | 
					 | 
				
			||||||
		else if (cq->cq_type == I40IW_CQ_TYPE_IWARP)
 | 
					 | 
				
			||||||
			i40iw_iwarp_ce_handler(iwdev, cq);
 | 
					 | 
				
			||||||
		else if ((cq->cq_type == I40IW_CQ_TYPE_ILQ) ||
 | 
					 | 
				
			||||||
			 (cq->cq_type == I40IW_CQ_TYPE_IEQ))
 | 
					 | 
				
			||||||
			i40iw_puda_ce_handler(iwdev, cq);
 | 
					 | 
				
			||||||
	} while (1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_next_iw_state - modify qp state
 | 
					 | 
				
			||||||
 * @iwqp: iwarp qp to modify
 | 
					 | 
				
			||||||
 * @state: next state for qp
 | 
					 | 
				
			||||||
 * @del_hash: del hash
 | 
					 | 
				
			||||||
 * @term: term message
 | 
					 | 
				
			||||||
 * @termlen: length of term message
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void i40iw_next_iw_state(struct i40iw_qp *iwqp,
 | 
					 | 
				
			||||||
			 u8 state,
 | 
					 | 
				
			||||||
			 u8 del_hash,
 | 
					 | 
				
			||||||
			 u8 term,
 | 
					 | 
				
			||||||
			 u8 termlen)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_modify_qp_info info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(&info, 0, sizeof(info));
 | 
					 | 
				
			||||||
	info.next_iwarp_state = state;
 | 
					 | 
				
			||||||
	info.remove_hash_idx = del_hash;
 | 
					 | 
				
			||||||
	info.cq_num_valid = true;
 | 
					 | 
				
			||||||
	info.arp_cache_idx_valid = true;
 | 
					 | 
				
			||||||
	info.dont_send_term = true;
 | 
					 | 
				
			||||||
	info.dont_send_fin = true;
 | 
					 | 
				
			||||||
	info.termlen = termlen;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (term & I40IWQP_TERM_SEND_TERM_ONLY)
 | 
					 | 
				
			||||||
		info.dont_send_term = false;
 | 
					 | 
				
			||||||
	if (term & I40IWQP_TERM_SEND_FIN_ONLY)
 | 
					 | 
				
			||||||
		info.dont_send_fin = false;
 | 
					 | 
				
			||||||
	if (iwqp->sc_qp.term_flags && (state == I40IW_QP_STATE_ERROR))
 | 
					 | 
				
			||||||
		info.reset_tcp_conn = true;
 | 
					 | 
				
			||||||
	iwqp->hw_iwarp_state = state;
 | 
					 | 
				
			||||||
	i40iw_hw_modify_qp(iwqp->iwdev, iwqp, &info, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_process_aeq - handle aeq events
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void i40iw_process_aeq(struct i40iw_device *iwdev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_sc_dev *dev = &iwdev->sc_dev;
 | 
					 | 
				
			||||||
	struct i40iw_aeq *aeq = &iwdev->aeq;
 | 
					 | 
				
			||||||
	struct i40iw_sc_aeq *sc_aeq = &aeq->sc_aeq;
 | 
					 | 
				
			||||||
	struct i40iw_aeqe_info aeinfo;
 | 
					 | 
				
			||||||
	struct i40iw_aeqe_info *info = &aeinfo;
 | 
					 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
	struct i40iw_qp *iwqp = NULL;
 | 
					 | 
				
			||||||
	struct i40iw_sc_cq *cq = NULL;
 | 
					 | 
				
			||||||
	struct i40iw_cq *iwcq = NULL;
 | 
					 | 
				
			||||||
	struct i40iw_sc_qp *qp = NULL;
 | 
					 | 
				
			||||||
	struct i40iw_qp_host_ctx_info *ctx_info = NULL;
 | 
					 | 
				
			||||||
	unsigned long flags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u32 aeqcnt = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!sc_aeq->size)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	do {
 | 
					 | 
				
			||||||
		memset(info, 0, sizeof(*info));
 | 
					 | 
				
			||||||
		ret = dev->aeq_ops->get_next_aeqe(sc_aeq, info);
 | 
					 | 
				
			||||||
		if (ret)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		aeqcnt++;
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_AEQ,
 | 
					 | 
				
			||||||
			    "%s ae_id = 0x%x bool qp=%d qp_id = %d\n",
 | 
					 | 
				
			||||||
			    __func__, info->ae_id, info->qp, info->qp_cq_id);
 | 
					 | 
				
			||||||
		if (info->qp) {
 | 
					 | 
				
			||||||
			spin_lock_irqsave(&iwdev->qptable_lock, flags);
 | 
					 | 
				
			||||||
			iwqp = iwdev->qp_table[info->qp_cq_id];
 | 
					 | 
				
			||||||
			if (!iwqp) {
 | 
					 | 
				
			||||||
				spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
 | 
					 | 
				
			||||||
				i40iw_debug(dev, I40IW_DEBUG_AEQ,
 | 
					 | 
				
			||||||
					    "%s qp_id %d is already freed\n",
 | 
					 | 
				
			||||||
					    __func__, info->qp_cq_id);
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			i40iw_qp_add_ref(&iwqp->ibqp);
 | 
					 | 
				
			||||||
			spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
 | 
					 | 
				
			||||||
			qp = &iwqp->sc_qp;
 | 
					 | 
				
			||||||
			spin_lock_irqsave(&iwqp->lock, flags);
 | 
					 | 
				
			||||||
			iwqp->hw_tcp_state = info->tcp_state;
 | 
					 | 
				
			||||||
			iwqp->hw_iwarp_state = info->iwarp_state;
 | 
					 | 
				
			||||||
			iwqp->last_aeq = info->ae_id;
 | 
					 | 
				
			||||||
			spin_unlock_irqrestore(&iwqp->lock, flags);
 | 
					 | 
				
			||||||
			ctx_info = &iwqp->ctx_info;
 | 
					 | 
				
			||||||
			ctx_info->err_rq_idx_valid = true;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			if (info->ae_id != I40IW_AE_CQ_OPERATION_ERROR)
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		switch (info->ae_id) {
 | 
					 | 
				
			||||||
		case I40IW_AE_LLP_FIN_RECEIVED:
 | 
					 | 
				
			||||||
			if (qp->term_flags)
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			if (atomic_inc_return(&iwqp->close_timer_started) == 1) {
 | 
					 | 
				
			||||||
				iwqp->hw_tcp_state = I40IW_TCP_STATE_CLOSE_WAIT;
 | 
					 | 
				
			||||||
				if ((iwqp->hw_tcp_state == I40IW_TCP_STATE_CLOSE_WAIT) &&
 | 
					 | 
				
			||||||
				    (iwqp->ibqp_state == IB_QPS_RTS)) {
 | 
					 | 
				
			||||||
					i40iw_next_iw_state(iwqp,
 | 
					 | 
				
			||||||
							    I40IW_QP_STATE_CLOSING, 0, 0, 0);
 | 
					 | 
				
			||||||
					i40iw_cm_disconn(iwqp);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				iwqp->cm_id->add_ref(iwqp->cm_id);
 | 
					 | 
				
			||||||
				i40iw_schedule_cm_timer(iwqp->cm_node,
 | 
					 | 
				
			||||||
							(struct i40iw_puda_buf *)iwqp,
 | 
					 | 
				
			||||||
							I40IW_TIMER_TYPE_CLOSE, 1, 0);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_AE_LLP_CLOSE_COMPLETE:
 | 
					 | 
				
			||||||
			if (qp->term_flags)
 | 
					 | 
				
			||||||
				i40iw_terminate_done(qp, 0);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				i40iw_cm_disconn(iwqp);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_AE_BAD_CLOSE:
 | 
					 | 
				
			||||||
		case I40IW_AE_RESET_SENT:
 | 
					 | 
				
			||||||
			i40iw_next_iw_state(iwqp, I40IW_QP_STATE_ERROR, 1, 0, 0);
 | 
					 | 
				
			||||||
			i40iw_cm_disconn(iwqp);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_AE_LLP_CONNECTION_RESET:
 | 
					 | 
				
			||||||
			if (atomic_read(&iwqp->close_timer_started))
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			i40iw_cm_disconn(iwqp);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_AE_QP_SUSPEND_COMPLETE:
 | 
					 | 
				
			||||||
			i40iw_qp_suspend_resume(dev, &iwqp->sc_qp, false);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_AE_TERMINATE_SENT:
 | 
					 | 
				
			||||||
			i40iw_terminate_send_fin(qp);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_AE_LLP_TERMINATE_RECEIVED:
 | 
					 | 
				
			||||||
			i40iw_terminate_received(qp, info);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_AE_CQ_OPERATION_ERROR:
 | 
					 | 
				
			||||||
			i40iw_pr_err("Processing an iWARP related AE for CQ misc = 0x%04X\n",
 | 
					 | 
				
			||||||
				     info->ae_id);
 | 
					 | 
				
			||||||
			cq = (struct i40iw_sc_cq *)(unsigned long)info->compl_ctx;
 | 
					 | 
				
			||||||
			iwcq = (struct i40iw_cq *)cq->back_cq;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (iwcq->ibcq.event_handler) {
 | 
					 | 
				
			||||||
				struct ib_event ibevent;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				ibevent.device = iwcq->ibcq.device;
 | 
					 | 
				
			||||||
				ibevent.event = IB_EVENT_CQ_ERR;
 | 
					 | 
				
			||||||
				ibevent.element.cq = &iwcq->ibcq;
 | 
					 | 
				
			||||||
				iwcq->ibcq.event_handler(&ibevent, iwcq->ibcq.cq_context);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_AE_LLP_DOUBT_REACHABILITY:
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_AE_PRIV_OPERATION_DENIED:
 | 
					 | 
				
			||||||
		case I40IW_AE_STAG_ZERO_INVALID:
 | 
					 | 
				
			||||||
		case I40IW_AE_IB_RREQ_AND_Q1_FULL:
 | 
					 | 
				
			||||||
		case I40IW_AE_DDP_UBE_INVALID_DDP_VERSION:
 | 
					 | 
				
			||||||
		case I40IW_AE_DDP_UBE_INVALID_MO:
 | 
					 | 
				
			||||||
		case I40IW_AE_DDP_UBE_INVALID_QN:
 | 
					 | 
				
			||||||
		case I40IW_AE_DDP_NO_L_BIT:
 | 
					 | 
				
			||||||
		case I40IW_AE_RDMAP_ROE_INVALID_RDMAP_VERSION:
 | 
					 | 
				
			||||||
		case I40IW_AE_RDMAP_ROE_UNEXPECTED_OPCODE:
 | 
					 | 
				
			||||||
		case I40IW_AE_ROE_INVALID_RDMA_READ_REQUEST:
 | 
					 | 
				
			||||||
		case I40IW_AE_ROE_INVALID_RDMA_WRITE_OR_READ_RESP:
 | 
					 | 
				
			||||||
		case I40IW_AE_INVALID_ARP_ENTRY:
 | 
					 | 
				
			||||||
		case I40IW_AE_INVALID_TCP_OPTION_RCVD:
 | 
					 | 
				
			||||||
		case I40IW_AE_STALE_ARP_ENTRY:
 | 
					 | 
				
			||||||
		case I40IW_AE_LLP_RECEIVED_MPA_CRC_ERROR:
 | 
					 | 
				
			||||||
		case I40IW_AE_LLP_SEGMENT_TOO_SMALL:
 | 
					 | 
				
			||||||
		case I40IW_AE_LLP_SYN_RECEIVED:
 | 
					 | 
				
			||||||
		case I40IW_AE_LLP_TOO_MANY_RETRIES:
 | 
					 | 
				
			||||||
		case I40IW_AE_LCE_QP_CATASTROPHIC:
 | 
					 | 
				
			||||||
		case I40IW_AE_LCE_FUNCTION_CATASTROPHIC:
 | 
					 | 
				
			||||||
		case I40IW_AE_LCE_CQ_CATASTROPHIC:
 | 
					 | 
				
			||||||
		case I40IW_AE_UDA_XMIT_DGRAM_TOO_LONG:
 | 
					 | 
				
			||||||
		case I40IW_AE_UDA_XMIT_DGRAM_TOO_SHORT:
 | 
					 | 
				
			||||||
			ctx_info->err_rq_idx_valid = false;
 | 
					 | 
				
			||||||
			fallthrough;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			if (!info->sq && ctx_info->err_rq_idx_valid) {
 | 
					 | 
				
			||||||
				ctx_info->err_rq_idx = info->wqe_idx;
 | 
					 | 
				
			||||||
				ctx_info->tcp_info_valid = false;
 | 
					 | 
				
			||||||
				ctx_info->iwarp_info_valid = false;
 | 
					 | 
				
			||||||
				ret = dev->iw_priv_qp_ops->qp_setctx(&iwqp->sc_qp,
 | 
					 | 
				
			||||||
								     iwqp->host_ctx.va,
 | 
					 | 
				
			||||||
								     ctx_info);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			i40iw_terminate_connection(qp, info);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (info->qp)
 | 
					 | 
				
			||||||
			i40iw_qp_rem_ref(&iwqp->ibqp);
 | 
					 | 
				
			||||||
	} while (1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (aeqcnt)
 | 
					 | 
				
			||||||
		dev->aeq_ops->repost_aeq_entries(dev, aeqcnt);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_cqp_manage_abvpt_cmd - send cqp command manage abpvt
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @accel_local_port: port for apbvt
 | 
					 | 
				
			||||||
 * @add_port: add or delete port
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code
 | 
					 | 
				
			||||||
i40iw_cqp_manage_abvpt_cmd(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
			   u16 accel_local_port,
 | 
					 | 
				
			||||||
			   bool add_port)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_apbvt_info *info;
 | 
					 | 
				
			||||||
	struct i40iw_cqp_request *cqp_request;
 | 
					 | 
				
			||||||
	struct cqp_commands_info *cqp_info;
 | 
					 | 
				
			||||||
	enum i40iw_status_code status;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_request = i40iw_get_cqp_request(&iwdev->cqp, add_port);
 | 
					 | 
				
			||||||
	if (!cqp_request)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_info = &cqp_request->info;
 | 
					 | 
				
			||||||
	info = &cqp_info->in.u.manage_apbvt_entry.info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(info, 0, sizeof(*info));
 | 
					 | 
				
			||||||
	info->add = add_port;
 | 
					 | 
				
			||||||
	info->port = cpu_to_le16(accel_local_port);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_info->cqp_cmd = OP_MANAGE_APBVT_ENTRY;
 | 
					 | 
				
			||||||
	cqp_info->post_sq = 1;
 | 
					 | 
				
			||||||
	cqp_info->in.u.manage_apbvt_entry.cqp = &iwdev->cqp.sc_cqp;
 | 
					 | 
				
			||||||
	cqp_info->in.u.manage_apbvt_entry.scratch = (uintptr_t)cqp_request;
 | 
					 | 
				
			||||||
	status = i40iw_handle_cqp_op(iwdev, cqp_request);
 | 
					 | 
				
			||||||
	if (status)
 | 
					 | 
				
			||||||
		i40iw_pr_err("CQP-OP Manage APBVT entry fail");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return status;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_manage_apbvt - add or delete tcp port
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @accel_local_port: port for apbvt
 | 
					 | 
				
			||||||
 * @add_port: add or delete port
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_manage_apbvt(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
					  u16 accel_local_port,
 | 
					 | 
				
			||||||
					  bool add_port)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_cm_core *cm_core = &iwdev->cm_core;
 | 
					 | 
				
			||||||
	enum i40iw_status_code status;
 | 
					 | 
				
			||||||
	unsigned long flags;
 | 
					 | 
				
			||||||
	bool in_use;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* apbvt_lock is held across CQP delete APBVT OP (non-waiting) to
 | 
					 | 
				
			||||||
	 * protect against race where add APBVT CQP can race ahead of the delete
 | 
					 | 
				
			||||||
	 * APBVT for same port.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (add_port) {
 | 
					 | 
				
			||||||
		spin_lock_irqsave(&cm_core->apbvt_lock, flags);
 | 
					 | 
				
			||||||
		in_use = __test_and_set_bit(accel_local_port,
 | 
					 | 
				
			||||||
					    cm_core->ports_in_use);
 | 
					 | 
				
			||||||
		spin_unlock_irqrestore(&cm_core->apbvt_lock, flags);
 | 
					 | 
				
			||||||
		if (in_use)
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
		return i40iw_cqp_manage_abvpt_cmd(iwdev, accel_local_port,
 | 
					 | 
				
			||||||
						  true);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		spin_lock_irqsave(&cm_core->apbvt_lock, flags);
 | 
					 | 
				
			||||||
		in_use = i40iw_port_in_use(cm_core, accel_local_port);
 | 
					 | 
				
			||||||
		if (in_use) {
 | 
					 | 
				
			||||||
			spin_unlock_irqrestore(&cm_core->apbvt_lock, flags);
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		__clear_bit(accel_local_port, cm_core->ports_in_use);
 | 
					 | 
				
			||||||
		status = i40iw_cqp_manage_abvpt_cmd(iwdev, accel_local_port,
 | 
					 | 
				
			||||||
						    false);
 | 
					 | 
				
			||||||
		spin_unlock_irqrestore(&cm_core->apbvt_lock, flags);
 | 
					 | 
				
			||||||
		return status;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_manage_arp_cache - manage hw arp cache
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @mac_addr: mac address ptr
 | 
					 | 
				
			||||||
 * @ip_addr: ip addr for arp cache
 | 
					 | 
				
			||||||
 * @ipv4: flag indicating IPv4 when true
 | 
					 | 
				
			||||||
 * @action: add, delete or modify
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void i40iw_manage_arp_cache(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
			    unsigned char *mac_addr,
 | 
					 | 
				
			||||||
			    u32 *ip_addr,
 | 
					 | 
				
			||||||
			    bool ipv4,
 | 
					 | 
				
			||||||
			    u32 action)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_add_arp_cache_entry_info *info;
 | 
					 | 
				
			||||||
	struct i40iw_cqp_request *cqp_request;
 | 
					 | 
				
			||||||
	struct cqp_commands_info *cqp_info;
 | 
					 | 
				
			||||||
	int arp_index;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	arp_index = i40iw_arp_table(iwdev, ip_addr, ipv4, mac_addr, action);
 | 
					 | 
				
			||||||
	if (arp_index < 0)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	cqp_request = i40iw_get_cqp_request(&iwdev->cqp, false);
 | 
					 | 
				
			||||||
	if (!cqp_request)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_info = &cqp_request->info;
 | 
					 | 
				
			||||||
	if (action == I40IW_ARP_ADD) {
 | 
					 | 
				
			||||||
		cqp_info->cqp_cmd = OP_ADD_ARP_CACHE_ENTRY;
 | 
					 | 
				
			||||||
		info = &cqp_info->in.u.add_arp_cache_entry.info;
 | 
					 | 
				
			||||||
		memset(info, 0, sizeof(*info));
 | 
					 | 
				
			||||||
		info->arp_index = cpu_to_le16((u16)arp_index);
 | 
					 | 
				
			||||||
		info->permanent = true;
 | 
					 | 
				
			||||||
		ether_addr_copy(info->mac_addr, mac_addr);
 | 
					 | 
				
			||||||
		cqp_info->in.u.add_arp_cache_entry.scratch = (uintptr_t)cqp_request;
 | 
					 | 
				
			||||||
		cqp_info->in.u.add_arp_cache_entry.cqp = &iwdev->cqp.sc_cqp;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		cqp_info->cqp_cmd = OP_DELETE_ARP_CACHE_ENTRY;
 | 
					 | 
				
			||||||
		cqp_info->in.u.del_arp_cache_entry.scratch = (uintptr_t)cqp_request;
 | 
					 | 
				
			||||||
		cqp_info->in.u.del_arp_cache_entry.cqp = &iwdev->cqp.sc_cqp;
 | 
					 | 
				
			||||||
		cqp_info->in.u.del_arp_cache_entry.arp_index = arp_index;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_info->in.u.add_arp_cache_entry.cqp = &iwdev->cqp.sc_cqp;
 | 
					 | 
				
			||||||
	cqp_info->in.u.add_arp_cache_entry.scratch = (uintptr_t)cqp_request;
 | 
					 | 
				
			||||||
	cqp_info->post_sq = 1;
 | 
					 | 
				
			||||||
	if (i40iw_handle_cqp_op(iwdev, cqp_request))
 | 
					 | 
				
			||||||
		i40iw_pr_err("CQP-OP Add/Del Arp Cache entry fail");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_send_syn_cqp_callback - do syn/ack after qhash
 | 
					 | 
				
			||||||
 * @cqp_request: qhash cqp completion
 | 
					 | 
				
			||||||
 * @send_ack: flag send ack
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void i40iw_send_syn_cqp_callback(struct i40iw_cqp_request *cqp_request, u32 send_ack)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	i40iw_send_syn(cqp_request->param, send_ack);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_manage_qhash - add or modify qhash
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @cminfo: cm info for qhash
 | 
					 | 
				
			||||||
 * @etype: type (syn or quad)
 | 
					 | 
				
			||||||
 * @mtype: type of qhash
 | 
					 | 
				
			||||||
 * @cmnode: cmnode associated with connection
 | 
					 | 
				
			||||||
 * @wait: wait for completion
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_manage_qhash(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
					  struct i40iw_cm_info *cminfo,
 | 
					 | 
				
			||||||
					  enum i40iw_quad_entry_type etype,
 | 
					 | 
				
			||||||
					  enum i40iw_quad_hash_manage_type mtype,
 | 
					 | 
				
			||||||
					  void *cmnode,
 | 
					 | 
				
			||||||
					  bool wait)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_qhash_table_info *info;
 | 
					 | 
				
			||||||
	struct i40iw_sc_dev *dev = &iwdev->sc_dev;
 | 
					 | 
				
			||||||
	struct i40iw_sc_vsi *vsi = &iwdev->vsi;
 | 
					 | 
				
			||||||
	enum i40iw_status_code status;
 | 
					 | 
				
			||||||
	struct i40iw_cqp *iwcqp = &iwdev->cqp;
 | 
					 | 
				
			||||||
	struct i40iw_cqp_request *cqp_request;
 | 
					 | 
				
			||||||
	struct cqp_commands_info *cqp_info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_request = i40iw_get_cqp_request(iwcqp, wait);
 | 
					 | 
				
			||||||
	if (!cqp_request)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
	cqp_info = &cqp_request->info;
 | 
					 | 
				
			||||||
	info = &cqp_info->in.u.manage_qhash_table_entry.info;
 | 
					 | 
				
			||||||
	memset(info, 0, sizeof(*info));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	info->vsi = &iwdev->vsi;
 | 
					 | 
				
			||||||
	info->manage = mtype;
 | 
					 | 
				
			||||||
	info->entry_type = etype;
 | 
					 | 
				
			||||||
	if (cminfo->vlan_id != 0xFFFF) {
 | 
					 | 
				
			||||||
		info->vlan_valid = true;
 | 
					 | 
				
			||||||
		info->vlan_id = cpu_to_le16(cminfo->vlan_id);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		info->vlan_valid = false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	info->ipv4_valid = cminfo->ipv4;
 | 
					 | 
				
			||||||
	info->user_pri = cminfo->user_pri;
 | 
					 | 
				
			||||||
	ether_addr_copy(info->mac_addr, iwdev->netdev->dev_addr);
 | 
					 | 
				
			||||||
	info->qp_num = cpu_to_le32(vsi->ilq->qp_id);
 | 
					 | 
				
			||||||
	info->dest_port = cpu_to_le16(cminfo->loc_port);
 | 
					 | 
				
			||||||
	info->dest_ip[0] = cpu_to_le32(cminfo->loc_addr[0]);
 | 
					 | 
				
			||||||
	info->dest_ip[1] = cpu_to_le32(cminfo->loc_addr[1]);
 | 
					 | 
				
			||||||
	info->dest_ip[2] = cpu_to_le32(cminfo->loc_addr[2]);
 | 
					 | 
				
			||||||
	info->dest_ip[3] = cpu_to_le32(cminfo->loc_addr[3]);
 | 
					 | 
				
			||||||
	if (etype == I40IW_QHASH_TYPE_TCP_ESTABLISHED) {
 | 
					 | 
				
			||||||
		info->src_port = cpu_to_le16(cminfo->rem_port);
 | 
					 | 
				
			||||||
		info->src_ip[0] = cpu_to_le32(cminfo->rem_addr[0]);
 | 
					 | 
				
			||||||
		info->src_ip[1] = cpu_to_le32(cminfo->rem_addr[1]);
 | 
					 | 
				
			||||||
		info->src_ip[2] = cpu_to_le32(cminfo->rem_addr[2]);
 | 
					 | 
				
			||||||
		info->src_ip[3] = cpu_to_le32(cminfo->rem_addr[3]);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (cmnode) {
 | 
					 | 
				
			||||||
		cqp_request->callback_fcn = i40iw_send_syn_cqp_callback;
 | 
					 | 
				
			||||||
		cqp_request->param = (void *)cmnode;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (info->ipv4_valid)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_CM,
 | 
					 | 
				
			||||||
			    "%s:%s IP=%pI4, port=%d, mac=%pM, vlan_id=%d\n",
 | 
					 | 
				
			||||||
			    __func__, (!mtype) ? "DELETE" : "ADD",
 | 
					 | 
				
			||||||
			    info->dest_ip,
 | 
					 | 
				
			||||||
			    info->dest_port, info->mac_addr, cminfo->vlan_id);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_CM,
 | 
					 | 
				
			||||||
			    "%s:%s IP=%pI6, port=%d, mac=%pM, vlan_id=%d\n",
 | 
					 | 
				
			||||||
			    __func__, (!mtype) ? "DELETE" : "ADD",
 | 
					 | 
				
			||||||
			    info->dest_ip,
 | 
					 | 
				
			||||||
			    info->dest_port, info->mac_addr, cminfo->vlan_id);
 | 
					 | 
				
			||||||
	cqp_info->in.u.manage_qhash_table_entry.cqp = &iwdev->cqp.sc_cqp;
 | 
					 | 
				
			||||||
	cqp_info->in.u.manage_qhash_table_entry.scratch = (uintptr_t)cqp_request;
 | 
					 | 
				
			||||||
	cqp_info->cqp_cmd = OP_MANAGE_QHASH_TABLE_ENTRY;
 | 
					 | 
				
			||||||
	cqp_info->post_sq = 1;
 | 
					 | 
				
			||||||
	status = i40iw_handle_cqp_op(iwdev, cqp_request);
 | 
					 | 
				
			||||||
	if (status)
 | 
					 | 
				
			||||||
		i40iw_pr_err("CQP-OP Manage Qhash Entry fail");
 | 
					 | 
				
			||||||
	return status;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_hw_flush_wqes - flush qp's wqe
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @qp: hardware control qp
 | 
					 | 
				
			||||||
 * @info: info for flush
 | 
					 | 
				
			||||||
 * @wait: flag wait for completion
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_hw_flush_wqes(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
					   struct i40iw_sc_qp *qp,
 | 
					 | 
				
			||||||
					   struct i40iw_qp_flush_info *info,
 | 
					 | 
				
			||||||
					   bool wait)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code status;
 | 
					 | 
				
			||||||
	struct i40iw_qp_flush_info *hw_info;
 | 
					 | 
				
			||||||
	struct i40iw_cqp_request *cqp_request;
 | 
					 | 
				
			||||||
	struct cqp_commands_info *cqp_info;
 | 
					 | 
				
			||||||
	struct i40iw_qp *iwqp = (struct i40iw_qp *)qp->back_qp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_request = i40iw_get_cqp_request(&iwdev->cqp, wait);
 | 
					 | 
				
			||||||
	if (!cqp_request)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_info = &cqp_request->info;
 | 
					 | 
				
			||||||
	hw_info = &cqp_request->info.in.u.qp_flush_wqes.info;
 | 
					 | 
				
			||||||
	memcpy(hw_info, info, sizeof(*hw_info));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_info->cqp_cmd = OP_QP_FLUSH_WQES;
 | 
					 | 
				
			||||||
	cqp_info->post_sq = 1;
 | 
					 | 
				
			||||||
	cqp_info->in.u.qp_flush_wqes.qp = qp;
 | 
					 | 
				
			||||||
	cqp_info->in.u.qp_flush_wqes.scratch = (uintptr_t)cqp_request;
 | 
					 | 
				
			||||||
	status = i40iw_handle_cqp_op(iwdev, cqp_request);
 | 
					 | 
				
			||||||
	if (status) {
 | 
					 | 
				
			||||||
		i40iw_pr_err("CQP-OP Flush WQE's fail");
 | 
					 | 
				
			||||||
		complete(&iwqp->sq_drained);
 | 
					 | 
				
			||||||
		complete(&iwqp->rq_drained);
 | 
					 | 
				
			||||||
		return status;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!cqp_request->compl_info.maj_err_code) {
 | 
					 | 
				
			||||||
		switch (cqp_request->compl_info.min_err_code) {
 | 
					 | 
				
			||||||
		case I40IW_CQP_COMPL_RQ_WQE_FLUSHED:
 | 
					 | 
				
			||||||
			complete(&iwqp->sq_drained);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_CQP_COMPL_SQ_WQE_FLUSHED:
 | 
					 | 
				
			||||||
			complete(&iwqp->rq_drained);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case I40IW_CQP_COMPL_RQ_SQ_WQE_FLUSHED:
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			complete(&iwqp->sq_drained);
 | 
					 | 
				
			||||||
			complete(&iwqp->rq_drained);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_gen_ae - generate AE
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @qp: qp associated with AE
 | 
					 | 
				
			||||||
 * @info: info for ae
 | 
					 | 
				
			||||||
 * @wait: wait for completion
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void i40iw_gen_ae(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
		  struct i40iw_sc_qp *qp,
 | 
					 | 
				
			||||||
		  struct i40iw_gen_ae_info *info,
 | 
					 | 
				
			||||||
		  bool wait)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_gen_ae_info *ae_info;
 | 
					 | 
				
			||||||
	struct i40iw_cqp_request *cqp_request;
 | 
					 | 
				
			||||||
	struct cqp_commands_info *cqp_info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_request = i40iw_get_cqp_request(&iwdev->cqp, wait);
 | 
					 | 
				
			||||||
	if (!cqp_request)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_info = &cqp_request->info;
 | 
					 | 
				
			||||||
	ae_info = &cqp_request->info.in.u.gen_ae.info;
 | 
					 | 
				
			||||||
	memcpy(ae_info, info, sizeof(*ae_info));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_info->cqp_cmd = OP_GEN_AE;
 | 
					 | 
				
			||||||
	cqp_info->post_sq = 1;
 | 
					 | 
				
			||||||
	cqp_info->in.u.gen_ae.qp = qp;
 | 
					 | 
				
			||||||
	cqp_info->in.u.gen_ae.scratch = (uintptr_t)cqp_request;
 | 
					 | 
				
			||||||
	if (i40iw_handle_cqp_op(iwdev, cqp_request))
 | 
					 | 
				
			||||||
		i40iw_pr_err("CQP OP failed attempting to generate ae_code=0x%x\n",
 | 
					 | 
				
			||||||
			     info->ae_code);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_hw_manage_vf_pble_bp - manage vf pbles
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @info: info for managing pble
 | 
					 | 
				
			||||||
 * @wait: flag wait for completion
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_hw_manage_vf_pble_bp(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
						  struct i40iw_manage_vf_pble_info *info,
 | 
					 | 
				
			||||||
						  bool wait)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code status;
 | 
					 | 
				
			||||||
	struct i40iw_manage_vf_pble_info *hw_info;
 | 
					 | 
				
			||||||
	struct i40iw_cqp_request *cqp_request;
 | 
					 | 
				
			||||||
	struct cqp_commands_info *cqp_info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((iwdev->init_state < CCQ_CREATED) && wait)
 | 
					 | 
				
			||||||
		wait = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_request = i40iw_get_cqp_request(&iwdev->cqp, wait);
 | 
					 | 
				
			||||||
	if (!cqp_request)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_info = &cqp_request->info;
 | 
					 | 
				
			||||||
	hw_info = &cqp_request->info.in.u.manage_vf_pble_bp.info;
 | 
					 | 
				
			||||||
	memcpy(hw_info, info, sizeof(*hw_info));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cqp_info->cqp_cmd = OP_MANAGE_VF_PBLE_BP;
 | 
					 | 
				
			||||||
	cqp_info->post_sq = 1;
 | 
					 | 
				
			||||||
	cqp_info->in.u.manage_vf_pble_bp.cqp = &iwdev->cqp.sc_cqp;
 | 
					 | 
				
			||||||
	cqp_info->in.u.manage_vf_pble_bp.scratch = (uintptr_t)cqp_request;
 | 
					 | 
				
			||||||
	status = i40iw_handle_cqp_op(iwdev, cqp_request);
 | 
					 | 
				
			||||||
	if (status)
 | 
					 | 
				
			||||||
		i40iw_pr_err("CQP-OP Manage VF pble_bp fail");
 | 
					 | 
				
			||||||
	return status;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_get_ib_wc - return change flush code to IB's
 | 
					 | 
				
			||||||
 * @opcode: iwarp flush code
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum ib_wc_status i40iw_get_ib_wc(enum i40iw_flush_opcode opcode)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	switch (opcode) {
 | 
					 | 
				
			||||||
	case FLUSH_PROT_ERR:
 | 
					 | 
				
			||||||
		return IB_WC_LOC_PROT_ERR;
 | 
					 | 
				
			||||||
	case FLUSH_REM_ACCESS_ERR:
 | 
					 | 
				
			||||||
		return IB_WC_REM_ACCESS_ERR;
 | 
					 | 
				
			||||||
	case FLUSH_LOC_QP_OP_ERR:
 | 
					 | 
				
			||||||
		return IB_WC_LOC_QP_OP_ERR;
 | 
					 | 
				
			||||||
	case FLUSH_REM_OP_ERR:
 | 
					 | 
				
			||||||
		return IB_WC_REM_OP_ERR;
 | 
					 | 
				
			||||||
	case FLUSH_LOC_LEN_ERR:
 | 
					 | 
				
			||||||
		return IB_WC_LOC_LEN_ERR;
 | 
					 | 
				
			||||||
	case FLUSH_GENERAL_ERR:
 | 
					 | 
				
			||||||
		return IB_WC_GENERAL_ERR;
 | 
					 | 
				
			||||||
	case FLUSH_FATAL_ERR:
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return IB_WC_FATAL_ERR;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_set_flush_info - set flush info
 | 
					 | 
				
			||||||
 * @pinfo: set flush info
 | 
					 | 
				
			||||||
 * @min: minor err
 | 
					 | 
				
			||||||
 * @maj: major err
 | 
					 | 
				
			||||||
 * @opcode: flush error code
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void i40iw_set_flush_info(struct i40iw_qp_flush_info *pinfo,
 | 
					 | 
				
			||||||
				 u16 *min,
 | 
					 | 
				
			||||||
				 u16 *maj,
 | 
					 | 
				
			||||||
				 enum i40iw_flush_opcode opcode)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	*min = (u16)i40iw_get_ib_wc(opcode);
 | 
					 | 
				
			||||||
	*maj = CQE_MAJOR_DRV;
 | 
					 | 
				
			||||||
	pinfo->userflushcode = true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_flush_wqes - flush wqe for qp
 | 
					 | 
				
			||||||
 * @iwdev: iwarp device
 | 
					 | 
				
			||||||
 * @iwqp: qp to flush wqes
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void i40iw_flush_wqes(struct i40iw_device *iwdev, struct i40iw_qp *iwqp)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_qp_flush_info info;
 | 
					 | 
				
			||||||
	struct i40iw_qp_flush_info *pinfo = &info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct i40iw_sc_qp *qp = &iwqp->sc_qp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(pinfo, 0, sizeof(*pinfo));
 | 
					 | 
				
			||||||
	info.sq = true;
 | 
					 | 
				
			||||||
	info.rq = true;
 | 
					 | 
				
			||||||
	if (qp->term_flags) {
 | 
					 | 
				
			||||||
		i40iw_set_flush_info(pinfo, &pinfo->sq_minor_code,
 | 
					 | 
				
			||||||
				     &pinfo->sq_major_code, qp->flush_code);
 | 
					 | 
				
			||||||
		i40iw_set_flush_info(pinfo, &pinfo->rq_minor_code,
 | 
					 | 
				
			||||||
				     &pinfo->rq_major_code, qp->flush_code);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	(void)i40iw_hw_flush_wqes(iwdev, &iwqp->sc_qp, &info, true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,195 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_OSDEP_H
 | 
					 | 
				
			||||||
#define I40IW_OSDEP_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <linux/kernel.h>
 | 
					 | 
				
			||||||
#include <linux/string.h>
 | 
					 | 
				
			||||||
#include <linux/bitops.h>
 | 
					 | 
				
			||||||
#include <net/tcp.h>
 | 
					 | 
				
			||||||
#include <crypto/hash.h>
 | 
					 | 
				
			||||||
/* get readq/writeq support for 32 bit kernels, use the low-first version */
 | 
					 | 
				
			||||||
#include <linux/io-64-nonatomic-lo-hi.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define STATS_TIMER_DELAY 1000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void set_64bit_val(u64 *wqe_words, u32 byte_index, u64 value)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	wqe_words[byte_index >> 3] = value;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * get_64bit_val - read 64 bit value from wqe
 | 
					 | 
				
			||||||
 * @wqe_words: wqe addr
 | 
					 | 
				
			||||||
 * @byte_index: index to read from
 | 
					 | 
				
			||||||
 * @value: read value
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static inline void get_64bit_val(u64 *wqe_words, u32 byte_index, u64 *value)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	*value = wqe_words[byte_index >> 3];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_dma_mem {
 | 
					 | 
				
			||||||
	void *va;
 | 
					 | 
				
			||||||
	dma_addr_t pa;
 | 
					 | 
				
			||||||
	u32 size;
 | 
					 | 
				
			||||||
} __packed;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_virt_mem {
 | 
					 | 
				
			||||||
	void *va;
 | 
					 | 
				
			||||||
	u32 size;
 | 
					 | 
				
			||||||
} __packed;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define i40iw_debug(h, m, s, ...)                               \
 | 
					 | 
				
			||||||
do {                                                            \
 | 
					 | 
				
			||||||
	if (((m) & (h)->debug_mask))                            \
 | 
					 | 
				
			||||||
		pr_info("i40iw " s, ##__VA_ARGS__);             \
 | 
					 | 
				
			||||||
} while (0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define i40iw_flush(a)          readl((a)->hw_addr + I40E_GLGEN_STAT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD(_i)  (0x000C8000 + ((_i) * 4)) \
 | 
					 | 
				
			||||||
				/* _i=0...31 */
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_MAX_INDEX    31
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_PMSDIDX_SHIFT  0
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_PMSDIDX_MASK  (0xFFF \
 | 
					 | 
				
			||||||
					  << I40E_GLHMC_VFSDCMD_PMSDIDX_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_PF_SHIFT       16
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_PF_MASK        (0xF << I40E_GLHMC_VFSDCMD_PF_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_VF_SHIFT       20
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_VF_MASK        (0x1FF << I40E_GLHMC_VFSDCMD_VF_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_PMF_TYPE_SHIFT 29
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_PMF_TYPE_MASK  (0x3 \
 | 
					 | 
				
			||||||
					   << I40E_GLHMC_VFSDCMD_PMF_TYPE_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_PMSDWR_SHIFT   31
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDCMD_PMSDWR_MASK  (0x1 << I40E_GLHMC_VFSDCMD_PMSDWR_SHIFT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATAHIGH(_i)     (0x000C8200 + ((_i) * 4)) \
 | 
					 | 
				
			||||||
				/* _i=0...31 */
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATAHIGH_MAX_INDEX       31
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATAHIGH_PMSDDATAHIGH_SHIFT 0
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATAHIGH_PMSDDATAHIGH_MASK  (0xFFFFFFFF \
 | 
					 | 
				
			||||||
			<< I40E_GLHMC_VFSDDATAHIGH_PMSDDATAHIGH_SHIFT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATALOW(_i)      (0x000C8100 + ((_i) * 4)) \
 | 
					 | 
				
			||||||
				/* _i=0...31 */
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATALOW_MAX_INDEX        31
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATALOW_PMSDVALID_SHIFT   0
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATALOW_PMSDVALID_MASK  (0x1 \
 | 
					 | 
				
			||||||
			<< I40E_GLHMC_VFSDDATALOW_PMSDVALID_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATALOW_PMSDTYPE_SHIFT    1
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATALOW_PMSDTYPE_MASK  (0x1 \
 | 
					 | 
				
			||||||
			<< I40E_GLHMC_VFSDDATALOW_PMSDTYPE_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATALOW_PMSDBPCOUNT_SHIFT 2
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATALOW_PMSDBPCOUNT_MASK  (0x3FF \
 | 
					 | 
				
			||||||
			<< I40E_GLHMC_VFSDDATALOW_PMSDBPCOUNT_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATALOW_PMSDDATALOW_SHIFT 12
 | 
					 | 
				
			||||||
#define I40E_GLHMC_VFSDDATALOW_PMSDDATALOW_MASK  (0xFFFFF \
 | 
					 | 
				
			||||||
			<< I40E_GLHMC_VFSDDATALOW_PMSDDATALOW_SHIFT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS                     0x0000D200
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS_LOAD_REQUESTED_SHIFT 0
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS_LOAD_REQUESTED_MASK  (0x1 \
 | 
					 | 
				
			||||||
			<< I40E_GLPE_FWLDSTATUS_LOAD_REQUESTED_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS_DONE_SHIFT           1
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS_DONE_MASK  (0x1 << I40E_GLPE_FWLDSTATUS_DONE_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS_CQP_FAIL_SHIFT       2
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS_CQP_FAIL_MASK  (0x1 \
 | 
					 | 
				
			||||||
			 << I40E_GLPE_FWLDSTATUS_CQP_FAIL_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS_TEP_FAIL_SHIFT       3
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS_TEP_FAIL_MASK  (0x1 \
 | 
					 | 
				
			||||||
			 << I40E_GLPE_FWLDSTATUS_TEP_FAIL_SHIFT)
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS_OOP_FAIL_SHIFT       4
 | 
					 | 
				
			||||||
#define I40E_GLPE_FWLDSTATUS_OOP_FAIL_MASK  (0x1 \
 | 
					 | 
				
			||||||
			 << I40E_GLPE_FWLDSTATUS_OOP_FAIL_SHIFT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_sc_dev;
 | 
					 | 
				
			||||||
struct i40iw_sc_qp;
 | 
					 | 
				
			||||||
struct i40iw_puda_buf;
 | 
					 | 
				
			||||||
struct i40iw_puda_completion_info;
 | 
					 | 
				
			||||||
struct i40iw_update_sds_info;
 | 
					 | 
				
			||||||
struct i40iw_hmc_fcn_info;
 | 
					 | 
				
			||||||
struct i40iw_virtchnl_work_info;
 | 
					 | 
				
			||||||
struct i40iw_manage_vf_pble_info;
 | 
					 | 
				
			||||||
struct i40iw_device;
 | 
					 | 
				
			||||||
struct i40iw_hmc_info;
 | 
					 | 
				
			||||||
struct i40iw_hw;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
u8 __iomem *i40iw_get_hw_addr(void *dev);
 | 
					 | 
				
			||||||
void i40iw_ieq_mpa_crc_ae(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vf_wait_vchnl_resp(struct i40iw_sc_dev *dev);
 | 
					 | 
				
			||||||
bool i40iw_vf_clear_to_send(struct i40iw_sc_dev *dev);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_ieq_check_mpacrc(struct shash_desc *desc, void *addr,
 | 
					 | 
				
			||||||
					      u32 length, u32 value);
 | 
					 | 
				
			||||||
struct i40iw_sc_qp *i40iw_ieq_get_qp(struct i40iw_sc_dev *dev, struct i40iw_puda_buf *buf);
 | 
					 | 
				
			||||||
void i40iw_ieq_update_tcpip_info(struct i40iw_puda_buf *buf, u16 length, u32 seqnum);
 | 
					 | 
				
			||||||
void i40iw_free_hash_desc(struct shash_desc *);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_init_hash_desc(struct shash_desc **);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_puda_get_tcpip_info(struct i40iw_puda_completion_info *info,
 | 
					 | 
				
			||||||
						 struct i40iw_puda_buf *buf);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_cqp_sds_cmd(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					 struct i40iw_update_sds_info *info);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_cqp_manage_hmc_fcn_cmd(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						    struct i40iw_hmc_fcn_info *hmcfcninfo);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_cqp_query_fpm_values_cmd(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						      struct i40iw_dma_mem *values_mem,
 | 
					 | 
				
			||||||
						      u8 hmc_fn_id);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_cqp_commit_fpm_values_cmd(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						       struct i40iw_dma_mem *values_mem,
 | 
					 | 
				
			||||||
						       u8 hmc_fn_id);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_alloc_query_fpm_buf(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						 struct i40iw_dma_mem *mem);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_cqp_manage_vf_pble_bp(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						   struct i40iw_manage_vf_pble_info *info);
 | 
					 | 
				
			||||||
void i40iw_cqp_spawn_worker(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
			    struct i40iw_virtchnl_work_info *work_info, u32 iw_vf_idx);
 | 
					 | 
				
			||||||
void *i40iw_remove_head(struct list_head *list);
 | 
					 | 
				
			||||||
void i40iw_qp_suspend_resume(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp, bool suspend);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_term_modify_qp(struct i40iw_sc_qp *qp, u8 next_state, u8 term, u8 term_len);
 | 
					 | 
				
			||||||
void i40iw_terminate_done(struct i40iw_sc_qp *qp, int timeout_occurred);
 | 
					 | 
				
			||||||
void i40iw_terminate_start_timer(struct i40iw_sc_qp *qp);
 | 
					 | 
				
			||||||
void i40iw_terminate_del_timer(struct i40iw_sc_qp *qp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_hw_manage_vf_pble_bp(struct i40iw_device *iwdev,
 | 
					 | 
				
			||||||
						  struct i40iw_manage_vf_pble_info *info,
 | 
					 | 
				
			||||||
						  bool wait);
 | 
					 | 
				
			||||||
struct i40iw_sc_vsi;
 | 
					 | 
				
			||||||
void i40iw_hw_stats_start_timer(struct i40iw_sc_vsi *vsi);
 | 
					 | 
				
			||||||
void i40iw_hw_stats_stop_timer(struct i40iw_sc_vsi *vsi);
 | 
					 | 
				
			||||||
#define i40iw_mmiowb() do { } while (0)
 | 
					 | 
				
			||||||
void i40iw_wr32(struct i40iw_hw *hw, u32 reg, u32 value);
 | 
					 | 
				
			||||||
u32  i40iw_rd32(struct i40iw_hw *hw, u32 reg);
 | 
					 | 
				
			||||||
#endif				/* _I40IW_OSDEP_H_ */
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,129 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_P_H
 | 
					 | 
				
			||||||
#define I40IW_P_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PAUSE_TIMER_VALUE       0xFFFF
 | 
					 | 
				
			||||||
#define REFRESH_THRESHOLD       0x7FFF
 | 
					 | 
				
			||||||
#define HIGH_THRESHOLD          0x800
 | 
					 | 
				
			||||||
#define LOW_THRESHOLD           0x200
 | 
					 | 
				
			||||||
#define ALL_TC2PFC              0xFF
 | 
					 | 
				
			||||||
#define CQP_COMPL_WAIT_TIME     0x3E8
 | 
					 | 
				
			||||||
#define CQP_TIMEOUT_THRESHOLD   5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_debug_buf(struct i40iw_sc_dev *dev, enum i40iw_debug_flag mask,
 | 
					 | 
				
			||||||
		     char *desc, u64 *buf, u32 size);
 | 
					 | 
				
			||||||
/* init operations */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_device_init(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					 struct i40iw_device_init_info *info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_sc_cqp_post_sq(struct i40iw_sc_cqp *cqp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
u64 *i40iw_sc_cqp_get_next_send_wqe(struct i40iw_sc_cqp *cqp, u64 scratch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_check_cqp_progress(struct i40iw_cqp_timeout *cqp_timeout, struct i40iw_sc_dev *dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_sc_mr_fast_register(struct i40iw_sc_qp *qp,
 | 
					 | 
				
			||||||
						 struct i40iw_fast_reg_stag_info *info,
 | 
					 | 
				
			||||||
						 bool post_sq);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_insert_wqe_hdr(u64 *wqe, u64 header);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* HMC/FPM functions */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_sc_init_iw_hmc(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					    u8 hmc_fn_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_pf_init_vfhmc(struct i40iw_sc_dev *dev, u8 vf_hmc_fn_id,
 | 
					 | 
				
			||||||
					   u32 *vf_cnt_array);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* stats functions */
 | 
					 | 
				
			||||||
void i40iw_hw_stats_refresh_all(struct i40iw_vsi_pestat *stats);
 | 
					 | 
				
			||||||
void i40iw_hw_stats_read_all(struct i40iw_vsi_pestat *stats, struct i40iw_dev_hw_stats *stats_values);
 | 
					 | 
				
			||||||
void i40iw_hw_stats_read_32(struct i40iw_vsi_pestat *stats,
 | 
					 | 
				
			||||||
			    enum i40iw_hw_stats_index_32b index,
 | 
					 | 
				
			||||||
			    u64 *value);
 | 
					 | 
				
			||||||
void i40iw_hw_stats_read_64(struct i40iw_vsi_pestat *stats,
 | 
					 | 
				
			||||||
			    enum i40iw_hw_stats_index_64b index,
 | 
					 | 
				
			||||||
			    u64 *value);
 | 
					 | 
				
			||||||
void i40iw_hw_stats_init(struct i40iw_vsi_pestat *stats, u8 index, bool is_pf);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* vsi misc functions */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vsi_stats_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_stats_info *info);
 | 
					 | 
				
			||||||
void i40iw_vsi_stats_free(struct i40iw_sc_vsi *vsi);
 | 
					 | 
				
			||||||
void i40iw_sc_vsi_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_init_info *info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_change_l2params(struct i40iw_sc_vsi *vsi, struct i40iw_l2params *l2params);
 | 
					 | 
				
			||||||
void i40iw_qp_add_qos(struct i40iw_sc_qp *qp);
 | 
					 | 
				
			||||||
void i40iw_qp_rem_qos(struct i40iw_sc_qp *qp);
 | 
					 | 
				
			||||||
void i40iw_terminate_send_fin(struct i40iw_sc_qp *qp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_terminate_connection(struct i40iw_sc_qp *qp, struct i40iw_aeqe_info *info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_terminate_received(struct i40iw_sc_qp *qp, struct i40iw_aeqe_info *info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_sc_suspend_qp(struct i40iw_sc_cqp *cqp,
 | 
					 | 
				
			||||||
					   struct i40iw_sc_qp *qp, u64 scratch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_sc_resume_qp(struct i40iw_sc_cqp *cqp,
 | 
					 | 
				
			||||||
					  struct i40iw_sc_qp *qp, u64 scratch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_sc_static_hmc_pages_allocated(struct i40iw_sc_cqp *cqp,
 | 
					 | 
				
			||||||
							   u64 scratch, u8 hmc_fn_id,
 | 
					 | 
				
			||||||
							   bool post_sq,
 | 
					 | 
				
			||||||
							   bool poll_registers);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_config_fpm_values(struct i40iw_sc_dev *dev, u32 qp_count);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_get_rdma_features(struct i40iw_sc_dev *dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void free_sd_mem(struct i40iw_sc_dev *dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_process_cqp_cmd(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					     struct cqp_commands_info *pcmdinfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_process_bh(struct i40iw_sc_dev *dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* prototype for functions used for dynamic memory allocation */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_allocate_dma_mem(struct i40iw_hw *hw,
 | 
					 | 
				
			||||||
					      struct i40iw_dma_mem *mem, u64 size,
 | 
					 | 
				
			||||||
					      u32 alignment);
 | 
					 | 
				
			||||||
void i40iw_free_dma_mem(struct i40iw_hw *hw, struct i40iw_dma_mem *mem);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_allocate_virt_mem(struct i40iw_hw *hw,
 | 
					 | 
				
			||||||
					       struct i40iw_virt_mem *mem, u32 size);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_free_virt_mem(struct i40iw_hw *hw,
 | 
					 | 
				
			||||||
					   struct i40iw_virt_mem *mem);
 | 
					 | 
				
			||||||
u8 i40iw_get_encoded_wqe_size(u32 wqsize, bool cqpsq);
 | 
					 | 
				
			||||||
void i40iw_reinitialize_ieq(struct i40iw_sc_dev *dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,611 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "i40iw_status.h"
 | 
					 | 
				
			||||||
#include "i40iw_osdep.h"
 | 
					 | 
				
			||||||
#include "i40iw_register.h"
 | 
					 | 
				
			||||||
#include "i40iw_hmc.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "i40iw_d.h"
 | 
					 | 
				
			||||||
#include "i40iw_type.h"
 | 
					 | 
				
			||||||
#include "i40iw_p.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <linux/pci.h>
 | 
					 | 
				
			||||||
#include <linux/genalloc.h>
 | 
					 | 
				
			||||||
#include <linux/vmalloc.h>
 | 
					 | 
				
			||||||
#include "i40iw_pble.h"
 | 
					 | 
				
			||||||
#include "i40iw.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_device;
 | 
					 | 
				
			||||||
static enum i40iw_status_code add_pble_pool(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					    struct i40iw_hmc_pble_rsrc *pble_rsrc);
 | 
					 | 
				
			||||||
static void i40iw_free_vmalloc_mem(struct i40iw_hw *hw, struct i40iw_chunk *chunk);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_destroy_pble_pool - destroy pool during module unload
 | 
					 | 
				
			||||||
 * @dev: i40iw_sc_dev struct
 | 
					 | 
				
			||||||
 * @pble_rsrc:	pble resources
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void i40iw_destroy_pble_pool(struct i40iw_sc_dev *dev, struct i40iw_hmc_pble_rsrc *pble_rsrc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct list_head *clist;
 | 
					 | 
				
			||||||
	struct list_head *tlist;
 | 
					 | 
				
			||||||
	struct i40iw_chunk *chunk;
 | 
					 | 
				
			||||||
	struct i40iw_pble_pool *pinfo = &pble_rsrc->pinfo;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (pinfo->pool) {
 | 
					 | 
				
			||||||
		list_for_each_safe(clist, tlist, &pinfo->clist) {
 | 
					 | 
				
			||||||
			chunk = list_entry(clist, struct i40iw_chunk, list);
 | 
					 | 
				
			||||||
			if (chunk->type == I40IW_VMALLOC)
 | 
					 | 
				
			||||||
				i40iw_free_vmalloc_mem(dev->hw, chunk);
 | 
					 | 
				
			||||||
			kfree(chunk);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		gen_pool_destroy(pinfo->pool);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_hmc_init_pble - Initialize pble resources during module load
 | 
					 | 
				
			||||||
 * @dev: i40iw_sc_dev struct
 | 
					 | 
				
			||||||
 * @pble_rsrc:	pble resources
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_hmc_init_pble(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					   struct i40iw_hmc_pble_rsrc *pble_rsrc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info;
 | 
					 | 
				
			||||||
	u32 fpm_idx = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hmc_info = dev->hmc_info;
 | 
					 | 
				
			||||||
	pble_rsrc->fpm_base_addr = hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].base;
 | 
					 | 
				
			||||||
	/* Now start the pble' on 4k boundary */
 | 
					 | 
				
			||||||
	if (pble_rsrc->fpm_base_addr & 0xfff)
 | 
					 | 
				
			||||||
		fpm_idx = (PAGE_SIZE - (pble_rsrc->fpm_base_addr & 0xfff)) >> 3;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pble_rsrc->unallocated_pble =
 | 
					 | 
				
			||||||
	    hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt - fpm_idx;
 | 
					 | 
				
			||||||
	pble_rsrc->next_fpm_addr = pble_rsrc->fpm_base_addr + (fpm_idx << 3);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pble_rsrc->pinfo.pool_shift = POOL_SHIFT;
 | 
					 | 
				
			||||||
	pble_rsrc->pinfo.pool = gen_pool_create(pble_rsrc->pinfo.pool_shift, -1);
 | 
					 | 
				
			||||||
	INIT_LIST_HEAD(&pble_rsrc->pinfo.clist);
 | 
					 | 
				
			||||||
	if (!pble_rsrc->pinfo.pool)
 | 
					 | 
				
			||||||
		goto error;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (add_pble_pool(dev, pble_rsrc))
 | 
					 | 
				
			||||||
		goto error;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 error:i40iw_destroy_pble_pool(dev, pble_rsrc);
 | 
					 | 
				
			||||||
	return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * get_sd_pd_idx -  Returns sd index, pd index and rel_pd_idx from fpm address
 | 
					 | 
				
			||||||
 * @pble_rsrc:	structure containing fpm address
 | 
					 | 
				
			||||||
 * @idx: where to return indexes
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void get_sd_pd_idx(struct i40iw_hmc_pble_rsrc *pble_rsrc,
 | 
					 | 
				
			||||||
				 struct sd_pd_idx *idx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	idx->sd_idx = (u32)(pble_rsrc->next_fpm_addr) / I40IW_HMC_DIRECT_BP_SIZE;
 | 
					 | 
				
			||||||
	idx->pd_idx = (u32)(pble_rsrc->next_fpm_addr) / I40IW_HMC_PAGED_BP_SIZE;
 | 
					 | 
				
			||||||
	idx->rel_pd_idx = (idx->pd_idx % I40IW_HMC_PD_CNT_IN_SD);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * add_sd_direct - add sd direct for pble
 | 
					 | 
				
			||||||
 * @dev: hardware control device structure
 | 
					 | 
				
			||||||
 * @pble_rsrc: pble resource ptr
 | 
					 | 
				
			||||||
 * @info: page info for sd
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code add_sd_direct(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					    struct i40iw_hmc_pble_rsrc *pble_rsrc,
 | 
					 | 
				
			||||||
					    struct i40iw_add_page_info *info)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = 0;
 | 
					 | 
				
			||||||
	struct sd_pd_idx *idx = &info->idx;
 | 
					 | 
				
			||||||
	struct i40iw_chunk *chunk = info->chunk;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info = info->hmc_info;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry = info->sd_entry;
 | 
					 | 
				
			||||||
	u32 offset = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!sd_entry->valid) {
 | 
					 | 
				
			||||||
		if (dev->is_pf) {
 | 
					 | 
				
			||||||
			ret_code = i40iw_add_sd_table_entry(dev->hw, hmc_info,
 | 
					 | 
				
			||||||
							    info->idx.sd_idx,
 | 
					 | 
				
			||||||
							    I40IW_SD_TYPE_DIRECT,
 | 
					 | 
				
			||||||
							    I40IW_HMC_DIRECT_BP_SIZE);
 | 
					 | 
				
			||||||
			if (ret_code)
 | 
					 | 
				
			||||||
				return ret_code;
 | 
					 | 
				
			||||||
			chunk->type = I40IW_DMA_COHERENT;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	offset = idx->rel_pd_idx << I40IW_HMC_PAGED_BP_SHIFT;
 | 
					 | 
				
			||||||
	chunk->size = info->pages << I40IW_HMC_PAGED_BP_SHIFT;
 | 
					 | 
				
			||||||
	chunk->vaddr = ((u8 *)sd_entry->u.bp.addr.va + offset);
 | 
					 | 
				
			||||||
	chunk->fpm_addr = pble_rsrc->next_fpm_addr;
 | 
					 | 
				
			||||||
	i40iw_debug(dev, I40IW_DEBUG_PBLE, "chunk_size[%d] = 0x%x vaddr=%p fpm_addr = %llx\n",
 | 
					 | 
				
			||||||
		    chunk->size, chunk->size, chunk->vaddr, chunk->fpm_addr);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_free_vmalloc_mem - free vmalloc during close
 | 
					 | 
				
			||||||
 * @hw: hw struct
 | 
					 | 
				
			||||||
 * @chunk: chunk information for vmalloc
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void i40iw_free_vmalloc_mem(struct i40iw_hw *hw, struct i40iw_chunk *chunk)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct pci_dev *pcidev = hw->pcidev;
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!chunk->pg_cnt)
 | 
					 | 
				
			||||||
		goto done;
 | 
					 | 
				
			||||||
	for (i = 0; i < chunk->pg_cnt; i++)
 | 
					 | 
				
			||||||
		dma_unmap_page(&pcidev->dev, chunk->dmaaddrs[i], PAGE_SIZE, DMA_BIDIRECTIONAL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 done:
 | 
					 | 
				
			||||||
	kfree(chunk->dmaaddrs);
 | 
					 | 
				
			||||||
	chunk->dmaaddrs = NULL;
 | 
					 | 
				
			||||||
	vfree(chunk->vaddr);
 | 
					 | 
				
			||||||
	chunk->vaddr = NULL;
 | 
					 | 
				
			||||||
	chunk->type = 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_get_vmalloc_mem - get 2M page for sd
 | 
					 | 
				
			||||||
 * @hw: hardware address
 | 
					 | 
				
			||||||
 * @chunk: chunk to adf
 | 
					 | 
				
			||||||
 * @pg_cnt: #of 4 K pages
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code i40iw_get_vmalloc_mem(struct i40iw_hw *hw,
 | 
					 | 
				
			||||||
						    struct i40iw_chunk *chunk,
 | 
					 | 
				
			||||||
						    int pg_cnt)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct pci_dev *pcidev = hw->pcidev;
 | 
					 | 
				
			||||||
	struct page *page;
 | 
					 | 
				
			||||||
	u8 *addr;
 | 
					 | 
				
			||||||
	u32 size;
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chunk->dmaaddrs = kzalloc(pg_cnt << 3, GFP_KERNEL);
 | 
					 | 
				
			||||||
	if (!chunk->dmaaddrs)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
	size = PAGE_SIZE * pg_cnt;
 | 
					 | 
				
			||||||
	chunk->vaddr = vmalloc(size);
 | 
					 | 
				
			||||||
	if (!chunk->vaddr) {
 | 
					 | 
				
			||||||
		kfree(chunk->dmaaddrs);
 | 
					 | 
				
			||||||
		chunk->dmaaddrs = NULL;
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	chunk->size = size;
 | 
					 | 
				
			||||||
	addr = (u8 *)chunk->vaddr;
 | 
					 | 
				
			||||||
	for (i = 0; i < pg_cnt; i++) {
 | 
					 | 
				
			||||||
		page = vmalloc_to_page((void *)addr);
 | 
					 | 
				
			||||||
		if (!page)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		chunk->dmaaddrs[i] = dma_map_page(&pcidev->dev, page, 0,
 | 
					 | 
				
			||||||
						  PAGE_SIZE, DMA_BIDIRECTIONAL);
 | 
					 | 
				
			||||||
		if (dma_mapping_error(&pcidev->dev, chunk->dmaaddrs[i]))
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		addr += PAGE_SIZE;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chunk->pg_cnt = i;
 | 
					 | 
				
			||||||
	chunk->type = I40IW_VMALLOC;
 | 
					 | 
				
			||||||
	if (i == pg_cnt)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i40iw_free_vmalloc_mem(hw, chunk);
 | 
					 | 
				
			||||||
	return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * fpm_to_idx - given fpm address, get pble index
 | 
					 | 
				
			||||||
 * @pble_rsrc: pble resource management
 | 
					 | 
				
			||||||
 * @addr: fpm address for index
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline u32 fpm_to_idx(struct i40iw_hmc_pble_rsrc *pble_rsrc, u64 addr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return (addr - (pble_rsrc->fpm_base_addr)) >> 3;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * add_bp_pages - add backing pages for sd
 | 
					 | 
				
			||||||
 * @dev: hardware control device structure
 | 
					 | 
				
			||||||
 * @pble_rsrc: pble resource management
 | 
					 | 
				
			||||||
 * @info: page info for sd
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code add_bp_pages(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					   struct i40iw_hmc_pble_rsrc *pble_rsrc,
 | 
					 | 
				
			||||||
					   struct i40iw_add_page_info *info)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u8 *addr;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem mem;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pd_entry *pd_entry;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry = info->sd_entry;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info = info->hmc_info;
 | 
					 | 
				
			||||||
	struct i40iw_chunk *chunk = info->chunk;
 | 
					 | 
				
			||||||
	struct i40iw_manage_vf_pble_info vf_pble_info;
 | 
					 | 
				
			||||||
	enum i40iw_status_code status = 0;
 | 
					 | 
				
			||||||
	u32 rel_pd_idx = info->idx.rel_pd_idx;
 | 
					 | 
				
			||||||
	u32 pd_idx = info->idx.pd_idx;
 | 
					 | 
				
			||||||
	u32 i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	status = i40iw_get_vmalloc_mem(dev->hw, chunk, info->pages);
 | 
					 | 
				
			||||||
	if (status)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
	status = i40iw_add_sd_table_entry(dev->hw, hmc_info,
 | 
					 | 
				
			||||||
					  info->idx.sd_idx, I40IW_SD_TYPE_PAGED,
 | 
					 | 
				
			||||||
					  I40IW_HMC_DIRECT_BP_SIZE);
 | 
					 | 
				
			||||||
	if (status)
 | 
					 | 
				
			||||||
		goto error;
 | 
					 | 
				
			||||||
	if (!dev->is_pf) {
 | 
					 | 
				
			||||||
		status = i40iw_vchnl_vf_add_hmc_objs(dev, I40IW_HMC_IW_PBLE,
 | 
					 | 
				
			||||||
						     fpm_to_idx(pble_rsrc,
 | 
					 | 
				
			||||||
								pble_rsrc->next_fpm_addr),
 | 
					 | 
				
			||||||
						     (info->pages << PBLE_512_SHIFT));
 | 
					 | 
				
			||||||
		if (status) {
 | 
					 | 
				
			||||||
			i40iw_pr_err("allocate PBLEs in the PF.  Error %i\n", status);
 | 
					 | 
				
			||||||
			goto error;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	addr = chunk->vaddr;
 | 
					 | 
				
			||||||
	for (i = 0; i < info->pages; i++) {
 | 
					 | 
				
			||||||
		mem.pa = chunk->dmaaddrs[i];
 | 
					 | 
				
			||||||
		mem.size = PAGE_SIZE;
 | 
					 | 
				
			||||||
		mem.va = (void *)(addr);
 | 
					 | 
				
			||||||
		pd_entry = &sd_entry->u.pd_table.pd_entry[rel_pd_idx++];
 | 
					 | 
				
			||||||
		if (!pd_entry->valid) {
 | 
					 | 
				
			||||||
			status = i40iw_add_pd_table_entry(dev->hw, hmc_info, pd_idx++, &mem);
 | 
					 | 
				
			||||||
			if (status)
 | 
					 | 
				
			||||||
				goto error;
 | 
					 | 
				
			||||||
			addr += PAGE_SIZE;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			i40iw_pr_err("pd entry is valid expecting to be invalid\n");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!dev->is_pf) {
 | 
					 | 
				
			||||||
		vf_pble_info.first_pd_index = info->idx.rel_pd_idx;
 | 
					 | 
				
			||||||
		vf_pble_info.inv_pd_ent = false;
 | 
					 | 
				
			||||||
		vf_pble_info.pd_entry_cnt = PBLE_PER_PAGE;
 | 
					 | 
				
			||||||
		vf_pble_info.pd_pl_pba = sd_entry->u.pd_table.pd_page_addr.pa;
 | 
					 | 
				
			||||||
		vf_pble_info.sd_index = info->idx.sd_idx;
 | 
					 | 
				
			||||||
		status = i40iw_hw_manage_vf_pble_bp(dev->back_dev,
 | 
					 | 
				
			||||||
						    &vf_pble_info, true);
 | 
					 | 
				
			||||||
		if (status) {
 | 
					 | 
				
			||||||
			i40iw_pr_err("CQP manage VF PBLE BP failed.  %i\n", status);
 | 
					 | 
				
			||||||
			goto error;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	chunk->fpm_addr = pble_rsrc->next_fpm_addr;
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
error:
 | 
					 | 
				
			||||||
	i40iw_free_vmalloc_mem(dev->hw, chunk);
 | 
					 | 
				
			||||||
	return status;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * add_pble_pool - add a sd entry for pble resoure
 | 
					 | 
				
			||||||
 * @dev: hardware control device structure
 | 
					 | 
				
			||||||
 * @pble_rsrc: pble resource management
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code add_pble_pool(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					    struct i40iw_hmc_pble_rsrc *pble_rsrc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info;
 | 
					 | 
				
			||||||
	struct i40iw_chunk *chunk;
 | 
					 | 
				
			||||||
	struct i40iw_add_page_info info;
 | 
					 | 
				
			||||||
	struct sd_pd_idx *idx = &info.idx;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = 0;
 | 
					 | 
				
			||||||
	enum i40iw_sd_entry_type sd_entry_type;
 | 
					 | 
				
			||||||
	u64 sd_reg_val = 0;
 | 
					 | 
				
			||||||
	u32 pages;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (pble_rsrc->unallocated_pble < PBLE_PER_PAGE)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
	if (pble_rsrc->next_fpm_addr & 0xfff) {
 | 
					 | 
				
			||||||
		i40iw_pr_err("next fpm_addr %llx\n", pble_rsrc->next_fpm_addr);
 | 
					 | 
				
			||||||
		return I40IW_ERR_INVALID_PAGE_DESC_INDEX;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	chunk = kzalloc(sizeof(*chunk), GFP_KERNEL);
 | 
					 | 
				
			||||||
	if (!chunk)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
	hmc_info = dev->hmc_info;
 | 
					 | 
				
			||||||
	chunk->fpm_addr = pble_rsrc->next_fpm_addr;
 | 
					 | 
				
			||||||
	get_sd_pd_idx(pble_rsrc, idx);
 | 
					 | 
				
			||||||
	sd_entry = &hmc_info->sd_table.sd_entry[idx->sd_idx];
 | 
					 | 
				
			||||||
	pages = (idx->rel_pd_idx) ? (I40IW_HMC_PD_CNT_IN_SD -
 | 
					 | 
				
			||||||
			idx->rel_pd_idx) : I40IW_HMC_PD_CNT_IN_SD;
 | 
					 | 
				
			||||||
	pages = min(pages, pble_rsrc->unallocated_pble >> PBLE_512_SHIFT);
 | 
					 | 
				
			||||||
	info.chunk = chunk;
 | 
					 | 
				
			||||||
	info.hmc_info = hmc_info;
 | 
					 | 
				
			||||||
	info.pages = pages;
 | 
					 | 
				
			||||||
	info.sd_entry = sd_entry;
 | 
					 | 
				
			||||||
	if (!sd_entry->valid) {
 | 
					 | 
				
			||||||
		sd_entry_type = (!idx->rel_pd_idx &&
 | 
					 | 
				
			||||||
				 (pages == I40IW_HMC_PD_CNT_IN_SD) &&
 | 
					 | 
				
			||||||
				 dev->is_pf) ? I40IW_SD_TYPE_DIRECT : I40IW_SD_TYPE_PAGED;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		sd_entry_type = sd_entry->entry_type;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	i40iw_debug(dev, I40IW_DEBUG_PBLE,
 | 
					 | 
				
			||||||
		    "pages = %d, unallocated_pble[%u] current_fpm_addr = %llx\n",
 | 
					 | 
				
			||||||
		    pages, pble_rsrc->unallocated_pble, pble_rsrc->next_fpm_addr);
 | 
					 | 
				
			||||||
	i40iw_debug(dev, I40IW_DEBUG_PBLE, "sd_entry_type = %d sd_entry valid = %d\n",
 | 
					 | 
				
			||||||
		    sd_entry_type, sd_entry->valid);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (sd_entry_type == I40IW_SD_TYPE_DIRECT)
 | 
					 | 
				
			||||||
		ret_code = add_sd_direct(dev, pble_rsrc, &info);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		sd_entry_type = I40IW_SD_TYPE_PAGED;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		pble_rsrc->stats_direct_sds++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (sd_entry_type == I40IW_SD_TYPE_PAGED) {
 | 
					 | 
				
			||||||
		ret_code = add_bp_pages(dev, pble_rsrc, &info);
 | 
					 | 
				
			||||||
		if (ret_code)
 | 
					 | 
				
			||||||
			goto error;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			pble_rsrc->stats_paged_sds++;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (gen_pool_add_virt(pble_rsrc->pinfo.pool, (unsigned long)chunk->vaddr,
 | 
					 | 
				
			||||||
			      (phys_addr_t)chunk->fpm_addr, chunk->size, -1)) {
 | 
					 | 
				
			||||||
		i40iw_pr_err("could not allocate memory by gen_pool_addr_virt()\n");
 | 
					 | 
				
			||||||
		ret_code = I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
		goto error;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pble_rsrc->next_fpm_addr += chunk->size;
 | 
					 | 
				
			||||||
	i40iw_debug(dev, I40IW_DEBUG_PBLE, "next_fpm_addr = %llx chunk_size[%u] = 0x%x\n",
 | 
					 | 
				
			||||||
		    pble_rsrc->next_fpm_addr, chunk->size, chunk->size);
 | 
					 | 
				
			||||||
	pble_rsrc->unallocated_pble -= (chunk->size >> 3);
 | 
					 | 
				
			||||||
	sd_reg_val = (sd_entry_type == I40IW_SD_TYPE_PAGED) ?
 | 
					 | 
				
			||||||
			sd_entry->u.pd_table.pd_page_addr.pa : sd_entry->u.bp.addr.pa;
 | 
					 | 
				
			||||||
	if (dev->is_pf && !sd_entry->valid) {
 | 
					 | 
				
			||||||
		ret_code = i40iw_hmc_sd_one(dev, hmc_info->hmc_fn_id,
 | 
					 | 
				
			||||||
					    sd_reg_val, idx->sd_idx,
 | 
					 | 
				
			||||||
					    sd_entry->entry_type, true);
 | 
					 | 
				
			||||||
		if (ret_code) {
 | 
					 | 
				
			||||||
			i40iw_pr_err("cqp cmd failed for sd (pbles)\n");
 | 
					 | 
				
			||||||
			goto error;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sd_entry->valid = true;
 | 
					 | 
				
			||||||
	list_add(&chunk->list, &pble_rsrc->pinfo.clist);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
 error:
 | 
					 | 
				
			||||||
	kfree(chunk);
 | 
					 | 
				
			||||||
	return ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * free_lvl2 - fee level 2 pble
 | 
					 | 
				
			||||||
 * @pble_rsrc: pble resource management
 | 
					 | 
				
			||||||
 * @palloc: level 2 pble allocation
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void free_lvl2(struct i40iw_hmc_pble_rsrc *pble_rsrc,
 | 
					 | 
				
			||||||
		      struct i40iw_pble_alloc *palloc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u32 i;
 | 
					 | 
				
			||||||
	struct gen_pool *pool;
 | 
					 | 
				
			||||||
	struct i40iw_pble_level2 *lvl2 = &palloc->level2;
 | 
					 | 
				
			||||||
	struct i40iw_pble_info *root = &lvl2->root;
 | 
					 | 
				
			||||||
	struct i40iw_pble_info *leaf = lvl2->leaf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pool = pble_rsrc->pinfo.pool;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {
 | 
					 | 
				
			||||||
		if (leaf->addr)
 | 
					 | 
				
			||||||
			gen_pool_free(pool, leaf->addr, (leaf->cnt << 3));
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (root->addr)
 | 
					 | 
				
			||||||
		gen_pool_free(pool, root->addr, (root->cnt << 3));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	kfree(lvl2->leaf);
 | 
					 | 
				
			||||||
	lvl2->leaf = NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * get_lvl2_pble - get level 2 pble resource
 | 
					 | 
				
			||||||
 * @pble_rsrc: pble resource management
 | 
					 | 
				
			||||||
 * @palloc: level 2 pble allocation
 | 
					 | 
				
			||||||
 * @pool: pool pointer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code get_lvl2_pble(struct i40iw_hmc_pble_rsrc *pble_rsrc,
 | 
					 | 
				
			||||||
					    struct i40iw_pble_alloc *palloc,
 | 
					 | 
				
			||||||
					    struct gen_pool *pool)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u32 lf4k, lflast, total, i;
 | 
					 | 
				
			||||||
	u32 pblcnt = PBLE_PER_PAGE;
 | 
					 | 
				
			||||||
	u64 *addr;
 | 
					 | 
				
			||||||
	struct i40iw_pble_level2 *lvl2 = &palloc->level2;
 | 
					 | 
				
			||||||
	struct i40iw_pble_info *root = &lvl2->root;
 | 
					 | 
				
			||||||
	struct i40iw_pble_info *leaf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* number of full 512 (4K) leafs) */
 | 
					 | 
				
			||||||
	lf4k = palloc->total_cnt >> 9;
 | 
					 | 
				
			||||||
	lflast = palloc->total_cnt % PBLE_PER_PAGE;
 | 
					 | 
				
			||||||
	total = (lflast == 0) ? lf4k : lf4k + 1;
 | 
					 | 
				
			||||||
	lvl2->leaf_cnt = total;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	leaf = kzalloc((sizeof(*leaf) * total), GFP_ATOMIC);
 | 
					 | 
				
			||||||
	if (!leaf)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
	lvl2->leaf = leaf;
 | 
					 | 
				
			||||||
	/* allocate pbles for the root */
 | 
					 | 
				
			||||||
	root->addr = gen_pool_alloc(pool, (total << 3));
 | 
					 | 
				
			||||||
	if (!root->addr) {
 | 
					 | 
				
			||||||
		kfree(lvl2->leaf);
 | 
					 | 
				
			||||||
		lvl2->leaf = NULL;
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	root->idx = fpm_to_idx(pble_rsrc,
 | 
					 | 
				
			||||||
			       (u64)gen_pool_virt_to_phys(pool, root->addr));
 | 
					 | 
				
			||||||
	root->cnt = total;
 | 
					 | 
				
			||||||
	addr = (u64 *)root->addr;
 | 
					 | 
				
			||||||
	for (i = 0; i < total; i++, leaf++) {
 | 
					 | 
				
			||||||
		pblcnt = (lflast && ((i + 1) == total)) ? lflast : PBLE_PER_PAGE;
 | 
					 | 
				
			||||||
		leaf->addr = gen_pool_alloc(pool, (pblcnt << 3));
 | 
					 | 
				
			||||||
		if (!leaf->addr)
 | 
					 | 
				
			||||||
			goto error;
 | 
					 | 
				
			||||||
		leaf->idx = fpm_to_idx(pble_rsrc, (u64)gen_pool_virt_to_phys(pool, leaf->addr));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		leaf->cnt = pblcnt;
 | 
					 | 
				
			||||||
		*addr = (u64)leaf->idx;
 | 
					 | 
				
			||||||
		addr++;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	palloc->level = I40IW_LEVEL_2;
 | 
					 | 
				
			||||||
	pble_rsrc->stats_lvl2++;
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
 error:
 | 
					 | 
				
			||||||
	free_lvl2(pble_rsrc, palloc);
 | 
					 | 
				
			||||||
	return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * get_lvl1_pble - get level 1 pble resource
 | 
					 | 
				
			||||||
 * @dev: hardware control device structure
 | 
					 | 
				
			||||||
 * @pble_rsrc: pble resource management
 | 
					 | 
				
			||||||
 * @palloc: level 1 pble allocation
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code get_lvl1_pble(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					    struct i40iw_hmc_pble_rsrc *pble_rsrc,
 | 
					 | 
				
			||||||
					    struct i40iw_pble_alloc *palloc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u64 *addr;
 | 
					 | 
				
			||||||
	struct gen_pool *pool;
 | 
					 | 
				
			||||||
	struct i40iw_pble_info *lvl1 = &palloc->level1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pool = pble_rsrc->pinfo.pool;
 | 
					 | 
				
			||||||
	addr = (u64 *)gen_pool_alloc(pool, (palloc->total_cnt << 3));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!addr)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NO_MEMORY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	palloc->level = I40IW_LEVEL_1;
 | 
					 | 
				
			||||||
	lvl1->addr = (unsigned long)addr;
 | 
					 | 
				
			||||||
	lvl1->idx = fpm_to_idx(pble_rsrc, (u64)gen_pool_virt_to_phys(pool,
 | 
					 | 
				
			||||||
			       (unsigned long)addr));
 | 
					 | 
				
			||||||
	lvl1->cnt = palloc->total_cnt;
 | 
					 | 
				
			||||||
	pble_rsrc->stats_lvl1++;
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * get_lvl1_lvl2_pble - calls get_lvl1 and get_lvl2 pble routine
 | 
					 | 
				
			||||||
 * @dev: i40iw_sc_dev struct
 | 
					 | 
				
			||||||
 * @pble_rsrc:	pble resources
 | 
					 | 
				
			||||||
 * @palloc: contains all inforamtion regarding pble (idx + pble addr)
 | 
					 | 
				
			||||||
 * @pool: pointer to general purpose special memory pool descriptor
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline enum i40iw_status_code get_lvl1_lvl2_pble(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
							struct i40iw_hmc_pble_rsrc *pble_rsrc,
 | 
					 | 
				
			||||||
							struct i40iw_pble_alloc *palloc,
 | 
					 | 
				
			||||||
							struct gen_pool *pool)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code status = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	status = get_lvl1_pble(dev, pble_rsrc, palloc);
 | 
					 | 
				
			||||||
	if (status && (palloc->total_cnt > PBLE_PER_PAGE))
 | 
					 | 
				
			||||||
		status = get_lvl2_pble(pble_rsrc, palloc, pool);
 | 
					 | 
				
			||||||
	return status;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_get_pble - allocate pbles from the pool
 | 
					 | 
				
			||||||
 * @dev: i40iw_sc_dev struct
 | 
					 | 
				
			||||||
 * @pble_rsrc:	pble resources
 | 
					 | 
				
			||||||
 * @palloc: contains all inforamtion regarding pble (idx + pble addr)
 | 
					 | 
				
			||||||
 * @pble_cnt: #of pbles requested
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_get_pble(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
				      struct i40iw_hmc_pble_rsrc *pble_rsrc,
 | 
					 | 
				
			||||||
				      struct i40iw_pble_alloc *palloc,
 | 
					 | 
				
			||||||
				      u32 pble_cnt)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gen_pool *pool;
 | 
					 | 
				
			||||||
	enum i40iw_status_code status = 0;
 | 
					 | 
				
			||||||
	u32 max_sds = 0;
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pool = pble_rsrc->pinfo.pool;
 | 
					 | 
				
			||||||
	palloc->total_cnt = pble_cnt;
 | 
					 | 
				
			||||||
	palloc->level = I40IW_LEVEL_0;
 | 
					 | 
				
			||||||
	/*check first to see if we can get pble's without acquiring additional sd's */
 | 
					 | 
				
			||||||
	status = get_lvl1_lvl2_pble(dev, pble_rsrc, palloc, pool);
 | 
					 | 
				
			||||||
	if (!status)
 | 
					 | 
				
			||||||
		goto exit;
 | 
					 | 
				
			||||||
	max_sds = (palloc->total_cnt >> 18) + 1;
 | 
					 | 
				
			||||||
	for (i = 0; i < max_sds; i++) {
 | 
					 | 
				
			||||||
		status = add_pble_pool(dev, pble_rsrc);
 | 
					 | 
				
			||||||
		if (status)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		status = get_lvl1_lvl2_pble(dev, pble_rsrc, palloc, pool);
 | 
					 | 
				
			||||||
		if (!status)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
exit:
 | 
					 | 
				
			||||||
	if (!status)
 | 
					 | 
				
			||||||
		pble_rsrc->stats_alloc_ok++;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		pble_rsrc->stats_alloc_fail++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return status;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_free_pble - put pbles back into pool
 | 
					 | 
				
			||||||
 * @pble_rsrc:	pble resources
 | 
					 | 
				
			||||||
 * @palloc: contains all inforamtion regarding pble resource being freed
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void i40iw_free_pble(struct i40iw_hmc_pble_rsrc *pble_rsrc,
 | 
					 | 
				
			||||||
		     struct i40iw_pble_alloc *palloc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gen_pool *pool;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pool = pble_rsrc->pinfo.pool;
 | 
					 | 
				
			||||||
	if (palloc->level == I40IW_LEVEL_2)
 | 
					 | 
				
			||||||
		free_lvl2(pble_rsrc, palloc);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		gen_pool_free(pool, palloc->level1.addr,
 | 
					 | 
				
			||||||
			      (palloc->level1.cnt << 3));
 | 
					 | 
				
			||||||
	pble_rsrc->stats_alloc_freed++;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,131 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_PBLE_H
 | 
					 | 
				
			||||||
#define I40IW_PBLE_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define POOL_SHIFT      6
 | 
					 | 
				
			||||||
#define PBLE_PER_PAGE   512
 | 
					 | 
				
			||||||
#define I40IW_HMC_PAGED_BP_SHIFT 12
 | 
					 | 
				
			||||||
#define PBLE_512_SHIFT  9
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_pble_level {
 | 
					 | 
				
			||||||
	I40IW_LEVEL_0 = 0,
 | 
					 | 
				
			||||||
	I40IW_LEVEL_1 = 1,
 | 
					 | 
				
			||||||
	I40IW_LEVEL_2 = 2
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_alloc_type {
 | 
					 | 
				
			||||||
	I40IW_NO_ALLOC = 0,
 | 
					 | 
				
			||||||
	I40IW_DMA_COHERENT = 1,
 | 
					 | 
				
			||||||
	I40IW_VMALLOC = 2
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_pble_info {
 | 
					 | 
				
			||||||
	unsigned long addr;
 | 
					 | 
				
			||||||
	u32 idx;
 | 
					 | 
				
			||||||
	u32 cnt;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_pble_level2 {
 | 
					 | 
				
			||||||
	struct i40iw_pble_info root;
 | 
					 | 
				
			||||||
	struct i40iw_pble_info *leaf;
 | 
					 | 
				
			||||||
	u32 leaf_cnt;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_pble_alloc {
 | 
					 | 
				
			||||||
	u32 total_cnt;
 | 
					 | 
				
			||||||
	enum i40iw_pble_level level;
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct i40iw_pble_info level1;
 | 
					 | 
				
			||||||
		struct i40iw_pble_level2 level2;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sd_pd_idx {
 | 
					 | 
				
			||||||
	u32 sd_idx;
 | 
					 | 
				
			||||||
	u32 pd_idx;
 | 
					 | 
				
			||||||
	u32 rel_pd_idx;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_add_page_info {
 | 
					 | 
				
			||||||
	struct i40iw_chunk *chunk;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_sd_entry *sd_entry;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info;
 | 
					 | 
				
			||||||
	struct sd_pd_idx idx;
 | 
					 | 
				
			||||||
	u32 pages;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_chunk {
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
					 | 
				
			||||||
	u32 size;
 | 
					 | 
				
			||||||
	void *vaddr;
 | 
					 | 
				
			||||||
	u64 fpm_addr;
 | 
					 | 
				
			||||||
	u32 pg_cnt;
 | 
					 | 
				
			||||||
	dma_addr_t *dmaaddrs;
 | 
					 | 
				
			||||||
	enum i40iw_alloc_type type;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_pble_pool {
 | 
					 | 
				
			||||||
	struct gen_pool *pool;
 | 
					 | 
				
			||||||
	struct list_head clist;
 | 
					 | 
				
			||||||
	u32 total_pble_alloc;
 | 
					 | 
				
			||||||
	u32 free_pble_cnt;
 | 
					 | 
				
			||||||
	u32 pool_shift;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_pble_rsrc {
 | 
					 | 
				
			||||||
	u32 unallocated_pble;
 | 
					 | 
				
			||||||
	u64 fpm_base_addr;
 | 
					 | 
				
			||||||
	u64 next_fpm_addr;
 | 
					 | 
				
			||||||
	struct i40iw_pble_pool pinfo;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u32 stats_direct_sds;
 | 
					 | 
				
			||||||
	u32 stats_paged_sds;
 | 
					 | 
				
			||||||
	u64 stats_alloc_ok;
 | 
					 | 
				
			||||||
	u64 stats_alloc_fail;
 | 
					 | 
				
			||||||
	u64 stats_alloc_freed;
 | 
					 | 
				
			||||||
	u64 stats_lvl1;
 | 
					 | 
				
			||||||
	u64 stats_lvl2;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_destroy_pble_pool(struct i40iw_sc_dev *dev, struct i40iw_hmc_pble_rsrc *pble_rsrc);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_hmc_init_pble(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					   struct i40iw_hmc_pble_rsrc *pble_rsrc);
 | 
					 | 
				
			||||||
void i40iw_free_pble(struct i40iw_hmc_pble_rsrc *pble_rsrc, struct i40iw_pble_alloc *palloc);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_get_pble(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
				      struct i40iw_hmc_pble_rsrc *pble_rsrc,
 | 
					 | 
				
			||||||
				      struct i40iw_pble_alloc *palloc,
 | 
					 | 
				
			||||||
				      u32 pble_cnt);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,188 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_PUDA_H
 | 
					 | 
				
			||||||
#define I40IW_PUDA_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_IEQ_MPA_FRAMING 6
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_sc_dev;
 | 
					 | 
				
			||||||
struct i40iw_sc_qp;
 | 
					 | 
				
			||||||
struct i40iw_sc_cq;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum puda_resource_type {
 | 
					 | 
				
			||||||
	I40IW_PUDA_RSRC_TYPE_ILQ = 1,
 | 
					 | 
				
			||||||
	I40IW_PUDA_RSRC_TYPE_IEQ
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum puda_rsrc_complete {
 | 
					 | 
				
			||||||
	PUDA_CQ_CREATED = 1,
 | 
					 | 
				
			||||||
	PUDA_QP_CREATED,
 | 
					 | 
				
			||||||
	PUDA_TX_COMPLETE,
 | 
					 | 
				
			||||||
	PUDA_RX_COMPLETE,
 | 
					 | 
				
			||||||
	PUDA_HASH_CRC_COMPLETE
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_puda_completion_info {
 | 
					 | 
				
			||||||
	struct i40iw_qp_uk *qp;
 | 
					 | 
				
			||||||
	u8 q_type;
 | 
					 | 
				
			||||||
	u8 vlan_valid;
 | 
					 | 
				
			||||||
	u8 l3proto;
 | 
					 | 
				
			||||||
	u8 l4proto;
 | 
					 | 
				
			||||||
	u16 payload_len;
 | 
					 | 
				
			||||||
	u32 compl_error;	/* No_err=0, else major and minor err code */
 | 
					 | 
				
			||||||
	u32 qp_id;
 | 
					 | 
				
			||||||
	u32 wqe_idx;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_puda_send_info {
 | 
					 | 
				
			||||||
	u64 paddr;		/* Physical address */
 | 
					 | 
				
			||||||
	u32 len;
 | 
					 | 
				
			||||||
	u8 tcplen;
 | 
					 | 
				
			||||||
	u8 maclen;
 | 
					 | 
				
			||||||
	bool ipv4;
 | 
					 | 
				
			||||||
	bool doloopback;
 | 
					 | 
				
			||||||
	void *scratch;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_puda_buf {
 | 
					 | 
				
			||||||
	struct list_head list;	/* MUST be first entry */
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem mem;	/* DMA memory for the buffer */
 | 
					 | 
				
			||||||
	struct i40iw_puda_buf *next;	/* for alloclist in rsrc struct */
 | 
					 | 
				
			||||||
	struct i40iw_virt_mem buf_mem;	/* Buffer memory for this buffer */
 | 
					 | 
				
			||||||
	void *scratch;
 | 
					 | 
				
			||||||
	u8 *iph;
 | 
					 | 
				
			||||||
	u8 *tcph;
 | 
					 | 
				
			||||||
	u8 *data;
 | 
					 | 
				
			||||||
	u16 datalen;
 | 
					 | 
				
			||||||
	u16 vlan_id;
 | 
					 | 
				
			||||||
	u8 tcphlen;		/* tcp length in bytes */
 | 
					 | 
				
			||||||
	u8 maclen;		/* mac length in bytes */
 | 
					 | 
				
			||||||
	u32 totallen;		/* machlen+iphlen+tcphlen+datalen */
 | 
					 | 
				
			||||||
	atomic_t refcount;
 | 
					 | 
				
			||||||
	u8 hdrlen;
 | 
					 | 
				
			||||||
	bool ipv4;
 | 
					 | 
				
			||||||
	u32 seqnum;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_puda_rsrc_info {
 | 
					 | 
				
			||||||
	enum puda_resource_type type;	/* ILQ or IEQ */
 | 
					 | 
				
			||||||
	u32 count;
 | 
					 | 
				
			||||||
	u16 pd_id;
 | 
					 | 
				
			||||||
	u32 cq_id;
 | 
					 | 
				
			||||||
	u32 qp_id;
 | 
					 | 
				
			||||||
	u32 sq_size;
 | 
					 | 
				
			||||||
	u32 rq_size;
 | 
					 | 
				
			||||||
	u16 buf_size;
 | 
					 | 
				
			||||||
	u16 mss;
 | 
					 | 
				
			||||||
	u32 tx_buf_cnt;		/* total bufs allocated will be rq_size + tx_buf_cnt */
 | 
					 | 
				
			||||||
	void (*receive)(struct i40iw_sc_vsi *, struct i40iw_puda_buf *);
 | 
					 | 
				
			||||||
	void (*xmit_complete)(struct i40iw_sc_vsi *, void *);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_puda_rsrc {
 | 
					 | 
				
			||||||
	struct i40iw_sc_cq cq;
 | 
					 | 
				
			||||||
	struct i40iw_sc_qp qp;
 | 
					 | 
				
			||||||
	struct i40iw_sc_pd sc_pd;
 | 
					 | 
				
			||||||
	struct i40iw_sc_dev *dev;
 | 
					 | 
				
			||||||
	struct i40iw_sc_vsi *vsi;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem cqmem;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem qpmem;
 | 
					 | 
				
			||||||
	struct i40iw_virt_mem ilq_mem;
 | 
					 | 
				
			||||||
	enum puda_rsrc_complete completion;
 | 
					 | 
				
			||||||
	enum puda_resource_type type;
 | 
					 | 
				
			||||||
	u16 buf_size;		/*buffer must be max datalen + tcpip hdr + mac */
 | 
					 | 
				
			||||||
	u16 mss;
 | 
					 | 
				
			||||||
	u32 cq_id;
 | 
					 | 
				
			||||||
	u32 qp_id;
 | 
					 | 
				
			||||||
	u32 sq_size;
 | 
					 | 
				
			||||||
	u32 rq_size;
 | 
					 | 
				
			||||||
	u32 cq_size;
 | 
					 | 
				
			||||||
	struct i40iw_sq_uk_wr_trk_info *sq_wrtrk_array;
 | 
					 | 
				
			||||||
	u64 *rq_wrid_array;
 | 
					 | 
				
			||||||
	u32 compl_rxwqe_idx;
 | 
					 | 
				
			||||||
	u32 rx_wqe_idx;
 | 
					 | 
				
			||||||
	u32 rxq_invalid_cnt;
 | 
					 | 
				
			||||||
	u32 tx_wqe_avail_cnt;
 | 
					 | 
				
			||||||
	bool check_crc;
 | 
					 | 
				
			||||||
	struct shash_desc *hash_desc;
 | 
					 | 
				
			||||||
	struct list_head txpend;
 | 
					 | 
				
			||||||
	struct list_head bufpool;	/* free buffers pool list for recv and xmit */
 | 
					 | 
				
			||||||
	u32 alloc_buf_count;
 | 
					 | 
				
			||||||
	u32 avail_buf_count;		/* snapshot of currently available buffers */
 | 
					 | 
				
			||||||
	spinlock_t bufpool_lock;
 | 
					 | 
				
			||||||
	struct i40iw_puda_buf *alloclist;
 | 
					 | 
				
			||||||
	void (*receive)(struct i40iw_sc_vsi *, struct i40iw_puda_buf *);
 | 
					 | 
				
			||||||
	void (*xmit_complete)(struct i40iw_sc_vsi *, void *);
 | 
					 | 
				
			||||||
	/* puda stats */
 | 
					 | 
				
			||||||
	u64 stats_buf_alloc_fail;
 | 
					 | 
				
			||||||
	u64 stats_pkt_rcvd;
 | 
					 | 
				
			||||||
	u64 stats_pkt_sent;
 | 
					 | 
				
			||||||
	u64 stats_rcvd_pkt_err;
 | 
					 | 
				
			||||||
	u64 stats_sent_pkt_q;
 | 
					 | 
				
			||||||
	u64 stats_bad_qp_id;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_puda_buf *i40iw_puda_get_bufpool(struct i40iw_puda_rsrc *rsrc);
 | 
					 | 
				
			||||||
void i40iw_puda_ret_bufpool(struct i40iw_puda_rsrc *rsrc,
 | 
					 | 
				
			||||||
			    struct i40iw_puda_buf *buf);
 | 
					 | 
				
			||||||
void i40iw_puda_send_buf(struct i40iw_puda_rsrc *rsrc,
 | 
					 | 
				
			||||||
			 struct i40iw_puda_buf *buf);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_puda_send(struct i40iw_sc_qp *qp,
 | 
					 | 
				
			||||||
				       struct i40iw_puda_send_info *info);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_vsi *vsi,
 | 
					 | 
				
			||||||
					      struct i40iw_puda_rsrc_info *info);
 | 
					 | 
				
			||||||
void i40iw_puda_dele_resources(struct i40iw_sc_vsi *vsi,
 | 
					 | 
				
			||||||
			       enum puda_resource_type type,
 | 
					 | 
				
			||||||
			       bool reset);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_puda_poll_completion(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						  struct i40iw_sc_cq *cq, u32 *compl_err);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_sc_qp *i40iw_ieq_get_qp(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
				     struct i40iw_puda_buf *buf);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_puda_get_tcpip_info(struct i40iw_puda_completion_info *info,
 | 
					 | 
				
			||||||
						 struct i40iw_puda_buf *buf);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_ieq_check_mpacrc(struct shash_desc *desc,
 | 
					 | 
				
			||||||
					      void *addr, u32 length, u32 value);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_init_hash_desc(struct shash_desc **desc);
 | 
					 | 
				
			||||||
void i40iw_ieq_mpa_crc_ae(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp);
 | 
					 | 
				
			||||||
void i40iw_free_hash_desc(struct shash_desc *desc);
 | 
					 | 
				
			||||||
void i40iw_ieq_update_tcpip_info(struct i40iw_puda_buf *buf, u16 length,
 | 
					 | 
				
			||||||
				 u32 seqnum);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_cqp_qp_create_cmd(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_cqp_cq_create_cmd(struct i40iw_sc_dev *dev, struct i40iw_sc_cq *cq);
 | 
					 | 
				
			||||||
void i40iw_cqp_qp_destroy_cmd(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp);
 | 
					 | 
				
			||||||
void i40iw_cqp_cq_destroy_cmd(struct i40iw_sc_dev *dev, struct i40iw_sc_cq *cq);
 | 
					 | 
				
			||||||
void i40iw_ieq_cleanup_qp(struct i40iw_puda_rsrc *ieq, struct i40iw_sc_qp *qp);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,101 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_STATUS_H
 | 
					 | 
				
			||||||
#define I40IW_STATUS_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Error Codes */
 | 
					 | 
				
			||||||
enum i40iw_status_code {
 | 
					 | 
				
			||||||
	I40IW_SUCCESS = 0,
 | 
					 | 
				
			||||||
	I40IW_ERR_NVM = -1,
 | 
					 | 
				
			||||||
	I40IW_ERR_NVM_CHECKSUM = -2,
 | 
					 | 
				
			||||||
	I40IW_ERR_CONFIG = -4,
 | 
					 | 
				
			||||||
	I40IW_ERR_PARAM = -5,
 | 
					 | 
				
			||||||
	I40IW_ERR_DEVICE_NOT_SUPPORTED = -6,
 | 
					 | 
				
			||||||
	I40IW_ERR_RESET_FAILED = -7,
 | 
					 | 
				
			||||||
	I40IW_ERR_SWFW_SYNC = -8,
 | 
					 | 
				
			||||||
	I40IW_ERR_NO_MEMORY = -9,
 | 
					 | 
				
			||||||
	I40IW_ERR_BAD_PTR = -10,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_PD_ID = -11,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_QP_ID = -12,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_CQ_ID = -13,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_CEQ_ID = -14,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_AEQ_ID = -15,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_SIZE = -16,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_ARP_INDEX = -17,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_FPM_FUNC_ID = -18,
 | 
					 | 
				
			||||||
	I40IW_ERR_QP_INVALID_MSG_SIZE = -19,
 | 
					 | 
				
			||||||
	I40IW_ERR_QP_TOOMANY_WRS_POSTED = -20,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_FRAG_COUNT = -21,
 | 
					 | 
				
			||||||
	I40IW_ERR_QUEUE_EMPTY = -22,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_ALIGNMENT = -23,
 | 
					 | 
				
			||||||
	I40IW_ERR_FLUSHED_QUEUE = -24,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_INLINE_DATA_SIZE = -26,
 | 
					 | 
				
			||||||
	I40IW_ERR_TIMEOUT = -27,
 | 
					 | 
				
			||||||
	I40IW_ERR_OPCODE_MISMATCH = -28,
 | 
					 | 
				
			||||||
	I40IW_ERR_CQP_COMPL_ERROR = -29,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_VF_ID = -30,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_HMCFN_ID = -31,
 | 
					 | 
				
			||||||
	I40IW_ERR_BACKING_PAGE_ERROR = -32,
 | 
					 | 
				
			||||||
	I40IW_ERR_NO_PBLCHUNKS_AVAILABLE = -33,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_PBLE_INDEX = -34,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_SD_INDEX = -35,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_PAGE_DESC_INDEX = -36,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_SD_TYPE = -37,
 | 
					 | 
				
			||||||
	I40IW_ERR_MEMCPY_FAILED = -38,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_HMC_OBJ_INDEX = -39,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_HMC_OBJ_COUNT = -40,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_SRQ_ARM_LIMIT = -41,
 | 
					 | 
				
			||||||
	I40IW_ERR_SRQ_ENABLED = -42,
 | 
					 | 
				
			||||||
	I40IW_ERR_BUF_TOO_SHORT = -43,
 | 
					 | 
				
			||||||
	I40IW_ERR_BAD_IWARP_CQE = -44,
 | 
					 | 
				
			||||||
	I40IW_ERR_NVM_BLANK_MODE = -45,
 | 
					 | 
				
			||||||
	I40IW_ERR_NOT_IMPLEMENTED = -46,
 | 
					 | 
				
			||||||
	I40IW_ERR_PE_DOORBELL_NOT_ENABLED = -47,
 | 
					 | 
				
			||||||
	I40IW_ERR_NOT_READY = -48,
 | 
					 | 
				
			||||||
	I40IW_NOT_SUPPORTED = -49,
 | 
					 | 
				
			||||||
	I40IW_ERR_FIRMWARE_API_VERSION = -50,
 | 
					 | 
				
			||||||
	I40IW_ERR_RING_FULL = -51,
 | 
					 | 
				
			||||||
	I40IW_ERR_MPA_CRC = -61,
 | 
					 | 
				
			||||||
	I40IW_ERR_NO_TXBUFS = -62,
 | 
					 | 
				
			||||||
	I40IW_ERR_SEQ_NUM = -63,
 | 
					 | 
				
			||||||
	I40IW_ERR_list_empty = -64,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_MAC_ADDR = -65,
 | 
					 | 
				
			||||||
	I40IW_ERR_BAD_STAG      = -66,
 | 
					 | 
				
			||||||
	I40IW_ERR_CQ_COMPL_ERROR = -67,
 | 
					 | 
				
			||||||
	I40IW_ERR_QUEUE_DESTROYED = -68,
 | 
					 | 
				
			||||||
	I40IW_ERR_INVALID_FEAT_CNT = -69
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,422 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_USER_H
 | 
					 | 
				
			||||||
#define I40IW_USER_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_device_capabilities_const {
 | 
					 | 
				
			||||||
	I40IW_WQE_SIZE =			4,
 | 
					 | 
				
			||||||
	I40IW_CQP_WQE_SIZE =			8,
 | 
					 | 
				
			||||||
	I40IW_CQE_SIZE =			4,
 | 
					 | 
				
			||||||
	I40IW_EXTENDED_CQE_SIZE =		8,
 | 
					 | 
				
			||||||
	I40IW_AEQE_SIZE =			2,
 | 
					 | 
				
			||||||
	I40IW_CEQE_SIZE =			1,
 | 
					 | 
				
			||||||
	I40IW_CQP_CTX_SIZE =			8,
 | 
					 | 
				
			||||||
	I40IW_SHADOW_AREA_SIZE =		8,
 | 
					 | 
				
			||||||
	I40IW_CEQ_MAX_COUNT =			256,
 | 
					 | 
				
			||||||
	I40IW_QUERY_FPM_BUF_SIZE =		128,
 | 
					 | 
				
			||||||
	I40IW_COMMIT_FPM_BUF_SIZE =		128,
 | 
					 | 
				
			||||||
	I40IW_MIN_IW_QP_ID =			1,
 | 
					 | 
				
			||||||
	I40IW_MAX_IW_QP_ID =			262143,
 | 
					 | 
				
			||||||
	I40IW_MIN_CEQID =			0,
 | 
					 | 
				
			||||||
	I40IW_MAX_CEQID =			256,
 | 
					 | 
				
			||||||
	I40IW_MIN_CQID =			0,
 | 
					 | 
				
			||||||
	I40IW_MAX_CQID =			131071,
 | 
					 | 
				
			||||||
	I40IW_MIN_AEQ_ENTRIES =			1,
 | 
					 | 
				
			||||||
	I40IW_MAX_AEQ_ENTRIES =			524287,
 | 
					 | 
				
			||||||
	I40IW_MIN_CEQ_ENTRIES =			1,
 | 
					 | 
				
			||||||
	I40IW_MAX_CEQ_ENTRIES =			131071,
 | 
					 | 
				
			||||||
	I40IW_MIN_CQ_SIZE =			1,
 | 
					 | 
				
			||||||
	I40IW_MAX_CQ_SIZE =			1048575,
 | 
					 | 
				
			||||||
	I40IW_DB_ID_ZERO =			0,
 | 
					 | 
				
			||||||
	I40IW_MAX_WQ_FRAGMENT_COUNT =		3,
 | 
					 | 
				
			||||||
	I40IW_MAX_SGE_RD =			1,
 | 
					 | 
				
			||||||
	I40IW_MAX_OUTBOUND_MESSAGE_SIZE =	2147483647,
 | 
					 | 
				
			||||||
	I40IW_MAX_INBOUND_MESSAGE_SIZE =	2147483647,
 | 
					 | 
				
			||||||
	I40IW_MAX_PE_ENABLED_VF_COUNT =		32,
 | 
					 | 
				
			||||||
	I40IW_MAX_VF_FPM_ID =			47,
 | 
					 | 
				
			||||||
	I40IW_MAX_VF_PER_PF =			127,
 | 
					 | 
				
			||||||
	I40IW_MAX_SQ_PAYLOAD_SIZE =		2145386496,
 | 
					 | 
				
			||||||
	I40IW_MAX_INLINE_DATA_SIZE =		48,
 | 
					 | 
				
			||||||
	I40IW_MAX_IRD_SIZE =			64,
 | 
					 | 
				
			||||||
	I40IW_MAX_ORD_SIZE =			127,
 | 
					 | 
				
			||||||
	I40IW_MAX_WQ_ENTRIES =			2048,
 | 
					 | 
				
			||||||
	I40IW_Q2_BUFFER_SIZE =			(248 + 100),
 | 
					 | 
				
			||||||
	I40IW_MAX_WQE_SIZE_RQ =			128,
 | 
					 | 
				
			||||||
	I40IW_QP_CTX_SIZE =			248,
 | 
					 | 
				
			||||||
	I40IW_MAX_PDS = 			32768
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define i40iw_handle void *
 | 
					 | 
				
			||||||
#define i40iw_adapter_handle i40iw_handle
 | 
					 | 
				
			||||||
#define i40iw_qp_handle i40iw_handle
 | 
					 | 
				
			||||||
#define i40iw_cq_handle i40iw_handle
 | 
					 | 
				
			||||||
#define i40iw_srq_handle i40iw_handle
 | 
					 | 
				
			||||||
#define i40iw_pd_id i40iw_handle
 | 
					 | 
				
			||||||
#define i40iw_stag_handle i40iw_handle
 | 
					 | 
				
			||||||
#define i40iw_stag_index u32
 | 
					 | 
				
			||||||
#define i40iw_stag u32
 | 
					 | 
				
			||||||
#define i40iw_stag_key u8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define i40iw_tagged_offset u64
 | 
					 | 
				
			||||||
#define i40iw_access_privileges u32
 | 
					 | 
				
			||||||
#define i40iw_physical_fragment u64
 | 
					 | 
				
			||||||
#define i40iw_address_list u64 *
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	I40IW_MAX_MR_SIZE	0x10000000000L
 | 
					 | 
				
			||||||
#define	I40IW_MAX_RQ_WQE_SHIFT	2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_qp_uk;
 | 
					 | 
				
			||||||
struct i40iw_cq_uk;
 | 
					 | 
				
			||||||
struct i40iw_srq_uk;
 | 
					 | 
				
			||||||
struct i40iw_qp_uk_init_info;
 | 
					 | 
				
			||||||
struct i40iw_cq_uk_init_info;
 | 
					 | 
				
			||||||
struct i40iw_srq_uk_init_info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_sge {
 | 
					 | 
				
			||||||
	i40iw_tagged_offset tag_off;
 | 
					 | 
				
			||||||
	u32 len;
 | 
					 | 
				
			||||||
	i40iw_stag stag;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define i40iw_sgl struct i40iw_sge *
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_ring {
 | 
					 | 
				
			||||||
	u32 head;
 | 
					 | 
				
			||||||
	u32 tail;
 | 
					 | 
				
			||||||
	u32 size;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cqe {
 | 
					 | 
				
			||||||
	u64 buf[I40IW_CQE_SIZE];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_extended_cqe {
 | 
					 | 
				
			||||||
	u64 buf[I40IW_EXTENDED_CQE_SIZE];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_wqe {
 | 
					 | 
				
			||||||
	u64 buf[I40IW_WQE_SIZE];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_qp_uk_ops;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_addressing_type {
 | 
					 | 
				
			||||||
	I40IW_ADDR_TYPE_ZERO_BASED = 0,
 | 
					 | 
				
			||||||
	I40IW_ADDR_TYPE_VA_BASED = 1,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_ACCESS_FLAGS_LOCALREAD		0x01
 | 
					 | 
				
			||||||
#define I40IW_ACCESS_FLAGS_LOCALWRITE		0x02
 | 
					 | 
				
			||||||
#define I40IW_ACCESS_FLAGS_REMOTEREAD_ONLY	0x04
 | 
					 | 
				
			||||||
#define I40IW_ACCESS_FLAGS_REMOTEREAD		0x05
 | 
					 | 
				
			||||||
#define I40IW_ACCESS_FLAGS_REMOTEWRITE_ONLY	0x08
 | 
					 | 
				
			||||||
#define I40IW_ACCESS_FLAGS_REMOTEWRITE		0x0a
 | 
					 | 
				
			||||||
#define I40IW_ACCESS_FLAGS_BIND_WINDOW		0x10
 | 
					 | 
				
			||||||
#define I40IW_ACCESS_FLAGS_ALL			0x1F
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_RDMA_WRITE	0
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_RDMA_READ		1
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_SEND		3
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_SEND_INV		4
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_SEND_SOL		5
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_SEND_SOL_INV	6
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_REC		7
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_BIND_MW		8
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_FAST_REG_NSMR	9
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_INV_STAG		10
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_RDMA_READ_INV_STAG 11
 | 
					 | 
				
			||||||
#define I40IW_OP_TYPE_NOP		12
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_completion_status {
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_SUCCESS = 0,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_FLUSHED,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_WQE,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_QP_CATASTROPHIC,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_REMOTE_TERMINATION,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_STAG,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_BASE_BOUND_VIOLATION,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_ACCESS_VIOLATION,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_PD_ID,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_WRAP_ERROR,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_STAG_INVALID_PDID,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_RDMA_READ_ZERO_ORD,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_QP_NOT_PRIVLEDGED,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_STAG_NOT_INVALID,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_PHYS_BUFFER_SIZE,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_PHYS_BUFFER_ENTRY,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_FBO,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_LENGTH,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_ACCESS,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_PHYS_BUFFER_LIST_TOO_LONG,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_VIRT_ADDRESS,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_REGION,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_WINDOW,
 | 
					 | 
				
			||||||
	I40IW_COMPL_STATUS_INVALID_TOTAL_LENGTH
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_completion_notify {
 | 
					 | 
				
			||||||
	IW_CQ_COMPL_EVENT = 0,
 | 
					 | 
				
			||||||
	IW_CQ_COMPL_SOLICITED = 1
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_post_send {
 | 
					 | 
				
			||||||
	i40iw_sgl sg_list;
 | 
					 | 
				
			||||||
	u32 num_sges;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_post_inline_send {
 | 
					 | 
				
			||||||
	void *data;
 | 
					 | 
				
			||||||
	u32 len;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_rdma_write {
 | 
					 | 
				
			||||||
	i40iw_sgl lo_sg_list;
 | 
					 | 
				
			||||||
	u32 num_lo_sges;
 | 
					 | 
				
			||||||
	struct i40iw_sge rem_addr;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_inline_rdma_write {
 | 
					 | 
				
			||||||
	void *data;
 | 
					 | 
				
			||||||
	u32 len;
 | 
					 | 
				
			||||||
	struct i40iw_sge rem_addr;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_rdma_read {
 | 
					 | 
				
			||||||
	struct i40iw_sge lo_addr;
 | 
					 | 
				
			||||||
	struct i40iw_sge rem_addr;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_bind_window {
 | 
					 | 
				
			||||||
	i40iw_stag mr_stag;
 | 
					 | 
				
			||||||
	u64 bind_length;
 | 
					 | 
				
			||||||
	void *va;
 | 
					 | 
				
			||||||
	enum i40iw_addressing_type addressing_type;
 | 
					 | 
				
			||||||
	bool enable_reads;
 | 
					 | 
				
			||||||
	bool enable_writes;
 | 
					 | 
				
			||||||
	i40iw_stag mw_stag;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_inv_local_stag {
 | 
					 | 
				
			||||||
	i40iw_stag target_stag;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_post_sq_info {
 | 
					 | 
				
			||||||
	u64 wr_id;
 | 
					 | 
				
			||||||
	u8 op_type;
 | 
					 | 
				
			||||||
	bool signaled;
 | 
					 | 
				
			||||||
	bool read_fence;
 | 
					 | 
				
			||||||
	bool local_fence;
 | 
					 | 
				
			||||||
	bool inline_data;
 | 
					 | 
				
			||||||
	bool defer_flag;
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct i40iw_post_send send;
 | 
					 | 
				
			||||||
		struct i40iw_rdma_write rdma_write;
 | 
					 | 
				
			||||||
		struct i40iw_rdma_read rdma_read;
 | 
					 | 
				
			||||||
		struct i40iw_rdma_read rdma_read_inv;
 | 
					 | 
				
			||||||
		struct i40iw_bind_window bind_window;
 | 
					 | 
				
			||||||
		struct i40iw_inv_local_stag inv_local_stag;
 | 
					 | 
				
			||||||
		struct i40iw_inline_rdma_write inline_rdma_write;
 | 
					 | 
				
			||||||
		struct i40iw_post_inline_send inline_send;
 | 
					 | 
				
			||||||
	} op;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_post_rq_info {
 | 
					 | 
				
			||||||
	u64 wr_id;
 | 
					 | 
				
			||||||
	i40iw_sgl sg_list;
 | 
					 | 
				
			||||||
	u32 num_sges;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cq_poll_info {
 | 
					 | 
				
			||||||
	u64 wr_id;
 | 
					 | 
				
			||||||
	i40iw_qp_handle qp_handle;
 | 
					 | 
				
			||||||
	u32 bytes_xfered;
 | 
					 | 
				
			||||||
	u32 tcp_seq_num;
 | 
					 | 
				
			||||||
	u32 qp_id;
 | 
					 | 
				
			||||||
	i40iw_stag inv_stag;
 | 
					 | 
				
			||||||
	enum i40iw_completion_status comp_status;
 | 
					 | 
				
			||||||
	u16 major_err;
 | 
					 | 
				
			||||||
	u16 minor_err;
 | 
					 | 
				
			||||||
	u8 op_type;
 | 
					 | 
				
			||||||
	bool stag_invalid_set;
 | 
					 | 
				
			||||||
	bool error;
 | 
					 | 
				
			||||||
	bool is_srq;
 | 
					 | 
				
			||||||
	bool solicited_event;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_qp_uk_ops {
 | 
					 | 
				
			||||||
	void (*iw_qp_post_wr)(struct i40iw_qp_uk *);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_rdma_write)(struct i40iw_qp_uk *,
 | 
					 | 
				
			||||||
						struct i40iw_post_sq_info *, bool);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_rdma_read)(struct i40iw_qp_uk *,
 | 
					 | 
				
			||||||
					       struct i40iw_post_sq_info *, bool, bool);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_send)(struct i40iw_qp_uk *,
 | 
					 | 
				
			||||||
					  struct i40iw_post_sq_info *, u32, bool);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_inline_rdma_write)(struct i40iw_qp_uk *,
 | 
					 | 
				
			||||||
						       struct i40iw_post_sq_info *, bool);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_inline_send)(struct i40iw_qp_uk *,
 | 
					 | 
				
			||||||
						 struct i40iw_post_sq_info *, u32, bool);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_stag_local_invalidate)(struct i40iw_qp_uk *,
 | 
					 | 
				
			||||||
							   struct i40iw_post_sq_info *, bool);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_mw_bind)(struct i40iw_qp_uk *,
 | 
					 | 
				
			||||||
					     struct i40iw_post_sq_info *, bool);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_post_receive)(struct i40iw_qp_uk *,
 | 
					 | 
				
			||||||
						  struct i40iw_post_rq_info *);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_post_nop)(struct i40iw_qp_uk *, u64, bool, bool);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cq_ops {
 | 
					 | 
				
			||||||
	void (*iw_cq_request_notification)(struct i40iw_cq_uk *,
 | 
					 | 
				
			||||||
					   enum i40iw_completion_notify);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_cq_poll_completion)(struct i40iw_cq_uk *,
 | 
					 | 
				
			||||||
							struct i40iw_cq_poll_info *);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iw_cq_post_entries)(struct i40iw_cq_uk *, u8 count);
 | 
					 | 
				
			||||||
	void (*iw_cq_clean)(void *, struct i40iw_cq_uk *);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_dev_uk;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_device_uk_ops {
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iwarp_cq_uk_init)(struct i40iw_cq_uk *,
 | 
					 | 
				
			||||||
						   struct i40iw_cq_uk_init_info *);
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*iwarp_qp_uk_init)(struct i40iw_qp_uk *,
 | 
					 | 
				
			||||||
						   struct i40iw_qp_uk_init_info *);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_dev_uk {
 | 
					 | 
				
			||||||
	struct i40iw_device_uk_ops ops_uk;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_sq_uk_wr_trk_info {
 | 
					 | 
				
			||||||
	u64 wrid;
 | 
					 | 
				
			||||||
	u32 wr_len;
 | 
					 | 
				
			||||||
	u8 wqe_size;
 | 
					 | 
				
			||||||
	u8 reserved[3];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_qp_quanta {
 | 
					 | 
				
			||||||
	u64 elem[I40IW_WQE_SIZE];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_qp_uk {
 | 
					 | 
				
			||||||
	struct i40iw_qp_quanta *sq_base;
 | 
					 | 
				
			||||||
	struct i40iw_qp_quanta *rq_base;
 | 
					 | 
				
			||||||
	u32 __iomem *wqe_alloc_reg;
 | 
					 | 
				
			||||||
	struct i40iw_sq_uk_wr_trk_info *sq_wrtrk_array;
 | 
					 | 
				
			||||||
	u64 *rq_wrid_array;
 | 
					 | 
				
			||||||
	u64 *shadow_area;
 | 
					 | 
				
			||||||
	struct i40iw_ring sq_ring;
 | 
					 | 
				
			||||||
	struct i40iw_ring rq_ring;
 | 
					 | 
				
			||||||
	struct i40iw_ring initial_ring;
 | 
					 | 
				
			||||||
	u32 qp_id;
 | 
					 | 
				
			||||||
	u32 sq_size;
 | 
					 | 
				
			||||||
	u32 rq_size;
 | 
					 | 
				
			||||||
	u32 max_sq_frag_cnt;
 | 
					 | 
				
			||||||
	u32 max_rq_frag_cnt;
 | 
					 | 
				
			||||||
	struct i40iw_qp_uk_ops ops;
 | 
					 | 
				
			||||||
	bool use_srq;
 | 
					 | 
				
			||||||
	u8 swqe_polarity;
 | 
					 | 
				
			||||||
	u8 swqe_polarity_deferred;
 | 
					 | 
				
			||||||
	u8 rwqe_polarity;
 | 
					 | 
				
			||||||
	u8 rq_wqe_size;
 | 
					 | 
				
			||||||
	u8 rq_wqe_size_multiplier;
 | 
					 | 
				
			||||||
	bool first_sq_wq;
 | 
					 | 
				
			||||||
	bool deferred_flag;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cq_uk {
 | 
					 | 
				
			||||||
	struct i40iw_cqe *cq_base;
 | 
					 | 
				
			||||||
	u32 __iomem *cqe_alloc_reg;
 | 
					 | 
				
			||||||
	u64 *shadow_area;
 | 
					 | 
				
			||||||
	u32 cq_id;
 | 
					 | 
				
			||||||
	u32 cq_size;
 | 
					 | 
				
			||||||
	struct i40iw_ring cq_ring;
 | 
					 | 
				
			||||||
	u8 polarity;
 | 
					 | 
				
			||||||
	bool avoid_mem_cflct;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct i40iw_cq_ops ops;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_qp_uk_init_info {
 | 
					 | 
				
			||||||
	struct i40iw_qp_quanta *sq;
 | 
					 | 
				
			||||||
	struct i40iw_qp_quanta *rq;
 | 
					 | 
				
			||||||
	u32 __iomem *wqe_alloc_reg;
 | 
					 | 
				
			||||||
	u64 *shadow_area;
 | 
					 | 
				
			||||||
	struct i40iw_sq_uk_wr_trk_info *sq_wrtrk_array;
 | 
					 | 
				
			||||||
	u64 *rq_wrid_array;
 | 
					 | 
				
			||||||
	u32 qp_id;
 | 
					 | 
				
			||||||
	u32 sq_size;
 | 
					 | 
				
			||||||
	u32 rq_size;
 | 
					 | 
				
			||||||
	u32 max_sq_frag_cnt;
 | 
					 | 
				
			||||||
	u32 max_rq_frag_cnt;
 | 
					 | 
				
			||||||
	u32 max_inline_data;
 | 
					 | 
				
			||||||
	int abi_ver;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cq_uk_init_info {
 | 
					 | 
				
			||||||
	u32 __iomem *cqe_alloc_reg;
 | 
					 | 
				
			||||||
	struct i40iw_cqe *cq_base;
 | 
					 | 
				
			||||||
	u64 *shadow_area;
 | 
					 | 
				
			||||||
	u32 cq_size;
 | 
					 | 
				
			||||||
	u32 cq_id;
 | 
					 | 
				
			||||||
	bool avoid_mem_cflct;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_device_init_uk(struct i40iw_dev_uk *dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_qp_post_wr(struct i40iw_qp_uk *qp);
 | 
					 | 
				
			||||||
u64 *i40iw_qp_get_next_send_wqe(struct i40iw_qp_uk *qp, u32 *wqe_idx,
 | 
					 | 
				
			||||||
				u8 wqe_size,
 | 
					 | 
				
			||||||
				u32 total_size,
 | 
					 | 
				
			||||||
				u64 wr_id
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
u64 *i40iw_qp_get_next_recv_wqe(struct i40iw_qp_uk *qp, u32 *wqe_idx);
 | 
					 | 
				
			||||||
u64 *i40iw_qp_get_next_srq_wqe(struct i40iw_srq_uk *srq, u32 *wqe_idx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_cq_uk_init(struct i40iw_cq_uk *cq,
 | 
					 | 
				
			||||||
					struct i40iw_cq_uk_init_info *info);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_qp_uk_init(struct i40iw_qp_uk *qp,
 | 
					 | 
				
			||||||
					struct i40iw_qp_uk_init_info *info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i40iw_clean_cq(void *queue, struct i40iw_cq_uk *cq);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_nop(struct i40iw_qp_uk *qp, u64 wr_id,
 | 
					 | 
				
			||||||
				 bool signaled, bool post_sq);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_fragcnt_to_wqesize_sq(u32 frag_cnt, u8 *wqe_size);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_fragcnt_to_wqesize_rq(u32 frag_cnt, u8 *wqe_size);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_inline_data_size_to_wqesize(u32 data_size,
 | 
					 | 
				
			||||||
							 u8 *wqe_size);
 | 
					 | 
				
			||||||
void i40iw_get_wqe_shift(u32 sge, u32 inline_data, u8 *shift);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_get_sqdepth(u32 sq_size, u8 shift, u32 *sqdepth);
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_get_rqdepth(u32 rq_size, u8 shift, u32 *rqdepth);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,179 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_VERBS_H
 | 
					 | 
				
			||||||
#define I40IW_VERBS_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_ucontext {
 | 
					 | 
				
			||||||
	struct ib_ucontext ibucontext;
 | 
					 | 
				
			||||||
	struct i40iw_device *iwdev;
 | 
					 | 
				
			||||||
	struct list_head cq_reg_mem_list;
 | 
					 | 
				
			||||||
	spinlock_t cq_reg_mem_list_lock; /* memory list for cq's */
 | 
					 | 
				
			||||||
	struct list_head qp_reg_mem_list;
 | 
					 | 
				
			||||||
	spinlock_t qp_reg_mem_list_lock; /* memory list for qp's */
 | 
					 | 
				
			||||||
	int abi_ver;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_pd {
 | 
					 | 
				
			||||||
	struct ib_pd ibpd;
 | 
					 | 
				
			||||||
	struct i40iw_sc_pd sc_pd;
 | 
					 | 
				
			||||||
	atomic_t usecount;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_hmc_pble {
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		u32 idx;
 | 
					 | 
				
			||||||
		dma_addr_t addr;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cq_mr {
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pble cq_pbl;
 | 
					 | 
				
			||||||
	dma_addr_t shadow;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_qp_mr {
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pble sq_pbl;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_pble rq_pbl;
 | 
					 | 
				
			||||||
	dma_addr_t shadow;
 | 
					 | 
				
			||||||
	struct page *sq_page;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_pbl {
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct i40iw_qp_mr qp_mr;
 | 
					 | 
				
			||||||
		struct i40iw_cq_mr cq_mr;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool pbl_allocated;
 | 
					 | 
				
			||||||
	bool on_list;
 | 
					 | 
				
			||||||
	u64 user_base;
 | 
					 | 
				
			||||||
	struct i40iw_pble_alloc pble_alloc;
 | 
					 | 
				
			||||||
	struct i40iw_mr *iwmr;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAX_SAVE_PAGE_ADDRS     4
 | 
					 | 
				
			||||||
struct i40iw_mr {
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct ib_mr ibmr;
 | 
					 | 
				
			||||||
		struct ib_mw ibmw;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	struct ib_umem *region;
 | 
					 | 
				
			||||||
	u16 type;
 | 
					 | 
				
			||||||
	u32 page_cnt;
 | 
					 | 
				
			||||||
	u64 page_size;
 | 
					 | 
				
			||||||
	u32 npages;
 | 
					 | 
				
			||||||
	u32 stag;
 | 
					 | 
				
			||||||
	u64 length;
 | 
					 | 
				
			||||||
	u64 pgaddrmem[MAX_SAVE_PAGE_ADDRS];
 | 
					 | 
				
			||||||
	struct i40iw_pbl iwpbl;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_cq {
 | 
					 | 
				
			||||||
	struct ib_cq ibcq;
 | 
					 | 
				
			||||||
	struct i40iw_sc_cq sc_cq;
 | 
					 | 
				
			||||||
	u16 cq_head;
 | 
					 | 
				
			||||||
	u16 cq_size;
 | 
					 | 
				
			||||||
	u16 cq_number;
 | 
					 | 
				
			||||||
	bool user_mode;
 | 
					 | 
				
			||||||
	u32 polled_completions;
 | 
					 | 
				
			||||||
	u32 cq_mem_size;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem kmem;
 | 
					 | 
				
			||||||
	spinlock_t lock; /* for poll cq */
 | 
					 | 
				
			||||||
	struct i40iw_pbl *iwpbl;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct disconn_work {
 | 
					 | 
				
			||||||
	struct work_struct work;
 | 
					 | 
				
			||||||
	struct i40iw_qp *iwqp;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct iw_cm_id;
 | 
					 | 
				
			||||||
struct ietf_mpa_frame;
 | 
					 | 
				
			||||||
struct i40iw_ud_file;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_qp_kmode {
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem dma_mem;
 | 
					 | 
				
			||||||
	u64 *wrid_mem;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_qp {
 | 
					 | 
				
			||||||
	struct ib_qp ibqp;
 | 
					 | 
				
			||||||
	struct i40iw_sc_qp sc_qp;
 | 
					 | 
				
			||||||
	struct i40iw_device *iwdev;
 | 
					 | 
				
			||||||
	struct i40iw_cq *iwscq;
 | 
					 | 
				
			||||||
	struct i40iw_cq *iwrcq;
 | 
					 | 
				
			||||||
	struct i40iw_pd *iwpd;
 | 
					 | 
				
			||||||
	struct i40iw_qp_host_ctx_info ctx_info;
 | 
					 | 
				
			||||||
	struct i40iwarp_offload_info iwarp_info;
 | 
					 | 
				
			||||||
	void *allocated_buffer;
 | 
					 | 
				
			||||||
	refcount_t refcount;
 | 
					 | 
				
			||||||
	struct iw_cm_id *cm_id;
 | 
					 | 
				
			||||||
	void *cm_node;
 | 
					 | 
				
			||||||
	struct ib_mr *lsmm_mr;
 | 
					 | 
				
			||||||
	struct work_struct work;
 | 
					 | 
				
			||||||
	enum ib_qp_state ibqp_state;
 | 
					 | 
				
			||||||
	u32 iwarp_state;
 | 
					 | 
				
			||||||
	u32 qp_mem_size;
 | 
					 | 
				
			||||||
	u32 last_aeq;
 | 
					 | 
				
			||||||
	atomic_t close_timer_started;
 | 
					 | 
				
			||||||
	spinlock_t lock; /* for post work requests */
 | 
					 | 
				
			||||||
	struct i40iw_qp_context *iwqp_context;
 | 
					 | 
				
			||||||
	void *pbl_vbase;
 | 
					 | 
				
			||||||
	dma_addr_t pbl_pbase;
 | 
					 | 
				
			||||||
	struct page *page;
 | 
					 | 
				
			||||||
	u8 active_conn:1;
 | 
					 | 
				
			||||||
	u8 user_mode:1;
 | 
					 | 
				
			||||||
	u8 hte_added:1;
 | 
					 | 
				
			||||||
	u8 flush_issued:1;
 | 
					 | 
				
			||||||
	u8 destroyed:1;
 | 
					 | 
				
			||||||
	u8 sig_all:1;
 | 
					 | 
				
			||||||
	u8 pau_mode:1;
 | 
					 | 
				
			||||||
	u8 rsvd:1;
 | 
					 | 
				
			||||||
	u16 term_sq_flush_code;
 | 
					 | 
				
			||||||
	u16 term_rq_flush_code;
 | 
					 | 
				
			||||||
	u8 hw_iwarp_state;
 | 
					 | 
				
			||||||
	u8 hw_tcp_state;
 | 
					 | 
				
			||||||
	struct i40iw_qp_kmode kqp;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem host_ctx;
 | 
					 | 
				
			||||||
	struct timer_list terminate_timer;
 | 
					 | 
				
			||||||
	struct i40iw_pbl iwpbl;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem q2_ctx_mem;
 | 
					 | 
				
			||||||
	struct i40iw_dma_mem ietf_mem;
 | 
					 | 
				
			||||||
	struct completion sq_drained;
 | 
					 | 
				
			||||||
	struct completion rq_drained;
 | 
					 | 
				
			||||||
	struct completion free_qp;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,85 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "i40iw_osdep.h"
 | 
					 | 
				
			||||||
#include "i40iw_register.h"
 | 
					 | 
				
			||||||
#include "i40iw_status.h"
 | 
					 | 
				
			||||||
#include "i40iw_hmc.h"
 | 
					 | 
				
			||||||
#include "i40iw_d.h"
 | 
					 | 
				
			||||||
#include "i40iw_type.h"
 | 
					 | 
				
			||||||
#include "i40iw_p.h"
 | 
					 | 
				
			||||||
#include "i40iw_vf.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_manage_vf_pble_bp - manage vf pble
 | 
					 | 
				
			||||||
 * @cqp: cqp for cqp' sq wqe
 | 
					 | 
				
			||||||
 * @info: pble info
 | 
					 | 
				
			||||||
 * @scratch: pointer for completion
 | 
					 | 
				
			||||||
 * @post_sq: to post and ring
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_manage_vf_pble_bp(struct i40iw_sc_cqp *cqp,
 | 
					 | 
				
			||||||
					       struct i40iw_manage_vf_pble_info *info,
 | 
					 | 
				
			||||||
					       u64 scratch,
 | 
					 | 
				
			||||||
					       bool post_sq)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u64 *wqe;
 | 
					 | 
				
			||||||
	u64 temp, header, pd_pl_pba = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
 | 
					 | 
				
			||||||
	if (!wqe)
 | 
					 | 
				
			||||||
		return I40IW_ERR_RING_FULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	temp = LS_64(info->pd_entry_cnt, I40IW_CQPSQ_MVPBP_PD_ENTRY_CNT) |
 | 
					 | 
				
			||||||
	    LS_64(info->first_pd_index, I40IW_CQPSQ_MVPBP_FIRST_PD_INX) |
 | 
					 | 
				
			||||||
	    LS_64(info->sd_index, I40IW_CQPSQ_MVPBP_SD_INX);
 | 
					 | 
				
			||||||
	set_64bit_val(wqe, 16, temp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	header = LS_64((info->inv_pd_ent ? 1 : 0), I40IW_CQPSQ_MVPBP_INV_PD_ENT) |
 | 
					 | 
				
			||||||
	    LS_64(I40IW_CQP_OP_MANAGE_VF_PBLE_BP, I40IW_CQPSQ_OPCODE) |
 | 
					 | 
				
			||||||
	    LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);
 | 
					 | 
				
			||||||
	set_64bit_val(wqe, 24, header);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pd_pl_pba = LS_64(info->pd_pl_pba >> 3, I40IW_CQPSQ_MVPBP_PD_PLPBA);
 | 
					 | 
				
			||||||
	set_64bit_val(wqe, 32, pd_pl_pba);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "MANAGE VF_PBLE_BP WQE", wqe, I40IW_CQP_WQE_SIZE * 8);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (post_sq)
 | 
					 | 
				
			||||||
		i40iw_sc_cqp_post_sq(cqp);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const struct i40iw_vf_cqp_ops iw_vf_cqp_ops = {
 | 
					 | 
				
			||||||
	i40iw_manage_vf_pble_bp
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,62 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_VF_H
 | 
					 | 
				
			||||||
#define I40IW_VF_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_sc_cqp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_manage_vf_pble_info {
 | 
					 | 
				
			||||||
	u32 sd_index;
 | 
					 | 
				
			||||||
	u16 first_pd_index;
 | 
					 | 
				
			||||||
	u16 pd_entry_cnt;
 | 
					 | 
				
			||||||
	u8 inv_pd_ent;
 | 
					 | 
				
			||||||
	u64 pd_pl_pba;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_vf_cqp_ops {
 | 
					 | 
				
			||||||
	enum i40iw_status_code (*manage_vf_pble_bp)(struct i40iw_sc_cqp *,
 | 
					 | 
				
			||||||
						    struct i40iw_manage_vf_pble_info *,
 | 
					 | 
				
			||||||
						    u64,
 | 
					 | 
				
			||||||
						    bool);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_manage_vf_pble_bp(struct i40iw_sc_cqp *cqp,
 | 
					 | 
				
			||||||
					       struct i40iw_manage_vf_pble_info *info,
 | 
					 | 
				
			||||||
					       u64 scratch,
 | 
					 | 
				
			||||||
					       bool post_sq);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern const struct i40iw_vf_cqp_ops iw_vf_cqp_ops;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,759 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "i40iw_osdep.h"
 | 
					 | 
				
			||||||
#include "i40iw_register.h"
 | 
					 | 
				
			||||||
#include "i40iw_status.h"
 | 
					 | 
				
			||||||
#include "i40iw_hmc.h"
 | 
					 | 
				
			||||||
#include "i40iw_d.h"
 | 
					 | 
				
			||||||
#include "i40iw_type.h"
 | 
					 | 
				
			||||||
#include "i40iw_p.h"
 | 
					 | 
				
			||||||
#include "i40iw_virtchnl.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * vchnl_vf_send_get_ver_req - Request Channel version
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vchnl_req: Virtual channel message request pointer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code vchnl_vf_send_get_ver_req(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
							struct i40iw_virtchnl_req *vchnl_req)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = I40IW_ERR_NOT_READY;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_op_buf *vchnl_msg = vchnl_req->vchnl_msg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!dev->vchnl_up)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(vchnl_msg, 0, sizeof(*vchnl_msg));
 | 
					 | 
				
			||||||
	vchnl_msg->iw_chnl_op_ctx = (uintptr_t)vchnl_req;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_chnl_buf_len = sizeof(*vchnl_msg);
 | 
					 | 
				
			||||||
	vchnl_msg->iw_op_code = I40IW_VCHNL_OP_GET_VER;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_op_ver = I40IW_VCHNL_OP_GET_VER_V0;
 | 
					 | 
				
			||||||
	ret_code = dev->vchnl_if.vchnl_send(dev, 0, (u8 *)vchnl_msg, vchnl_msg->iw_chnl_buf_len);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: virt channel send failed 0x%x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
	return ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * vchnl_vf_send_get_hmc_fcn_req - Request HMC Function from VF
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vchnl_req: Virtual channel message request pointer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code vchnl_vf_send_get_hmc_fcn_req(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
							    struct i40iw_virtchnl_req *vchnl_req)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = I40IW_ERR_NOT_READY;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_op_buf *vchnl_msg = vchnl_req->vchnl_msg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!dev->vchnl_up)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(vchnl_msg, 0, sizeof(*vchnl_msg));
 | 
					 | 
				
			||||||
	vchnl_msg->iw_chnl_op_ctx = (uintptr_t)vchnl_req;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_chnl_buf_len = sizeof(*vchnl_msg);
 | 
					 | 
				
			||||||
	vchnl_msg->iw_op_code = I40IW_VCHNL_OP_GET_HMC_FCN;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_op_ver = I40IW_VCHNL_OP_GET_HMC_FCN_V0;
 | 
					 | 
				
			||||||
	ret_code = dev->vchnl_if.vchnl_send(dev, 0, (u8 *)vchnl_msg, vchnl_msg->iw_chnl_buf_len);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: virt channel send failed 0x%x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
	return ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * vchnl_vf_send_get_pe_stats_req - Request PE stats from VF
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vchnl_req: Virtual channel message request pointer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code vchnl_vf_send_get_pe_stats_req(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
							     struct i40iw_virtchnl_req  *vchnl_req)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = I40IW_ERR_NOT_READY;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_op_buf *vchnl_msg = vchnl_req->vchnl_msg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!dev->vchnl_up)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(vchnl_msg, 0, sizeof(*vchnl_msg));
 | 
					 | 
				
			||||||
	vchnl_msg->iw_chnl_op_ctx = (uintptr_t)vchnl_req;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_chnl_buf_len = sizeof(*vchnl_msg) + sizeof(struct i40iw_dev_hw_stats) - 1;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_op_code = I40IW_VCHNL_OP_GET_STATS;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_op_ver = I40IW_VCHNL_OP_GET_STATS_V0;
 | 
					 | 
				
			||||||
	ret_code = dev->vchnl_if.vchnl_send(dev, 0, (u8 *)vchnl_msg, vchnl_msg->iw_chnl_buf_len);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: virt channel send failed 0x%x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
	return ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * vchnl_vf_send_add_hmc_objs_req - Add HMC objects
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vchnl_req: Virtual channel message request pointer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code vchnl_vf_send_add_hmc_objs_req(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
							     struct i40iw_virtchnl_req *vchnl_req,
 | 
					 | 
				
			||||||
							     enum i40iw_hmc_rsrc_type rsrc_type,
 | 
					 | 
				
			||||||
							     u32 start_index,
 | 
					 | 
				
			||||||
							     u32 rsrc_count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = I40IW_ERR_NOT_READY;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_op_buf *vchnl_msg = vchnl_req->vchnl_msg;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_hmc_obj_range *add_hmc_obj;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!dev->vchnl_up)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	add_hmc_obj = (struct i40iw_virtchnl_hmc_obj_range *)vchnl_msg->iw_chnl_buf;
 | 
					 | 
				
			||||||
	memset(vchnl_msg, 0, sizeof(*vchnl_msg));
 | 
					 | 
				
			||||||
	memset(add_hmc_obj, 0, sizeof(*add_hmc_obj));
 | 
					 | 
				
			||||||
	vchnl_msg->iw_chnl_op_ctx = (uintptr_t)vchnl_req;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_chnl_buf_len = sizeof(*vchnl_msg) + sizeof(struct i40iw_virtchnl_hmc_obj_range) - 1;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_op_code = I40IW_VCHNL_OP_ADD_HMC_OBJ_RANGE;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_op_ver = I40IW_VCHNL_OP_ADD_HMC_OBJ_RANGE_V0;
 | 
					 | 
				
			||||||
	add_hmc_obj->obj_type = (u16)rsrc_type;
 | 
					 | 
				
			||||||
	add_hmc_obj->start_index = start_index;
 | 
					 | 
				
			||||||
	add_hmc_obj->obj_count = rsrc_count;
 | 
					 | 
				
			||||||
	ret_code = dev->vchnl_if.vchnl_send(dev, 0, (u8 *)vchnl_msg, vchnl_msg->iw_chnl_buf_len);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: virt channel send failed 0x%x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
	return ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * vchnl_vf_send_del_hmc_objs_req - del HMC objects
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vchnl_req: Virtual channel message request pointer
 | 
					 | 
				
			||||||
 * @rsrc_type: resource type to delete
 | 
					 | 
				
			||||||
 * @start_index: starting index for resource
 | 
					 | 
				
			||||||
 * @rsrc_count: number of resource type to delete
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static enum i40iw_status_code vchnl_vf_send_del_hmc_objs_req(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
							     struct i40iw_virtchnl_req *vchnl_req,
 | 
					 | 
				
			||||||
							     enum i40iw_hmc_rsrc_type rsrc_type,
 | 
					 | 
				
			||||||
							     u32 start_index,
 | 
					 | 
				
			||||||
							     u32 rsrc_count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = I40IW_ERR_NOT_READY;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_op_buf *vchnl_msg = vchnl_req->vchnl_msg;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_hmc_obj_range *add_hmc_obj;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!dev->vchnl_up)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	add_hmc_obj = (struct i40iw_virtchnl_hmc_obj_range *)vchnl_msg->iw_chnl_buf;
 | 
					 | 
				
			||||||
	memset(vchnl_msg, 0, sizeof(*vchnl_msg));
 | 
					 | 
				
			||||||
	memset(add_hmc_obj, 0, sizeof(*add_hmc_obj));
 | 
					 | 
				
			||||||
	vchnl_msg->iw_chnl_op_ctx = (uintptr_t)vchnl_req;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_chnl_buf_len = sizeof(*vchnl_msg) + sizeof(struct i40iw_virtchnl_hmc_obj_range) - 1;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_op_code = I40IW_VCHNL_OP_DEL_HMC_OBJ_RANGE;
 | 
					 | 
				
			||||||
	vchnl_msg->iw_op_ver = I40IW_VCHNL_OP_DEL_HMC_OBJ_RANGE_V0;
 | 
					 | 
				
			||||||
	add_hmc_obj->obj_type = (u16)rsrc_type;
 | 
					 | 
				
			||||||
	add_hmc_obj->start_index = start_index;
 | 
					 | 
				
			||||||
	add_hmc_obj->obj_count = rsrc_count;
 | 
					 | 
				
			||||||
	ret_code = dev->vchnl_if.vchnl_send(dev, 0, (u8 *)vchnl_msg, vchnl_msg->iw_chnl_buf_len);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: virt channel send failed 0x%x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
	return ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * vchnl_pf_send_get_ver_resp - Send channel version to VF
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vf_id: Virtual function ID associated with the message
 | 
					 | 
				
			||||||
 * @vchnl_msg: Virtual channel message buffer pointer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void vchnl_pf_send_get_ver_resp(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
				       u32 vf_id,
 | 
					 | 
				
			||||||
				       struct i40iw_virtchnl_op_buf *vchnl_msg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
	u8 resp_buffer[sizeof(struct i40iw_virtchnl_resp_buf) + sizeof(u32) - 1];
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_resp_buf *vchnl_msg_resp = (struct i40iw_virtchnl_resp_buf *)resp_buffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(resp_buffer, 0, sizeof(*resp_buffer));
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_chnl_op_ctx = vchnl_msg->iw_chnl_op_ctx;
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_chnl_buf_len = sizeof(resp_buffer);
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_op_ret_code = I40IW_SUCCESS;
 | 
					 | 
				
			||||||
	*((u32 *)vchnl_msg_resp->iw_chnl_buf) = I40IW_VCHNL_CHNL_VER_V0;
 | 
					 | 
				
			||||||
	ret_code = dev->vchnl_if.vchnl_send(dev, vf_id, resp_buffer, sizeof(resp_buffer));
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: virt channel send failed 0x%x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * vchnl_pf_send_get_hmc_fcn_resp - Send HMC Function to VF
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vf_id: Virtual function ID associated with the message
 | 
					 | 
				
			||||||
 * @vchnl_msg: Virtual channel message buffer pointer
 | 
					 | 
				
			||||||
 * @hmc_fcn: HMC function index pointer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void vchnl_pf_send_get_hmc_fcn_resp(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					   u32 vf_id,
 | 
					 | 
				
			||||||
					   struct i40iw_virtchnl_op_buf *vchnl_msg,
 | 
					 | 
				
			||||||
					   u16 hmc_fcn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
	u8 resp_buffer[sizeof(struct i40iw_virtchnl_resp_buf) + sizeof(u16) - 1];
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_resp_buf *vchnl_msg_resp = (struct i40iw_virtchnl_resp_buf *)resp_buffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(resp_buffer, 0, sizeof(*resp_buffer));
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_chnl_op_ctx = vchnl_msg->iw_chnl_op_ctx;
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_chnl_buf_len = sizeof(resp_buffer);
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_op_ret_code = I40IW_SUCCESS;
 | 
					 | 
				
			||||||
	*((u16 *)vchnl_msg_resp->iw_chnl_buf) = hmc_fcn;
 | 
					 | 
				
			||||||
	ret_code = dev->vchnl_if.vchnl_send(dev, vf_id, resp_buffer, sizeof(resp_buffer));
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: virt channel send failed 0x%x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * vchnl_pf_send_get_pe_stats_resp - Send PE Stats to VF
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vf_id: Virtual function ID associated with the message
 | 
					 | 
				
			||||||
 * @vchnl_msg: Virtual channel message buffer pointer
 | 
					 | 
				
			||||||
 * @hw_stats: HW Stats struct
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void vchnl_pf_send_get_pe_stats_resp(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					    u32 vf_id,
 | 
					 | 
				
			||||||
					    struct i40iw_virtchnl_op_buf *vchnl_msg,
 | 
					 | 
				
			||||||
					    struct i40iw_dev_hw_stats *hw_stats)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
	u8 resp_buffer[sizeof(struct i40iw_virtchnl_resp_buf) + sizeof(struct i40iw_dev_hw_stats) - 1];
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_resp_buf *vchnl_msg_resp = (struct i40iw_virtchnl_resp_buf *)resp_buffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(resp_buffer, 0, sizeof(*resp_buffer));
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_chnl_op_ctx = vchnl_msg->iw_chnl_op_ctx;
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_chnl_buf_len = sizeof(resp_buffer);
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_op_ret_code = I40IW_SUCCESS;
 | 
					 | 
				
			||||||
	*((struct i40iw_dev_hw_stats *)vchnl_msg_resp->iw_chnl_buf) = *hw_stats;
 | 
					 | 
				
			||||||
	ret_code = dev->vchnl_if.vchnl_send(dev, vf_id, resp_buffer, sizeof(resp_buffer));
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: virt channel send failed 0x%x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * vchnl_pf_send_error_resp - Send an error response to VF
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vf_id: Virtual function ID associated with the message
 | 
					 | 
				
			||||||
 * @vchnl_msg: Virtual channel message buffer pointer
 | 
					 | 
				
			||||||
 * @op_ret_code: I40IW_ERR_* status code
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void vchnl_pf_send_error_resp(struct i40iw_sc_dev *dev, u32 vf_id,
 | 
					 | 
				
			||||||
				     struct i40iw_virtchnl_op_buf *vchnl_msg,
 | 
					 | 
				
			||||||
				     u16 op_ret_code)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
	u8 resp_buffer[sizeof(struct i40iw_virtchnl_resp_buf)];
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_resp_buf *vchnl_msg_resp = (struct i40iw_virtchnl_resp_buf *)resp_buffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(resp_buffer, 0, sizeof(resp_buffer));
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_chnl_op_ctx = vchnl_msg->iw_chnl_op_ctx;
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_chnl_buf_len = sizeof(resp_buffer);
 | 
					 | 
				
			||||||
	vchnl_msg_resp->iw_op_ret_code = (u16)op_ret_code;
 | 
					 | 
				
			||||||
	ret_code = dev->vchnl_if.vchnl_send(dev, vf_id, resp_buffer, sizeof(resp_buffer));
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: virt channel send failed 0x%x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * pf_cqp_get_hmc_fcn_callback - Callback for Get HMC Fcn
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @callback_param: unused CQP callback parameter
 | 
					 | 
				
			||||||
 * @cqe_info: CQE information pointer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void pf_cqp_get_hmc_fcn_callback(struct i40iw_sc_dev *dev, void *callback_param,
 | 
					 | 
				
			||||||
					struct i40iw_ccq_cqe_info *cqe_info)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_vfdev *vf_dev = callback_param;
 | 
					 | 
				
			||||||
	struct i40iw_virt_mem vf_dev_mem;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (cqe_info->error) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "CQP Completion Error on Get HMC Function.  Maj = 0x%04x, Minor = 0x%04x\n",
 | 
					 | 
				
			||||||
			    cqe_info->maj_err_code, cqe_info->min_err_code);
 | 
					 | 
				
			||||||
		dev->vf_dev[vf_dev->iw_vf_idx] = NULL;
 | 
					 | 
				
			||||||
		vchnl_pf_send_error_resp(dev, vf_dev->vf_id, &vf_dev->vf_msg_buffer.vchnl_msg,
 | 
					 | 
				
			||||||
					 (u16)I40IW_ERR_CQP_COMPL_ERROR);
 | 
					 | 
				
			||||||
		vf_dev_mem.va = vf_dev;
 | 
					 | 
				
			||||||
		vf_dev_mem.size = sizeof(*vf_dev);
 | 
					 | 
				
			||||||
		i40iw_free_virt_mem(dev->hw, &vf_dev_mem);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "CQP Completion Operation Return information = 0x%08x\n",
 | 
					 | 
				
			||||||
			    cqe_info->op_ret_val);
 | 
					 | 
				
			||||||
		vf_dev->pmf_index = (u16)cqe_info->op_ret_val;
 | 
					 | 
				
			||||||
		vf_dev->msg_count--;
 | 
					 | 
				
			||||||
		vchnl_pf_send_get_hmc_fcn_resp(dev,
 | 
					 | 
				
			||||||
					       vf_dev->vf_id,
 | 
					 | 
				
			||||||
					       &vf_dev->vf_msg_buffer.vchnl_msg,
 | 
					 | 
				
			||||||
					       vf_dev->pmf_index);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * pf_add_hmc_obj_callback - Callback for Add HMC Object
 | 
					 | 
				
			||||||
 * @work_vf_dev: pointer to the VF Device
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void pf_add_hmc_obj_callback(void *work_vf_dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_vfdev *vf_dev = (struct i40iw_vfdev *)work_vf_dev;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info = &vf_dev->hmc_info;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_op_buf *vchnl_msg = &vf_dev->vf_msg_buffer.vchnl_msg;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_create_obj_info info;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_hmc_obj_range *add_hmc_obj;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!vf_dev->pf_hmc_initialized) {
 | 
					 | 
				
			||||||
		ret_code = i40iw_pf_init_vfhmc(vf_dev->pf_dev, (u8)vf_dev->pmf_index, NULL);
 | 
					 | 
				
			||||||
		if (ret_code)
 | 
					 | 
				
			||||||
			goto add_out;
 | 
					 | 
				
			||||||
		vf_dev->pf_hmc_initialized = true;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	add_hmc_obj = (struct i40iw_virtchnl_hmc_obj_range *)vchnl_msg->iw_chnl_buf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(&info, 0, sizeof(info));
 | 
					 | 
				
			||||||
	info.hmc_info = hmc_info;
 | 
					 | 
				
			||||||
	info.is_pf = false;
 | 
					 | 
				
			||||||
	info.rsrc_type = (u32)add_hmc_obj->obj_type;
 | 
					 | 
				
			||||||
	info.entry_type = (info.rsrc_type == I40IW_HMC_IW_PBLE) ? I40IW_SD_TYPE_PAGED : I40IW_SD_TYPE_DIRECT;
 | 
					 | 
				
			||||||
	info.start_idx = add_hmc_obj->start_index;
 | 
					 | 
				
			||||||
	info.count = add_hmc_obj->obj_count;
 | 
					 | 
				
			||||||
	i40iw_debug(vf_dev->pf_dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
		    "I40IW_VCHNL_OP_ADD_HMC_OBJ_RANGE.  Add %u type %u objects\n",
 | 
					 | 
				
			||||||
		    info.count, info.rsrc_type);
 | 
					 | 
				
			||||||
	ret_code = i40iw_sc_create_hmc_obj(vf_dev->pf_dev, &info);
 | 
					 | 
				
			||||||
	if (!ret_code)
 | 
					 | 
				
			||||||
		vf_dev->hmc_info.hmc_obj[add_hmc_obj->obj_type].cnt = add_hmc_obj->obj_count;
 | 
					 | 
				
			||||||
add_out:
 | 
					 | 
				
			||||||
	vf_dev->msg_count--;
 | 
					 | 
				
			||||||
	vchnl_pf_send_error_resp(vf_dev->pf_dev, vf_dev->vf_id, vchnl_msg, (u16)ret_code);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * pf_del_hmc_obj_callback - Callback for delete HMC Object
 | 
					 | 
				
			||||||
 * @work_vf_dev: pointer to the VF Device
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void pf_del_hmc_obj_callback(void *work_vf_dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_vfdev *vf_dev = (struct i40iw_vfdev *)work_vf_dev;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_info *hmc_info = &vf_dev->hmc_info;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_op_buf *vchnl_msg = &vf_dev->vf_msg_buffer.vchnl_msg;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_del_obj_info info;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_hmc_obj_range *del_hmc_obj;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code = I40IW_SUCCESS;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!vf_dev->pf_hmc_initialized)
 | 
					 | 
				
			||||||
		goto del_out;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	del_hmc_obj = (struct i40iw_virtchnl_hmc_obj_range *)vchnl_msg->iw_chnl_buf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(&info, 0, sizeof(info));
 | 
					 | 
				
			||||||
	info.hmc_info = hmc_info;
 | 
					 | 
				
			||||||
	info.is_pf = false;
 | 
					 | 
				
			||||||
	info.rsrc_type = (u32)del_hmc_obj->obj_type;
 | 
					 | 
				
			||||||
	info.start_idx = del_hmc_obj->start_index;
 | 
					 | 
				
			||||||
	info.count = del_hmc_obj->obj_count;
 | 
					 | 
				
			||||||
	i40iw_debug(vf_dev->pf_dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
		    "I40IW_VCHNL_OP_DEL_HMC_OBJ_RANGE.  Delete %u type %u objects\n",
 | 
					 | 
				
			||||||
		    info.count, info.rsrc_type);
 | 
					 | 
				
			||||||
	ret_code = i40iw_sc_del_hmc_obj(vf_dev->pf_dev, &info, false);
 | 
					 | 
				
			||||||
del_out:
 | 
					 | 
				
			||||||
	vf_dev->msg_count--;
 | 
					 | 
				
			||||||
	vchnl_pf_send_error_resp(vf_dev->pf_dev, vf_dev->vf_id, vchnl_msg, (u16)ret_code);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_vf_init_pestat - Initialize stats for VF
 | 
					 | 
				
			||||||
 * @dev: pointer to the VF Device
 | 
					 | 
				
			||||||
 * @stats: Statistics structure pointer
 | 
					 | 
				
			||||||
 * @index: Stats index
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void i40iw_vf_init_pestat(struct i40iw_sc_dev *dev, struct i40iw_vsi_pestat *stats, u16 index)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stats->hw = dev->hw;
 | 
					 | 
				
			||||||
	i40iw_hw_stats_init(stats, (u8)index, false);
 | 
					 | 
				
			||||||
	spin_lock_init(&stats->lock);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_vchnl_recv_pf - Receive PF virtual channel messages
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vf_id: Virtual function ID associated with the message
 | 
					 | 
				
			||||||
 * @msg: Virtual channel message buffer pointer
 | 
					 | 
				
			||||||
 * @len: Length of the virtual channels message
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_recv_pf(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					   u32 vf_id,
 | 
					 | 
				
			||||||
					   u8 *msg,
 | 
					 | 
				
			||||||
					   u16 len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_op_buf *vchnl_msg = (struct i40iw_virtchnl_op_buf *)msg;
 | 
					 | 
				
			||||||
	struct i40iw_vfdev *vf_dev = NULL;
 | 
					 | 
				
			||||||
	struct i40iw_hmc_fcn_info hmc_fcn_info;
 | 
					 | 
				
			||||||
	u16 iw_vf_idx;
 | 
					 | 
				
			||||||
	u16 first_avail_iw_vf = I40IW_MAX_PE_ENABLED_VF_COUNT;
 | 
					 | 
				
			||||||
	struct i40iw_virt_mem vf_dev_mem;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_work_info work_info;
 | 
					 | 
				
			||||||
	struct i40iw_vsi_pestat *stats;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!dev || !msg || !len)
 | 
					 | 
				
			||||||
		return I40IW_ERR_PARAM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!dev->vchnl_up)
 | 
					 | 
				
			||||||
		return I40IW_ERR_NOT_READY;
 | 
					 | 
				
			||||||
	if (vchnl_msg->iw_op_code == I40IW_VCHNL_OP_GET_VER) {
 | 
					 | 
				
			||||||
		vchnl_pf_send_get_ver_resp(dev, vf_id, vchnl_msg);
 | 
					 | 
				
			||||||
		return I40IW_SUCCESS;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for (iw_vf_idx = 0; iw_vf_idx < I40IW_MAX_PE_ENABLED_VF_COUNT; iw_vf_idx++) {
 | 
					 | 
				
			||||||
		if (!dev->vf_dev[iw_vf_idx]) {
 | 
					 | 
				
			||||||
			if (first_avail_iw_vf == I40IW_MAX_PE_ENABLED_VF_COUNT)
 | 
					 | 
				
			||||||
				first_avail_iw_vf = iw_vf_idx;
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (dev->vf_dev[iw_vf_idx]->vf_id == vf_id) {
 | 
					 | 
				
			||||||
			vf_dev = dev->vf_dev[iw_vf_idx];
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (vf_dev) {
 | 
					 | 
				
			||||||
		if (!vf_dev->msg_count) {
 | 
					 | 
				
			||||||
			vf_dev->msg_count++;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
				    "VF%u already has a channel message in progress.\n",
 | 
					 | 
				
			||||||
				    vf_id);
 | 
					 | 
				
			||||||
			return I40IW_SUCCESS;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	switch (vchnl_msg->iw_op_code) {
 | 
					 | 
				
			||||||
	case I40IW_VCHNL_OP_GET_HMC_FCN:
 | 
					 | 
				
			||||||
		if (!vf_dev &&
 | 
					 | 
				
			||||||
		    (first_avail_iw_vf != I40IW_MAX_PE_ENABLED_VF_COUNT)) {
 | 
					 | 
				
			||||||
			ret_code = i40iw_allocate_virt_mem(dev->hw, &vf_dev_mem, sizeof(struct i40iw_vfdev) +
 | 
					 | 
				
			||||||
							   (sizeof(struct i40iw_hmc_obj_info) * I40IW_HMC_IW_MAX));
 | 
					 | 
				
			||||||
			if (!ret_code) {
 | 
					 | 
				
			||||||
				vf_dev = vf_dev_mem.va;
 | 
					 | 
				
			||||||
				vf_dev->stats_initialized = false;
 | 
					 | 
				
			||||||
				vf_dev->pf_dev = dev;
 | 
					 | 
				
			||||||
				vf_dev->msg_count = 1;
 | 
					 | 
				
			||||||
				vf_dev->vf_id = vf_id;
 | 
					 | 
				
			||||||
				vf_dev->iw_vf_idx = first_avail_iw_vf;
 | 
					 | 
				
			||||||
				vf_dev->pf_hmc_initialized = false;
 | 
					 | 
				
			||||||
				vf_dev->hmc_info.hmc_obj = (struct i40iw_hmc_obj_info *)(&vf_dev[1]);
 | 
					 | 
				
			||||||
				i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
					    "vf_dev %p, hmc_info %p, hmc_obj %p\n",
 | 
					 | 
				
			||||||
					    vf_dev, &vf_dev->hmc_info, vf_dev->hmc_info.hmc_obj);
 | 
					 | 
				
			||||||
				dev->vf_dev[first_avail_iw_vf] = vf_dev;
 | 
					 | 
				
			||||||
				iw_vf_idx = first_avail_iw_vf;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
					    "VF%u Unable to allocate a VF device structure.\n",
 | 
					 | 
				
			||||||
					    vf_id);
 | 
					 | 
				
			||||||
				vchnl_pf_send_error_resp(dev, vf_id, vchnl_msg, (u16)I40IW_ERR_NO_MEMORY);
 | 
					 | 
				
			||||||
				return I40IW_SUCCESS;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			memcpy(&vf_dev->vf_msg_buffer.vchnl_msg, vchnl_msg, len);
 | 
					 | 
				
			||||||
			hmc_fcn_info.callback_fcn = pf_cqp_get_hmc_fcn_callback;
 | 
					 | 
				
			||||||
			hmc_fcn_info.vf_id = vf_id;
 | 
					 | 
				
			||||||
			hmc_fcn_info.iw_vf_idx = vf_dev->iw_vf_idx;
 | 
					 | 
				
			||||||
			hmc_fcn_info.cqp_callback_param = vf_dev;
 | 
					 | 
				
			||||||
			hmc_fcn_info.free_fcn = false;
 | 
					 | 
				
			||||||
			ret_code = i40iw_cqp_manage_hmc_fcn_cmd(dev, &hmc_fcn_info);
 | 
					 | 
				
			||||||
			if (ret_code)
 | 
					 | 
				
			||||||
				i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
					    "VF%u error CQP HMC Function operation.\n",
 | 
					 | 
				
			||||||
					    vf_id);
 | 
					 | 
				
			||||||
			i40iw_vf_init_pestat(dev, &vf_dev->pestat, vf_dev->pmf_index);
 | 
					 | 
				
			||||||
			vf_dev->stats_initialized = true;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			if (vf_dev) {
 | 
					 | 
				
			||||||
				vf_dev->msg_count--;
 | 
					 | 
				
			||||||
				vchnl_pf_send_get_hmc_fcn_resp(dev, vf_id, vchnl_msg, vf_dev->pmf_index);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				vchnl_pf_send_error_resp(dev, vf_id, vchnl_msg,
 | 
					 | 
				
			||||||
							 (u16)I40IW_ERR_NO_MEMORY);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case I40IW_VCHNL_OP_ADD_HMC_OBJ_RANGE:
 | 
					 | 
				
			||||||
		if (!vf_dev)
 | 
					 | 
				
			||||||
			return I40IW_ERR_BAD_PTR;
 | 
					 | 
				
			||||||
		work_info.worker_vf_dev = vf_dev;
 | 
					 | 
				
			||||||
		work_info.callback_fcn = pf_add_hmc_obj_callback;
 | 
					 | 
				
			||||||
		memcpy(&vf_dev->vf_msg_buffer.vchnl_msg, vchnl_msg, len);
 | 
					 | 
				
			||||||
		i40iw_cqp_spawn_worker(dev, &work_info, vf_dev->iw_vf_idx);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case I40IW_VCHNL_OP_DEL_HMC_OBJ_RANGE:
 | 
					 | 
				
			||||||
		if (!vf_dev)
 | 
					 | 
				
			||||||
			return I40IW_ERR_BAD_PTR;
 | 
					 | 
				
			||||||
		work_info.worker_vf_dev = vf_dev;
 | 
					 | 
				
			||||||
		work_info.callback_fcn = pf_del_hmc_obj_callback;
 | 
					 | 
				
			||||||
		memcpy(&vf_dev->vf_msg_buffer.vchnl_msg, vchnl_msg, len);
 | 
					 | 
				
			||||||
		i40iw_cqp_spawn_worker(dev, &work_info, vf_dev->iw_vf_idx);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case I40IW_VCHNL_OP_GET_STATS:
 | 
					 | 
				
			||||||
		if (!vf_dev)
 | 
					 | 
				
			||||||
			return I40IW_ERR_BAD_PTR;
 | 
					 | 
				
			||||||
		stats = &vf_dev->pestat;
 | 
					 | 
				
			||||||
		i40iw_hw_stats_read_all(stats, &stats->hw_stats);
 | 
					 | 
				
			||||||
		vf_dev->msg_count--;
 | 
					 | 
				
			||||||
		vchnl_pf_send_get_pe_stats_resp(dev, vf_id, vchnl_msg, &stats->hw_stats);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "40iw_vchnl_recv_pf: Invalid OpCode 0x%x\n",
 | 
					 | 
				
			||||||
			    vchnl_msg->iw_op_code);
 | 
					 | 
				
			||||||
		vchnl_pf_send_error_resp(dev, vf_id,
 | 
					 | 
				
			||||||
					 vchnl_msg, (u16)I40IW_ERR_NOT_IMPLEMENTED);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return I40IW_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_vchnl_recv_vf - Receive VF virtual channel messages
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vf_id: Virtual function ID associated with the message
 | 
					 | 
				
			||||||
 * @msg: Virtual channel message buffer pointer
 | 
					 | 
				
			||||||
 * @len: Length of the virtual channels message
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_recv_vf(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					   u32 vf_id,
 | 
					 | 
				
			||||||
					   u8 *msg,
 | 
					 | 
				
			||||||
					   u16 len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_resp_buf *vchnl_msg_resp = (struct i40iw_virtchnl_resp_buf *)msg;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_req *vchnl_req;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	vchnl_req = (struct i40iw_virtchnl_req *)(uintptr_t)vchnl_msg_resp->iw_chnl_op_ctx;
 | 
					 | 
				
			||||||
	vchnl_req->ret_code = (enum i40iw_status_code)vchnl_msg_resp->iw_op_ret_code;
 | 
					 | 
				
			||||||
	if (len == (sizeof(*vchnl_msg_resp) + vchnl_req->parm_len - 1)) {
 | 
					 | 
				
			||||||
		if (vchnl_req->parm_len && vchnl_req->parm)
 | 
					 | 
				
			||||||
			memcpy(vchnl_req->parm, vchnl_msg_resp->iw_chnl_buf, vchnl_req->parm_len);
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: Got response, data size %u\n", __func__,
 | 
					 | 
				
			||||||
			    vchnl_req->parm_len);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s: error length on response, Got %u, expected %u\n", __func__,
 | 
					 | 
				
			||||||
			    len, (u32)(sizeof(*vchnl_msg_resp) + vchnl_req->parm_len - 1));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return I40IW_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_vchnl_vf_get_ver - Request Channel version
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @vchnl_ver: Virtual channel message version pointer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_vf_get_ver(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					      u32 *vchnl_ver)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_req vchnl_req;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!i40iw_vf_clear_to_send(dev))
 | 
					 | 
				
			||||||
		return I40IW_ERR_TIMEOUT;
 | 
					 | 
				
			||||||
	memset(&vchnl_req, 0, sizeof(vchnl_req));
 | 
					 | 
				
			||||||
	vchnl_req.dev = dev;
 | 
					 | 
				
			||||||
	vchnl_req.parm = vchnl_ver;
 | 
					 | 
				
			||||||
	vchnl_req.parm_len = sizeof(*vchnl_ver);
 | 
					 | 
				
			||||||
	vchnl_req.vchnl_msg = &dev->vchnl_vf_msg_buf.vchnl_msg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret_code = vchnl_vf_send_get_ver_req(dev, &vchnl_req);
 | 
					 | 
				
			||||||
	if (ret_code) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s Send message failed 0x%0x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ret_code = i40iw_vf_wait_vchnl_resp(dev);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		return vchnl_req.ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_vchnl_vf_get_hmc_fcn - Request HMC Function
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @hmc_fcn: HMC function index pointer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_vf_get_hmc_fcn(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						  u16 *hmc_fcn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_req vchnl_req;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!i40iw_vf_clear_to_send(dev))
 | 
					 | 
				
			||||||
		return I40IW_ERR_TIMEOUT;
 | 
					 | 
				
			||||||
	memset(&vchnl_req, 0, sizeof(vchnl_req));
 | 
					 | 
				
			||||||
	vchnl_req.dev = dev;
 | 
					 | 
				
			||||||
	vchnl_req.parm = hmc_fcn;
 | 
					 | 
				
			||||||
	vchnl_req.parm_len = sizeof(*hmc_fcn);
 | 
					 | 
				
			||||||
	vchnl_req.vchnl_msg = &dev->vchnl_vf_msg_buf.vchnl_msg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret_code = vchnl_vf_send_get_hmc_fcn_req(dev, &vchnl_req);
 | 
					 | 
				
			||||||
	if (ret_code) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s Send message failed 0x%0x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ret_code = i40iw_vf_wait_vchnl_resp(dev);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		return vchnl_req.ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_vchnl_vf_add_hmc_objs - Add HMC Object
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @rsrc_type: HMC Resource type
 | 
					 | 
				
			||||||
 * @start_index: Starting index of the objects to be added
 | 
					 | 
				
			||||||
 * @rsrc_count: Number of resources to be added
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_vf_add_hmc_objs(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						   enum i40iw_hmc_rsrc_type rsrc_type,
 | 
					 | 
				
			||||||
						   u32 start_index,
 | 
					 | 
				
			||||||
						   u32 rsrc_count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_req vchnl_req;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!i40iw_vf_clear_to_send(dev))
 | 
					 | 
				
			||||||
		return I40IW_ERR_TIMEOUT;
 | 
					 | 
				
			||||||
	memset(&vchnl_req, 0, sizeof(vchnl_req));
 | 
					 | 
				
			||||||
	vchnl_req.dev = dev;
 | 
					 | 
				
			||||||
	vchnl_req.vchnl_msg = &dev->vchnl_vf_msg_buf.vchnl_msg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret_code = vchnl_vf_send_add_hmc_objs_req(dev,
 | 
					 | 
				
			||||||
						  &vchnl_req,
 | 
					 | 
				
			||||||
						  rsrc_type,
 | 
					 | 
				
			||||||
						  start_index,
 | 
					 | 
				
			||||||
						  rsrc_count);
 | 
					 | 
				
			||||||
	if (ret_code) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s Send message failed 0x%0x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ret_code = i40iw_vf_wait_vchnl_resp(dev);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		return vchnl_req.ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_vchnl_vf_del_hmc_obj - del HMC obj
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @rsrc_type: HMC Resource type
 | 
					 | 
				
			||||||
 * @start_index: Starting index of the object to delete
 | 
					 | 
				
			||||||
 * @rsrc_count: Number of resources to be delete
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_vf_del_hmc_obj(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						  enum i40iw_hmc_rsrc_type rsrc_type,
 | 
					 | 
				
			||||||
						  u32 start_index,
 | 
					 | 
				
			||||||
						  u32 rsrc_count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_req vchnl_req;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!i40iw_vf_clear_to_send(dev))
 | 
					 | 
				
			||||||
		return I40IW_ERR_TIMEOUT;
 | 
					 | 
				
			||||||
	memset(&vchnl_req, 0, sizeof(vchnl_req));
 | 
					 | 
				
			||||||
	vchnl_req.dev = dev;
 | 
					 | 
				
			||||||
	vchnl_req.vchnl_msg = &dev->vchnl_vf_msg_buf.vchnl_msg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret_code = vchnl_vf_send_del_hmc_objs_req(dev,
 | 
					 | 
				
			||||||
						  &vchnl_req,
 | 
					 | 
				
			||||||
						  rsrc_type,
 | 
					 | 
				
			||||||
						  start_index,
 | 
					 | 
				
			||||||
						  rsrc_count);
 | 
					 | 
				
			||||||
	if (ret_code) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s Send message failed 0x%0x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ret_code = i40iw_vf_wait_vchnl_resp(dev);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		return vchnl_req.ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40iw_vchnl_vf_get_pe_stats - Get PE stats
 | 
					 | 
				
			||||||
 * @dev: IWARP device pointer
 | 
					 | 
				
			||||||
 * @hw_stats: HW stats struct
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_vf_get_pe_stats(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						   struct i40iw_dev_hw_stats *hw_stats)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_req  vchnl_req;
 | 
					 | 
				
			||||||
	enum i40iw_status_code ret_code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!i40iw_vf_clear_to_send(dev))
 | 
					 | 
				
			||||||
		return I40IW_ERR_TIMEOUT;
 | 
					 | 
				
			||||||
	memset(&vchnl_req, 0, sizeof(vchnl_req));
 | 
					 | 
				
			||||||
	vchnl_req.dev = dev;
 | 
					 | 
				
			||||||
	vchnl_req.parm = hw_stats;
 | 
					 | 
				
			||||||
	vchnl_req.parm_len = sizeof(*hw_stats);
 | 
					 | 
				
			||||||
	vchnl_req.vchnl_msg = &dev->vchnl_vf_msg_buf.vchnl_msg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret_code = vchnl_vf_send_get_pe_stats_req(dev, &vchnl_req);
 | 
					 | 
				
			||||||
	if (ret_code) {
 | 
					 | 
				
			||||||
		i40iw_debug(dev, I40IW_DEBUG_VIRT,
 | 
					 | 
				
			||||||
			    "%s Send message failed 0x%0x\n", __func__, ret_code);
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ret_code = i40iw_vf_wait_vchnl_resp(dev);
 | 
					 | 
				
			||||||
	if (ret_code)
 | 
					 | 
				
			||||||
		return ret_code;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		return vchnl_req.ret_code;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,124 +0,0 @@
 | 
				
			||||||
/*******************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
* licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
* General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
* COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
* OpenFabrics.org BSD license below:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
*   without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
*   conditions are met:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*    - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
*	copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
*	disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
*	provided with the distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
* SOFTWARE.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*******************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_VIRTCHNL_H
 | 
					 | 
				
			||||||
#define I40IW_VIRTCHNL_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "i40iw_hmc.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma pack(push, 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_virtchnl_op_buf {
 | 
					 | 
				
			||||||
	u16 iw_op_code;
 | 
					 | 
				
			||||||
	u16 iw_op_ver;
 | 
					 | 
				
			||||||
	u16 iw_chnl_buf_len;
 | 
					 | 
				
			||||||
	u16 rsvd;
 | 
					 | 
				
			||||||
	u64 iw_chnl_op_ctx;
 | 
					 | 
				
			||||||
	/* Member alignment MUST be maintained above this location */
 | 
					 | 
				
			||||||
	u8 iw_chnl_buf[1];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_virtchnl_resp_buf {
 | 
					 | 
				
			||||||
	u64 iw_chnl_op_ctx;
 | 
					 | 
				
			||||||
	u16 iw_chnl_buf_len;
 | 
					 | 
				
			||||||
	s16 iw_op_ret_code;
 | 
					 | 
				
			||||||
	/* Member alignment MUST be maintained above this location */
 | 
					 | 
				
			||||||
	u16 rsvd[2];
 | 
					 | 
				
			||||||
	u8 iw_chnl_buf[1];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_virtchnl_ops {
 | 
					 | 
				
			||||||
	I40IW_VCHNL_OP_GET_VER = 0,
 | 
					 | 
				
			||||||
	I40IW_VCHNL_OP_GET_HMC_FCN,
 | 
					 | 
				
			||||||
	I40IW_VCHNL_OP_ADD_HMC_OBJ_RANGE,
 | 
					 | 
				
			||||||
	I40IW_VCHNL_OP_DEL_HMC_OBJ_RANGE,
 | 
					 | 
				
			||||||
	I40IW_VCHNL_OP_GET_STATS
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_VCHNL_OP_GET_VER_V0 0
 | 
					 | 
				
			||||||
#define I40IW_VCHNL_OP_GET_HMC_FCN_V0 0
 | 
					 | 
				
			||||||
#define I40IW_VCHNL_OP_ADD_HMC_OBJ_RANGE_V0 0
 | 
					 | 
				
			||||||
#define I40IW_VCHNL_OP_DEL_HMC_OBJ_RANGE_V0 0
 | 
					 | 
				
			||||||
#define I40IW_VCHNL_OP_GET_STATS_V0 0
 | 
					 | 
				
			||||||
#define I40IW_VCHNL_CHNL_VER_V0 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_dev_hw_stats;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_virtchnl_hmc_obj_range {
 | 
					 | 
				
			||||||
	u16 obj_type;
 | 
					 | 
				
			||||||
	u16 rsvd;
 | 
					 | 
				
			||||||
	u32 start_index;
 | 
					 | 
				
			||||||
	u32 obj_count;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_recv_pf(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					   u32 vf_id,
 | 
					 | 
				
			||||||
					   u8 *msg,
 | 
					 | 
				
			||||||
					   u16 len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_recv_vf(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					   u32 vf_id,
 | 
					 | 
				
			||||||
					   u8 *msg,
 | 
					 | 
				
			||||||
					   u16 len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_virtchnl_req {
 | 
					 | 
				
			||||||
	struct i40iw_sc_dev *dev;
 | 
					 | 
				
			||||||
	struct i40iw_virtchnl_op_buf *vchnl_msg;
 | 
					 | 
				
			||||||
	void *parm;
 | 
					 | 
				
			||||||
	u32 vf_id;
 | 
					 | 
				
			||||||
	u16 parm_len;
 | 
					 | 
				
			||||||
	s16 ret_code;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma pack(pop)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_vf_get_ver(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
					      u32 *vchnl_ver);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_vf_get_hmc_fcn(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						  u16 *hmc_fcn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_vf_add_hmc_objs(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						   enum i40iw_hmc_rsrc_type rsrc_type,
 | 
					 | 
				
			||||||
						   u32 start_index,
 | 
					 | 
				
			||||||
						   u32 rsrc_count);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_vf_del_hmc_obj(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						  enum i40iw_hmc_rsrc_type rsrc_type,
 | 
					 | 
				
			||||||
						  u32 start_index,
 | 
					 | 
				
			||||||
						  u32 rsrc_count);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_status_code i40iw_vchnl_vf_get_pe_stats(struct i40iw_sc_dev *dev,
 | 
					 | 
				
			||||||
						   struct i40iw_dev_hw_stats *hw_stats);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
							
								
								
									
										12
									
								
								drivers/infiniband/hw/irdma/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								drivers/infiniband/hw/irdma/Kconfig
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					# SPDX-License-Identifier: GPL-2.0-only
 | 
				
			||||||
 | 
					config INFINIBAND_IRDMA
 | 
				
			||||||
 | 
						tristate "Intel(R) Ethernet Protocol Driver for RDMA"
 | 
				
			||||||
 | 
						depends on INET
 | 
				
			||||||
 | 
						depends on IPV6 || !IPV6
 | 
				
			||||||
 | 
						depends on PCI
 | 
				
			||||||
 | 
						depends on ICE && I40E
 | 
				
			||||||
 | 
						select GENERIC_ALLOCATOR
 | 
				
			||||||
 | 
						select CONFIG_AUXILIARY_BUS
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  This is an Intel(R) Ethernet Protocol Driver for RDMA driver
 | 
				
			||||||
 | 
						  that support E810 (iWARP/RoCE) and X722 (iWARP) network devices.
 | 
				
			||||||
							
								
								
									
										27
									
								
								drivers/infiniband/hw/irdma/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								drivers/infiniband/hw/irdma/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					# SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
 | 
				
			||||||
 | 
					# Copyright (c) 2019, Intel Corporation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Makefile for the Intel(R) Ethernet Connection RDMA Linux Driver
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					obj-$(CONFIG_INFINIBAND_IRDMA) += irdma.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					irdma-objs := cm.o        \
 | 
				
			||||||
 | 
					              ctrl.o      \
 | 
				
			||||||
 | 
					              hmc.o       \
 | 
				
			||||||
 | 
					              hw.o        \
 | 
				
			||||||
 | 
					              i40iw_hw.o  \
 | 
				
			||||||
 | 
					              i40iw_if.o  \
 | 
				
			||||||
 | 
					              icrdma_hw.o \
 | 
				
			||||||
 | 
					              main.o      \
 | 
				
			||||||
 | 
					              pble.o      \
 | 
				
			||||||
 | 
					              puda.o      \
 | 
				
			||||||
 | 
					              trace.o     \
 | 
				
			||||||
 | 
					              uda.o       \
 | 
				
			||||||
 | 
					              uk.o        \
 | 
				
			||||||
 | 
					              utils.o     \
 | 
				
			||||||
 | 
					              verbs.o     \
 | 
				
			||||||
 | 
					              ws.o        \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CFLAGS_trace.o = -I$(src)
 | 
				
			||||||
| 
						 | 
					@ -8,8 +8,6 @@
 | 
				
			||||||
#include "i40e.h"
 | 
					#include "i40e.h"
 | 
				
			||||||
#include "i40e_prototype.h"
 | 
					#include "i40e_prototype.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char i40e_client_interface_version_str[] = I40E_CLIENT_VERSION_STR;
 | 
					 | 
				
			||||||
static struct i40e_client *registered_client;
 | 
					 | 
				
			||||||
static LIST_HEAD(i40e_devices);
 | 
					static LIST_HEAD(i40e_devices);
 | 
				
			||||||
static DEFINE_MUTEX(i40e_device_mutex);
 | 
					static DEFINE_MUTEX(i40e_device_mutex);
 | 
				
			||||||
DEFINE_IDA(i40e_client_ida);
 | 
					DEFINE_IDA(i40e_client_ida);
 | 
				
			||||||
| 
						 | 
					@ -367,7 +365,6 @@ static void i40e_client_add_instance(struct i40e_pf *pf)
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		dev_err(&pf->pdev->dev, "MAC address list is empty!\n");
 | 
							dev_err(&pf->pdev->dev, "MAC address list is empty!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cdev->client = registered_client;
 | 
					 | 
				
			||||||
	pf->cinst = cdev;
 | 
						pf->cinst = cdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cdev->lan_info.msix_count = pf->num_iwarp_msix;
 | 
						cdev->lan_info.msix_count = pf->num_iwarp_msix;
 | 
				
			||||||
| 
						 | 
					@ -525,69 +522,6 @@ int i40e_lan_del_device(struct i40e_pf *pf)
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40e_client_release - release client specific resources
 | 
					 | 
				
			||||||
 * @client: pointer to the registered client
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static void i40e_client_release(struct i40e_client *client)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40e_client_instance *cdev;
 | 
					 | 
				
			||||||
	struct i40e_device *ldev;
 | 
					 | 
				
			||||||
	struct i40e_pf *pf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mutex_lock(&i40e_device_mutex);
 | 
					 | 
				
			||||||
	list_for_each_entry(ldev, &i40e_devices, list) {
 | 
					 | 
				
			||||||
		pf = ldev->pf;
 | 
					 | 
				
			||||||
		cdev = pf->cinst;
 | 
					 | 
				
			||||||
		if (!cdev)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		while (test_and_set_bit(__I40E_SERVICE_SCHED,
 | 
					 | 
				
			||||||
					pf->state))
 | 
					 | 
				
			||||||
			usleep_range(500, 1000);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
 | 
					 | 
				
			||||||
			if (client->ops && client->ops->close)
 | 
					 | 
				
			||||||
				client->ops->close(&cdev->lan_info, client,
 | 
					 | 
				
			||||||
						   false);
 | 
					 | 
				
			||||||
			i40e_client_release_qvlist(&cdev->lan_info);
 | 
					 | 
				
			||||||
			clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			dev_warn(&pf->pdev->dev,
 | 
					 | 
				
			||||||
				 "Client %s instance for PF id %d closed\n",
 | 
					 | 
				
			||||||
				 client->name, pf->hw.pf_id);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		/* delete the client instance */
 | 
					 | 
				
			||||||
		i40e_client_del_instance(pf);
 | 
					 | 
				
			||||||
		dev_info(&pf->pdev->dev, "Deleted client instance of Client %s\n",
 | 
					 | 
				
			||||||
			 client->name);
 | 
					 | 
				
			||||||
		clear_bit(__I40E_SERVICE_SCHED, pf->state);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mutex_unlock(&i40e_device_mutex);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40e_client_prepare - prepare client specific resources
 | 
					 | 
				
			||||||
 * @client: pointer to the registered client
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
static void i40e_client_prepare(struct i40e_client *client)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct i40e_device *ldev;
 | 
					 | 
				
			||||||
	struct i40e_pf *pf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mutex_lock(&i40e_device_mutex);
 | 
					 | 
				
			||||||
	list_for_each_entry(ldev, &i40e_devices, list) {
 | 
					 | 
				
			||||||
		pf = ldev->pf;
 | 
					 | 
				
			||||||
		i40e_client_add_instance(pf);
 | 
					 | 
				
			||||||
		/* Start the client subtask */
 | 
					 | 
				
			||||||
		set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state);
 | 
					 | 
				
			||||||
		i40e_service_event_schedule(pf);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mutex_unlock(&i40e_device_mutex);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * i40e_client_virtchnl_send - TBD
 | 
					 * i40e_client_virtchnl_send - TBD
 | 
				
			||||||
 * @ldev: pointer to L2 context
 | 
					 * @ldev: pointer to L2 context
 | 
				
			||||||
| 
						 | 
					@ -817,86 +751,3 @@ void i40e_client_device_unregister(struct i40e_info *ldev)
 | 
				
			||||||
	clear_bit(__I40E_SERVICE_SCHED, pf->state);
 | 
						clear_bit(__I40E_SERVICE_SCHED, pf->state);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(i40e_client_device_unregister);
 | 
					EXPORT_SYMBOL_GPL(i40e_client_device_unregister);
 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Retain these legacy global registration/unregistration calls till i40iw is
 | 
					 | 
				
			||||||
 * removed from the kernel. The irdma unified driver does not use these
 | 
					 | 
				
			||||||
 * exported symbols.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40e_register_client - Register a i40e client driver with the L2 driver
 | 
					 | 
				
			||||||
 * @client: pointer to the i40e_client struct
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Returns 0 on success or non-0 on error
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
int i40e_register_client(struct i40e_client *client)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int ret = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!client) {
 | 
					 | 
				
			||||||
		ret = -EIO;
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (strlen(client->name) == 0) {
 | 
					 | 
				
			||||||
		pr_info("i40e: Failed to register client with no name\n");
 | 
					 | 
				
			||||||
		ret = -EIO;
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (registered_client) {
 | 
					 | 
				
			||||||
		pr_info("i40e: Client %s has already been registered!\n",
 | 
					 | 
				
			||||||
			client->name);
 | 
					 | 
				
			||||||
		ret = -EEXIST;
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((client->version.major != I40E_CLIENT_VERSION_MAJOR) ||
 | 
					 | 
				
			||||||
	    (client->version.minor != I40E_CLIENT_VERSION_MINOR)) {
 | 
					 | 
				
			||||||
		pr_info("i40e: Failed to register client %s due to mismatched client interface version\n",
 | 
					 | 
				
			||||||
			client->name);
 | 
					 | 
				
			||||||
		pr_info("Client is using version: %02d.%02d.%02d while LAN driver supports %s\n",
 | 
					 | 
				
			||||||
			client->version.major, client->version.minor,
 | 
					 | 
				
			||||||
			client->version.build,
 | 
					 | 
				
			||||||
			i40e_client_interface_version_str);
 | 
					 | 
				
			||||||
		ret = -EIO;
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	registered_client = client;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i40e_client_prepare(client);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pr_info("i40e: Registered client %s\n", client->name);
 | 
					 | 
				
			||||||
out:
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(i40e_register_client);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * i40e_unregister_client - Unregister a i40e client driver with the L2 driver
 | 
					 | 
				
			||||||
 * @client: pointer to the i40e_client struct
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Returns 0 on success or non-0 on error
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
int i40e_unregister_client(struct i40e_client *client)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int ret = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (registered_client != client) {
 | 
					 | 
				
			||||||
		pr_info("i40e: Client %s has not been registered\n",
 | 
					 | 
				
			||||||
			client->name);
 | 
					 | 
				
			||||||
		ret = -ENODEV;
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	registered_client = NULL;
 | 
					 | 
				
			||||||
	/* When a unregister request comes through we would have to send
 | 
					 | 
				
			||||||
	 * a close for each of the client instances that were opened.
 | 
					 | 
				
			||||||
	 * client_release function is called to handle this.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	i40e_client_release(client);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pr_info("i40e: Unregistered client %s\n", client->name);
 | 
					 | 
				
			||||||
out:
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(i40e_unregister_client);
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -197,8 +197,5 @@ static inline bool i40e_client_is_registered(struct i40e_client *client)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void i40e_client_device_register(struct i40e_info *ldev, struct i40e_client *client);
 | 
					void i40e_client_device_register(struct i40e_info *ldev, struct i40e_client *client);
 | 
				
			||||||
void i40e_client_device_unregister(struct i40e_info *ldev);
 | 
					void i40e_client_device_unregister(struct i40e_info *ldev);
 | 
				
			||||||
/* used by clients */
 | 
					 | 
				
			||||||
int i40e_register_client(struct i40e_client *client);
 | 
					 | 
				
			||||||
int i40e_unregister_client(struct i40e_client *client);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _I40E_CLIENT_H_ */
 | 
					#endif /* _I40E_CLIENT_H_ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,107 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2006 - 2016 Intel Corporation.  All rights reserved.
 | 
					 | 
				
			||||||
 * Copyright (c) 2005 Topspin Communications.  All rights reserved.
 | 
					 | 
				
			||||||
 * Copyright (c) 2005 Cisco Systems.  All rights reserved.
 | 
					 | 
				
			||||||
 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This software is available to you under a choice of one of two
 | 
					 | 
				
			||||||
 * licenses.  You may choose to be licensed under the terms of the GNU
 | 
					 | 
				
			||||||
 * General Public License (GPL) Version 2, available from the file
 | 
					 | 
				
			||||||
 * COPYING in the main directory of this source tree, or the
 | 
					 | 
				
			||||||
 * OpenIB.org BSD license below:
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *     Redistribution and use in source and binary forms, with or
 | 
					 | 
				
			||||||
 *     without modification, are permitted provided that the following
 | 
					 | 
				
			||||||
 *     conditions are met:
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *      - Redistributions of source code must retain the above
 | 
					 | 
				
			||||||
 *        copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
 *        disclaimer.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *      - Redistributions in binary form must reproduce the above
 | 
					 | 
				
			||||||
 *        copyright notice, this list of conditions and the following
 | 
					 | 
				
			||||||
 *        disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
 *        provided with the distribution.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
					 | 
				
			||||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
					 | 
				
			||||||
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
					 | 
				
			||||||
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
					 | 
				
			||||||
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
					 | 
				
			||||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
 * SOFTWARE.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef I40IW_ABI_H
 | 
					 | 
				
			||||||
#define I40IW_ABI_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <linux/types.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define I40IW_ABI_VER 5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_alloc_ucontext_req {
 | 
					 | 
				
			||||||
	__u32 reserved32;
 | 
					 | 
				
			||||||
	__u8 userspace_ver;
 | 
					 | 
				
			||||||
	__u8 reserved8[3];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_alloc_ucontext_resp {
 | 
					 | 
				
			||||||
	__u32 max_pds;		/* maximum pds allowed for this user process */
 | 
					 | 
				
			||||||
	__u32 max_qps;		/* maximum qps allowed for this user process */
 | 
					 | 
				
			||||||
	__u32 wq_size;		/* size of the WQs (sq+rq) allocated to the mmaped area */
 | 
					 | 
				
			||||||
	__u8 kernel_ver;
 | 
					 | 
				
			||||||
	__u8 reserved[3];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_alloc_pd_resp {
 | 
					 | 
				
			||||||
	__u32 pd_id;
 | 
					 | 
				
			||||||
	__u8 reserved[4];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_create_cq_req {
 | 
					 | 
				
			||||||
	__aligned_u64 user_cq_buffer;
 | 
					 | 
				
			||||||
	__aligned_u64 user_shadow_area;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_create_qp_req {
 | 
					 | 
				
			||||||
	__aligned_u64 user_wqe_buffers;
 | 
					 | 
				
			||||||
	__aligned_u64 user_compl_ctx;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* UDA QP PHB */
 | 
					 | 
				
			||||||
	__aligned_u64 user_sq_phb;	/* place for VA of the sq phb buff */
 | 
					 | 
				
			||||||
	__aligned_u64 user_rq_phb;	/* place for VA of the rq phb buff */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum i40iw_memreg_type {
 | 
					 | 
				
			||||||
	IW_MEMREG_TYPE_MEM = 0x0000,
 | 
					 | 
				
			||||||
	IW_MEMREG_TYPE_QP = 0x0001,
 | 
					 | 
				
			||||||
	IW_MEMREG_TYPE_CQ = 0x0002,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_mem_reg_req {
 | 
					 | 
				
			||||||
	__u16 reg_type;		/* Memory, QP or CQ */
 | 
					 | 
				
			||||||
	__u16 cq_pages;
 | 
					 | 
				
			||||||
	__u16 rq_pages;
 | 
					 | 
				
			||||||
	__u16 sq_pages;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_create_cq_resp {
 | 
					 | 
				
			||||||
	__u32 cq_id;
 | 
					 | 
				
			||||||
	__u32 cq_size;
 | 
					 | 
				
			||||||
	__u32 mmap_db_index;
 | 
					 | 
				
			||||||
	__u32 reserved;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct i40iw_create_qp_resp {
 | 
					 | 
				
			||||||
	__u32 qp_id;
 | 
					 | 
				
			||||||
	__u32 actual_sq_size;
 | 
					 | 
				
			||||||
	__u32 actual_rq_size;
 | 
					 | 
				
			||||||
	__u32 i40iw_drv_opt;
 | 
					 | 
				
			||||||
	__u16 push_idx;
 | 
					 | 
				
			||||||
	__u8  lsmm;
 | 
					 | 
				
			||||||
	__u8  rsvd2;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in a new issue