mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	qed: Add Light L2 support
Other protocols beside the networking driver need the ability of passing some L2 traffic, usually [although not limited] for the purpose of some management traffic. Signed-off-by: Yuval Mintz <Yuval.Mintz@caviumnetworks.com> Signed-off-by: Ram Amrani <Ram.Amrani@caviumnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									b9118b7221
								
							
						
					
					
						commit
						0a7fb11c23
					
				
					 13 changed files with 2334 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -88,6 +88,14 @@ config QED
 | 
			
		|||
	---help---
 | 
			
		||||
	  This enables the support for ...
 | 
			
		||||
 | 
			
		||||
config QED_LL2
 | 
			
		||||
	bool "Qlogic QED Light L2 interface"
 | 
			
		||||
	default n
 | 
			
		||||
	depends on QED
 | 
			
		||||
	---help---
 | 
			
		||||
	This enables support for Light L2 interface which is required
 | 
			
		||||
	by all qed protocol drivers other than qede.
 | 
			
		||||
 | 
			
		||||
config QED_SRIOV
 | 
			
		||||
	bool "QLogic QED 25/40/100Gb SR-IOV support"
 | 
			
		||||
	depends on QED && PCI_IOV
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,3 +4,4 @@ qed-y := qed_cxt.o qed_dev.o qed_hw.o qed_init_fw_funcs.o qed_init_ops.o \
 | 
			
		|||
	 qed_int.o qed_main.o qed_mcp.o qed_sp_commands.o qed_spq.o qed_l2.o \
 | 
			
		||||
	 qed_selftest.o qed_dcbx.o qed_debug.o
 | 
			
		||||
qed-$(CONFIG_QED_SRIOV) += qed_sriov.o qed_vf.o
 | 
			
		||||
qed-$(CONFIG_QED_LL2) += qed_ll2.o
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,7 @@ struct qed_sb_info;
 | 
			
		|||
struct qed_sb_attn_info;
 | 
			
		||||
struct qed_cxt_mngr;
 | 
			
		||||
struct qed_sb_sp_info;
 | 
			
		||||
struct qed_ll2_info;
 | 
			
		||||
struct qed_mcp_info;
 | 
			
		||||
 | 
			
		||||
struct qed_rt_data {
 | 
			
		||||
| 
						 | 
				
			
			@ -152,6 +153,7 @@ enum QED_RESOURCES {
 | 
			
		|||
	QED_MAC,
 | 
			
		||||
	QED_VLAN,
 | 
			
		||||
	QED_ILT,
 | 
			
		||||
	QED_LL2_QUEUE,
 | 
			
		||||
	QED_MAX_RESC,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -360,6 +362,8 @@ struct qed_hwfn {
 | 
			
		|||
	struct qed_sb_attn_info		*p_sb_attn;
 | 
			
		||||
 | 
			
		||||
	/* Protocol related */
 | 
			
		||||
	bool				using_ll2;
 | 
			
		||||
	struct qed_ll2_info		*p_ll2_info;
 | 
			
		||||
	struct qed_pf_params		pf_params;
 | 
			
		||||
 | 
			
		||||
	bool b_rdma_enabled_in_prs;
 | 
			
		||||
| 
						 | 
				
			
			@ -564,6 +568,11 @@ struct qed_dev {
 | 
			
		|||
 | 
			
		||||
	struct qed_dbg_params		dbg_params;
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_QED_LL2
 | 
			
		||||
	struct qed_cb_ll2_info		*ll2;
 | 
			
		||||
	u8				ll2_mac_address[ETH_ALEN];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	const struct firmware		*firmware;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1839,6 +1839,8 @@ int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn)
 | 
			
		|||
	/* Set the number of required CORE connections */
 | 
			
		||||
	u32 core_cids = 1; /* SPQ */
 | 
			
		||||
 | 
			
		||||
	if (p_hwfn->using_ll2)
 | 
			
		||||
		core_cids += 4;
 | 
			
		||||
	qed_cxt_set_proto_cid_count(p_hwfn, PROTOCOLID_CORE, core_cids, 0);
 | 
			
		||||
 | 
			
		||||
	switch (p_hwfn->hw_info.personality) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@
 | 
			
		|||
#include "qed_hw.h"
 | 
			
		||||
#include "qed_init_ops.h"
 | 
			
		||||
#include "qed_int.h"
 | 
			
		||||
#include "qed_ll2.h"
 | 
			
		||||
#include "qed_mcp.h"
 | 
			
		||||
#include "qed_reg_addr.h"
 | 
			
		||||
#include "qed_sp.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -147,6 +148,9 @@ void qed_resc_free(struct qed_dev *cdev)
 | 
			
		|||
		qed_eq_free(p_hwfn, p_hwfn->p_eq);
 | 
			
		||||
		qed_consq_free(p_hwfn, p_hwfn->p_consq);
 | 
			
		||||
		qed_int_free(p_hwfn);
 | 
			
		||||
#ifdef CONFIG_QED_LL2
 | 
			
		||||
		qed_ll2_free(p_hwfn, p_hwfn->p_ll2_info);
 | 
			
		||||
#endif
 | 
			
		||||
		qed_iov_free(p_hwfn);
 | 
			
		||||
		qed_dmae_info_free(p_hwfn);
 | 
			
		||||
		qed_dcbx_info_free(p_hwfn, p_hwfn->p_dcbx_info);
 | 
			
		||||
| 
						 | 
				
			
			@ -403,6 +407,9 @@ int qed_qm_reconf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 | 
			
		|||
 | 
			
		||||
int qed_resc_alloc(struct qed_dev *cdev)
 | 
			
		||||
{
 | 
			
		||||
#ifdef CONFIG_QED_LL2
 | 
			
		||||
	struct qed_ll2_info *p_ll2_info;
 | 
			
		||||
#endif
 | 
			
		||||
	struct qed_consq *p_consq;
 | 
			
		||||
	struct qed_eq *p_eq;
 | 
			
		||||
	int i, rc = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -513,6 +520,15 @@ int qed_resc_alloc(struct qed_dev *cdev)
 | 
			
		|||
			goto alloc_no_mem;
 | 
			
		||||
		p_hwfn->p_consq = p_consq;
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_QED_LL2
 | 
			
		||||
		if (p_hwfn->using_ll2) {
 | 
			
		||||
			p_ll2_info = qed_ll2_alloc(p_hwfn);
 | 
			
		||||
			if (!p_ll2_info)
 | 
			
		||||
				goto alloc_no_mem;
 | 
			
		||||
			p_hwfn->p_ll2_info = p_ll2_info;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/* DMA info initialization */
 | 
			
		||||
		rc = qed_dmae_info_alloc(p_hwfn);
 | 
			
		||||
		if (rc)
 | 
			
		||||
| 
						 | 
				
			
			@ -561,6 +577,10 @@ void qed_resc_setup(struct qed_dev *cdev)
 | 
			
		|||
		qed_int_setup(p_hwfn, p_hwfn->p_main_ptt);
 | 
			
		||||
 | 
			
		||||
		qed_iov_setup(p_hwfn, p_hwfn->p_main_ptt);
 | 
			
		||||
#ifdef CONFIG_QED_LL2
 | 
			
		||||
		if (p_hwfn->using_ll2)
 | 
			
		||||
			qed_ll2_setup(p_hwfn, p_hwfn->p_ll2_info);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1304,6 +1324,7 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn)
 | 
			
		|||
	resc_num[QED_VLAN] = (ETH_NUM_VLAN_FILTERS - 1 /*For vlan0*/) /
 | 
			
		||||
			     num_funcs;
 | 
			
		||||
	resc_num[QED_ILT] = PXP_NUM_ILT_RECORDS_BB / num_funcs;
 | 
			
		||||
	resc_num[QED_LL2_QUEUE] = MAX_NUM_LL2_RX_QUEUES / num_funcs;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < QED_MAX_RESC; i++)
 | 
			
		||||
		resc_start[i] = resc_num[i] * enabled_func_idx;
 | 
			
		||||
| 
						 | 
				
			
			@ -1327,7 +1348,8 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn)
 | 
			
		|||
		   "RL = %d start = %d\n"
 | 
			
		||||
		   "MAC = %d start = %d\n"
 | 
			
		||||
		   "VLAN = %d start = %d\n"
 | 
			
		||||
		   "ILT = %d start = %d\n",
 | 
			
		||||
		   "ILT = %d start = %d\n"
 | 
			
		||||
		   "LL2_QUEUE = %d start = %d\n",
 | 
			
		||||
		   p_hwfn->hw_info.resc_num[QED_SB],
 | 
			
		||||
		   p_hwfn->hw_info.resc_start[QED_SB],
 | 
			
		||||
		   p_hwfn->hw_info.resc_num[QED_L2_QUEUE],
 | 
			
		||||
| 
						 | 
				
			
			@ -1343,7 +1365,9 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn)
 | 
			
		|||
		   p_hwfn->hw_info.resc_num[QED_VLAN],
 | 
			
		||||
		   p_hwfn->hw_info.resc_start[QED_VLAN],
 | 
			
		||||
		   p_hwfn->hw_info.resc_num[QED_ILT],
 | 
			
		||||
		   p_hwfn->hw_info.resc_start[QED_ILT]);
 | 
			
		||||
		   p_hwfn->hw_info.resc_start[QED_ILT],
 | 
			
		||||
		   RESC_NUM(p_hwfn, QED_LL2_QUEUE),
 | 
			
		||||
		   RESC_START(p_hwfn, QED_LL2_QUEUE));
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2133,6 +2157,98 @@ int qed_fw_rss_eng(struct qed_hwfn *p_hwfn, u8 src_id, u8 *dst_id)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void qed_llh_mac_to_filter(u32 *p_high, u32 *p_low,
 | 
			
		||||
				  u8 *p_filter)
 | 
			
		||||
{
 | 
			
		||||
	*p_high = p_filter[1] | (p_filter[0] << 8);
 | 
			
		||||
	*p_low = p_filter[5] | (p_filter[4] << 8) |
 | 
			
		||||
		 (p_filter[3] << 16) | (p_filter[2] << 24);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qed_llh_add_mac_filter(struct qed_hwfn *p_hwfn,
 | 
			
		||||
			   struct qed_ptt *p_ptt, u8 *p_filter)
 | 
			
		||||
{
 | 
			
		||||
	u32 high = 0, low = 0, en;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn)))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	qed_llh_mac_to_filter(&high, &low, p_filter);
 | 
			
		||||
 | 
			
		||||
	/* Find a free entry and utilize it */
 | 
			
		||||
	for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) {
 | 
			
		||||
		en = qed_rd(p_hwfn, p_ptt,
 | 
			
		||||
			    NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32));
 | 
			
		||||
		if (en)
 | 
			
		||||
			continue;
 | 
			
		||||
		qed_wr(p_hwfn, p_ptt,
 | 
			
		||||
		       NIG_REG_LLH_FUNC_FILTER_VALUE +
 | 
			
		||||
		       2 * i * sizeof(u32), low);
 | 
			
		||||
		qed_wr(p_hwfn, p_ptt,
 | 
			
		||||
		       NIG_REG_LLH_FUNC_FILTER_VALUE +
 | 
			
		||||
		       (2 * i + 1) * sizeof(u32), high);
 | 
			
		||||
		qed_wr(p_hwfn, p_ptt,
 | 
			
		||||
		       NIG_REG_LLH_FUNC_FILTER_MODE + i * sizeof(u32), 0);
 | 
			
		||||
		qed_wr(p_hwfn, p_ptt,
 | 
			
		||||
		       NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE +
 | 
			
		||||
		       i * sizeof(u32), 0);
 | 
			
		||||
		qed_wr(p_hwfn, p_ptt,
 | 
			
		||||
		       NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32), 1);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE) {
 | 
			
		||||
		DP_NOTICE(p_hwfn,
 | 
			
		||||
			  "Failed to find an empty LLH filter to utilize\n");
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DP_VERBOSE(p_hwfn, NETIF_MSG_HW,
 | 
			
		||||
		   "mac: %pM is added at %d\n",
 | 
			
		||||
		   p_filter, i);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qed_llh_remove_mac_filter(struct qed_hwfn *p_hwfn,
 | 
			
		||||
			       struct qed_ptt *p_ptt, u8 *p_filter)
 | 
			
		||||
{
 | 
			
		||||
	u32 high = 0, low = 0;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn)))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	qed_llh_mac_to_filter(&high, &low, p_filter);
 | 
			
		||||
 | 
			
		||||
	/* Find the entry and clean it */
 | 
			
		||||
	for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) {
 | 
			
		||||
		if (qed_rd(p_hwfn, p_ptt,
 | 
			
		||||
			   NIG_REG_LLH_FUNC_FILTER_VALUE +
 | 
			
		||||
			   2 * i * sizeof(u32)) != low)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (qed_rd(p_hwfn, p_ptt,
 | 
			
		||||
			   NIG_REG_LLH_FUNC_FILTER_VALUE +
 | 
			
		||||
			   (2 * i + 1) * sizeof(u32)) != high)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		qed_wr(p_hwfn, p_ptt,
 | 
			
		||||
		       NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32), 0);
 | 
			
		||||
		qed_wr(p_hwfn, p_ptt,
 | 
			
		||||
		       NIG_REG_LLH_FUNC_FILTER_VALUE + 2 * i * sizeof(u32), 0);
 | 
			
		||||
		qed_wr(p_hwfn, p_ptt,
 | 
			
		||||
		       NIG_REG_LLH_FUNC_FILTER_VALUE +
 | 
			
		||||
		       (2 * i + 1) * sizeof(u32), 0);
 | 
			
		||||
 | 
			
		||||
		DP_VERBOSE(p_hwfn, NETIF_MSG_HW,
 | 
			
		||||
			   "mac: %pM is removed from %d\n",
 | 
			
		||||
			   p_filter, i);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE)
 | 
			
		||||
		DP_NOTICE(p_hwfn, "Tried to remove a non-configured filter\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qed_set_coalesce(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
 | 
			
		||||
			    u32 hw_addr, void *p_eth_qzone,
 | 
			
		||||
			    size_t eth_qzone_size, u8 timeset)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -309,6 +309,26 @@ int qed_fw_rss_eng(struct qed_hwfn *p_hwfn,
 | 
			
		|||
		   u8 src_id,
 | 
			
		||||
		   u8 *dst_id);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_llh_add_mac_filter - configures a MAC filter in llh
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param p_ptt
 | 
			
		||||
 * @param p_filter - MAC to add
 | 
			
		||||
 */
 | 
			
		||||
int qed_llh_add_mac_filter(struct qed_hwfn *p_hwfn,
 | 
			
		||||
			   struct qed_ptt *p_ptt, u8 *p_filter);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_llh_remove_mac_filter - removes a MAC filter from llh
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param p_ptt
 | 
			
		||||
 * @param p_filter - MAC to remove
 | 
			
		||||
 */
 | 
			
		||||
void qed_llh_remove_mac_filter(struct qed_hwfn *p_hwfn,
 | 
			
		||||
			       struct qed_ptt *p_ptt, u8 *p_filter);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * *@brief Cleanup of previous driver remains prior to load
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1699
									
								
								drivers/net/ethernet/qlogic/qed/qed_ll2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1699
									
								
								drivers/net/ethernet/qlogic/qed/qed_ll2.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										289
									
								
								drivers/net/ethernet/qlogic/qed/qed_ll2.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								drivers/net/ethernet/qlogic/qed/qed_ll2.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,289 @@
 | 
			
		|||
/* QLogic qed NIC Driver
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2015 QLogic Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * This software is available 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _QED_LL2_H
 | 
			
		||||
#define _QED_LL2_H
 | 
			
		||||
 | 
			
		||||
#include <linux/types.h>
 | 
			
		||||
#include <linux/kernel.h>
 | 
			
		||||
#include <linux/list.h>
 | 
			
		||||
#include <linux/mutex.h>
 | 
			
		||||
#include <linux/slab.h>
 | 
			
		||||
#include <linux/spinlock.h>
 | 
			
		||||
#include <linux/qed/qed_chain.h>
 | 
			
		||||
#include <linux/qed/qed_ll2_if.h>
 | 
			
		||||
#include "qed.h"
 | 
			
		||||
#include "qed_hsi.h"
 | 
			
		||||
#include "qed_sp.h"
 | 
			
		||||
 | 
			
		||||
#define QED_MAX_NUM_OF_LL2_CONNECTIONS                    (4)
 | 
			
		||||
 | 
			
		||||
enum qed_ll2_conn_type {
 | 
			
		||||
	QED_LL2_TYPE_RESERVED,
 | 
			
		||||
	QED_LL2_TYPE_ISCSI,
 | 
			
		||||
	QED_LL2_TYPE_TEST,
 | 
			
		||||
	QED_LL2_TYPE_ISCSI_OOO,
 | 
			
		||||
	QED_LL2_TYPE_RESERVED2,
 | 
			
		||||
	QED_LL2_TYPE_ROCE,
 | 
			
		||||
	QED_LL2_TYPE_RESERVED3,
 | 
			
		||||
	MAX_QED_LL2_RX_CONN_TYPE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qed_ll2_rx_packet {
 | 
			
		||||
	struct list_head list_entry;
 | 
			
		||||
	struct core_rx_bd_with_buff_len *rxq_bd;
 | 
			
		||||
	dma_addr_t rx_buf_addr;
 | 
			
		||||
	u16 buf_length;
 | 
			
		||||
	void *cookie;
 | 
			
		||||
	u8 placement_offset;
 | 
			
		||||
	u16 parse_flags;
 | 
			
		||||
	u16 packet_length;
 | 
			
		||||
	u16 vlan;
 | 
			
		||||
	u32 opaque_data[2];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qed_ll2_tx_packet {
 | 
			
		||||
	struct list_head list_entry;
 | 
			
		||||
	u16 bd_used;
 | 
			
		||||
	u16 vlan;
 | 
			
		||||
	u16 l4_hdr_offset_w;
 | 
			
		||||
	u8 bd_flags;
 | 
			
		||||
	bool notify_fw;
 | 
			
		||||
	void *cookie;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		struct core_tx_bd *txq_bd;
 | 
			
		||||
		dma_addr_t tx_frag;
 | 
			
		||||
		u16 frag_len;
 | 
			
		||||
	} bds_set[ETH_TX_MAX_BDS_PER_NON_LSO_PACKET];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qed_ll2_rx_queue {
 | 
			
		||||
	/* Lock protecting the Rx queue manipulation */
 | 
			
		||||
	spinlock_t lock;
 | 
			
		||||
	struct qed_chain rxq_chain;
 | 
			
		||||
	struct qed_chain rcq_chain;
 | 
			
		||||
	u8 rx_sb_index;
 | 
			
		||||
	bool b_cb_registred;
 | 
			
		||||
	__le16 *p_fw_cons;
 | 
			
		||||
	struct list_head active_descq;
 | 
			
		||||
	struct list_head free_descq;
 | 
			
		||||
	struct list_head posting_descq;
 | 
			
		||||
	struct qed_ll2_rx_packet *descq_array;
 | 
			
		||||
	void __iomem *set_prod_addr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qed_ll2_tx_queue {
 | 
			
		||||
	/* Lock protecting the Tx queue manipulation */
 | 
			
		||||
	spinlock_t lock;
 | 
			
		||||
	struct qed_chain txq_chain;
 | 
			
		||||
	u8 tx_sb_index;
 | 
			
		||||
	bool b_cb_registred;
 | 
			
		||||
	__le16 *p_fw_cons;
 | 
			
		||||
	struct list_head active_descq;
 | 
			
		||||
	struct list_head free_descq;
 | 
			
		||||
	struct list_head sending_descq;
 | 
			
		||||
	struct qed_ll2_tx_packet *descq_array;
 | 
			
		||||
	struct qed_ll2_tx_packet *cur_send_packet;
 | 
			
		||||
	struct qed_ll2_tx_packet cur_completing_packet;
 | 
			
		||||
	u16 cur_completing_bd_idx;
 | 
			
		||||
	void __iomem *doorbell_addr;
 | 
			
		||||
	u16 bds_idx;
 | 
			
		||||
	u16 cur_send_frag_num;
 | 
			
		||||
	u16 cur_completing_frag_num;
 | 
			
		||||
	bool b_completing_packet;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qed_ll2_info {
 | 
			
		||||
	/* Lock protecting the state of LL2 */
 | 
			
		||||
	struct mutex mutex;
 | 
			
		||||
	enum qed_ll2_conn_type conn_type;
 | 
			
		||||
	u32 cid;
 | 
			
		||||
	u8 my_id;
 | 
			
		||||
	u8 queue_id;
 | 
			
		||||
	u8 tx_stats_id;
 | 
			
		||||
	bool b_active;
 | 
			
		||||
	u16 mtu;
 | 
			
		||||
	u8 rx_drop_ttl0_flg;
 | 
			
		||||
	u8 rx_vlan_removal_en;
 | 
			
		||||
	u8 tx_tc;
 | 
			
		||||
	enum core_tx_dest tx_dest;
 | 
			
		||||
	enum core_error_handle ai_err_packet_too_big;
 | 
			
		||||
	enum core_error_handle ai_err_no_buf;
 | 
			
		||||
	u8 tx_stats_en;
 | 
			
		||||
	struct qed_ll2_rx_queue rx_queue;
 | 
			
		||||
	struct qed_ll2_tx_queue tx_queue;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_acquire_connection - allocate resources,
 | 
			
		||||
 *        starts rx & tx (if relevant) queues pair. Provides
 | 
			
		||||
 *        connecion handler as output parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param p_params		Contain various configuration properties
 | 
			
		||||
 * @param rx_num_desc
 | 
			
		||||
 * @param tx_num_desc
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_connection_handle  Output container for LL2 connection's handle
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, failure otherwise
 | 
			
		||||
 */
 | 
			
		||||
int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
 | 
			
		||||
			       struct qed_ll2_info *p_params,
 | 
			
		||||
			       u16 rx_num_desc,
 | 
			
		||||
			       u16 tx_num_desc,
 | 
			
		||||
			       u8 *p_connection_handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_establish_connection - start previously
 | 
			
		||||
 *        allocated LL2 queues pair
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param p_ptt
 | 
			
		||||
 * @param connection_handle	LL2 connection's handle obtained from
 | 
			
		||||
 *                              qed_ll2_require_connection
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, failure otherwise
 | 
			
		||||
 */
 | 
			
		||||
int qed_ll2_establish_connection(struct qed_hwfn *p_hwfn, u8 connection_handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_post_rx_buffers - submit buffers to LL2 Rx queue.
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param connection_handle	LL2 connection's handle obtained from
 | 
			
		||||
 *				qed_ll2_require_connection
 | 
			
		||||
 * @param addr			rx (physical address) buffers to submit
 | 
			
		||||
 * @param cookie
 | 
			
		||||
 * @param notify_fw		produce corresponding Rx BD immediately
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, failure otherwise
 | 
			
		||||
 */
 | 
			
		||||
int qed_ll2_post_rx_buffer(struct qed_hwfn *p_hwfn,
 | 
			
		||||
			   u8 connection_handle,
 | 
			
		||||
			   dma_addr_t addr,
 | 
			
		||||
			   u16 buf_len, void *cookie, u8 notify_fw);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_prepare_tx_packet - request for start Tx BD
 | 
			
		||||
 *				      to prepare Tx packet submission to FW.
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param connection_handle	LL2 connection's handle obtained from
 | 
			
		||||
 *				qed_ll2_require_connection
 | 
			
		||||
 * @param num_of_bds		a number of requested BD equals a number of
 | 
			
		||||
 *				fragments in Tx packet
 | 
			
		||||
 * @param vlan			VLAN to insert to packet (if insertion set)
 | 
			
		||||
 * @param bd_flags
 | 
			
		||||
 * @param l4_hdr_offset_w	L4 Header Offset from start of packet
 | 
			
		||||
 *				(in words). This is needed if both l4_csum
 | 
			
		||||
 *				and ipv6_ext are set
 | 
			
		||||
 * @param first_frag
 | 
			
		||||
 * @param first_frag_len
 | 
			
		||||
 * @param cookie
 | 
			
		||||
 *
 | 
			
		||||
 * @param notify_fw
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, failure otherwise
 | 
			
		||||
 */
 | 
			
		||||
int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
 | 
			
		||||
			      u8 connection_handle,
 | 
			
		||||
			      u8 num_of_bds,
 | 
			
		||||
			      u16 vlan,
 | 
			
		||||
			      u8 bd_flags,
 | 
			
		||||
			      u16 l4_hdr_offset_w,
 | 
			
		||||
			      dma_addr_t first_frag,
 | 
			
		||||
			      u16 first_frag_len, void *cookie, u8 notify_fw);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_release_connection -	releases resources
 | 
			
		||||
 *					allocated for LL2 connection
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param connection_handle		LL2 connection's handle obtained from
 | 
			
		||||
 *					qed_ll2_require_connection
 | 
			
		||||
 */
 | 
			
		||||
void qed_ll2_release_connection(struct qed_hwfn *p_hwfn, u8 connection_handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_set_fragment_of_tx_packet -	provides fragments to fill
 | 
			
		||||
 *						Tx BD of BDs requested by
 | 
			
		||||
 *						qed_ll2_prepare_tx_packet
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param connection_handle			LL2 connection's handle
 | 
			
		||||
 *						obtained from
 | 
			
		||||
 *						qed_ll2_require_connection
 | 
			
		||||
 * @param addr
 | 
			
		||||
 * @param nbytes
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, failure otherwise
 | 
			
		||||
 */
 | 
			
		||||
int qed_ll2_set_fragment_of_tx_packet(struct qed_hwfn *p_hwfn,
 | 
			
		||||
				      u8 connection_handle,
 | 
			
		||||
				      dma_addr_t addr, u16 nbytes);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_terminate_connection -	stops Tx/Rx queues
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param connection_handle			LL2 connection's handle
 | 
			
		||||
 *						obtained from
 | 
			
		||||
 *						qed_ll2_require_connection
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, failure otherwise
 | 
			
		||||
 */
 | 
			
		||||
int qed_ll2_terminate_connection(struct qed_hwfn *p_hwfn, u8 connection_handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_get_stats -	get LL2 queue's statistics
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param connection_handle	LL2 connection's handle obtained from
 | 
			
		||||
 *				qed_ll2_require_connection
 | 
			
		||||
 * @param p_stats
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, failure otherwise
 | 
			
		||||
 */
 | 
			
		||||
int qed_ll2_get_stats(struct qed_hwfn *p_hwfn,
 | 
			
		||||
		      u8 connection_handle, struct qed_ll2_stats *p_stats);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_alloc - Allocates LL2 connections set
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 *
 | 
			
		||||
 * @return pointer to alocated qed_ll2_info or NULL
 | 
			
		||||
 */
 | 
			
		||||
struct qed_ll2_info *qed_ll2_alloc(struct qed_hwfn *p_hwfn);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_setup - Inits LL2 connections set
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param p_ll2_connections
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void qed_ll2_setup(struct qed_hwfn *p_hwfn,
 | 
			
		||||
		   struct qed_ll2_info *p_ll2_connections);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief qed_ll2_free - Releases LL2 connections set
 | 
			
		||||
 *
 | 
			
		||||
 * @param p_hwfn
 | 
			
		||||
 * @param p_ll2_connections
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void qed_ll2_free(struct qed_hwfn *p_hwfn,
 | 
			
		||||
		  struct qed_ll2_info *p_ll2_connections);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -22,11 +22,13 @@
 | 
			
		|||
#include <linux/etherdevice.h>
 | 
			
		||||
#include <linux/vmalloc.h>
 | 
			
		||||
#include <linux/qed/qed_if.h>
 | 
			
		||||
#include <linux/qed/qed_ll2_if.h>
 | 
			
		||||
 | 
			
		||||
#include "qed.h"
 | 
			
		||||
#include "qed_sriov.h"
 | 
			
		||||
#include "qed_sp.h"
 | 
			
		||||
#include "qed_dev_api.h"
 | 
			
		||||
#include "qed_ll2.h"
 | 
			
		||||
#include "qed_mcp.h"
 | 
			
		||||
#include "qed_hw.h"
 | 
			
		||||
#include "qed_selftest.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -608,7 +610,16 @@ static int qed_nic_reset(struct qed_dev *cdev)
 | 
			
		|||
 | 
			
		||||
static int qed_nic_setup(struct qed_dev *cdev)
 | 
			
		||||
{
 | 
			
		||||
	int rc;
 | 
			
		||||
	int rc, i;
 | 
			
		||||
 | 
			
		||||
	/* Determine if interface is going to require LL2 */
 | 
			
		||||
	if (QED_LEADING_HWFN(cdev)->hw_info.personality != QED_PCI_ETH) {
 | 
			
		||||
		for (i = 0; i < cdev->num_hwfns; i++) {
 | 
			
		||||
			struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
 | 
			
		||||
 | 
			
		||||
			p_hwfn->using_ll2 = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rc = qed_resc_alloc(cdev);
 | 
			
		||||
	if (rc)
 | 
			
		||||
| 
						 | 
				
			
			@ -873,6 +884,12 @@ static int qed_slowpath_start(struct qed_dev *cdev,
 | 
			
		|||
	DP_INFO(cdev,
 | 
			
		||||
		"HW initialization and function start completed successfully\n");
 | 
			
		||||
 | 
			
		||||
	/* Allocate LL2 interface if needed */
 | 
			
		||||
	if (QED_LEADING_HWFN(cdev)->using_ll2) {
 | 
			
		||||
		rc = qed_ll2_alloc_if(cdev);
 | 
			
		||||
		if (rc)
 | 
			
		||||
			goto err3;
 | 
			
		||||
	}
 | 
			
		||||
	if (IS_PF(cdev)) {
 | 
			
		||||
		hwfn = QED_LEADING_HWFN(cdev);
 | 
			
		||||
		drv_version.version = (params->drv_major << 24) |
 | 
			
		||||
| 
						 | 
				
			
			@ -893,6 +910,8 @@ static int qed_slowpath_start(struct qed_dev *cdev,
 | 
			
		|||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
err3:
 | 
			
		||||
	qed_hw_stop(cdev);
 | 
			
		||||
err2:
 | 
			
		||||
	qed_hw_timers_stop_all(cdev);
 | 
			
		||||
	if (IS_PF(cdev))
 | 
			
		||||
| 
						 | 
				
			
			@ -915,6 +934,8 @@ static int qed_slowpath_stop(struct qed_dev *cdev)
 | 
			
		|||
	if (!cdev)
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
 | 
			
		||||
	qed_ll2_dealloc_if(cdev);
 | 
			
		||||
 | 
			
		||||
	if (IS_PF(cdev)) {
 | 
			
		||||
		qed_free_stream_mem(cdev);
 | 
			
		||||
		if (IS_QED_ETH_IF(cdev))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,6 +208,26 @@
 | 
			
		|||
	0x50196cUL
 | 
			
		||||
#define NIG_REG_LLH_CLS_TYPE_DUALMODE \
 | 
			
		||||
	0x501964UL
 | 
			
		||||
#define NIG_REG_LLH_FUNC_FILTER_VALUE \
 | 
			
		||||
	0x501a00UL
 | 
			
		||||
#define NIG_REG_LLH_FUNC_FILTER_VALUE_SIZE \
 | 
			
		||||
	32
 | 
			
		||||
#define NIG_REG_LLH_FUNC_FILTER_EN \
 | 
			
		||||
	0x501a80UL
 | 
			
		||||
#define NIG_REG_LLH_FUNC_FILTER_EN_SIZE	\
 | 
			
		||||
	16
 | 
			
		||||
#define NIG_REG_LLH_FUNC_FILTER_MODE \
 | 
			
		||||
	0x501ac0UL
 | 
			
		||||
#define NIG_REG_LLH_FUNC_FILTER_MODE_SIZE \
 | 
			
		||||
	16
 | 
			
		||||
#define NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE \
 | 
			
		||||
	0x501b00UL
 | 
			
		||||
#define NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE_SIZE \
 | 
			
		||||
	16
 | 
			
		||||
#define NIG_REG_LLH_FUNC_FILTER_HDR_SEL	\
 | 
			
		||||
	0x501b40UL
 | 
			
		||||
#define NIG_REG_LLH_FUNC_FILTER_HDR_SEL_SIZE \
 | 
			
		||||
	16
 | 
			
		||||
#define  NCSI_REG_CONFIG	\
 | 
			
		||||
	0x040200UL
 | 
			
		||||
#define  PBF_REG_INIT \
 | 
			
		||||
| 
						 | 
				
			
			@ -264,6 +284,8 @@
 | 
			
		|||
	0x1f0a1cUL
 | 
			
		||||
#define PRS_REG_ROCE_DEST_QP_MAX_PF \
 | 
			
		||||
	0x1f0430UL
 | 
			
		||||
#define PRS_REG_USE_LIGHT_L2 \
 | 
			
		||||
	0x1f096cUL
 | 
			
		||||
#define  PSDM_REG_ENABLE_IN1 \
 | 
			
		||||
	0xfa0004UL
 | 
			
		||||
#define  PSEM_REG_ENABLE_IN \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,6 +61,10 @@ union ramrod_data {
 | 
			
		|||
	struct vport_start_ramrod_data vport_start;
 | 
			
		||||
	struct vport_stop_ramrod_data vport_stop;
 | 
			
		||||
	struct vport_update_ramrod_data vport_update;
 | 
			
		||||
	struct core_rx_start_ramrod_data core_rx_queue_start;
 | 
			
		||||
	struct core_rx_stop_ramrod_data core_rx_queue_stop;
 | 
			
		||||
	struct core_tx_start_ramrod_data core_tx_queue_start;
 | 
			
		||||
	struct core_tx_stop_ramrod_data core_tx_queue_stop;
 | 
			
		||||
	struct vport_filter_update_ramrod_data vport_filter_update;
 | 
			
		||||
 | 
			
		||||
	struct rdma_init_func_ramrod_data rdma_init_func;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -627,6 +627,7 @@ enum DP_MODULE {
 | 
			
		|||
	QED_MSG_SP	= 0x100000,
 | 
			
		||||
	QED_MSG_STORAGE = 0x200000,
 | 
			
		||||
	QED_MSG_CXT	= 0x800000,
 | 
			
		||||
	QED_MSG_LL2	= 0x1000000,
 | 
			
		||||
	QED_MSG_ILT	= 0x2000000,
 | 
			
		||||
	QED_MSG_ROCE	= 0x4000000,
 | 
			
		||||
	QED_MSG_DEBUG	= 0x8000000,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										139
									
								
								include/linux/qed/qed_ll2_if.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								include/linux/qed/qed_ll2_if.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,139 @@
 | 
			
		|||
/* QLogic qed NIC Driver
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2015 QLogic Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * This software is available 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _QED_LL2_IF_H
 | 
			
		||||
#define _QED_LL2_IF_H
 | 
			
		||||
 | 
			
		||||
#include <linux/types.h>
 | 
			
		||||
#include <linux/interrupt.h>
 | 
			
		||||
#include <linux/netdevice.h>
 | 
			
		||||
#include <linux/pci.h>
 | 
			
		||||
#include <linux/skbuff.h>
 | 
			
		||||
#include <linux/version.h>
 | 
			
		||||
#include <linux/kernel.h>
 | 
			
		||||
#include <linux/slab.h>
 | 
			
		||||
#include <linux/qed/qed_if.h>
 | 
			
		||||
 | 
			
		||||
struct qed_ll2_stats {
 | 
			
		||||
	u64 gsi_invalid_hdr;
 | 
			
		||||
	u64 gsi_invalid_pkt_length;
 | 
			
		||||
	u64 gsi_unsupported_pkt_typ;
 | 
			
		||||
	u64 gsi_crcchksm_error;
 | 
			
		||||
 | 
			
		||||
	u64 packet_too_big_discard;
 | 
			
		||||
	u64 no_buff_discard;
 | 
			
		||||
 | 
			
		||||
	u64 rcv_ucast_bytes;
 | 
			
		||||
	u64 rcv_mcast_bytes;
 | 
			
		||||
	u64 rcv_bcast_bytes;
 | 
			
		||||
	u64 rcv_ucast_pkts;
 | 
			
		||||
	u64 rcv_mcast_pkts;
 | 
			
		||||
	u64 rcv_bcast_pkts;
 | 
			
		||||
 | 
			
		||||
	u64 sent_ucast_bytes;
 | 
			
		||||
	u64 sent_mcast_bytes;
 | 
			
		||||
	u64 sent_bcast_bytes;
 | 
			
		||||
	u64 sent_ucast_pkts;
 | 
			
		||||
	u64 sent_mcast_pkts;
 | 
			
		||||
	u64 sent_bcast_pkts;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define QED_LL2_UNUSED_HANDLE   (0xff)
 | 
			
		||||
 | 
			
		||||
struct qed_ll2_cb_ops {
 | 
			
		||||
	int (*rx_cb)(void *, struct sk_buff *, u32, u32);
 | 
			
		||||
	int (*tx_cb)(void *, struct sk_buff *, bool);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qed_ll2_params {
 | 
			
		||||
	u16 mtu;
 | 
			
		||||
	bool drop_ttl0_packets;
 | 
			
		||||
	bool rx_vlan_stripping;
 | 
			
		||||
	u8 tx_tc;
 | 
			
		||||
	bool frags_mapped;
 | 
			
		||||
	u8 ll2_mac_address[ETH_ALEN];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qed_ll2_ops {
 | 
			
		||||
/**
 | 
			
		||||
 * @brief start - initializes ll2
 | 
			
		||||
 *
 | 
			
		||||
 * @param cdev
 | 
			
		||||
 * @param params - protocol driver configuration for the ll2.
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, otherwise error value.
 | 
			
		||||
 */
 | 
			
		||||
	int (*start)(struct qed_dev *cdev, struct qed_ll2_params *params);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief stop - stops the ll2
 | 
			
		||||
 *
 | 
			
		||||
 * @param cdev
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, otherwise error value.
 | 
			
		||||
 */
 | 
			
		||||
	int (*stop)(struct qed_dev *cdev);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief start_xmit - transmits an skb over the ll2 interface
 | 
			
		||||
 *
 | 
			
		||||
 * @param cdev
 | 
			
		||||
 * @param skb
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, otherwise error value.
 | 
			
		||||
 */
 | 
			
		||||
	int (*start_xmit)(struct qed_dev *cdev, struct sk_buff *skb);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief register_cb_ops - protocol driver register the callback for Rx/Tx
 | 
			
		||||
 * packets. Should be called before `start'.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cdev
 | 
			
		||||
 * @param cookie - to be passed to the callback functions.
 | 
			
		||||
 * @param ops - the callback functions to register for Rx / Tx.
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, otherwise error value.
 | 
			
		||||
 */
 | 
			
		||||
	void (*register_cb_ops)(struct qed_dev *cdev,
 | 
			
		||||
				const struct qed_ll2_cb_ops *ops,
 | 
			
		||||
				void *cookie);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief get LL2 related statistics
 | 
			
		||||
 *
 | 
			
		||||
 * @param cdev
 | 
			
		||||
 * @param stats - pointer to struct that would be filled with stats
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, error otherwise.
 | 
			
		||||
 */
 | 
			
		||||
	int (*get_stats)(struct qed_dev *cdev, struct qed_ll2_stats *stats);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_QED_LL2
 | 
			
		||||
int qed_ll2_alloc_if(struct qed_dev *);
 | 
			
		||||
void qed_ll2_dealloc_if(struct qed_dev *);
 | 
			
		||||
#else
 | 
			
		||||
static const struct qed_ll2_ops qed_ll2_ops_pass = {
 | 
			
		||||
	.start = NULL,
 | 
			
		||||
	.stop = NULL,
 | 
			
		||||
	.start_xmit = NULL,
 | 
			
		||||
	.register_cb_ops = NULL,
 | 
			
		||||
	.get_stats = NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline int qed_ll2_alloc_if(struct qed_dev *cdev)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void qed_ll2_dealloc_if(struct qed_dev *cdev)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
		Reference in a new issue