114b24e2bSVaishali Kulkarni /*
214b24e2bSVaishali Kulkarni * CDDL HEADER START
314b24e2bSVaishali Kulkarni *
414b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the
514b24e2bSVaishali Kulkarni * Common Development and Distribution License, v.1,  (the "License").
614b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License.
714b24e2bSVaishali Kulkarni *
814b24e2bSVaishali Kulkarni * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
914b24e2bSVaishali Kulkarni * or http://opensource.org/licenses/CDDL-1.0.
1014b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions
1114b24e2bSVaishali Kulkarni * and limitations under the License.
1214b24e2bSVaishali Kulkarni *
1314b24e2bSVaishali Kulkarni * When distributing Covered Code, include this CDDL HEADER in each
1414b24e2bSVaishali Kulkarni * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1514b24e2bSVaishali Kulkarni * If applicable, add the following below this CDDL HEADER, with the
1614b24e2bSVaishali Kulkarni * fields enclosed by brackets "[]" replaced with your own identifying
1714b24e2bSVaishali Kulkarni * information: Portions Copyright [yyyy] [name of copyright owner]
1814b24e2bSVaishali Kulkarni *
1914b24e2bSVaishali Kulkarni * CDDL HEADER END
2014b24e2bSVaishali Kulkarni */
2114b24e2bSVaishali Kulkarni 
2214b24e2bSVaishali Kulkarni /*
2314b24e2bSVaishali Kulkarni * Copyright 2014-2017 Cavium, Inc.
2414b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the Common Development
2514b24e2bSVaishali Kulkarni * and Distribution License, v.1,  (the "License").
2614b24e2bSVaishali Kulkarni 
2714b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License.
2814b24e2bSVaishali Kulkarni 
2914b24e2bSVaishali Kulkarni * You can obtain a copy of the License at available
3014b24e2bSVaishali Kulkarni * at http://opensource.org/licenses/CDDL-1.0
3114b24e2bSVaishali Kulkarni 
3214b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions and
3314b24e2bSVaishali Kulkarni * limitations under the License.
3414b24e2bSVaishali Kulkarni */
3514b24e2bSVaishali Kulkarni 
3614b24e2bSVaishali Kulkarni #include "bcm_osal.h"
3714b24e2bSVaishali Kulkarni 
3814b24e2bSVaishali Kulkarni #include "ecore.h"
3914b24e2bSVaishali Kulkarni #include "ecore_status.h"
4014b24e2bSVaishali Kulkarni #include "ecore_hsi_eth.h"
4114b24e2bSVaishali Kulkarni #include "ecore_chain.h"
4214b24e2bSVaishali Kulkarni #include "ecore_spq.h"
4314b24e2bSVaishali Kulkarni #include "ecore_init_fw_funcs.h"
4414b24e2bSVaishali Kulkarni #include "ecore_cxt.h"
4514b24e2bSVaishali Kulkarni #include "ecore_l2.h"
4614b24e2bSVaishali Kulkarni #include "ecore_sp_commands.h"
4714b24e2bSVaishali Kulkarni #include "ecore_gtt_reg_addr.h"
4814b24e2bSVaishali Kulkarni #include "ecore_iro.h"
4914b24e2bSVaishali Kulkarni #include "reg_addr.h"
5014b24e2bSVaishali Kulkarni #include "ecore_int.h"
5114b24e2bSVaishali Kulkarni #include "ecore_hw.h"
5214b24e2bSVaishali Kulkarni #include "ecore_vf.h"
5314b24e2bSVaishali Kulkarni #include "ecore_sriov.h"
5414b24e2bSVaishali Kulkarni #include "ecore_mcp.h"
5514b24e2bSVaishali Kulkarni 
5614b24e2bSVaishali Kulkarni #define ECORE_MAX_SGES_NUM 16
5714b24e2bSVaishali Kulkarni #define CRC32_POLY 0x1edc6f41
5814b24e2bSVaishali Kulkarni 
5914b24e2bSVaishali Kulkarni struct ecore_l2_info {
6014b24e2bSVaishali Kulkarni 	u32 queues;
6114b24e2bSVaishali Kulkarni 	unsigned long **pp_qid_usage;
6214b24e2bSVaishali Kulkarni 
6314b24e2bSVaishali Kulkarni 	/* The lock is meant to synchronize access to the qid usage */
6414b24e2bSVaishali Kulkarni 	osal_mutex_t lock;
6514b24e2bSVaishali Kulkarni };
6614b24e2bSVaishali Kulkarni 
ecore_l2_alloc(struct ecore_hwfn * p_hwfn)6714b24e2bSVaishali Kulkarni enum _ecore_status_t ecore_l2_alloc(struct ecore_hwfn *p_hwfn)
6814b24e2bSVaishali Kulkarni {
6914b24e2bSVaishali Kulkarni 	struct ecore_l2_info *p_l2_info;
7014b24e2bSVaishali Kulkarni 	unsigned long **pp_qids;
7114b24e2bSVaishali Kulkarni 	u32 i;
7214b24e2bSVaishali Kulkarni 
7314b24e2bSVaishali Kulkarni 	if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
7414b24e2bSVaishali Kulkarni 		return ECORE_SUCCESS;
7514b24e2bSVaishali Kulkarni 
7614b24e2bSVaishali Kulkarni 	p_l2_info = OSAL_VZALLOC(p_hwfn->p_dev, sizeof(*p_l2_info));
7714b24e2bSVaishali Kulkarni 	if (!p_l2_info)
7814b24e2bSVaishali Kulkarni 		return ECORE_NOMEM;
7914b24e2bSVaishali Kulkarni 	p_hwfn->p_l2_info = p_l2_info;
8014b24e2bSVaishali Kulkarni 
8114b24e2bSVaishali Kulkarni 	if (IS_PF(p_hwfn->p_dev)) {
8214b24e2bSVaishali Kulkarni 		p_l2_info->queues = RESC_NUM(p_hwfn, ECORE_L2_QUEUE);
8314b24e2bSVaishali Kulkarni 	} else {
8414b24e2bSVaishali Kulkarni 		u8 rx = 0, tx = 0;
8514b24e2bSVaishali Kulkarni 
8614b24e2bSVaishali Kulkarni 		ecore_vf_get_num_rxqs(p_hwfn, &rx);
8714b24e2bSVaishali Kulkarni 		ecore_vf_get_num_txqs(p_hwfn, &tx);
8814b24e2bSVaishali Kulkarni 
8914b24e2bSVaishali Kulkarni 		p_l2_info->queues = (u32)OSAL_MAX_T(u8, rx, tx);
9014b24e2bSVaishali Kulkarni 	}
9114b24e2bSVaishali Kulkarni 
9214b24e2bSVaishali Kulkarni 	pp_qids = OSAL_VZALLOC(p_hwfn->p_dev,
9314b24e2bSVaishali Kulkarni 			       sizeof(unsigned long *) *
9414b24e2bSVaishali Kulkarni 			       p_l2_info->queues);
9514b24e2bSVaishali Kulkarni 	if (pp_qids == OSAL_NULL)
9614b24e2bSVaishali Kulkarni 		return ECORE_NOMEM;
9714b24e2bSVaishali Kulkarni 	p_l2_info->pp_qid_usage = pp_qids;
9814b24e2bSVaishali Kulkarni 
9914b24e2bSVaishali Kulkarni 	for (i = 0; i < p_l2_info->queues; i++) {
10014b24e2bSVaishali Kulkarni 		pp_qids[i] = OSAL_VZALLOC(p_hwfn->p_dev,
10114b24e2bSVaishali Kulkarni 					  MAX_QUEUES_PER_QZONE / 8);
10214b24e2bSVaishali Kulkarni 		if (pp_qids[i] == OSAL_NULL)
10314b24e2bSVaishali Kulkarni 			return ECORE_NOMEM;
10414b24e2bSVaishali Kulkarni 	}
10514b24e2bSVaishali Kulkarni 
10614b24e2bSVaishali Kulkarni #ifdef CONFIG_ECORE_LOCK_ALLOC
10714b24e2bSVaishali Kulkarni 	OSAL_MUTEX_ALLOC(p_hwfn, &p_l2_info->lock);
10814b24e2bSVaishali Kulkarni #endif
10914b24e2bSVaishali Kulkarni 
11014b24e2bSVaishali Kulkarni 	return ECORE_SUCCESS;
11114b24e2bSVaishali Kulkarni }
11214b24e2bSVaishali Kulkarni 
ecore_l2_setup(struct ecore_hwfn * p_hwfn)11314b24e2bSVaishali Kulkarni void ecore_l2_setup(struct ecore_hwfn *p_hwfn)
11414b24e2bSVaishali Kulkarni {
11514b24e2bSVaishali Kulkarni 	if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
11614b24e2bSVaishali Kulkarni 		return;
11714b24e2bSVaishali Kulkarni 
11814b24e2bSVaishali Kulkarni 	OSAL_MUTEX_INIT(&p_hwfn->p_l2_info->lock);
11914b24e2bSVaishali Kulkarni }
12014b24e2bSVaishali Kulkarni 
ecore_l2_free(struct ecore_hwfn * p_hwfn)12114b24e2bSVaishali Kulkarni void ecore_l2_free(struct ecore_hwfn *p_hwfn)
12214b24e2bSVaishali Kulkarni {
12314b24e2bSVaishali Kulkarni 	u32 i;
12414b24e2bSVaishali Kulkarni 
12514b24e2bSVaishali Kulkarni 	if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
12614b24e2bSVaishali Kulkarni 		return;
12714b24e2bSVaishali Kulkarni 
12814b24e2bSVaishali Kulkarni 	if (p_hwfn->p_l2_info == OSAL_NULL)
12914b24e2bSVaishali Kulkarni 		return;
13014b24e2bSVaishali Kulkarni 
13114b24e2bSVaishali Kulkarni 	if (p_hwfn->p_l2_info->pp_qid_usage == OSAL_NULL)
13214b24e2bSVaishali Kulkarni 		goto out_l2_info;
13314b24e2bSVaishali Kulkarni 
13414b24e2bSVaishali Kulkarni 	/* Free until hit first uninitialized entry */
13514b24e2bSVaishali Kulkarni 	for (i = 0; i < p_hwfn->p_l2_info->queues; i++) {
13614b24e2bSVaishali Kulkarni 		if (p_hwfn->p_l2_info->pp_qid_usage[i] == OSAL_NULL)
13714b24e2bSVaishali Kulkarni 			break;
13814b24e2bSVaishali Kulkarni 		OSAL_VFREE(p_hwfn->p_dev,
13914b24e2bSVaishali Kulkarni 			   p_hwfn->p_l2_info->pp_qid_usage[i]);
14014b24e2bSVaishali Kulkarni 	}
14114b24e2bSVaishali Kulkarni 
14214b24e2bSVaishali Kulkarni #ifdef CONFIG_ECORE_LOCK_ALLOC
14314b24e2bSVaishali Kulkarni 	/* Lock is last to initialize, if everything else was */
14414b24e2bSVaishali Kulkarni 	if (i == p_hwfn->p_l2_info->queues)
14514b24e2bSVaishali Kulkarni 		OSAL_MUTEX_DEALLOC(&p_hwfn->p_l2_info->lock);
14614b24e2bSVaishali Kulkarni #endif
14714b24e2bSVaishali Kulkarni 
14814b24e2bSVaishali Kulkarni 	OSAL_VFREE(p_hwfn->p_dev, p_hwfn->p_l2_info->pp_qid_usage);
14914b24e2bSVaishali Kulkarni 
15014b24e2bSVaishali Kulkarni out_l2_info:
15114b24e2bSVaishali Kulkarni 	OSAL_VFREE(p_hwfn->p_dev, p_hwfn->p_l2_info);
15214b24e2bSVaishali Kulkarni 	p_hwfn->p_l2_info = OSAL_NULL;
15314b24e2bSVaishali Kulkarni }
15414b24e2bSVaishali Kulkarni 
15514b24e2bSVaishali Kulkarni /* TODO - we'll need locking around these... */
ecore_eth_queue_qid_usage_add(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)15614b24e2bSVaishali Kulkarni static bool ecore_eth_queue_qid_usage_add(struct ecore_hwfn *p_hwfn,
15714b24e2bSVaishali Kulkarni 					  struct ecore_queue_cid *p_cid)
15814b24e2bSVaishali Kulkarni {
15914b24e2bSVaishali Kulkarni 	struct ecore_l2_info *p_l2_info = p_hwfn->p_l2_info;
16014b24e2bSVaishali Kulkarni 	u16 queue_id = p_cid->rel.queue_id;
16114b24e2bSVaishali Kulkarni 	bool b_rc = true;
16214b24e2bSVaishali Kulkarni 	u8 first;
16314b24e2bSVaishali Kulkarni 
16414b24e2bSVaishali Kulkarni 	OSAL_MUTEX_ACQUIRE(&p_l2_info->lock);
16514b24e2bSVaishali Kulkarni 
16614b24e2bSVaishali Kulkarni 	if (queue_id > p_l2_info->queues) {
16714b24e2bSVaishali Kulkarni 		DP_NOTICE(p_hwfn, true,
16814b24e2bSVaishali Kulkarni 			  "Requested to increase usage for qzone %04x out of %08x\n",
16914b24e2bSVaishali Kulkarni 			  queue_id, p_l2_info->queues);
17014b24e2bSVaishali Kulkarni 		b_rc = false;
17114b24e2bSVaishali Kulkarni 		goto out;
17214b24e2bSVaishali Kulkarni 	}
17314b24e2bSVaishali Kulkarni 
17414b24e2bSVaishali Kulkarni 	first = (u8)OSAL_FIND_FIRST_ZERO_BIT(p_l2_info->pp_qid_usage[queue_id],
17514b24e2bSVaishali Kulkarni 					     MAX_QUEUES_PER_QZONE);
17614b24e2bSVaishali Kulkarni 	if (first >= MAX_QUEUES_PER_QZONE) {
17714b24e2bSVaishali Kulkarni 		b_rc = false;
17814b24e2bSVaishali Kulkarni 		goto out;
17914b24e2bSVaishali Kulkarni 	}
18014b24e2bSVaishali Kulkarni 
18114b24e2bSVaishali Kulkarni 	OSAL_SET_BIT(first, p_l2_info->pp_qid_usage[queue_id]);
18214b24e2bSVaishali Kulkarni 	p_cid->qid_usage_idx = first;
18314b24e2bSVaishali Kulkarni 
18414b24e2bSVaishali Kulkarni out:
18514b24e2bSVaishali Kulkarni 	OSAL_MUTEX_RELEASE(&p_l2_info->lock);
18614b24e2bSVaishali Kulkarni 	return b_rc;
18714b24e2bSVaishali Kulkarni }
18814b24e2bSVaishali Kulkarni 
ecore_eth_queue_qid_usage_del(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)18914b24e2bSVaishali Kulkarni static void ecore_eth_queue_qid_usage_del(struct ecore_hwfn *p_hwfn,
19014b24e2bSVaishali Kulkarni 					  struct ecore_queue_cid *p_cid)
19114b24e2bSVaishali Kulkarni {
19214b24e2bSVaishali Kulkarni 	OSAL_MUTEX_ACQUIRE(&p_hwfn->p_l2_info->lock);
19314b24e2bSVaishali Kulkarni 
19414b24e2bSVaishali Kulkarni 	OSAL_CLEAR_BIT(p_cid->qid_usage_idx,
19514b24e2bSVaishali Kulkarni 		       p_hwfn->p_l2_info->pp_qid_usage[p_cid->rel.queue_id]);
19614b24e2bSVaishali Kulkarni 
19714b24e2bSVaishali Kulkarni 	OSAL_MUTEX_RELEASE(&p_hwfn->p_l2_info->lock);
19814b24e2bSVaishali Kulkarni }
19914b24e2bSVaishali Kulkarni 
ecore_eth_queue_cid_release(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)20014b24e2bSVaishali Kulkarni void ecore_eth_queue_cid_release(struct ecore_hwfn *p_hwfn,
20114b24e2bSVaishali Kulkarni 				 struct ecore_queue_cid *p_cid)
20214b24e2bSVaishali Kulkarni {
20314b24e2bSVaishali Kulkarni 	bool b_legacy_vf = !!(p_cid->vf_legacy &
20414b24e2bSVaishali Kulkarni 			      ECORE_QCID_LEGACY_VF_CID);
20514b24e2bSVaishali Kulkarni 
20614b24e2bSVaishali Kulkarni 	/* VFs' CIDs are 0-based in PF-view, and uninitialized on VF.
20714b24e2bSVaishali Kulkarni 	 * For legacy vf-queues, the CID doesn't go through here.
20814b24e2bSVaishali Kulkarni 	 */
20914b24e2bSVaishali Kulkarni 	if (IS_PF(p_hwfn->p_dev) && !b_legacy_vf)
21014b24e2bSVaishali Kulkarni 		_ecore_cxt_release_cid(p_hwfn, p_cid->cid, p_cid->vfid);
21114b24e2bSVaishali Kulkarni 
21214b24e2bSVaishali Kulkarni 	/* VFs maintain the index inside queue-zone on their own */
21314b24e2bSVaishali Kulkarni 	if (p_cid->vfid == ECORE_QUEUE_CID_PF)
21414b24e2bSVaishali Kulkarni 		ecore_eth_queue_qid_usage_del(p_hwfn, p_cid);
21514b24e2bSVaishali Kulkarni 
21614b24e2bSVaishali Kulkarni 	OSAL_VFREE(p_hwfn->p_dev, p_cid);
21714b24e2bSVaishali Kulkarni }
21814b24e2bSVaishali Kulkarni 
21914b24e2bSVaishali Kulkarni /* The internal is only meant to be directly called by PFs initializeing CIDs
22014b24e2bSVaishali Kulkarni  * for their VFs.
22114b24e2bSVaishali Kulkarni  */
22214b24e2bSVaishali Kulkarni static struct ecore_queue_cid *
_ecore_eth_queue_to_cid(struct ecore_hwfn * p_hwfn,u16 opaque_fid,u32 cid,struct ecore_queue_start_common_params * p_params,struct ecore_queue_cid_vf_params * p_vf_params)22314b24e2bSVaishali Kulkarni _ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn,
22414b24e2bSVaishali Kulkarni 			u16 opaque_fid, u32 cid,
22514b24e2bSVaishali Kulkarni 			struct ecore_queue_start_common_params *p_params,
22614b24e2bSVaishali Kulkarni 			struct ecore_queue_cid_vf_params *p_vf_params)
22714b24e2bSVaishali Kulkarni {
22814b24e2bSVaishali Kulkarni 	struct ecore_queue_cid *p_cid;
22914b24e2bSVaishali Kulkarni 	enum _ecore_status_t rc;
23014b24e2bSVaishali Kulkarni 
23114b24e2bSVaishali Kulkarni 	p_cid = OSAL_VZALLOC(p_hwfn->p_dev, sizeof(*p_cid));
23214b24e2bSVaishali Kulkarni 	if (p_cid == OSAL_NULL)
23314b24e2bSVaishali Kulkarni 		return OSAL_NULL;
23414b24e2bSVaishali Kulkarni 
23514b24e2bSVaishali Kulkarni 	p_cid->opaque_fid = opaque_fid;
23614b24e2bSVaishali Kulkarni 	p_cid->cid = cid;
23714b24e2bSVaishali Kulkarni 	p_cid->p_owner = p_hwfn;
23814b24e2bSVaishali Kulkarni 
23914b24e2bSVaishali Kulkarni 	/* Fill in parameters */
24014b24e2bSVaishali Kulkarni 	p_cid->rel.vport_id = p_params->vport_id;
24114b24e2bSVaishali Kulkarni 	p_cid->rel.queue_id = p_params->queue_id;
24214b24e2bSVaishali Kulkarni 	p_cid->rel.stats_id = p_params->stats_id;
24314b24e2bSVaishali Kulkarni 	p_cid->sb_igu_id = p_params->p_sb->igu_sb_id;
24414b24e2bSVaishali Kulkarni 	p_cid->sb_idx = p_params->sb_idx;
24514b24e2bSVaishali Kulkarni 
24614b24e2bSVaishali Kulkarni 	/* Fill-in bits related to VFs' queues if information was provided */
24714b24e2bSVaishali Kulkarni 	if (p_vf_params != OSAL_NULL) {
24814b24e2bSVaishali Kulkarni 		p_cid->vfid = p_vf_params->vfid;
24914b24e2bSVaishali Kulkarni 		p_cid->vf_qid = p_vf_params->vf_qid;
25014b24e2bSVaishali Kulkarni 		p_cid->vf_legacy = p_vf_params->vf_legacy;
25114b24e2bSVaishali Kulkarni 	} else {
25214b24e2bSVaishali Kulkarni 		p_cid->vfid = ECORE_QUEUE_CID_PF;
25314b24e2bSVaishali Kulkarni 	}
25414b24e2bSVaishali Kulkarni 
25514b24e2bSVaishali Kulkarni 	/* Don't try calculating the absolute indices for VFs */
25614b24e2bSVaishali Kulkarni 	if (IS_VF(p_hwfn->p_dev)) {
25714b24e2bSVaishali Kulkarni 		p_cid->abs = p_cid->rel;
25814b24e2bSVaishali Kulkarni 
25914b24e2bSVaishali Kulkarni 		goto out;
26014b24e2bSVaishali Kulkarni 	}
26114b24e2bSVaishali Kulkarni 
26214b24e2bSVaishali Kulkarni 	/* Calculate the engine-absolute indices of the resources.
26314b24e2bSVaishali Kulkarni 	 * The would guarantee they're valid later on.
26414b24e2bSVaishali Kulkarni 	 * In some cases [SBs] we already have the right values.
26514b24e2bSVaishali Kulkarni 	 */
26614b24e2bSVaishali Kulkarni 	rc = ecore_fw_vport(p_hwfn, p_cid->rel.vport_id, &p_cid->abs.vport_id);
26714b24e2bSVaishali Kulkarni 	if (rc != ECORE_SUCCESS)
26814b24e2bSVaishali Kulkarni 		goto fail;
26914b24e2bSVaishali Kulkarni 
27014b24e2bSVaishali Kulkarni 	rc = ecore_fw_l2_queue(p_hwfn, p_cid->rel.queue_id,
27114b24e2bSVaishali Kulkarni 			       &p_cid->abs.queue_id);
27214b24e2bSVaishali Kulkarni 	if (rc != ECORE_SUCCESS)
27314b24e2bSVaishali Kulkarni 		goto fail;
27414b24e2bSVaishali Kulkarni 
27514b24e2bSVaishali Kulkarni 	/* In case of a PF configuring its VF's queues, the stats-id is already
27614b24e2bSVaishali Kulkarni 	 * absolute [since there's a single index that's suitable per-VF].
27714b24e2bSVaishali Kulkarni 	 */
27814b24e2bSVaishali Kulkarni 	if (p_cid->vfid == ECORE_QUEUE_CID_PF) {
27914b24e2bSVaishali Kulkarni 		rc = ecore_fw_vport(p_hwfn, p_cid->rel.stats_id,
28014b24e2bSVaishali Kulkarni 				    &p_cid->abs.stats_id);
28114b24e2bSVaishali Kulkarni 		if (rc != ECORE_SUCCESS)
28214b24e2bSVaishali Kulkarni 			goto fail;
28314b24e2bSVaishali Kulkarni 	} else {
28414b24e2bSVaishali Kulkarni 		p_cid->abs.stats_id = p_cid->rel.stats_id;
28514b24e2bSVaishali Kulkarni 	}
28614b24e2bSVaishali Kulkarni 
28714b24e2bSVaishali Kulkarni out:
28814b24e2bSVaishali Kulkarni 	/* VF-images have provided the qid_usage_idx on their own.
28914b24e2bSVaishali Kulkarni 	 * Otherwise, we need to allocate a unique one.
29014b24e2bSVaishali Kulkarni 	 */
29114b24e2bSVaishali Kulkarni 	if (!p_vf_params) {
29214b24e2bSVaishali Kulkarni 		if (!ecore_eth_queue_qid_usage_add(p_hwfn, p_cid))
29314b24e2bSVaishali Kulkarni 			goto fail;
29414b24e2bSVaishali Kulkarni 	} else {
29514b24e2bSVaishali Kulkarni 		p_cid->qid_usage_idx = p_vf_params->qid_usage_idx;
29614b24e2bSVaishali Kulkarni 	}
29714b24e2bSVaishali Kulkarni 
29814b24e2bSVaishali Kulkarni 	DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
29914b24e2bSVaishali Kulkarni 		   "opaque_fid: %04x CID %08x vport %02x [%02x] qzone %04x.%02x [%04x] stats %02x [%02x] SB %04x PI %02x\n",
30014b24e2bSVaishali Kulkarni 		   p_cid->opaque_fid, p_cid->cid,
30114b24e2bSVaishali Kulkarni 		   p_cid->rel.vport_id, p_cid->abs.vport_id,
30214b24e2bSVaishali Kulkarni 		   p_cid->rel.queue_id,	p_cid->qid_usage_idx,
30314b24e2bSVaishali Kulkarni 		   p_cid->abs.queue_id,
30414b24e2bSVaishali Kulkarni 		   p_cid->rel.stats_id, p_cid->abs.stats_id,
30514b24e2bSVaishali Kulkarni 		   p_cid->sb_igu_id, p_cid->sb_idx);
30614b24e2bSVaishali Kulkarni 
30714b24e2bSVaishali Kulkarni 	return p_cid;
30814b24e2bSVaishali Kulkarni 
30914b24e2bSVaishali Kulkarni fail:
31014b24e2bSVaishali Kulkarni 	OSAL_VFREE(p_hwfn->p_dev, p_cid);
31114b24e2bSVaishali Kulkarni 	return OSAL_NULL;
31214b24e2bSVaishali Kulkarni }
31314b24e2bSVaishali Kulkarni 
31414b24e2bSVaishali Kulkarni struct ecore_queue_cid *
ecore_eth_queue_to_cid(struct ecore_hwfn * p_hwfn,u16 opaque_fid,struct ecore_queue_start_common_params * p_params,struct ecore_queue_cid_vf_params * p_vf_params)31514b24e2bSVaishali Kulkarni ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
31614b24e2bSVaishali Kulkarni 		       struct ecore_queue_start_common_params *p_params,
31714b24e2bSVaishali Kulkarni 		       struct ecore_queue_cid_vf_params *p_vf_params)
31814b24e2bSVaishali Kulkarni {
31914b24e2bSVaishali Kulkarni 	struct ecore_queue_cid *p_cid;
32014b24e2bSVaishali Kulkarni 	u8 vfid = ECORE_CXT_PF_CID;
32114b24e2bSVaishali Kulkarni 	bool b_legacy_vf = false;
32214b24e2bSVaishali Kulkarni 	u32 cid = 0;
32314b24e2bSVaishali Kulkarni 
32414b24e2bSVaishali Kulkarni 	/* In case of legacy VFs, The CID can be derived from the additional
32514b24e2bSVaishali Kulkarni 	 * VF parameters - the VF assumes queue X uses CID X, so we can simply
32614b24e2bSVaishali Kulkarni 	 * use the vf_qid for this purpose as well.
32714b24e2bSVaishali Kulkarni 	 */
32814b24e2bSVaishali Kulkarni 	if (p_vf_params) {
32914b24e2bSVaishali Kulkarni 		vfid = p_vf_params->vfid;
33014b24e2bSVaishali Kulkarni 
33114b24e2bSVaishali Kulkarni 		if (p_vf_params->vf_legacy &
33214b24e2bSVaishali Kulkarni 		    ECORE_QCID_LEGACY_VF_CID) {
33314b24e2bSVaishali Kulkarni 			b_legacy_vf = true;
33414b24e2bSVaishali Kulkarni 			cid = p_vf_params->vf_qid;
33514b24e2bSVaishali Kulkarni 		}
33614b24e2bSVaishali Kulkarni 	}
33714b24e2bSVaishali Kulkarni 
33814b24e2bSVaishali Kulkarni 	/* Get a unique firmware CID for this queue, in case it's a PF.
33914b24e2bSVaishali Kulkarni 	 * VF's don't need a CID as the queue configuration will be done
34014b24e2bSVaishali Kulkarni 	 * by PF.
34114b24e2bSVaishali Kulkarni 	 */
34214b24e2bSVaishali Kulkarni 	if (IS_PF(p_hwfn->p_dev) && !b_legacy_vf) {
34314b24e2bSVaishali Kulkarni 		if (_ecore_cxt_acquire_cid(p_hwfn, PROTOCOLID_ETH,
34414b24e2bSVaishali Kulkarni 					   &cid, vfid) != ECORE_SUCCESS) {
34514b24e2bSVaishali Kulkarni 			DP_NOTICE(p_hwfn, true, "Failed to acquire cid\n");
34614b24e2bSVaishali Kulkarni 			return OSAL_NULL;
34714b24e2bSVaishali Kulkarni 		}
34814b24e2bSVaishali Kulkarni 	}
34914b24e2bSVaishali Kulkarni 
35014b24e2bSVaishali Kulkarni 	p_cid = _ecore_eth_queue_to_cid(p_hwfn, opaque_fid, cid,
35114b24e2bSVaishali Kulkarni 					p_params, p_vf_params);
35214b24e2bSVaishali Kulkarni 	if ((p_cid == OSAL_NULL) && IS_PF(p_hwfn->p_dev) && !b_legacy_vf)
35314b24e2bSVaishali Kulkarni 		_ecore_cxt_release_cid(p_hwfn, cid, vfid);
35414b24e2bSVaishali Kulkarni 
35514b24e2bSVaishali Kulkarni 	return p_cid;
35614b24e2bSVaishali Kulkarni }
35714b24e2bSVaishali Kulkarni 
35814b24e2bSVaishali Kulkarni static struct ecore_queue_cid *
ecore_eth_queue_to_cid_pf(struct ecore_hwfn * p_hwfn,u16 opaque_fid,struct ecore_queue_start_common_params * p_params)35914b24e2bSVaishali Kulkarni ecore_eth_queue_to_cid_pf(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
36014b24e2bSVaishali Kulkarni 			  struct ecore_queue_start_common_params *p_params)
36114b24e2bSVaishali Kulkarni {
36214b24e2bSVaishali Kulkarni 	return ecore_eth_queue_to_cid(p_hwfn, opaque_fid, p_params, OSAL_NULL);
36314b24e2bSVaishali Kulkarni }
36414b24e2bSVaishali Kulkarni 
ecore_sp_eth_vport_start(struct ecore_hwfn * p_hwfn,struct ecore_sp_vport_start_params * p_params)36514b24e2bSVaishali Kulkarni enum _ecore_status_t ecore_sp_eth_vport_start(struct ecore_hwfn *p_hwfn,
36614b24e2bSVaishali Kulkarni 					      struct ecore_sp_vport_start_params *p_params)
36714b24e2bSVaishali Kulkarni {
36814b24e2bSVaishali Kulkarni 	struct vport_start_ramrod_data *p_ramrod = OSAL_NULL;
36914b24e2bSVaishali Kulkarni 	struct ecore_spq_entry *p_ent = OSAL_NULL;
37014b24e2bSVaishali Kulkarni 	struct ecore_sp_init_data init_data;
37114b24e2bSVaishali Kulkarni 	u16 rx_mode = 0, tx_err = 0;
37214b24e2bSVaishali Kulkarni 	u8 abs_vport_id = 0;
37314b24e2bSVaishali Kulkarni 	enum _ecore_status_t rc = ECORE_NOTIMPL;
37414b24e2bSVaishali Kulkarni 
37514b24e2bSVaishali Kulkarni 	rc = ecore_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
37614b24e2bSVaishali Kulkarni 	if (rc != ECORE_SUCCESS)
37714b24e2bSVaishali Kulkarni 		return rc;
37814b24e2bSVaishali Kulkarni 
37914b24e2bSVaishali Kulkarni 	/* Get SPQ entry */
38014b24e2bSVaishali Kulkarni 	OSAL_MEMSET(&init_data, 0, sizeof(init_data));
38114b24e2bSVaishali Kulkarni 	init_data.cid = ecore_spq_get_cid(p_hwfn);
38214b24e2bSVaishali Kulkarni 	init_data.opaque_fid = p_params->opaque_fid;
38314b24e2bSVaishali Kulkarni 	init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
38414b24e2bSVaishali Kulkarni 
38514b24e2bSVaishali Kulkarni 	rc = ecore_sp_init_request(p_hwfn, &p_ent,
38614b24e2bSVaishali Kulkarni 				   ETH_RAMROD_VPORT_START,
38714b24e2bSVaishali Kulkarni 				   PROTOCOLID_ETH, &init_data);
38814b24e2bSVaishali Kulkarni 	if (rc != ECORE_SUCCESS)
38914b24e2bSVaishali Kulkarni 		return rc;
39014b24e2bSVaishali Kulkarni 
39114b24e2bSVaishali Kulkarni 	p_ramrod = &p_ent->ramrod.vport_start;
39214b24e2bSVaishali Kulkarni 	p_ramrod->vport_id = abs_vport_id;
39314b24e2bSVaishali Kulkarni 
39414b24e2bSVaishali Kulkarni 	p_ramrod->mtu = OSAL_CPU_TO_LE16(p_params->mtu);
39514b24e2bSVaishali Kulkarni 	p_ramrod->inner_vlan_removal_en	= p_params->remove_inner_vlan;
39614b24e2bSVaishali Kulkarni 	p_ramrod->handle_ptp_pkts = p_params->handle_ptp_pkts;
39714b24e2bSVaishali Kulkarni 	p_ramrod->drop_ttl0_en	= p_params->drop_ttl0;
39814b24e2bSVaishali Kulkarni 	p_ramrod->untagged = p_params->only_untagged;
39914b24e2bSVaishali Kulkarni 	p_ramrod->zero_placement_offset = p_params->zero_placement_offset;
40014b24e2bSVaishali Kulkarni 
40114b24e2bSVaishali Kulkarni 	SET_FIELD(rx_mode, ETH_VPORT_RX_MODE_UCAST_DROP_ALL, 1);
40214b24e2bSVaishali Kulkarni 	SET_FIELD(rx_mode, ETH_VPORT_RX_MODE_MCAST_DROP_ALL, 1);
40314b24e2bSVaishali Kulkarni 
40414b24e2bSVaishali Kulkarni 	p_ramrod->rx_mode.state	= OSAL_CPU_TO_LE16(rx_mode);
40514b24e2bSVaishali Kulkarni 
40614b24e2bSVaishali Kulkarni 	/* Handle requests for strict behavior on transmission errors */
40714b24e2bSVaishali Kulkarni 	SET_FIELD(tx_err, ETH_TX_ERR_VALS_ILLEGAL_VLAN_MODE,
40814b24e2bSVaishali Kulkarni 		  p_params->b_err_illegal_vlan_mode ?
40914b24e2bSVaishali Kulkarni 		  ETH_TX_ERR_ASSERT_MALICIOUS : 0);
41014b24e2bSVaishali Kulkarni 	SET_FIELD(tx_err, ETH_TX_ERR_VALS_PACKET_TOO_SMALL,
41114b24e2bSVaishali Kulkarni 		  p_params->b_err_small_pkt ?
41214b24e2bSVaishali Kulkarni 		  ETH_TX_ERR_ASSERT_MALICIOUS : 0);
41314b24e2bSVaishali Kulkarni 	SET_FIELD(tx_err, ETH_TX_ERR_VALS_ANTI_SPOOFING_ERR,
41414b24e2bSVaishali Kulkarni 		  p_params->b_err_anti_spoof ?
41514b24e2bSVaishali Kulkarni 		  ETH_TX_ERR_ASSERT_MALICIOUS : 0);
41614b24e2bSVaishali Kulkarni 	SET_FIELD(tx_err, ETH_TX_ERR_VALS_ILLEGAL_INBAND_TAGS,
41714b24e2bSVaishali Kulkarni 		  p_params->b_err_illegal_inband_mode ?
41814b24e2bSVaishali Kulkarni 		  ETH_TX_ERR_ASSERT_MALICIOUS : 0);
41914b24e2bSVaishali Kulkarni 	SET_FIELD(tx_err, ETH_TX_ERR_VALS_VLAN_INSERTION_W_INBAND_TAG,
42014b24e2bSVaishali Kulkarni 		  p_params->b_err_vlan_insert_with_inband ?
42114b24e2bSVaishali Kulkarni 		  ETH_TX_ERR_ASSERT_MALICIOUS : 0);
42214b24e2bSVaishali Kulkarni 	SET_FIELD(tx_err, ETH_TX_ERR_VALS_MTU_VIOLATION,
42314b24e2bSVaishali Kulkarni 		  p_params->b_err_big_pkt ?
42414b24e2bSVaishali Kulkarni 		  ETH_TX_ERR_ASSERT_MALICIOUS : 0);
42514b24e2bSVaishali Kulkarni 	SET_FIELD(tx_err, ETH_TX_ERR_VALS_ILLEGAL_CONTROL_FRAME,
42614b24e2bSVaishali Kulkarni 		  p_params->b_err_ctrl_frame ?
42714b24e2bSVaishali Kulkarni 		  ETH_TX_ERR_ASSERT_MALICIOUS : 0);
42814b24e2bSVaishali Kulkarni 	p_ramrod->tx_err_behav.values = OSAL_CPU_TO_LE16(tx_err);
42914b24e2bSVaishali Kulkarni 
43014b24e2bSVaishali Kulkarni 	/* TPA related fields */
43114b24e2bSVaishali Kulkarni 	OSAL_MEMSET(&p_ramrod->tpa_param, 0,
43214b24e2bSVaishali Kulkarni 		    sizeof(struct eth_vport_tpa_param));
43314b24e2bSVaishali Kulkarni 	p_ramrod->tpa_param.max_buff_num = p_params->max_buffers_per_cqe;
43414b24e2bSVaishali Kulkarni 
43514b24e2bSVaishali Kulkarni 	switch (p_params->tpa_mode) {
43614b24e2bSVaishali Kulkarni 	case ECORE_TPA_MODE_GRO:
43714b24e2bSVaishali Kulkarni 		p_ramrod->tpa_param.tpa_max_aggs_num = ETH_TPA_MAX_AGGS_NUM;
43814b24e2bSVaishali Kulkarni 		p_ramrod->tpa_param.tpa_max_size = (u16)-1;
43914b24e2bSVaishali Kulkarni 		p_ramrod->tpa_param.tpa_min_size_to_cont = p_params->mtu/2;
44014b24e2bSVaishali Kulkarni 		p_ramrod->tpa_param.tpa_min_size_to_start = p_params->mtu/2;
44114b24e2bSVaishali Kulkarni 		p_ramrod->tpa_param.tpa_ipv4_en_flg = 1;
44214b24e2bSVaishali Kulkarni 		p_ramrod->tpa_param.tpa_ipv6_en_flg = 1;
44314b24e2bSVaishali Kulkarni 		p_ramrod->tpa_param.tpa_ipv4_tunn_en_flg = 1;
44414b24e2bSVaishali Kulkarni 		p_ramrod->tpa_param.tpa_ipv6_tunn_en_flg = 1;
44514b24e2bSVaishali Kulkarni 		p_ramrod->tpa_param.tpa_pkt_split_flg = 1;
44614b24e2bSVaishali Kulkarni 		p_ramrod->tpa_param.tpa_gro_consistent_flg = 1;
44714b24e2bSVaishali Kulkarni 		break;
44814b24e2bSVaishali Kulkarni 	default:
44914b24e2bSVaishali Kulkarni 		break;
45014b24e2bSVaishali Kulkarni 	}
45114b24e2bSVaishali Kulkarni 
45214b24e2bSVaishali Kulkarni 	p_ramrod->tx_switching_en = p_params->tx_switching;
45314b24e2bSVaishali Kulkarni #ifndef ASIC_ONLY
45414b24e2bSVaishali Kulkarni 	if (CHIP_REV_IS_SLOW(p_hwfn->p_dev))
45514b24e2bSVaishali Kulkarni 		p_ramrod->tx_switching_en = 0;
45614b24e2bSVaishali Kulkarni #endif
45714b24e2bSVaishali Kulkarni 
45814b24e2bSVaishali Kulkarni 	p_ramrod->ctl_frame_mac_check_en = !!p_params->check_mac;
45914b24e2bSVaishali Kulkarni 	p_ramrod->ctl_frame_ethtype_check_en = !!p_params->check_ethtype;
46014b24e2bSVaishali Kulkarni 
46114b24e2bSVaishali Kulkarni 	/* Software Function ID in hwfn (PFs are 0 - 15, VFs are 16 - 135) */
46214b24e2bSVaishali Kulkarni 	p_ramrod->sw_fid = ecore_concrete_to_sw_fid(p_hwfn->p_dev,
46314b24e2bSVaishali Kulkarni 						    p_params->concrete_fid);
46414b24e2bSVaishali Kulkarni 
46514b24e2bSVaishali Kulkarni 	return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
46614b24e2bSVaishali Kulkarni }
46714b24e2bSVaishali Kulkarni 
ecore_sp_vport_start(struct ecore_hwfn * p_hwfn,struct ecore_sp_vport_start_params * p_params)46814b24e2bSVaishali Kulkarni enum _ecore_status_t ecore_sp_vport_start(struct ecore_hwfn *p_hwfn,
46914b24e2bSVaishali Kulkarni 					  struct ecore_sp_vport_start_params *p_params)
47014b24e2bSVaishali Kulkarni {
47114b24e2bSVaishali Kulkarni 	if (IS_VF(p_hwfn->p_dev))
47214b24e2bSVaishali Kulkarni 		return ecore_vf_pf_vport_start(p_hwfn, p_params->vport_id,
47314b24e2bSVaishali Kulkarni 					       p_params->mtu,
47414b24e2bSVaishali Kulkarni 					       p_params->remove_inner_vlan,
47514b24e2bSVaishali Kulkarni 					       p_params->tpa_mode,
47614b24e2bSVaishali Kulkarni 					       p_params->max_buffers_per_cqe,
47714b24e2bSVaishali Kulkarni 					       p_params->only_untagged);
47814b24e2bSVaishali Kulkarni 
47914b24e2bSVaishali Kulkarni 	return ecore_sp_eth_vport_start(p_hwfn, p_params);
48014b24e2bSVaishali Kulkarni }
48114b24e2bSVaishali Kulkarni 
48214b24e2bSVaishali Kulkarni static enum _ecore_status_t
ecore_sp_vport_update_rss(struct ecore_hwfn * p_hwfn,struct vport_update_ramrod_data * p_ramrod,struct ecore_rss_params * p_rss)48314b24e2bSVaishali Kulkarni ecore_sp_vport_update_rss(struct ecore_hwfn *p_hwfn,
48414b24e2bSVaishali Kulkarni 			  struct vport_update_ramrod_data *p_ramrod,
48514b24e2bSVaishali Kulkarni 			  struct ecore_rss_params *p_rss)
48614b24e2bSVaishali Kulkarni {
48714b24e2bSVaishali Kulkarni 	struct eth_vport_rss_config *p_config;
48814b24e2bSVaishali Kulkarni 	int i, table_size;
48914b24e2bSVaishali Kulkarni 	enum _ecore_status_t rc = ECORE_SUCCESS;
49014b24e2bSVaishali Kulkarni 
49114b24e2bSVaishali Kulkarni 	if (!p_rss) {
49214b24e2bSVaishali Kulkarni 		p_ramrod->common.update_rss_flg = 0;
49314b24e2bSVaishali Kulkarni 		return rc;
49414b24e2bSVaishali Kulkarni 	}
49514b24e2bSVaishali Kulkarni 	p_config = &p_ramrod->rss_config;
49614b24e2bSVaishali Kulkarni 
49714b24e2bSVaishali Kulkarni 	OSAL_BUILD_BUG_ON(ECORE_RSS_IND_TABLE_SIZE !=
49814b24e2bSVaishali Kulkarni 			   ETH_RSS_IND_TABLE_ENTRIES_NUM);
49914b24e2bSVaishali Kulkarni 
50014b24e2bSVaishali Kulkarni 	rc = ecore_fw_rss_eng(p_hwfn, p_rss->rss_eng_id,
50114b24e2bSVaishali Kulkarni 			      &p_config->rss_id);
50214b24e2bSVaishali Kulkarni 	if (rc != ECORE_SUCCESS)
50314b24e2bSVaishali Kulkarni 		return rc;
50414b24e2bSVaishali Kulkarni 
50514b24e2bSVaishali Kulkarni 	p_ramrod->common.update_rss_flg = p_rss->update_rss_config;
50614b24e2bSVaishali Kulkarni 	p_config->update_rss_capabilities = p_rss->update_rss_capabilities;
50714b24e2bSVaishali Kulkarni 	p_config->update_rss_ind_table = p_rss->update_rss_ind_table;
50814b24e2bSVaishali Kulkarni 	p_config->update_rss_key = p_rss->update_rss_key;
50914b24e2bSVaishali Kulkarni 
51014b24e2bSVaishali Kulkarni 	p_config->rss_mode = p_rss->rss_enable ?
51114b24e2bSVaishali Kulkarni 			     ETH_VPORT_RSS_MODE_REGULAR :
51214b24e2bSVaishali Kulkarni 			     ETH_VPORT_RSS_MODE_DISABLED;
51314b24e2bSVaishali Kulkarni 
51414b24e2bSVaishali Kulkarni 	p_config->capabilities = 0;
51514b24e2bSVaishali Kulkarni 
51614b24e2bSVaishali Kulkarni 	SET_FIELD(p_config->capabilities,
51714b24e2bSVaishali Kulkarni 		  ETH_VPORT_RSS_CONFIG_IPV4_CAPABILITY,
51814b24e2bSVaishali Kulkarni 		  !!(p_rss->rss_caps & ECORE_RSS_IPV4));
51914b24e2bSVaishali Kulkarni 	SET_FIELD(p_config->capabilities,
52014b24e2bSVaishali Kulkarni 		  ETH_VPORT_RSS_CONFIG_IPV6_CAPABILITY,
52114b24e2bSVaishali Kulkarni 		  !!(p_rss->rss_caps & ECORE_RSS_IPV6));
52214b24e2bSVaishali Kulkarni 	SET_FIELD(p_config->capabilities,
52314b24e2bSVaishali Kulkarni 		  ETH_VPORT_RSS_CONFIG_IPV4_TCP_CAPABILITY,
52414b24e2bSVaishali Kulkarni 		  !!(p_rss->rss_caps & ECORE_RSS_IPV4_TCP));
52514b24e2bSVaishali Kulkarni 	SET_FIELD(p_config->capabilities,
52614b24e2bSVaishali Kulkarni 		  ETH_VPORT_RSS_CONFIG_IPV6_TCP_CAPABILITY,
52714b24e2bSVaishali Kulkarni 		  !!(p_rss->rss_caps & ECORE_RSS_IPV6_TCP));
52814b24e2bSVaishali Kulkarni 	SET_FIELD(p_config->capabilities,
52914b24e2bSVaishali Kulkarni 		  ETH_VPORT_RSS_CONFIG_IPV4_UDP_CAPABILITY,
53014b24e2bSVaishali Kulkarni 		  !!(p_rss->rss_caps & ECORE_RSS_IPV4_UDP));
53114b24e2bSVaishali Kulkarni 	SET_FIELD(p_config->capabilities,
53214b24e2bSVaishali Kulkarni 		  ETH_VPORT_RSS_CONFIG_IPV6_UDP_CAPABILITY,
53314b24e2bSVaishali Kulkarni 		  !!(p_rss->rss_caps & ECORE_RSS_IPV6_UDP));
53414b24e2bSVaishali Kulkarni 	p_config->tbl_size = p_rss->rss_table_size_log;
53514b24e2bSVaishali Kulkarni 	p_config->capabilities =
53614b24e2bSVaishali Kulkarni 		OSAL_CPU_TO_LE16(p_config->capabilities);
53714b24e2bSVaishali Kulkarni 
53814b24e2bSVaishali Kulkarni 	DP_VERBOSE(p_hwfn, ECORE_MSG_IFUP,
53914b24e2bSVaishali Kulkarni 		   "update rss flag %d, rss_mode = %d, update_caps = %d, capabilities = %d, update_ind = %d, update_rss_key = %d\n",
54014b24e2bSVaishali Kulkarni 		   p_ramrod->common.update_rss_flg,
54114b24e2bSVaishali Kulkarni 		   p_config->rss_mode,
54214b24e2bSVaishali Kulkarni 		   p_config->update_rss_capabilities,
54314b24e2bSVaishali Kulkarni 		   p_config->capabilities,
54414b24e2bSVaishali Kulkarni 		   p_config->update_rss_ind_table,
54514b24e2bSVaishali Kulkarni 		   p_config->update_rss_key);
54614b24e2bSVaishali Kulkarni 
54714b24e2bSVaishali Kulkarni 	table_size = OSAL_MIN_T(int, ECORE_RSS_IND_TABLE_SIZE,
54814b24e2bSVaishali Kulkarni 				1 << p_config->tbl_size);
54914b24e2bSVaishali Kulkarni 	for (i = 0; i < table_size; i++) {
55014b24e2bSVaishali Kulkarni 		struct ecore_queue_cid *p_queue = p_rss->rss_ind_table[i];
55114b24e2bSVaishali Kulkarni 
55214b24e2bSVaishali Kulkarni 		if (!p_queue)
55314b24e2bSVaishali Kulkarni 			return ECORE_INVAL;
55414b24e2bSVaishali Kulkarni 
55514b24e2bSVaishali Kulkarni 		p_config->indirection_table[i] =
55614b24e2bSVaishali Kulkarni 				OSAL_CPU_TO_LE16(p_queue->abs.queue_id);
55714b24e2bSVaishali Kulkarni 	}
55814b24e2bSVaishali Kulkarni 
55914b24e2bSVaishali Kulkarni 	DP_VERBOSE(p_hwfn, ECORE_MSG_IFUP,
56014b24e2bSVaishali Kulkarni 		   "Configured RSS indirection table [%d entries]:\n",
56114b24e2bSVaishali Kulkarni 		   table_size);
56214b24e2bSVaishali Kulkarni 	for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i += 0x10) {
56314b24e2bSVaishali Kulkarni 		DP_VERBOSE(p_hwfn, ECORE_MSG_IFUP,
56414b24e2bSVaishali Kulkarni 			   "%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n",
56514b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i]),
56614b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 1]),
56714b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 2]),
56814b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 3]),
56914b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 4]),
57014b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 5]),
57114b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 6]),
57214b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 7]),
57314b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 8]),
57414b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 9]),
57514b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 10]),
57614b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 11]),
57714b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 12]),
57814b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 13]),
57914b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 14]),
58014b24e2bSVaishali Kulkarni 			   OSAL_LE16_TO_CPU(p_config->indirection_table[i + 15]));
58114b24e2bSVaishali Kulkarni 	}
58214b24e2bSVaishali Kulkarni 
58314b24e2bSVaishali Kulkarni 	for (i = 0; i <  10; i++)
58414b24e2bSVaishali Kulkarni 		p_config->rss_key[i] = OSAL_CPU_TO_LE32(p_rss->rss_key[i]);
58514b24e2bSVaishali Kulkarni 
58614b24e2bSVaishali Kulkarni 	return rc;
58714b24e2bSVaishali Kulkarni }
58814b24e2bSVaishali Kulkarni 
58914b24e2bSVaishali Kulkarni static void
ecore_sp_update_accept_mode(struct ecore_hwfn * p_hwfn,struct vport_update_ramrod_data * p_ramrod,struct ecore_filter_accept_flags accept_flags)59014b24e2bSVaishali Kulkarni ecore_sp_update_accept_mode(struct ecore_hwfn *p_hwfn,
59114b24e2bSVaishali Kulkarni 			    struct vport_update_ramrod_data *p_ramrod,
59214b24e2bSVaishali Kulkarni 			    struct ecore_filter_accept_flags accept_flags)
59314b24e2bSVaishali Kulkarni {
59414b24e2bSVaishali Kulkarni 	p_ramrod->common.update_rx_mode_flg =
59514b24e2bSVaishali Kulkarni 					accept_flags.update_rx_mode_config;
59614b24e2bSVaishali Kulkarni 	p_ramrod->common.update_tx_mode_flg =
59714b24e2bSVaishali Kulkarni 					accept_flags.update_tx_mode_config;
59814b24e2bSVaishali Kulkarni 
59914b24e2bSVaishali Kulkarni #ifndef ASIC_ONLY
60014b24e2bSVaishali Kulkarni 	/* On B0 emulation we cannot enable Tx, since this would cause writes
60114b24e2bSVaishali Kulkarni 	 * to PVFC HW block which isn't implemented in emulation.
60214b24e2bSVaishali Kulkarni 	 */
60314b24e2bSVaishali Kulkarni 	if (CHIP_REV_IS_SLOW(p_hwfn->p_dev)) {
60414b24e2bSVaishali Kulkarni 		DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
60514b24e2bSVaishali Kulkarni 			   "Non-Asic - prevent Tx mode in vport update\n");
60614b24e2bSVaishali Kulkarni 		p_ramrod->common.update_tx_mode_flg = 0;
60714b24e2bSVaishali Kulkarni 	}
60814b24e2bSVaishali Kulkarni #endif
60914b24e2bSVaishali Kulkarni 
61014b24e2bSVaishali Kulkarni 	/* Set Rx mode accept flags */
61114b24e2bSVaishali Kulkarni 	if (p_ramrod->common.update_rx_mode_flg) {
61214b24e2bSVaishali Kulkarni 		u8 accept_filter = accept_flags.rx_accept_filter;
61314b24e2bSVaishali Kulkarni 		u16 state = 0;
61414b24e2bSVaishali Kulkarni 
61514b24e2bSVaishali Kulkarni 		SET_FIELD(state, ETH_VPORT_RX_MODE_UCAST_DROP_ALL,
61614b24e2bSVaishali Kulkarni 			  !(!!(accept_filter & ECORE_ACCEPT_UCAST_MATCHED) ||
61714b24e2bSVaishali Kulkarni 			   !!(accept_filter & ECORE_ACCEPT_UCAST_UNMATCHED)));
61814b24e2bSVaishali Kulkarni 
61914b24e2bSVaishali Kulkarni 		SET_FIELD(state, ETH_VPORT_RX_MODE_UCAST_ACCEPT_UNMATCHED,
62014b24e2bSVaishali Kulkarni 			  !!(accept_filter & ECORE_ACCEPT_UCAST_UNMATCHED));
62114b24e2bSVaishali Kulkarni 
62214b24e2bSVaishali Kulkarni 		SET_FIELD(state, ETH_VPORT_RX_MODE_MCAST_DROP_ALL,
62314b24e2bSVaishali Kulkarni 			  !(!!(accept_filter & ECORE_ACCEPT_MCAST_MATCHED) ||
62414b24e2bSVaishali Kulkarni 			   !!(accept_filter & ECORE_ACCEPT_MCAST_UNMATCHED)));
62514b24e2bSVaishali Kulkarni 
62614b24e2bSVaishali Kulkarni 		SET_FIELD(state, ETH_VPORT_RX_MODE_MCAST_ACCEPT_ALL,
62714b24e2bSVaishali Kulkarni 			  (!!(accept_filter & ECORE_ACCEPT_MCAST_MATCHED) &&
62814b24e2bSVaishali Kulkarni 			   !!(accept_filter & ECORE_ACCEPT_MCAST_UNMATCHED)));
62914b24e2bSVaishali Kulkarni 
63014b24e2bSVaishali Kulkarni 		SET_FIELD(state, ETH_VPORT_RX_MODE_BCAST_ACCEPT_ALL,
63114b24e2bSVaishali Kulkarni 			  !!(accept_filter & ECORE_ACCEPT_BCAST));
63214b24e2bSVaishali Kulkarni 
63314b24e2bSVaishali Kulkarni 		p_ramrod->rx_mode.state = OSAL_CPU_TO_LE16(state);
63414b24e2bSVaishali Kulkarni 		DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
63514b24e2bSVaishali Kulkarni 			   "vport[%02x] p_ramrod->rx_mode.state = 0x%x\n",
63614b24e2bSVaishali Kulkarni 			   p_ramrod->common.vport_id, state);
63714b24e2bSVaishali Kulkarni 	}
63814b24e2bSVaishali Kulkarni 
63914b24e2bSVaishali Kulkarni 	/* Set Tx mode accept flags */
64014b24e2bSVaishali Kulkarni 	if (p_ramrod->common.update_tx_mode_flg) {
64114b24e2bSVaishali Kulkarni 		u8 accept_filter = accept_flags.tx_accept_filter;
64214b24e2bSVaishali Kulkarni 		u16 state = 0;
64314b24e2bSVaishali Kulkarni 
64414b24e2bSVaishali Kulkarni 		SET_FIELD(state, ETH_VPORT_TX_MODE_UCAST_DROP_ALL,
64514b24e2bSVaishali Kulkarni 			  !!(accept_filter & ECORE_ACCEPT_NONE));
64614b24e2bSVaishali Kulkarni 
64714b24e2bSVaishali Kulkarni 		SET_FIELD(state, ETH_VPORT_TX_MODE_MCAST_DROP_ALL,
64814b24e2bSVaishali Kulkarni 			  !!(accept_filter & ECORE_ACCEPT_NONE));
64914b24e2bSVaishali Kulkarni 
65014b24e2bSVaishali Kulkarni 		SET_FIELD(state, ETH_VPORT_TX_MODE_MCAST_ACCEPT_ALL,
65114b24e2bSVaishali Kulkarni 			  (!!(accept_filter & ECORE_ACCEPT_MCAST_MATCHED) &&
65214b24e2bSVaishali Kulkarni 			   !!(accept_filter & ECORE_ACCEPT_MCAST_UNMATCHED)));
65314b24e2bSVaishali Kulkarni 
65414b24e2bSVaishali Kulkarni 		SET_FIELD(state, ETH_VPORT_TX_MODE_BCAST_ACCEPT_ALL,
65514b24e2bSVaishali Kulkarni 			  !!(accept_filter & ECORE_ACCEPT_BCAST));
65614b24e2bSVaishali Kulkarni 
65714b24e2bSVaishali Kulkarni 		p_ramrod->tx_mode.state = OSAL_CPU_TO_LE16(state);
65814b24e2bSVaishali Kulkarni 		DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
65914b24e2bSVaishali Kulkarni 			   "vport[%02x] p_ramrod->tx_mode.state = 0x%x\n",
66014b24e2bSVaishali Kulkarni 			   p_ramrod->common.vport_id, state);
66114b24e2bSVaishali Kulkarni 	}
66214b24e2bSVaishali Kulkarni }
66314b24e2bSVaishali Kulkarni 
66414b24e2bSVaishali Kulkarni static void
ecore_sp_vport_update_sge_tpa(struct ecore_hwfn * p_hwfn,struct vport_update_ramrod_data * p_ramrod,struct ecore_sge_tpa_params * p_params)66514b24e2bSVaishali Kulkarni ecore_sp_vport_update_sge_tpa(struct ecore_hwfn *p_hwfn,
66614b24e2bSVaishali Kulkarni 			      struct vport_update_ramrod_data *p_ramrod,
66714b24e2bSVaishali Kulkarni 			      struct ecore_sge_tpa_params *p_params)
66814b24e2bSVaishali Kulkarni {
66914b24e2bSVaishali Kulkarni 	struct eth_vport_tpa_param *p_tpa;
67014b24e2bSVaishali Kulkarni 
67114b24e2bSVaishali Kulkarni 	if (!p_params) {
67214b24e2bSVaishali Kulkarni 		p_ramrod->common.update_tpa_param_flg = 0;
67314b24e2bSVaishali Kulkarni 		p_ramrod->common.update_tpa_en_flg = 0;
67414b24e2bSVaishali Kulkarni 		p_ramrod->common.update_tpa_param_flg = 0;
67514b24e2bSVaishali Kulkarni 		return;
67614b24e2bSVaishali Kulkarni 	}
67714b24e2bSVaishali Kulkarni 
67814b24e2bSVaishali Kulkarni 	p_ramrod->common.update_tpa_en_flg = p_params->update_tpa_en_flg;
67914b24e2bSVaishali Kulkarni 	p_tpa = &p_ramrod->tpa_param;
68014b24e2bSVaishali Kulkarni 	p_tpa->tpa_ipv4_en_flg = p_params->tpa_ipv4_en_flg;
68114b24e2bSVaishali Kulkarni 	p_tpa->tpa_ipv6_en_flg = p_params->tpa_ipv6_en_flg;
68214b24e2bSVaishali Kulkarni 	p_tpa->tpa_ipv4_tunn_en_flg = p_params->tpa_ipv4_tunn_en_flg;
68314b24e2bSVaishali Kulkarni 	p_tpa->tpa_ipv6_tunn_en_flg = p_params->tpa_ipv6_tunn_en_flg;
68414b24e2bSVaishali Kulkarni 
68514b24e2bSVaishali Kulkarni 	p_ramrod->common.update_tpa_param_flg = p_params->update_tpa_param_flg;
68614b24e2bSVaishali Kulkarni 	p_tpa->max_buff_num = p_params->max_buffers_per_cqe;
68714b24e2bSVaishali Kulkarni 	p_tpa->tpa_pkt_split_flg = p_params->tpa_pkt_split_flg;
68814b24e2bSVaishali Kulkarni 	p_tpa->tpa_hdr_data_split_flg = p_params->tpa_hdr_data_split_flg;
68914b24e2bSVaishali Kulkarni 	p_tpa->tpa_gro_consistent_flg = p_params->tpa_gro_consistent_flg;
69014b24e2bSVaishali Kulkarni 	p_tpa->tpa_max_aggs_num = p_params->tpa_max_aggs_num;
69114b24e2bSVaishali Kulkarni 	p_tpa->tpa_max_size = p_params->tpa_max_size;
69214b24e2bSVaishali Kulkarni 	p_tpa->tpa_min_size_to_start = p_params->tpa_min_size_to_start;
69314b24e2bSVaishali Kulkarni 	p_tpa->tpa_min_size_to_cont = p_params->tpa_min_size_to_cont;
69414b24e2bSVaishali Kulkarni }
69514b24e2bSVaishali Kulkarni 
69614b24e2bSVaishali Kulkarni static void
ecore_sp_update_mcast_bin(struct ecore_hwfn * p_hwfn,struct vport_update_ramrod_data * p_ramrod,struct ecore_sp_vport_update_params * p_params)69714b24e2bSVaishali Kulkarni ecore_sp_update_mcast_bin(struct ecore_hwfn *p_hwfn,
69814b24e2bSVaishali Kulkarni 			  struct vport_update_ramrod_data *p_ramrod,
69914b24e2bSVaishali Kulkarni 			  struct ecore_sp_vport_update_params *p_params)
70014b24e2bSVaishali Kulkarni {
70114b24e2bSVaishali Kulkarni 	int i;
70214b24e2bSVaishali Kulkarni 
70314b24e2bSVaishali Kulkarni 	OSAL_MEMSET(&p_ramrod->approx_mcast.bins, 0,
70414b24e2bSVaishali Kulkarni 		    sizeof(p_ramrod->approx_mcast.bins));
70514b24e2bSVaishali Kulkarni 
70614b24e2bSVaishali Kulkarni 	if (!p_params->update_approx_mcast_flg)
70714b24e2bSVaishali Kulkarni 		return;
70814b24e2bSVaishali Kulkarni 
70914b24e2bSVaishali Kulkarni 	p_ramrod->common.update_approx_mcast_flg = 1;
71014b24e2bSVaishali Kulkarni 	for (i = 0; i < ETH_MULTICAST_MAC_BINS_IN_REGS; i++) {
71114b24e2bSVaishali Kulkarni 		u32 *p_bins = (u32 *)p_params->bins;
71214b24e2bSVaishali Kulkarni 
71314b24e2bSVaishali Kulkarni 		p_ramrod->approx_mcast.bins[i] = OSAL_CPU_TO_LE32(p_bins[i]);
71414b24e2bSVaishali Kulkarni 	}
71514b24e2bSVaishali Kulkarni }
71614b24e2bSVaishali Kulkarni 
ecore_sp_vport_update(struct ecore_hwfn * p_hwfn,struct ecore_sp_vport_update_params * p_params,enum spq_mode comp_mode,struct ecore_spq_comp_cb * p_comp_data)71714b24e2bSVaishali Kulkarni enum _ecore_status_t ecore_sp_vport_update(struct ecore_hwfn *p_hwfn,
71814b24e2bSVaishali Kulkarni 					   struct ecore_sp_vport_update_params *p_params,
71914b24e2bSVaishali Kulkarni 					   enum spq_mode comp_mode,
72014b24e2bSVaishali Kulkarni 					   struct ecore_spq_comp_cb *p_comp_data)
72114b24e2bSVaishali Kulkarni {
72214b24e2bSVaishali Kulkarni 	struct ecore_rss_params *p_rss_params = p_params->rss_params;
72314b24e2bSVaishali Kulkarni 	struct vport_update_ramrod_data_cmn *p_cmn;
72414b24e2bSVaishali Kulkarni 	struct ecore_sp_init_data init_data;
72514b24e2bSVaishali Kulkarni 	struct vport_update_ramrod_data *p_ramrod = OSAL_NULL;
72614b24e2bSVaishali Kulkarni 	struct ecore_spq_entry *p_ent = OSAL_NULL;
72714b24e2bSVaishali Kulkarni 	u8 abs_vport_id = 0, val;
72814b24e2bSVaishali Kulkarni 	enum _ecore_status_t rc = ECORE_NOTIMPL;
72914b24e2bSVaishali Kulkarni 
73014b24e2bSVaishali Kulkarni 	if (IS_VF(p_hwfn->p_dev)) {
73114b24e2bSVaishali Kulkarni 		rc = ecore_vf_pf_vport_update(p_hwfn, p_params);
73214b24e2bSVaishali Kulkarni 		return rc;
73314b24e2bSVaishali Kulkarni 	}
73414b24e2bSVaishali Kulkarni 
73514b24e2bSVaishali Kulkarni 	rc = ecore_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
73614b24e2bSVaishali Kulkarni 	if (rc != ECORE_SUCCESS)
73714b24e2bSVaishali Kulkarni 		return rc;
73814b24e2bSVaishali Kulkarni 
73914b24e2bSVaishali Kulkarni 	/* Get SPQ entry */
74014b24e2bSVaishali Kulkarni 	OSAL_MEMSET(&init_data, 0, sizeof(init_data));
74114b24e2bSVaishali Kulkarni 	init_data.cid = ecore_spq_get_cid(p_hwfn);
74214b24e2bSVaishali Kulkarni 	init_data.opaque_fid = p_params->opaque_fid;
74314b24e2bSVaishali Kulkarni 	init_data.comp_mode = comp_mode;
74414b24e2bSVaishali Kulkarni 	init_data.p_comp_data = p_comp_data;
74514b24e2bSVaishali Kulkarni 
74614b24e2bSVaishali Kulkarni 	rc = ecore_sp_init_request(p_hwfn, &p_ent,
74714b24e2bSVaishali Kulkarni 				   ETH_RAMROD_VPORT_UPDATE,
74814b24e2bSVaishali Kulkarni 				   PROTOCOLID_ETH, &init_data);
74914b24e2bSVaishali Kulkarni 	if (rc != ECORE_SUCCESS)
75014b24e2bSVaishali Kulkarni 		return rc;
75114b24e2bSVaishali Kulkarni 
75214b24e2bSVaishali Kulkarni 	/* Copy input params to ramrod according to FW struct */
75314b24e2bSVaishali Kulkarni 	p_ramrod = &p_ent->ramrod.vport_update;
75414b24e2bSVaishali Kulkarni 	p_cmn = &p_ramrod->common;
755