13126df22SRasesh Mody /* SPDX-License-Identifier: BSD-3-Clause
29adde217SRasesh Mody * Copyright (c) 2016 - 2018 Cavium Inc.
35cdd769aSRasesh Mody * All rights reserved.
49adde217SRasesh Mody * www.cavium.com
55cdd769aSRasesh Mody */
65cdd769aSRasesh Mody
75cdd769aSRasesh Mody #include "bcm_osal.h"
85cdd769aSRasesh Mody
95cdd769aSRasesh Mody #include "ecore.h"
105cdd769aSRasesh Mody #include "ecore_status.h"
115cdd769aSRasesh Mody #include "ecore_hsi_eth.h"
125cdd769aSRasesh Mody #include "ecore_chain.h"
135cdd769aSRasesh Mody #include "ecore_spq.h"
145cdd769aSRasesh Mody #include "ecore_init_fw_funcs.h"
155cdd769aSRasesh Mody #include "ecore_cxt.h"
165cdd769aSRasesh Mody #include "ecore_l2.h"
175cdd769aSRasesh Mody #include "ecore_sp_commands.h"
185cdd769aSRasesh Mody #include "ecore_gtt_reg_addr.h"
195cdd769aSRasesh Mody #include "ecore_iro.h"
205cdd769aSRasesh Mody #include "reg_addr.h"
215cdd769aSRasesh Mody #include "ecore_int.h"
225cdd769aSRasesh Mody #include "ecore_hw.h"
2386a2265eSRasesh Mody #include "ecore_vf.h"
2486a2265eSRasesh Mody #include "ecore_sriov.h"
255cdd769aSRasesh Mody #include "ecore_mcp.h"
265cdd769aSRasesh Mody
275cdd769aSRasesh Mody #define ECORE_MAX_SGES_NUM 16
285cdd769aSRasesh Mody #define CRC32_POLY 0x1edc6f41
295cdd769aSRasesh Mody
30eb8e81adSRasesh Mody struct ecore_l2_info {
31eb8e81adSRasesh Mody u32 queues;
32*5018f1fcSJoyce Kong u32 **pp_qid_usage;
33eb8e81adSRasesh Mody
34eb8e81adSRasesh Mody /* The lock is meant to synchronize access to the qid usage */
35eb8e81adSRasesh Mody osal_mutex_t lock;
36eb8e81adSRasesh Mody };
37eb8e81adSRasesh Mody
ecore_l2_alloc(struct ecore_hwfn * p_hwfn)38eb8e81adSRasesh Mody enum _ecore_status_t ecore_l2_alloc(struct ecore_hwfn *p_hwfn)
39eb8e81adSRasesh Mody {
40eb8e81adSRasesh Mody struct ecore_l2_info *p_l2_info;
41*5018f1fcSJoyce Kong u32 **pp_qids;
42eb8e81adSRasesh Mody u32 i;
43eb8e81adSRasesh Mody
44eb8e81adSRasesh Mody if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
45eb8e81adSRasesh Mody return ECORE_SUCCESS;
46eb8e81adSRasesh Mody
47eb8e81adSRasesh Mody p_l2_info = OSAL_VZALLOC(p_hwfn->p_dev, sizeof(*p_l2_info));
48eb8e81adSRasesh Mody if (!p_l2_info)
49eb8e81adSRasesh Mody return ECORE_NOMEM;
50eb8e81adSRasesh Mody p_hwfn->p_l2_info = p_l2_info;
51eb8e81adSRasesh Mody
52eb8e81adSRasesh Mody if (IS_PF(p_hwfn->p_dev)) {
53eb8e81adSRasesh Mody p_l2_info->queues = RESC_NUM(p_hwfn, ECORE_L2_QUEUE);
54eb8e81adSRasesh Mody } else {
55eb8e81adSRasesh Mody u8 rx = 0, tx = 0;
56eb8e81adSRasesh Mody
57eb8e81adSRasesh Mody ecore_vf_get_num_rxqs(p_hwfn, &rx);
58eb8e81adSRasesh Mody ecore_vf_get_num_txqs(p_hwfn, &tx);
59eb8e81adSRasesh Mody
60eb8e81adSRasesh Mody p_l2_info->queues = (u32)OSAL_MAX_T(u8, rx, tx);
61eb8e81adSRasesh Mody }
62eb8e81adSRasesh Mody
63eb8e81adSRasesh Mody pp_qids = OSAL_VZALLOC(p_hwfn->p_dev,
64eb8e81adSRasesh Mody sizeof(unsigned long *) *
65eb8e81adSRasesh Mody p_l2_info->queues);
66eb8e81adSRasesh Mody if (pp_qids == OSAL_NULL)
67eb8e81adSRasesh Mody return ECORE_NOMEM;
68eb8e81adSRasesh Mody p_l2_info->pp_qid_usage = pp_qids;
69eb8e81adSRasesh Mody
70eb8e81adSRasesh Mody for (i = 0; i < p_l2_info->queues; i++) {
71eb8e81adSRasesh Mody pp_qids[i] = OSAL_VZALLOC(p_hwfn->p_dev,
72eb8e81adSRasesh Mody MAX_QUEUES_PER_QZONE / 8);
73eb8e81adSRasesh Mody if (pp_qids[i] == OSAL_NULL)
74eb8e81adSRasesh Mody return ECORE_NOMEM;
75eb8e81adSRasesh Mody }
76eb8e81adSRasesh Mody
77eb8e81adSRasesh Mody #ifdef CONFIG_ECORE_LOCK_ALLOC
7898abf84eSRasesh Mody if (OSAL_MUTEX_ALLOC(p_hwfn, &p_l2_info->lock))
7998abf84eSRasesh Mody return ECORE_NOMEM;
80eb8e81adSRasesh Mody #endif
81eb8e81adSRasesh Mody
82eb8e81adSRasesh Mody return ECORE_SUCCESS;
83eb8e81adSRasesh Mody }
84eb8e81adSRasesh Mody
ecore_l2_setup(struct ecore_hwfn * p_hwfn)85eb8e81adSRasesh Mody void ecore_l2_setup(struct ecore_hwfn *p_hwfn)
86eb8e81adSRasesh Mody {
87eb8e81adSRasesh Mody if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
88eb8e81adSRasesh Mody return;
89eb8e81adSRasesh Mody
90eb8e81adSRasesh Mody OSAL_MUTEX_INIT(&p_hwfn->p_l2_info->lock);
91eb8e81adSRasesh Mody }
92eb8e81adSRasesh Mody
ecore_l2_free(struct ecore_hwfn * p_hwfn)93eb8e81adSRasesh Mody void ecore_l2_free(struct ecore_hwfn *p_hwfn)
94eb8e81adSRasesh Mody {
95eb8e81adSRasesh Mody u32 i;
96eb8e81adSRasesh Mody
97eb8e81adSRasesh Mody if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
98eb8e81adSRasesh Mody return;
99eb8e81adSRasesh Mody
100eb8e81adSRasesh Mody if (p_hwfn->p_l2_info == OSAL_NULL)
101eb8e81adSRasesh Mody return;
102eb8e81adSRasesh Mody
103eb8e81adSRasesh Mody if (p_hwfn->p_l2_info->pp_qid_usage == OSAL_NULL)
104eb8e81adSRasesh Mody goto out_l2_info;
105eb8e81adSRasesh Mody
106eb8e81adSRasesh Mody /* Free until hit first uninitialized entry */
107eb8e81adSRasesh Mody for (i = 0; i < p_hwfn->p_l2_info->queues; i++) {
108eb8e81adSRasesh Mody if (p_hwfn->p_l2_info->pp_qid_usage[i] == OSAL_NULL)
109eb8e81adSRasesh Mody break;
110eb8e81adSRasesh Mody OSAL_VFREE(p_hwfn->p_dev,
111eb8e81adSRasesh Mody p_hwfn->p_l2_info->pp_qid_usage[i]);
11298abf84eSRasesh Mody p_hwfn->p_l2_info->pp_qid_usage[i] = OSAL_NULL;
113eb8e81adSRasesh Mody }
114eb8e81adSRasesh Mody
115eb8e81adSRasesh Mody #ifdef CONFIG_ECORE_LOCK_ALLOC
116eb8e81adSRasesh Mody /* Lock is last to initialize, if everything else was */
117eb8e81adSRasesh Mody if (i == p_hwfn->p_l2_info->queues)
118eb8e81adSRasesh Mody OSAL_MUTEX_DEALLOC(&p_hwfn->p_l2_info->lock);
119eb8e81adSRasesh Mody #endif
120eb8e81adSRasesh Mody
121eb8e81adSRasesh Mody OSAL_VFREE(p_hwfn->p_dev, p_hwfn->p_l2_info->pp_qid_usage);
12298abf84eSRasesh Mody p_hwfn->p_l2_info->pp_qid_usage = OSAL_NULL;
123eb8e81adSRasesh Mody
124eb8e81adSRasesh Mody out_l2_info:
125eb8e81adSRasesh Mody OSAL_VFREE(p_hwfn->p_dev, p_hwfn->p_l2_info);
126eb8e81adSRasesh Mody p_hwfn->p_l2_info = OSAL_NULL;
127eb8e81adSRasesh Mody }
128eb8e81adSRasesh Mody
129eb8e81adSRasesh Mody /* TODO - we'll need locking around these... */
ecore_eth_queue_qid_usage_add(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)130eb8e81adSRasesh Mody static bool ecore_eth_queue_qid_usage_add(struct ecore_hwfn *p_hwfn,
131eb8e81adSRasesh Mody struct ecore_queue_cid *p_cid)
132eb8e81adSRasesh Mody {
133eb8e81adSRasesh Mody struct ecore_l2_info *p_l2_info = p_hwfn->p_l2_info;
134eb8e81adSRasesh Mody u16 queue_id = p_cid->rel.queue_id;
135eb8e81adSRasesh Mody bool b_rc = true;
136eb8e81adSRasesh Mody u8 first;
137eb8e81adSRasesh Mody
138eb8e81adSRasesh Mody OSAL_MUTEX_ACQUIRE(&p_l2_info->lock);
139eb8e81adSRasesh Mody
140eb8e81adSRasesh Mody if (queue_id > p_l2_info->queues) {
141eb8e81adSRasesh Mody DP_NOTICE(p_hwfn, true,
142eb8e81adSRasesh Mody "Requested to increase usage for qzone %04x out of %08x\n",
143eb8e81adSRasesh Mody queue_id, p_l2_info->queues);
144eb8e81adSRasesh Mody b_rc = false;
145eb8e81adSRasesh Mody goto out;
146eb8e81adSRasesh Mody }
147eb8e81adSRasesh Mody
148eb8e81adSRasesh Mody first = (u8)OSAL_FIND_FIRST_ZERO_BIT(p_l2_info->pp_qid_usage[queue_id],
149eb8e81adSRasesh Mody MAX_QUEUES_PER_QZONE);
150eb8e81adSRasesh Mody if (first >= MAX_QUEUES_PER_QZONE) {
151eb8e81adSRasesh Mody b_rc = false;
152eb8e81adSRasesh Mody goto out;
153eb8e81adSRasesh Mody }
154eb8e81adSRasesh Mody
155eb8e81adSRasesh Mody OSAL_SET_BIT(first, p_l2_info->pp_qid_usage[queue_id]);
156eb8e81adSRasesh Mody p_cid->qid_usage_idx = first;
157eb8e81adSRasesh Mody
158eb8e81adSRasesh Mody out:
159eb8e81adSRasesh Mody OSAL_MUTEX_RELEASE(&p_l2_info->lock);
160eb8e81adSRasesh Mody return b_rc;
161eb8e81adSRasesh Mody }
162eb8e81adSRasesh Mody
ecore_eth_queue_qid_usage_del(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)163eb8e81adSRasesh Mody static void ecore_eth_queue_qid_usage_del(struct ecore_hwfn *p_hwfn,
164eb8e81adSRasesh Mody struct ecore_queue_cid *p_cid)
165eb8e81adSRasesh Mody {
166eb8e81adSRasesh Mody OSAL_MUTEX_ACQUIRE(&p_hwfn->p_l2_info->lock);
167eb8e81adSRasesh Mody
168eb8e81adSRasesh Mody OSAL_CLEAR_BIT(p_cid->qid_usage_idx,
169eb8e81adSRasesh Mody p_hwfn->p_l2_info->pp_qid_usage[p_cid->rel.queue_id]);
170eb8e81adSRasesh Mody
171eb8e81adSRasesh Mody OSAL_MUTEX_RELEASE(&p_hwfn->p_l2_info->lock);
172eb8e81adSRasesh Mody }
173eb8e81adSRasesh Mody
ecore_eth_queue_cid_release(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)174a55e422eSRasesh Mody void ecore_eth_queue_cid_release(struct ecore_hwfn *p_hwfn,
175a55e422eSRasesh Mody struct ecore_queue_cid *p_cid)
176a55e422eSRasesh Mody {
177a90c566fSRasesh Mody bool b_legacy_vf = !!(p_cid->vf_legacy &
178a90c566fSRasesh Mody ECORE_QCID_LEGACY_VF_CID);
179eb8e81adSRasesh Mody
180a90c566fSRasesh Mody /* VFs' CIDs are 0-based in PF-view, and uninitialized on VF.
181a90c566fSRasesh Mody * For legacy vf-queues, the CID doesn't go through here.
182a90c566fSRasesh Mody */
183a90c566fSRasesh Mody if (IS_PF(p_hwfn->p_dev) && !b_legacy_vf)
184eb8e81adSRasesh Mody _ecore_cxt_release_cid(p_hwfn, p_cid->cid, p_cid->vfid);
185a90c566fSRasesh Mody
186a90c566fSRasesh Mody /* VFs maintain the index inside queue-zone on their own */
187a90c566fSRasesh Mody if (p_cid->vfid == ECORE_QUEUE_CID_PF)
188eb8e81adSRasesh Mody ecore_eth_queue_qid_usage_del(p_hwfn, p_cid);
189a90c566fSRasesh Mody
190a55e422eSRasesh Mody OSAL_VFREE(p_hwfn->p_dev, p_cid);
191a55e422eSRasesh Mody }
192a55e422eSRasesh Mody
193a55e422eSRasesh Mody /* The internal is only meant to be directly called by PFs initializeing CIDs
194a55e422eSRasesh Mody * for their VFs.
195a55e422eSRasesh Mody */
196eb8e81adSRasesh Mody 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,bool b_is_rx,struct ecore_queue_cid_vf_params * p_vf_params)197a55e422eSRasesh Mody _ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn,
198eb8e81adSRasesh Mody u16 opaque_fid, u32 cid,
199eb8e81adSRasesh Mody struct ecore_queue_start_common_params *p_params,
200823a84aaSRasesh Mody bool b_is_rx,
201eb8e81adSRasesh Mody struct ecore_queue_cid_vf_params *p_vf_params)
202a55e422eSRasesh Mody {
203a55e422eSRasesh Mody struct ecore_queue_cid *p_cid;
204a55e422eSRasesh Mody enum _ecore_status_t rc;
205a55e422eSRasesh Mody
206a261b214SRasesh Mody p_cid = OSAL_VZALLOC(p_hwfn->p_dev, sizeof(*p_cid));
207a55e422eSRasesh Mody if (p_cid == OSAL_NULL)
208a55e422eSRasesh Mody return OSAL_NULL;
209a55e422eSRasesh Mody
210a55e422eSRasesh Mody p_cid->opaque_fid = opaque_fid;
211a55e422eSRasesh Mody p_cid->cid = cid;
21269d7ba88SRasesh Mody p_cid->p_owner = p_hwfn;
213a55e422eSRasesh Mody
2146e4fcea9SRasesh Mody /* Fill in parameters */
2156e4fcea9SRasesh Mody p_cid->rel.vport_id = p_params->vport_id;
2166e4fcea9SRasesh Mody p_cid->rel.queue_id = p_params->queue_id;
2176e4fcea9SRasesh Mody p_cid->rel.stats_id = p_params->stats_id;
2186e4fcea9SRasesh Mody p_cid->sb_igu_id = p_params->p_sb->igu_sb_id;
219823a84aaSRasesh Mody p_cid->b_is_rx = b_is_rx;
2206e4fcea9SRasesh Mody p_cid->sb_idx = p_params->sb_idx;
2216e4fcea9SRasesh Mody
222eb8e81adSRasesh Mody /* Fill-in bits related to VFs' queues if information was provided */
223eb8e81adSRasesh Mody if (p_vf_params != OSAL_NULL) {
224eb8e81adSRasesh Mody p_cid->vfid = p_vf_params->vfid;
225eb8e81adSRasesh Mody p_cid->vf_qid = p_vf_params->vf_qid;
226a90c566fSRasesh Mody p_cid->vf_legacy = p_vf_params->vf_legacy;
227eb8e81adSRasesh Mody } else {
228eb8e81adSRasesh Mody p_cid->vfid = ECORE_QUEUE_CID_PF;
229eb8e81adSRasesh Mody }
230eb8e81adSRasesh Mody
231a55e422eSRasesh Mody /* Don't try calculating the absolute indices for VFs */
232a55e422eSRasesh Mody if (IS_VF(p_hwfn->p_dev)) {
233a55e422eSRasesh Mody p_cid->abs = p_cid->rel;
234eb8e81adSRasesh Mody
235a55e422eSRasesh Mody goto out;
236a55e422eSRasesh Mody }
237a55e422eSRasesh Mody
238a55e422eSRasesh Mody /* Calculate the engine-absolute indices of the resources.
239eafbc6fcSRasesh Mody * This would guarantee they're valid later on.
240a55e422eSRasesh Mody * In some cases [SBs] we already have the right values.
241a55e422eSRasesh Mody */
242a55e422eSRasesh Mody rc = ecore_fw_vport(p_hwfn, p_cid->rel.vport_id, &p_cid->abs.vport_id);
243a55e422eSRasesh Mody if (rc != ECORE_SUCCESS)
244a55e422eSRasesh Mody goto fail;
245a55e422eSRasesh Mody
246a55e422eSRasesh Mody rc = ecore_fw_l2_queue(p_hwfn, p_cid->rel.queue_id,
247a55e422eSRasesh Mody &p_cid->abs.queue_id);
248a55e422eSRasesh Mody if (rc != ECORE_SUCCESS)
249a55e422eSRasesh Mody goto fail;
250a55e422eSRasesh Mody
251a55e422eSRasesh Mody /* In case of a PF configuring its VF's queues, the stats-id is already
252a55e422eSRasesh Mody * absolute [since there's a single index that's suitable per-VF].
253a55e422eSRasesh Mody */
254eb8e81adSRasesh Mody if (p_cid->vfid == ECORE_QUEUE_CID_PF) {
255a55e422eSRasesh Mody rc = ecore_fw_vport(p_hwfn, p_cid->rel.stats_id,
256a55e422eSRasesh Mody &p_cid->abs.stats_id);
257a55e422eSRasesh Mody if (rc != ECORE_SUCCESS)
258a55e422eSRasesh Mody goto fail;
259a55e422eSRasesh Mody } else {
260a55e422eSRasesh Mody p_cid->abs.stats_id = p_cid->rel.stats_id;
261a55e422eSRasesh Mody }
262a55e422eSRasesh Mody
263a55e422eSRasesh Mody out:
264eb8e81adSRasesh Mody /* VF-images have provided the qid_usage_idx on their own.
265eb8e81adSRasesh Mody * Otherwise, we need to allocate a unique one.
266eb8e81adSRasesh Mody */
267eb8e81adSRasesh Mody if (!p_vf_params) {
268eb8e81adSRasesh Mody if (!ecore_eth_queue_qid_usage_add(p_hwfn, p_cid))
269eb8e81adSRasesh Mody goto fail;
270eb8e81adSRasesh Mody } else {
271eb8e81adSRasesh Mody p_cid->qid_usage_idx = p_vf_params->qid_usage_idx;
272eb8e81adSRasesh Mody }
273eb8e81adSRasesh Mody
274a55e422eSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
275eb8e81adSRasesh Mody "opaque_fid: %04x CID %08x vport %02x [%02x] qzone %04x.%02x [%04x] stats %02x [%02x] SB %04x PI %02x\n",
276a55e422eSRasesh Mody p_cid->opaque_fid, p_cid->cid,
277a55e422eSRasesh Mody p_cid->rel.vport_id, p_cid->abs.vport_id,
278eb8e81adSRasesh Mody p_cid->rel.queue_id, p_cid->qid_usage_idx,
279eb8e81adSRasesh Mody p_cid->abs.queue_id,
280a55e422eSRasesh Mody p_cid->rel.stats_id, p_cid->abs.stats_id,
2816e4fcea9SRasesh Mody p_cid->sb_igu_id, p_cid->sb_idx);
282a55e422eSRasesh Mody
283a55e422eSRasesh Mody return p_cid;
284a55e422eSRasesh Mody
285a55e422eSRasesh Mody fail:
286a55e422eSRasesh Mody OSAL_VFREE(p_hwfn->p_dev, p_cid);
287a55e422eSRasesh Mody return OSAL_NULL;
288a55e422eSRasesh Mody }
289a55e422eSRasesh Mody
290eb8e81adSRasesh Mody 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,bool b_is_rx,struct ecore_queue_cid_vf_params * p_vf_params)291eb8e81adSRasesh Mody ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
292eb8e81adSRasesh Mody struct ecore_queue_start_common_params *p_params,
293823a84aaSRasesh Mody bool b_is_rx,
294eb8e81adSRasesh Mody struct ecore_queue_cid_vf_params *p_vf_params)
295a55e422eSRasesh Mody {
296a55e422eSRasesh Mody struct ecore_queue_cid *p_cid;
297eb8e81adSRasesh Mody u8 vfid = ECORE_CXT_PF_CID;
298eb8e81adSRasesh Mody bool b_legacy_vf = false;
299a55e422eSRasesh Mody u32 cid = 0;
300a55e422eSRasesh Mody
301eb8e81adSRasesh Mody /* In case of legacy VFs, The CID can be derived from the additional
302eb8e81adSRasesh Mody * VF parameters - the VF assumes queue X uses CID X, so we can simply
303eb8e81adSRasesh Mody * use the vf_qid for this purpose as well.
304eb8e81adSRasesh Mody */
305eb8e81adSRasesh Mody if (p_vf_params) {
306eb8e81adSRasesh Mody vfid = p_vf_params->vfid;
307eb8e81adSRasesh Mody
308a90c566fSRasesh Mody if (p_vf_params->vf_legacy &
309a90c566fSRasesh Mody ECORE_QCID_LEGACY_VF_CID) {
310eb8e81adSRasesh Mody b_legacy_vf = true;
311eb8e81adSRasesh Mody cid = p_vf_params->vf_qid;
312eb8e81adSRasesh Mody }
313eb8e81adSRasesh Mody }
314eb8e81adSRasesh Mody
315a55e422eSRasesh Mody /* Get a unique firmware CID for this queue, in case it's a PF.
316a55e422eSRasesh Mody * VF's don't need a CID as the queue configuration will be done
317a55e422eSRasesh Mody * by PF.
318a55e422eSRasesh Mody */
319eb8e81adSRasesh Mody if (IS_PF(p_hwfn->p_dev) && !b_legacy_vf) {
320eb8e81adSRasesh Mody if (_ecore_cxt_acquire_cid(p_hwfn, PROTOCOLID_ETH,
321eb8e81adSRasesh Mody &cid, vfid) != ECORE_SUCCESS) {
322a55e422eSRasesh Mody DP_NOTICE(p_hwfn, true, "Failed to acquire cid\n");
323a55e422eSRasesh Mody return OSAL_NULL;
324a55e422eSRasesh Mody }
325a55e422eSRasesh Mody }
326a55e422eSRasesh Mody
327eb8e81adSRasesh Mody p_cid = _ecore_eth_queue_to_cid(p_hwfn, opaque_fid, cid,
328823a84aaSRasesh Mody p_params, b_is_rx, p_vf_params);
329eb8e81adSRasesh Mody if ((p_cid == OSAL_NULL) && IS_PF(p_hwfn->p_dev) && !b_legacy_vf)
330eb8e81adSRasesh Mody _ecore_cxt_release_cid(p_hwfn, cid, vfid);
331a55e422eSRasesh Mody
332a55e422eSRasesh Mody return p_cid;
333a55e422eSRasesh Mody }
334a55e422eSRasesh Mody
335eb8e81adSRasesh Mody static struct ecore_queue_cid *
ecore_eth_queue_to_cid_pf(struct ecore_hwfn * p_hwfn,u16 opaque_fid,bool b_is_rx,struct ecore_queue_start_common_params * p_params)336eb8e81adSRasesh Mody ecore_eth_queue_to_cid_pf(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
337823a84aaSRasesh Mody bool b_is_rx,
338eb8e81adSRasesh Mody struct ecore_queue_start_common_params *p_params)
339eb8e81adSRasesh Mody {
340823a84aaSRasesh Mody return ecore_eth_queue_to_cid(p_hwfn, opaque_fid, p_params, b_is_rx,
341823a84aaSRasesh Mody OSAL_NULL);
342eb8e81adSRasesh Mody }
343eb8e81adSRasesh Mody
3445cdd769aSRasesh Mody enum _ecore_status_t
ecore_sp_eth_vport_start(struct ecore_hwfn * p_hwfn,struct ecore_sp_vport_start_params * p_params)3455cdd769aSRasesh Mody ecore_sp_eth_vport_start(struct ecore_hwfn *p_hwfn,
3465cdd769aSRasesh Mody struct ecore_sp_vport_start_params *p_params)
3475cdd769aSRasesh Mody {
3485cdd769aSRasesh Mody struct vport_start_ramrod_data *p_ramrod = OSAL_NULL;
3495cdd769aSRasesh Mody struct ecore_spq_entry *p_ent = OSAL_NULL;
3505cdd769aSRasesh Mody struct ecore_sp_init_data init_data;
351eafbc6fcSRasesh Mody struct eth_vport_tpa_param *p_tpa;
35247b302d6SRasesh Mody u16 rx_mode = 0, tx_err = 0;
3535cdd769aSRasesh Mody u8 abs_vport_id = 0;
3549455b556SRasesh Mody enum _ecore_status_t rc = ECORE_NOTIMPL;
3555cdd769aSRasesh Mody
3565cdd769aSRasesh Mody rc = ecore_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
3575cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
3585cdd769aSRasesh Mody return rc;
3595cdd769aSRasesh Mody
3605cdd769aSRasesh Mody /* Get SPQ entry */
3615cdd769aSRasesh Mody OSAL_MEMSET(&init_data, 0, sizeof(init_data));
3625cdd769aSRasesh Mody init_data.cid = ecore_spq_get_cid(p_hwfn);
3635cdd769aSRasesh Mody init_data.opaque_fid = p_params->opaque_fid;
3645cdd769aSRasesh Mody init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
3655cdd769aSRasesh Mody
3665cdd769aSRasesh Mody rc = ecore_sp_init_request(p_hwfn, &p_ent,
3675cdd769aSRasesh Mody ETH_RAMROD_VPORT_START,
3685cdd769aSRasesh Mody PROTOCOLID_ETH, &init_data);
3695cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
3705cdd769aSRasesh Mody return rc;
3715cdd769aSRasesh Mody
3725cdd769aSRasesh Mody p_ramrod = &p_ent->ramrod.vport_start;
3735cdd769aSRasesh Mody p_ramrod->vport_id = abs_vport_id;
3745cdd769aSRasesh Mody
3755cdd769aSRasesh Mody p_ramrod->mtu = OSAL_CPU_TO_LE16(p_params->mtu);
3765cdd769aSRasesh Mody p_ramrod->handle_ptp_pkts = p_params->handle_ptp_pkts;
377eafbc6fcSRasesh Mody p_ramrod->inner_vlan_removal_en = p_params->remove_inner_vlan;
3785cdd769aSRasesh Mody p_ramrod->drop_ttl0_en = p_params->drop_ttl0;
3795cdd769aSRasesh Mody p_ramrod->untagged = p_params->only_untagged;
3805cdd769aSRasesh Mody p_ramrod->zero_placement_offset = p_params->zero_placement_offset;
3815cdd769aSRasesh Mody
3825cdd769aSRasesh Mody SET_FIELD(rx_mode, ETH_VPORT_RX_MODE_UCAST_DROP_ALL, 1);
3835cdd769aSRasesh Mody SET_FIELD(rx_mode, ETH_VPORT_RX_MODE_MCAST_DROP_ALL, 1);
3845cdd769aSRasesh Mody
3855cdd769aSRasesh Mody p_ramrod->rx_mode.state = OSAL_CPU_TO_LE16(rx_mode);
3865cdd769aSRasesh Mody
38747b302d6SRasesh Mody /* Handle requests for strict behavior on transmission errors */
38847b302d6SRasesh Mody SET_FIELD(tx_err, ETH_TX_ERR_VALS_ILLEGAL_VLAN_MODE,
38947b302d6SRasesh Mody p_params->b_err_illegal_vlan_mode ?
39047b302d6SRasesh Mody ETH_TX_ERR_ASSERT_MALICIOUS : 0);
39147b302d6SRasesh Mody SET_FIELD(tx_err, ETH_TX_ERR_VALS_PACKET_TOO_SMALL,
39247b302d6SRasesh Mody p_params->b_err_small_pkt ?
39347b302d6SRasesh Mody ETH_TX_ERR_ASSERT_MALICIOUS : 0);
39447b302d6SRasesh Mody SET_FIELD(tx_err, ETH_TX_ERR_VALS_ANTI_SPOOFING_ERR,
39547b302d6SRasesh Mody p_params->b_err_anti_spoof ?
39647b302d6SRasesh Mody ETH_TX_ERR_ASSERT_MALICIOUS : 0);
39747b302d6SRasesh Mody SET_FIELD(tx_err, ETH_TX_ERR_VALS_ILLEGAL_INBAND_TAGS,
39847b302d6SRasesh Mody p_params->b_err_illegal_inband_mode ?
39947b302d6SRasesh Mody ETH_TX_ERR_ASSERT_MALICIOUS : 0);
40047b302d6SRasesh Mody SET_FIELD(tx_err, ETH_TX_ERR_VALS_VLAN_INSERTION_W_INBAND_TAG,
40147b302d6SRasesh Mody p_params->b_err_vlan_insert_with_inband ?
40247b302d6SRasesh Mody ETH_TX_ERR_ASSERT_MALICIOUS : 0);
40347b302d6SRasesh Mody SET_FIELD(tx_err, ETH_TX_ERR_VALS_MTU_VIOLATION,
40447b302d6SRasesh Mody p_params->b_err_big_pkt ?
40547b302d6SRasesh Mody ETH_TX_ERR_ASSERT_MALICIOUS : 0);
40647b302d6SRasesh Mody SET_FIELD(tx_err, ETH_TX_ERR_VALS_ILLEGAL_CONTROL_FRAME,
40747b302d6SRasesh Mody p_params->b_err_ctrl_frame ?
40847b302d6SRasesh Mody ETH_TX_ERR_ASSERT_MALICIOUS : 0);
40947b302d6SRasesh Mody p_ramrod->tx_err_behav.values = OSAL_CPU_TO_LE16(tx_err);
41047b302d6SRasesh Mody
4115cdd769aSRasesh Mody /* TPA related fields */
412eafbc6fcSRasesh Mody p_tpa = &p_ramrod->tpa_param;
413eafbc6fcSRasesh Mody OSAL_MEMSET(p_tpa, 0, sizeof(struct eth_vport_tpa_param));
414eafbc6fcSRasesh Mody p_tpa->max_buff_num = p_params->max_buffers_per_cqe;
4155cdd769aSRasesh Mody
4165cdd769aSRasesh Mody switch (p_params->tpa_mode) {
4175cdd769aSRasesh Mody case ECORE_TPA_MODE_GRO:
418eafbc6fcSRasesh Mody p_tpa->tpa_max_aggs_num = ETH_TPA_MAX_AGGS_NUM;
419eafbc6fcSRasesh Mody p_tpa->tpa_max_size = (u16)-1;
420eafbc6fcSRasesh Mody p_tpa->tpa_min_size_to_cont = p_params->mtu / 2;
421eafbc6fcSRasesh Mody p_tpa->tpa_min_size_to_start = p_params->mtu / 2;
422eafbc6fcSRasesh Mody p_tpa->tpa_ipv4_en_flg = 1;
423eafbc6fcSRasesh Mody p_tpa->tpa_ipv6_en_flg = 1;
424eafbc6fcSRasesh Mody p_tpa->tpa_ipv4_tunn_en_flg = 1;
425eafbc6fcSRasesh Mody p_tpa->tpa_ipv6_tunn_en_flg = 1;
426eafbc6fcSRasesh Mody p_tpa->tpa_pkt_split_flg = 1;
427eafbc6fcSRasesh Mody p_tpa->tpa_gro_consistent_flg = 1;
4285cdd769aSRasesh Mody break;
4295cdd769aSRasesh Mody default:
4305cdd769aSRasesh Mody break;
4315cdd769aSRasesh Mody }
4325cdd769aSRasesh Mody
4335cdd769aSRasesh Mody p_ramrod->tx_switching_en = p_params->tx_switching;
4345cdd769aSRasesh Mody #ifndef ASIC_ONLY
4355cdd769aSRasesh Mody if (CHIP_REV_IS_SLOW(p_hwfn->p_dev))
4365cdd769aSRasesh Mody p_ramrod->tx_switching_en = 0;
4375cdd769aSRasesh Mody #endif
4385cdd769aSRasesh Mody
43922d07d93SRasesh Mody p_ramrod->ctl_frame_mac_check_en = !!p_params->check_mac;
44022d07d93SRasesh Mody p_ramrod->ctl_frame_ethtype_check_en = !!p_params->check_ethtype;
44122d07d93SRasesh Mody
4425cdd769aSRasesh Mody /* Software Function ID in hwfn (PFs are 0 - 15, VFs are 16 - 135) */
44330ecf673SRasesh Mody p_ramrod->sw_fid = ecore_concrete_to_sw_fid(p_params->concrete_fid);
4445cdd769aSRasesh Mody
4455cdd769aSRasesh Mody return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
4465cdd769aSRasesh Mody }
4475cdd769aSRasesh Mody
4485cdd769aSRasesh Mody enum _ecore_status_t
ecore_sp_vport_start(struct ecore_hwfn * p_hwfn,struct ecore_sp_vport_start_params * p_params)4495cdd769aSRasesh Mody ecore_sp_vport_start(struct ecore_hwfn *p_hwfn,
4505cdd769aSRasesh Mody struct ecore_sp_vport_start_params *p_params)
4515cdd769aSRasesh Mody {
45286a2265eSRasesh Mody if (IS_VF(p_hwfn->p_dev))
45386a2265eSRasesh Mody return ecore_vf_pf_vport_start(p_hwfn, p_params->vport_id,
45486a2265eSRasesh Mody p_params->mtu,
45586a2265eSRasesh Mody p_params->remove_inner_vlan,
45686a2265eSRasesh Mody p_params->tpa_mode,
45786a2265eSRasesh Mody p_params->max_buffers_per_cqe,
45886a2265eSRasesh Mody p_params->only_untagged);
45986a2265eSRasesh Mody
4605cdd769aSRasesh Mody return ecore_sp_eth_vport_start(p_hwfn, p_params);
4615cdd769aSRasesh Mody }
4625cdd769aSRasesh Mody
4635cdd769aSRasesh Mody 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)4645cdd769aSRasesh Mody ecore_sp_vport_update_rss(struct ecore_hwfn *p_hwfn,
4655cdd769aSRasesh Mody struct vport_update_ramrod_data *p_ramrod,
4665cdd769aSRasesh Mody struct ecore_rss_params *p_rss)
4675cdd769aSRasesh Mody {
4685cdd769aSRasesh Mody struct eth_vport_rss_config *p_config;
469eafbc6fcSRasesh Mody u16 capabilities = 0;
47069d7ba88SRasesh Mody int i, table_size;
47169d7ba88SRasesh Mody enum _ecore_status_t rc = ECORE_SUCCESS;
4725cdd769aSRasesh Mody
4735cdd769aSRasesh Mody if (!p_rss) {
4745cdd769aSRasesh Mody p_ramrod->common.update_rss_flg = 0;
4755cdd769aSRasesh Mody return rc;
4765cdd769aSRasesh Mody }
4775cdd769aSRasesh Mody p_config = &p_ramrod->rss_config;
4785cdd769aSRasesh Mody
4795cdd769aSRasesh Mody OSAL_BUILD_BUG_ON(ECORE_RSS_IND_TABLE_SIZE !=
4805cdd769aSRasesh Mody ETH_RSS_IND_TABLE_ENTRIES_NUM);
4815cdd769aSRasesh Mody
4825cdd769aSRasesh Mody rc = ecore_fw_rss_eng(p_hwfn, p_rss->rss_eng_id, &p_config->rss_id);
4835cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
4845cdd769aSRasesh Mody return rc;
4855cdd769aSRasesh Mody
4865cdd769aSRasesh Mody p_ramrod->common.update_rss_flg = p_rss->update_rss_config;
4875cdd769aSRasesh Mody p_config->update_rss_capabilities = p_rss->update_rss_capabilities;
4885cdd769aSRasesh Mody p_config->update_rss_ind_table = p_rss->update_rss_ind_table;
4895cdd769aSRasesh Mody p_config->update_rss_key = p_rss->update_rss_key;
4905cdd769aSRasesh Mody
4915cdd769aSRasesh Mody p_config->rss_mode = p_rss->rss_enable ?
4925cdd769aSRasesh Mody ETH_VPORT_RSS_MODE_REGULAR : ETH_VPORT_RSS_MODE_DISABLED;
4935cdd769aSRasesh Mody
4945cdd769aSRasesh Mody p_config->capabilities = 0;
4955cdd769aSRasesh Mody
496eafbc6fcSRasesh Mody SET_FIELD(capabilities,
4975cdd769aSRasesh Mody ETH_VPORT_RSS_CONFIG_IPV4_CAPABILITY,
4985cdd769aSRasesh Mody !!(p_rss->rss_caps & ECORE_RSS_IPV4));
499eafbc6fcSRasesh Mody SET_FIELD(capabilities,
5005cdd769aSRasesh Mody ETH_VPORT_RSS_CONFIG_IPV6_CAPABILITY,
5015cdd769aSRasesh Mody !!(p_rss->rss_caps & ECORE_RSS_IPV6));
502eafbc6fcSRasesh Mody SET_FIELD(capabilities,
5035cdd769aSRasesh Mody ETH_VPORT_RSS_CONFIG_IPV4_TCP_CAPABILITY,
5045cdd769aSRasesh Mody !!(p_rss->rss_caps & ECORE_RSS_IPV4_TCP));
505eafbc6fcSRasesh Mody SET_FIELD(capabilities,
5065cdd769aSRasesh Mody ETH_VPORT_RSS_CONFIG_IPV6_TCP_CAPABILITY,
5075cdd769aSRasesh Mody !!(p_rss->rss_caps & ECORE_RSS_IPV6_TCP));
508eafbc6fcSRasesh Mody SET_FIELD(capabilities,
5095cdd769aSRasesh Mody ETH_VPORT_RSS_CONFIG_IPV4_UDP_CAPABILITY,
5105cdd769aSRasesh Mody !!(p_rss->rss_caps & ECORE_RSS_IPV4_UDP));
511eafbc6fcSRasesh Mody SET_FIELD(capabilities,
5125cdd769aSRasesh Mody ETH_VPORT_RSS_CONFIG_IPV6_UDP_CAPABILITY,
5135cdd769aSRasesh Mody !!(p_rss->rss_caps & ECORE_RSS_IPV6_UDP));
5145cdd769aSRasesh Mody p_config->tbl_size = p_rss->rss_table_size_log;
515eafbc6fcSRasesh Mody p_config->capabilities = OSAL_CPU_TO_LE16(capabilities);
5165cdd769aSRasesh Mody
5175cdd769aSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_IFUP,
5185cdd769aSRasesh Mody "update rss flag %d, rss_mode = %d, update_caps = %d, capabilities = %d, update_ind = %d, update_rss_key = %d\n",
5195cdd769aSRasesh Mody p_ramrod->common.update_rss_flg,
5205cdd769aSRasesh Mody p_config->rss_mode,
5215cdd769aSRasesh Mody p_config->update_rss_capabilities,
5225cdd769aSRasesh Mody p_config->capabilities,
5235cdd769aSRasesh Mody p_config->update_rss_ind_table, p_config->update_rss_key);
5245cdd769aSRasesh Mody
52569d7ba88SRasesh Mody table_size = OSAL_MIN_T(int, ECORE_RSS_IND_TABLE_SIZE,
52669d7ba88SRasesh Mody 1 << p_config->tbl_size);
52769d7ba88SRasesh Mody for (i = 0; i < table_size; i++) {
52869d7ba88SRasesh Mody struct ecore_queue_cid *p_queue = p_rss->rss_ind_table[i];
5295cdd769aSRasesh Mody
53069d7ba88SRasesh Mody if (!p_queue)
53169d7ba88SRasesh Mody return ECORE_INVAL;
53269d7ba88SRasesh Mody
53369d7ba88SRasesh Mody p_config->indirection_table[i] =
53469d7ba88SRasesh Mody OSAL_CPU_TO_LE16(p_queue->abs.queue_id);
53569d7ba88SRasesh Mody }
53669d7ba88SRasesh Mody
53769d7ba88SRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_IFUP,
53869d7ba88SRasesh Mody "Configured RSS indirection table [%d entries]:\n",
53969d7ba88SRasesh Mody table_size);
54069d7ba88SRasesh Mody for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i += 0x10) {
54169d7ba88SRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_IFUP,
54269d7ba88SRasesh Mody "%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n",
54369d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i]),
54469d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 1]),
54569d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 2]),
54669d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 3]),
54769d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 4]),
54869d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 5]),
54969d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 6]),
55069d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 7]),
55169d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 8]),
55269d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 9]),
55369d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 10]),
55469d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 11]),
55569d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 12]),
55669d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 13]),
55769d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 14]),
55869d7ba88SRasesh Mody OSAL_LE16_TO_CPU(p_config->indirection_table[i + 15]));
5595cdd769aSRasesh Mody }
5605cdd769aSRasesh Mody
5615cdd769aSRasesh Mody for (i = 0; i < 10; i++)
5625cdd769aSRasesh Mody p_config->rss_key[i] = OSAL_CPU_TO_LE32(p_rss->rss_key[i]);
5635cdd769aSRasesh Mody
5645cdd769aSRasesh Mody return rc;
5655cdd769aSRasesh Mody }
5665cdd769aSRasesh Mody
5675cdd769aSRasesh Mody 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)5685cdd769aSRasesh Mody ecore_sp_update_accept_mode(struct ecore_hwfn *p_hwfn,
5695cdd769aSRasesh Mody struct vport_update_ramrod_data *p_ramrod,
57022d07d93SRasesh Mody struct ecore_filter_accept_flags accept_flags)
5715cdd769aSRasesh Mody {
57222d07d93SRasesh Mody p_ramrod->common.update_rx_mode_flg =
57322d07d93SRasesh Mody accept_flags.update_rx_mode_config;
57422d07d93SRasesh Mody p_ramrod->common.update_tx_mode_flg =
57522d07d93SRasesh Mody accept_flags.update_tx_mode_config;
5765cdd769aSRasesh Mody
5775cdd769aSRasesh Mody #ifndef ASIC_ONLY
5785cdd769aSRasesh Mody /* On B0 emulation we cannot enable Tx, since this would cause writes
5795cdd769aSRasesh Mody * to PVFC HW block which isn't implemented in emulation.
5805cdd769aSRasesh Mody */
5815cdd769aSRasesh Mody if (CHIP_REV_IS_SLOW(p_hwfn->p_dev)) {
5825cdd769aSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
5835cdd769aSRasesh Mody "Non-Asic - prevent Tx mode in vport update\n");
5845cdd769aSRasesh Mody p_ramrod->common.update_tx_mode_flg = 0;
5855cdd769aSRasesh Mody }
5865cdd769aSRasesh Mody #endif
5875cdd769aSRasesh Mody
5885cdd769aSRasesh Mody /* Set Rx mode accept flags */
5895cdd769aSRasesh Mody if (p_ramrod->common.update_rx_mode_flg) {
59022d07d93SRasesh Mody u8 accept_filter = accept_flags.rx_accept_filter;
59122d07d93SRasesh Mody u16 state = 0;
5925cdd769aSRasesh Mody
59322d07d93SRasesh Mody SET_FIELD(state, ETH_VPORT_RX_MODE_UCAST_DROP_ALL,
5945cdd769aSRasesh Mody !(!!(accept_filter & ECORE_ACCEPT_UCAST_MATCHED) ||
5955cdd769aSRasesh Mody !!(accept_filter & ECORE_ACCEPT_UCAST_UNMATCHED)));
5965cdd769aSRasesh Mody
59722d07d93SRasesh Mody SET_FIELD(state, ETH_VPORT_RX_MODE_UCAST_ACCEPT_UNMATCHED,
5985cdd769aSRasesh Mody !!(accept_filter & ECORE_ACCEPT_UCAST_UNMATCHED));
59922d07d93SRasesh Mody
60022d07d93SRasesh Mody SET_FIELD(state, ETH_VPORT_RX_MODE_MCAST_DROP_ALL,
6015cdd769aSRasesh Mody !(!!(accept_filter & ECORE_ACCEPT_MCAST_MATCHED) ||
6025cdd769aSRasesh Mody !!(accept_filter & ECORE_ACCEPT_MCAST_UNMATCHED)));
6035cdd769aSRasesh Mody
60422d07d93SRasesh Mody SET_FIELD(state, ETH_VPORT_RX_MODE_MCAST_ACCEPT_ALL,
6055cdd769aSRasesh Mody (!!(accept_filter & ECORE_ACCEPT_MCAST_MATCHED) &&
6065cdd769aSRasesh Mody !!(accept_filter & ECORE_ACCEPT_MCAST_UNMATCHED)));
6075cdd769aSRasesh Mody
60822d07d93SRasesh Mody SET_FIELD(state, ETH_VPORT_RX_MODE_BCAST_ACCEPT_ALL,
6095cdd769aSRasesh Mody !!(accept_filter & ECORE_ACCEPT_BCAST));
6105cdd769aSRasesh Mody
6113c361686SRasesh Mody SET_FIELD(state, ETH_VPORT_RX_MODE_ACCEPT_ANY_VNI,
6123c361686SRasesh Mody !!(accept_filter & ECORE_ACCEPT_ANY_VNI));
6133c361686SRasesh Mody
61422d07d93SRasesh Mody p_ramrod->rx_mode.state = OSAL_CPU_TO_LE16(state);
6155cdd769aSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
6166b190a98SRasesh Mody "vport[%02x] p_ramrod->rx_mode.state = 0x%x\n",
6176b190a98SRasesh Mody p_ramrod->common.vport_id, state);
6185cdd769aSRasesh Mody }
6195cdd769aSRasesh Mody
6205cdd769aSRasesh Mody /* Set Tx mode accept flags */
6215cdd769aSRasesh Mody if (p_ramrod->common.update_tx_mode_flg) {
62222d07d93SRasesh Mody u8 accept_filter = accept_flags.tx_accept_filter;
62322d07d93SRasesh Mody u16 state = 0;
6245cdd769aSRasesh Mody
62522d07d93SRasesh Mody SET_FIELD(state, ETH_VPORT_TX_MODE_UCAST_DROP_ALL,
6265cdd769aSRasesh Mody !!(accept_filter & ECORE_ACCEPT_NONE));
6275cdd769aSRasesh Mody
62822d07d93SRasesh Mody SET_FIELD(state, ETH_VPORT_TX_MODE_MCAST_DROP_ALL,
6295cdd769aSRasesh Mody !!(accept_filter & ECORE_ACCEPT_NONE));
6305cdd769aSRasesh Mody
63122d07d93SRasesh Mody SET_FIELD(state, ETH_VPORT_TX_MODE_MCAST_ACCEPT_ALL,
6325cdd769aSRasesh Mody (!!(accept_filter & ECORE_ACCEPT_MCAST_MATCHED) &&
6335cdd769aSRasesh Mody !!(accept_filter & ECORE_ACCEPT_MCAST_UNMATCHED)));
6345cdd769aSRasesh Mody
63522d07d93SRasesh Mody SET_FIELD(state, ETH_VPORT_TX_MODE_BCAST_ACCEPT_ALL,
6365cdd769aSRasesh Mody !!(accept_filter & ECORE_ACCEPT_BCAST));
6375cdd769aSRasesh Mody
63822d07d93SRasesh Mody p_ramrod->tx_mode.state = OSAL_CPU_TO_LE16(state);
6395cdd769aSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
6406b190a98SRasesh Mody "vport[%02x] p_ramrod->tx_mode.state = 0x%x\n",
6416b190a98SRasesh Mody p_ramrod->common.vport_id, state);
6425cdd769aSRasesh Mody }
6435cdd769aSRasesh Mody }
6445cdd769aSRasesh Mody
6455cdd769aSRasesh Mody static void
ecore_sp_vport_update_sge_tpa(struct vport_update_ramrod_data * p_ramrod,struct ecore_sge_tpa_params * p_params)64630ecf673SRasesh Mody ecore_sp_vport_update_sge_tpa(struct vport_update_ramrod_data *p_ramrod,
6475cdd769aSRasesh Mody struct ecore_sge_tpa_params *p_params)
6485cdd769aSRasesh Mody {
6495cdd769aSRasesh Mody struct eth_vport_tpa_param *p_tpa;
650eafbc6fcSRasesh Mody u16 val;
6515cdd769aSRasesh Mody
6525cdd769aSRasesh Mody if (!p_params) {
6535cdd769aSRasesh Mody p_ramrod->common.update_tpa_param_flg = 0;
6545cdd769aSRasesh Mody p_ramrod->common.update_tpa_en_flg = 0;
6555cdd769aSRasesh Mody p_ramrod->common.update_tpa_param_flg = 0;
6565cdd769aSRasesh Mody return;
6575cdd769aSRasesh Mody }
6585cdd769aSRasesh Mody
6595cdd769aSRasesh Mody p_ramrod->common.update_tpa_en_flg = p_params->update_tpa_en_flg;
6605cdd769aSRasesh Mody p_tpa = &p_ramrod->tpa_param;
6615cdd769aSRasesh Mody p_tpa->tpa_ipv4_en_flg = p_params->tpa_ipv4_en_flg;
6625cdd769aSRasesh Mody p_tpa->tpa_ipv6_en_flg = p_params->tpa_ipv6_en_flg;
6635cdd769aSRasesh Mody p_tpa->tpa_ipv4_tunn_en_flg = p_params->tpa_ipv4_tunn_en_flg;
6645cdd769aSRasesh Mody p_tpa->tpa_ipv6_tunn_en_flg = p_params->tpa_ipv6_tunn_en_flg;
6655cdd769aSRasesh Mody
6665cdd769aSRasesh Mody p_ramrod->common.update_tpa_param_flg = p_params->update_tpa_param_flg;
6675cdd769aSRasesh Mody p_tpa->max_buff_num = p_params->max_buffers_per_cqe;
6685cdd769aSRasesh Mody p_tpa->tpa_pkt_split_flg = p_params->tpa_pkt_split_flg;
6695cdd769aSRasesh Mody p_tpa->tpa_hdr_data_split_flg = p_params->tpa_hdr_data_split_flg;
6705cdd769aSRasesh Mody p_tpa->tpa_gro_consistent_flg = p_params->tpa_gro_consistent_flg;
6715cdd769aSRasesh Mody p_tpa->tpa_max_aggs_num = p_params->tpa_max_aggs_num;
672eafbc6fcSRasesh Mody val = p_params->tpa_max_size;
673eafbc6fcSRasesh Mody p_tpa->tpa_max_size = OSAL_CPU_TO_LE16(val);
674eafbc6fcSRasesh Mody val = p_params->tpa_min_size_to_start;
675eafbc6fcSRasesh Mody p_tpa->tpa_min_size_to_start = OSAL_CPU_TO_LE16(val);
676eafbc6fcSRasesh Mody val = p_params->tpa_min_size_to_cont;
677eafbc6fcSRasesh Mody p_tpa->tpa_min_size_to_cont = OSAL_CPU_TO_LE16(val);
6785cdd769aSRasesh Mody }
6795cdd769aSRasesh Mody
6805cdd769aSRasesh Mody static void
ecore_sp_update_mcast_bin(struct vport_update_ramrod_data * p_ramrod,struct ecore_sp_vport_update_params * p_params)68130ecf673SRasesh Mody ecore_sp_update_mcast_bin(struct vport_update_ramrod_data *p_ramrod,
6825cdd769aSRasesh Mody struct ecore_sp_vport_update_params *p_params)
6835cdd769aSRasesh Mody {
6845cdd769aSRasesh Mody int i;
6855cdd769aSRasesh Mody
6865cdd769aSRasesh Mody OSAL_MEMSET(&p_ramrod->approx_mcast.bins, 0,
6875cdd769aSRasesh Mody sizeof(p_ramrod->approx_mcast.bins));
6885cdd769aSRasesh Mody
6895cdd769aSRasesh Mody if (!p_params->update_approx_mcast_flg)
6905cdd769aSRasesh Mody return;
6915cdd769aSRasesh Mody
6925cdd769aSRasesh Mody p_ramrod->common.update_approx_mcast_flg = 1;
6935cdd769aSRasesh Mody for (i = 0; i < ETH_MULTICAST_MAC_BINS_IN_REGS; i++) {
694413ecf29SHarish Patil u32 *p_bins = p_params->bins;
6955cdd769aSRasesh Mody
6965cdd769aSRasesh Mody p_ramrod->approx_mcast.bins[i] = OSAL_CPU_TO_LE32(p_bins[i]);
6975cdd769aSRasesh Mody }
6985cdd769aSRasesh Mody }
6995cdd769aSRasesh Mody
7005cdd769aSRasesh Mody enum _ecore_status_t
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)7015cdd769aSRasesh Mody ecore_sp_vport_update(struct ecore_hwfn *p_hwfn,
7025cdd769aSRasesh Mody struct ecore_sp_vport_update_params *p_params,
7035cdd769aSRasesh Mody enum spq_mode comp_mode,
7045cdd769aSRasesh Mody struct ecore_spq_comp_cb *p_comp_data)
7055cdd769aSRasesh Mody {
7065cdd769aSRasesh Mody struct ecore_rss_params *p_rss_params = p_params->rss_params;
70722d07d93SRasesh Mody struct vport_update_ramrod_data_cmn *p_cmn;
70822d07d93SRasesh Mody struct ecore_sp_init_data init_data;
7095cdd769aSRasesh Mody struct vport_update_ramrod_data *p_ramrod = OSAL_NULL;
7105cdd769aSRasesh Mody struct ecore_spq_entry *p_ent = OSAL_NULL;
7115cdd769aSRasesh Mody u8 abs_vport_id = 0, val;
71222d07d93SRasesh Mody enum _ecore_status_t rc = ECORE_NOTIMPL;
7135cdd769aSRasesh Mody
71486a2265eSRasesh Mody if (IS_VF(p_hwfn->p_dev)) {
71586a2265eSRasesh Mody rc = ecore_vf_pf_vport_update(p_hwfn, p_params);
71686a2265eSRasesh Mody return rc;
71786a2265eSRasesh Mody }
71886a2265eSRasesh Mody
7195cdd769aSRasesh Mody rc = ecore_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
7205cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
7215cdd769aSRasesh Mody return rc;
7225cdd769aSRasesh Mody
7235cdd769aSRasesh Mody /* Get SPQ entry */
7245cdd769aSRasesh Mody OSAL_MEMSET(&init_data, 0, sizeof(init_data));
7255cdd769aSRasesh Mody init_data.cid = ecore_spq_get_cid(p_hwfn);
7265cdd769aSRasesh Mody init_data.opaque_fid = p_params->opaque_fid;
7275cdd769aSRasesh Mody init_data.comp_mode = comp_mode;
7285cdd769aSRasesh Mody init_data.p_comp_data = p_comp_data;
7295cdd769aSRasesh Mody
7305cdd769aSRasesh Mody rc = ecore_sp_init_request(p_hwfn, &p_ent,
7315cdd769aSRasesh Mody ETH_RAMROD_VPORT_UPDATE,
7325cdd769aSRasesh Mody PROTOCOLID_ETH, &init_data);
7335cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
7345cdd769aSRasesh Mody return rc;
7355cdd769aSRasesh Mody
7365cdd769aSRasesh Mody /* Copy input params to ramrod according to FW struct */
7375cdd769aSRasesh Mody p_ramrod = &p_ent->ramrod.vport_update;
73822d07d93SRasesh Mody p_cmn = &p_ramrod->common;
7395cdd769aSRasesh Mody
74022d07d93SRasesh Mody p_cmn->vport_id = abs_vport_id;
7415cdd769aSRasesh Mody
74222d07d93SRasesh Mody p_cmn->rx_active_flg = p_params->vport_active_rx_flg;
74322d07d93SRasesh Mody p_cmn->update_rx_active_flg = p_params->update_vport_active_rx_flg;
74422d07d93SRasesh Mody p_cmn->tx_active_flg = p_params->vport_active_tx_flg;
74522d07d93SRasesh Mody p_cmn->update_tx_active_flg = p_params->update_vport_active_tx_flg;
74622d07d93SRasesh Mody
74722d07d93SRasesh Mody p_cmn->accept_any_vlan = p_params->accept_any_vlan;
74822d07d93SRasesh Mody val = p_params->update_accept_any_vlan_flg;
74922d07d93SRasesh Mody p_cmn->update_accept_any_vlan_flg = val;
75022d07d93SRasesh Mody
75122d07d93SRasesh Mody p_cmn->inner_vlan_removal_en = p_params->inner_vlan_removal_flg;
7525cdd769aSRasesh Mody val = p_params->update_inner_vlan_removal_flg;
75322d07d93SRasesh Mody p_cmn->update_inner_vlan_removal_en_flg = val;
75422d07d93SRasesh Mody
75522d07d93SRasesh Mody p_cmn->default_vlan_en = p_params->default_vlan_enable_flg;
7565cdd769aSRasesh Mody val = p_params->update_default_vlan_enable_flg;
75722d07d93SRasesh Mody p_cmn->update_default_vlan_en_flg = val;
75822d07d93SRasesh Mody
75922d07d93SRasesh Mody p_cmn->default_vlan = OSAL_CPU_TO_LE16(p_params->default_vlan);
76022d07d93SRasesh Mody p_cmn->update_default_vlan_flg = p_params->update_default_vlan_flg;
76122d07d93SRasesh Mody
76222d07d93SRasesh Mody p_cmn->silent_vlan_removal_en = p_params->silent_vlan_removal_flg;
7635cdd769aSRasesh Mody
7645cdd769aSRasesh Mody p_ramrod->common.tx_switching_en = p_params->tx_switching_flg;
7655cdd769aSRasesh Mody
7665cdd769aSRasesh Mody #ifndef ASIC_ONLY
7675cdd769aSRasesh Mody if (CHIP_REV_IS_FPGA(p_hwfn->p_dev))
7685cdd769aSRasesh Mody if (p_ramrod->common.tx_switching_en ||
7695cdd769aSRasesh Mody p_ramrod->common.update_tx_switching_en_flg) {
7705cdd769aSRasesh Mody DP_NOTICE(p_hwfn, false,
7715cdd769aSRasesh Mody "FPGA - why are we seeing tx-switching? Overriding it\n");
7725cdd769aSRasesh Mody p_ramrod->common.tx_switching_en = 0;
7735cdd769aSRasesh Mody p_ramrod->common.update_tx_switching_en_flg = 1;
7745cdd769aSRasesh Mody }
7755cdd769aSRasesh Mody #endif
77622d07d93SRasesh Mody p_cmn->update_tx_switching_en_flg = p_params->update_tx_switching_flg;
7775cdd769aSRasesh Mody
77822d07d93SRasesh Mody p_cmn->anti_spoofing_en = p_params->anti_spoofing_en;
7795cdd769aSRasesh Mody val = p_params->update_anti_spoofing_en_flg;
7805cdd769aSRasesh Mody p_ramrod->common.update_anti_spoofing_en_flg = val;
7815cdd769aSRasesh Mody
7825cdd769aSRasesh Mody rc = ecore_sp_vport_update_rss(p_hwfn, p_ramrod, p_rss_params);
7835cdd769aSRasesh Mody if (rc != ECORE_SUCCESS) {
7845cdd769aSRasesh Mody /* Return spq entry which is taken in ecore_sp_init_request()*/
7855cdd769aSRasesh Mody ecore_spq_return_entry(p_hwfn, p_ent);
7865cdd769aSRasesh Mody return rc;
7875cdd769aSRasesh Mody }
7885cdd769aSRasesh Mody
789ab67e837SRasesh Mody if (p_params->update_ctl_frame_check) {
790ab67e837SRasesh Mody p_cmn->ctl_frame_mac_check_en = p_params->mac_chk_en;
791ab67e837SRasesh Mody p_cmn->ctl_frame_ethtype_check_en = p_params->ethtype_chk_en;
792ab67e837SRasesh Mody }
793ab67e837SRasesh Mody
7945cdd769aSRasesh Mody /* Update mcast bins for VFs, PF doesn't use this functionality */
79530ecf673SRasesh Mody ecore_sp_update_mcast_bin(p_ramrod, p_params);
7965cdd769aSRasesh Mody
7975cdd769aSRasesh Mody ecore_sp_update_accept_mode(p_hwfn, p_ramrod, p_params->accept_flags);
79830ecf673SRasesh Mody ecore_sp_vport_update_sge_tpa(p_ramrod, p_params->sge_tpa_params);
79920e961bcSHarish Patil if (p_params->mtu) {
80020e961bcSHarish Patil p_ramrod->common.update_mtu_flg = 1;
80120e961bcSHarish Patil p_ramrod->common.mtu = OSAL_CPU_TO_LE16(p_params->mtu);
80220e961bcSHarish Patil }
80320e961bcSHarish Patil
8045cdd769aSRasesh Mody return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
8055cdd769aSRasesh Mody }
8065cdd769aSRasesh Mody
ecore_sp_vport_stop(struct ecore_hwfn * p_hwfn,u16 opaque_fid,u8 vport_id)8075cdd769aSRasesh Mody enum _ecore_status_t ecore_sp_vport_stop(struct ecore_hwfn *p_hwfn,
8085cdd769aSRasesh Mody u16 opaque_fid, u8 vport_id)
8095cdd769aSRasesh Mody {
8105cdd769aSRasesh Mody struct vport_stop_ramrod_data *p_ramrod;
8115cdd769aSRasesh Mody struct ecore_sp_init_data init_data;
8125cdd769aSRasesh Mody struct ecore_spq_entry *p_ent;
8135cdd769aSRasesh Mody u8 abs_vport_id = 0;
8149455b556SRasesh Mody enum _ecore_status_t rc;
8155cdd769aSRasesh Mody
81686a2265eSRasesh Mody if (IS_VF(p_hwfn->p_dev))
81786a2265eSRasesh Mody return ecore_vf_pf_vport_stop(p_hwfn);
81886a2265eSRasesh Mody
8195cdd769aSRasesh Mody rc = ecore_fw_vport(p_hwfn, vport_id, &abs_vport_id);
8205cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
8215cdd769aSRasesh Mody return rc;
8225cdd769aSRasesh Mody
8235cdd769aSRasesh Mody /* Get SPQ entry */
8245cdd769aSRasesh Mody OSAL_MEMSET(&init_data, 0, sizeof(init_data));
8255cdd769aSRasesh Mody init_data.cid = ecore_spq_get_cid(p_hwfn);
8265cdd769aSRasesh Mody init_data.opaque_fid = opaque_fid;
8275cdd769aSRasesh Mody init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
8285cdd769aSRasesh Mody
8295cdd769aSRasesh Mody rc = ecore_sp_init_request(p_hwfn, &p_ent,
8305cdd769aSRasesh Mody ETH_RAMROD_VPORT_STOP,
8315cdd769aSRasesh Mody PROTOCOLID_ETH, &init_data);
8325cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
8335cdd769aSRasesh Mody return rc;
8345cdd769aSRasesh Mody
8355cdd769aSRasesh Mody p_ramrod = &p_ent->ramrod.vport_stop;
8365cdd769aSRasesh Mody p_ramrod->vport_id = abs_vport_id;
8375cdd769aSRasesh Mody
8385cdd769aSRasesh Mody return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
8395cdd769aSRasesh Mody }
8405cdd769aSRasesh Mody
84186a2265eSRasesh Mody static enum _ecore_status_t
ecore_vf_pf_accept_flags(struct ecore_hwfn * p_hwfn,struct ecore_filter_accept_flags * p_accept_flags)84286a2265eSRasesh Mody ecore_vf_pf_accept_flags(struct ecore_hwfn *p_hwfn,
84386a2265eSRasesh Mody struct ecore_filter_accept_flags *p_accept_flags)
84486a2265eSRasesh Mody {
84586a2265eSRasesh Mody struct ecore_sp_vport_update_params s_params;
84686a2265eSRasesh Mody
84786a2265eSRasesh Mody OSAL_MEMSET(&s_params, 0, sizeof(s_params));
84886a2265eSRasesh Mody OSAL_MEMCPY(&s_params.accept_flags, p_accept_flags,
84986a2265eSRasesh Mody sizeof(struct ecore_filter_accept_flags));
85086a2265eSRasesh Mody
85186a2265eSRasesh Mody return ecore_vf_pf_vport_update(p_hwfn, &s_params);
85286a2265eSRasesh Mody }
85386a2265eSRasesh Mody
8545cdd769aSRasesh Mody enum _ecore_status_t
ecore_filter_accept_cmd(struct ecore_dev * p_dev,u8 vport,struct ecore_filter_accept_flags accept_flags,u8 update_accept_any_vlan,u8 accept_any_vlan,enum spq_mode comp_mode,struct ecore_spq_comp_cb * p_comp_data)8555cdd769aSRasesh Mody ecore_filter_accept_cmd(struct ecore_dev *p_dev,
8565cdd769aSRasesh Mody u8 vport,
8575cdd769aSRasesh Mody struct ecore_filter_accept_flags accept_flags,
8585cdd769aSRasesh Mody u8 update_accept_any_vlan,
8595cdd769aSRasesh Mody u8 accept_any_vlan,
8605cdd769aSRasesh Mody enum spq_mode comp_mode,
8615cdd769aSRasesh Mody struct ecore_spq_comp_cb *p_comp_data)
8625cdd769aSRasesh Mody {
86322d07d93SRasesh Mody struct ecore_sp_vport_update_params vport_update_params;
8645cdd769aSRasesh Mody int i, rc;
8655cdd769aSRasesh Mody
8665cdd769aSRasesh Mody /* Prepare and send the vport rx_mode change */
86722d07d93SRasesh Mody OSAL_MEMSET(&vport_update_params, 0, sizeof(vport_update_params));
86822d07d93SRasesh Mody vport_update_params.vport_id = vport;
86922d07d93SRasesh Mody vport_update_params.accept_flags = accept_flags;
87022d07d93SRasesh Mody vport_update_params.update_accept_any_vlan_flg = update_accept_any_vlan;
87122d07d93SRasesh Mody vport_update_params.accept_any_vlan = accept_any_vlan;
8725cdd769aSRasesh Mody
8735cdd769aSRasesh Mody for_each_hwfn(p_dev, i) {
8745cdd769aSRasesh Mody struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
8755cdd769aSRasesh Mody
87622d07d93SRasesh Mody vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
8775cdd769aSRasesh Mody
87886a2265eSRasesh Mody if (IS_VF(p_dev)) {
87986a2265eSRasesh Mody rc = ecore_vf_pf_accept_flags(p_hwfn, &accept_flags);
88086a2265eSRasesh Mody if (rc != ECORE_SUCCESS)
88186a2265eSRasesh Mody return rc;
88286a2265eSRasesh Mody continue;
88386a2265eSRasesh Mody }
88486a2265eSRasesh Mody
88522d07d93SRasesh Mody rc = ecore_sp_vport_update(p_hwfn, &vport_update_params,
8865cdd769aSRasesh Mody comp_mode, p_comp_data);
8875cdd769aSRasesh Mody if (rc != ECORE_SUCCESS) {
8885cdd769aSRasesh Mody DP_ERR(p_dev, "Update rx_mode failed %d\n", rc);
8895cdd769aSRasesh Mody return rc;
8905cdd769aSRasesh Mody }
8915cdd769aSRasesh Mody
8925cdd769aSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
8935cdd769aSRasesh Mody "Accept filter configured, flags = [Rx]%x [Tx]%x\n",
8945cdd769aSRasesh Mody accept_flags.rx_accept_filter,
8955cdd769aSRasesh Mody accept_flags.tx_accept_filter);
8965cdd769aSRasesh Mody
8975cdd769aSRasesh Mody if (update_accept_any_vlan)
8985cdd769aSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
8995cdd769aSRasesh Mody "accept_any_vlan=%d configured\n",
9005cdd769aSRasesh Mody accept_any_vlan);
9015cdd769aSRasesh Mody }
9025cdd769aSRasesh Mody
9035cdd769aSRasesh Mody return 0;
9045cdd769aSRasesh Mody }
9055cdd769aSRasesh Mody
9065cdd769aSRasesh Mody enum _ecore_status_t
ecore_eth_rxq_start_ramrod(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid,u16 bd_max_bytes,dma_addr_t bd_chain_phys_addr,dma_addr_t cqe_pbl_addr,u16 cqe_pbl_size)907a55e422eSRasesh Mody ecore_eth_rxq_start_ramrod(struct ecore_hwfn *p_hwfn,
908a55e422eSRasesh Mody struct ecore_queue_cid *p_cid,
9095cdd769aSRasesh Mody u16 bd_max_bytes,
9105cdd769aSRasesh Mody dma_addr_t bd_chain_phys_addr,
91122d07d93SRasesh Mody dma_addr_t cqe_pbl_addr,
912a55e422eSRasesh Mody u16 cqe_pbl_size)
9135cdd769aSRasesh Mody {
9145cdd769aSRasesh Mody struct rx_queue_start_ramrod_data *p_ramrod = OSAL_NULL;
9155cdd769aSRasesh Mody struct ecore_spq_entry *p_ent = OSAL_NULL;
9165cdd769aSRasesh Mody struct ecore_sp_init_data init_data;
91722d07d93SRasesh Mody enum _ecore_status_t rc = ECORE_NOTIMPL;
9185cdd769aSRasesh Mody
9195cdd769aSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
920a55e422eSRasesh Mody "opaque_fid=0x%x, cid=0x%x, rx_qzone=0x%x, vport_id=0x%x, sb_id=0x%x\n",
921a55e422eSRasesh Mody p_cid->opaque_fid, p_cid->cid, p_cid->abs.queue_id,
9226e4fcea9SRasesh Mody p_cid->abs.vport_id, p_cid->sb_igu_id);
9235cdd769aSRasesh Mody
9245cdd769aSRasesh Mody /* Get SPQ entry */
9255cdd769aSRasesh Mody OSAL_MEMSET(&init_data, 0, sizeof(init_data));
926a55e422eSRasesh Mody init_data.cid = p_cid->cid;
927a55e422eSRasesh Mody init_data.opaque_fid = p_cid->opaque_fid;
9285cdd769aSRasesh Mody init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
9295cdd769aSRasesh Mody
9305cdd769aSRasesh Mody rc = ecore_sp_init_request(p_hwfn, &p_ent,
9315cdd769aSRasesh Mody ETH_RAMROD_RX_QUEUE_START,
9325cdd769aSRasesh Mody PROTOCOLID_ETH, &init_data);
9335cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
9345cdd769aSRasesh Mody return rc;
9355cdd769aSRasesh Mody
9365cdd769aSRasesh Mody p_ramrod = &p_ent->ramrod.rx_queue_start;
9375cdd769aSRasesh Mody
9386e4fcea9SRasesh Mody p_ramrod->sb_id = OSAL_CPU_TO_LE16(p_cid->sb_igu_id);
9396e4fcea9SRasesh Mody p_ramrod->sb_index = p_cid->sb_idx;
940a55e422eSRasesh Mody p_ramrod->vport_id = p_cid->abs.vport_id;
941a55e422eSRasesh Mody p_ramrod->stats_counter_id = p_cid->abs.stats_id;
942a55e422eSRasesh Mody p_ramrod->rx_queue_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
9435cdd769aSRasesh Mody p_ramrod->complete_cqe_flg = 0;
9445cdd769aSRasesh Mody p_ramrod->complete_event_flg = 1;
9455cdd769aSRasesh Mody
9465cdd769aSRasesh Mody p_ramrod->bd_max_bytes = OSAL_CPU_TO_LE16(bd_max_bytes);
9475cdd769aSRasesh Mody DMA_REGPAIR_LE(p_ramrod->bd_base, bd_chain_phys_addr);
9485cdd769aSRasesh Mody
9495cdd769aSRasesh Mody p_ramrod->num_of_pbl_pages = OSAL_CPU_TO_LE16(cqe_pbl_size);
9505cdd769aSRasesh Mody DMA_REGPAIR_LE(p_ramrod->cqe_pbl_addr, cqe_pbl_addr);
9515cdd769aSRasesh Mody
952eb8e81adSRasesh Mody if (p_cid->vfid != ECORE_QUEUE_CID_PF) {
953a90c566fSRasesh Mody bool b_legacy_vf = !!(p_cid->vf_legacy &
954a90c566fSRasesh Mody ECORE_QCID_LEGACY_VF_RX_PROD);
955a90c566fSRasesh Mody
956a55e422eSRasesh Mody p_ramrod->vf_rx_prod_index = p_cid->vf_qid;
95722d07d93SRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
95822d07d93SRasesh Mody "Queue%s is meant for VF rxq[%02x]\n",
959a90c566fSRasesh Mody b_legacy_vf ? " [legacy]" : "",
960a55e422eSRasesh Mody p_cid->vf_qid);
961a90c566fSRasesh Mody p_ramrod->vf_rx_prod_use_zone_a = b_legacy_vf;
96222d07d93SRasesh Mody }
96322d07d93SRasesh Mody
9645cdd769aSRasesh Mody return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
9655cdd769aSRasesh Mody }
9665cdd769aSRasesh Mody
967a55e422eSRasesh Mody static enum _ecore_status_t
ecore_eth_pf_rx_queue_start(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid,u16 bd_max_bytes,dma_addr_t bd_chain_phys_addr,dma_addr_t cqe_pbl_addr,u16 cqe_pbl_size,void OSAL_IOMEM ** pp_prod)968a55e422eSRasesh Mody ecore_eth_pf_rx_queue_start(struct ecore_hwfn *p_hwfn,
969a55e422eSRasesh Mody struct ecore_queue_cid *p_cid,
970a55e422eSRasesh Mody u16 bd_max_bytes,
971a55e422eSRasesh Mody dma_addr_t bd_chain_phys_addr,
972a55e422eSRasesh Mody dma_addr_t cqe_pbl_addr,
973a55e422eSRasesh Mody u16 cqe_pbl_size,
9747a5dfdc1SRasesh Mody void OSAL_IOMEM * *pp_prod)
975a55e422eSRasesh Mody {
976a55e422eSRasesh Mody u32 init_prod_val = 0;
977a55e422eSRasesh Mody
9787a5dfdc1SRasesh Mody *pp_prod = (u8 OSAL_IOMEM *)
979a55e422eSRasesh Mody p_hwfn->regview +
980a55e422eSRasesh Mody GTT_BAR0_MAP_REG_MSDM_RAM +
981a55e422eSRasesh Mody MSTORM_ETH_PF_PRODS_OFFSET(p_cid->abs.queue_id);
982a55e422eSRasesh Mody
983a55e422eSRasesh Mody /* Init the rcq, rx bd and rx sge (if valid) producers to 0 */
9847a5dfdc1SRasesh Mody __internal_ram_wr(p_hwfn, *pp_prod, sizeof(u32),
985a55e422eSRasesh Mody (u32 *)(&init_prod_val));
986a55e422eSRasesh Mody
987a55e422eSRasesh Mody return ecore_eth_rxq_start_ramrod(p_hwfn, p_cid,
988a55e422eSRasesh Mody bd_max_bytes,
989a55e422eSRasesh Mody bd_chain_phys_addr,
990a55e422eSRasesh Mody cqe_pbl_addr, cqe_pbl_size);
991a55e422eSRasesh Mody }
992a55e422eSRasesh Mody
99398bc693eSRasesh Mody enum _ecore_status_t
ecore_eth_rx_queue_start(struct ecore_hwfn * p_hwfn,u16 opaque_fid,struct ecore_queue_start_common_params * p_params,u16 bd_max_bytes,dma_addr_t bd_chain_phys_addr,dma_addr_t cqe_pbl_addr,u16 cqe_pbl_size,struct ecore_rxq_start_ret_params * p_ret_params)994a55e422eSRasesh Mody ecore_eth_rx_queue_start(struct ecore_hwfn *p_hwfn,
9955cdd769aSRasesh Mody u16 opaque_fid,
99698bc693eSRasesh Mody struct ecore_queue_start_common_params *p_params,
9975cdd769aSRasesh Mody u16 bd_max_bytes,
9985cdd769aSRasesh Mody dma_addr_t bd_chain_phys_addr,
9995cdd769aSRasesh Mody dma_addr_t cqe_pbl_addr,
10005cdd769aSRasesh Mody u16 cqe_pbl_size,
1001a55e422eSRasesh Mody struct ecore_rxq_start_ret_params *p_ret_params)
10025cdd769aSRasesh Mody {
1003a55e422eSRasesh Mody struct ecore_queue_cid *p_cid;
10045cdd769aSRasesh Mody enum _ecore_status_t rc;
10055cdd769aSRasesh Mody
1006a55e422eSRasesh Mody /* Allocate a CID for the queue */
1007823a84aaSRasesh Mody p_cid = ecore_eth_queue_to_cid_pf(p_hwfn, opaque_fid, true, p_params);
1008a55e422eSRasesh Mody if (p_cid == OSAL_NULL)
1009a55e422eSRasesh Mody return ECORE_NOMEM;
1010a55e422eSRasesh Mody
1011a55e422eSRasesh Mody if (IS_PF(p_hwfn->p_dev))
1012a55e422eSRasesh Mody rc = ecore_eth_pf_rx_queue_start(p_hwfn, p_cid,
101386a2265eSRasesh Mody bd_max_bytes,
101486a2265eSRasesh Mody bd_chain_phys_addr,
1015a55e422eSRasesh Mody cqe_pbl_addr, cqe_pbl_size,
1016a55e422eSRasesh Mody &p_ret_params->p_prod);
1017a55e422eSRasesh Mody else
1018a55e422eSRasesh Mody rc = ecore_vf_pf_rxq_start(p_hwfn, p_cid,
10195cdd769aSRasesh Mody bd_max_bytes,
10205cdd769aSRasesh Mody bd_chain_phys_addr,
102122d07d93SRasesh Mody cqe_pbl_addr,
102222d07d93SRasesh Mody cqe_pbl_size,
1023a55e422eSRasesh Mody &p_ret_params->p_prod);
10245cdd769aSRasesh Mody
1025a55e422eSRasesh Mody /* Provide the caller with a reference to as handler */
10265cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
1027a55e422eSRasesh Mody ecore_eth_queue_cid_release(p_hwfn, p_cid);
1028a55e422eSRasesh Mody else
1029a55e422eSRasesh Mody p_ret_params->p_handle = (void *)p_cid;
10305cdd769aSRasesh Mody
10315cdd769aSRasesh Mody return rc;
10325cdd769aSRasesh Mody }
10335cdd769aSRasesh Mody
10345cdd769aSRasesh Mody enum _ecore_status_t
ecore_sp_eth_rx_queues_update(struct ecore_hwfn * p_hwfn,void ** pp_rxq_handles,u8 num_rxqs,u8 complete_cqe_flg,u8 complete_event_flg,enum spq_mode comp_mode,struct ecore_spq_comp_cb * p_comp_data)10355cdd769aSRasesh Mody ecore_sp_eth_rx_queues_update(struct ecore_hwfn *p_hwfn,
1036a55e422eSRasesh Mody void **pp_rxq_handles,
10375cdd769aSRasesh Mody u8 num_rxqs,
10385cdd769aSRasesh Mody u8 complete_cqe_flg,
10395cdd769aSRasesh Mody u8 complete_event_flg,
10405cdd769aSRasesh Mody enum spq_mode comp_mode,
10415cdd769aSRasesh Mody struct ecore_spq_comp_cb *p_comp_data)
10425cdd769aSRasesh Mody {
10435cdd769aSRasesh Mody struct rx_queue_update_ramrod_data *p_ramrod = OSAL_NULL;
10445cdd769aSRasesh Mody struct ecore_spq_entry *p_ent = OSAL_NULL;
10455cdd769aSRasesh Mody struct ecore_sp_init_data init_data;
1046a55e422eSRasesh Mody struct ecore_queue_cid *p_cid;
10479455b556SRasesh Mody enum _ecore_status_t rc = ECORE_NOTIMPL;
10485cdd769aSRasesh Mody u8 i;
10495cdd769aSRasesh Mody
105086a2265eSRasesh Mody if (IS_VF(p_hwfn->p_dev))
105186a2265eSRasesh Mody return ecore_vf_pf_rxqs_update(p_hwfn,
1052a55e422eSRasesh Mody (struct ecore_queue_cid **)
1053a55e422eSRasesh Mody pp_rxq_handles,
105486a2265eSRasesh Mody num_rxqs,
105586a2265eSRasesh Mody complete_cqe_flg,
105686a2265eSRasesh Mody complete_event_flg);
105786a2265eSRasesh Mody
10585cdd769aSRasesh Mody OSAL_MEMSET(&init_data, 0, sizeof(init_data));
10595cdd769aSRasesh Mody init_data.comp_mode = comp_mode;
10605cdd769aSRasesh Mody init_data.p_comp_data = p_comp_data;
10615cdd769aSRasesh Mody
10625cdd769aSRasesh Mody for (i = 0; i < num_rxqs; i++) {
1063a55e422eSRasesh Mody p_cid = ((struct ecore_queue_cid **)pp_rxq_handles)[i];
10645cdd769aSRasesh Mody
10655cdd769aSRasesh Mody /* Get SPQ entry */
1066a55e422eSRasesh Mody init_data.cid = p_cid->cid;
1067a55e422eSRasesh Mody init_data.opaque_fid = p_cid->opaque_fid;
10685cdd769aSRasesh Mody
10695cdd769aSRasesh Mody rc = ecore_sp_init_request(p_hwfn, &p_ent,
10705cdd769aSRasesh Mody ETH_RAMROD_RX_QUEUE_UPDATE,
10715cdd769aSRasesh Mody PROTOCOLID_ETH, &init_data);
10725cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
10735cdd769aSRasesh Mody return rc;
10745cdd769aSRasesh Mody
10755cdd769aSRasesh Mody p_ramrod = &p_ent->ramrod.rx_queue_update;
1076a55e422eSRasesh Mody p_ramrod->vport_id = p_cid->abs.vport_id;
10775cdd769aSRasesh Mody
1078a55e422eSRasesh Mody p_ramrod->rx_queue_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
10795cdd769aSRasesh Mody p_ramrod->complete_cqe_flg = complete_cqe_flg;
10805cdd769aSRasesh Mody p_ramrod->complete_event_flg = complete_event_flg;
10815cdd769aSRasesh Mody
10825cdd769aSRasesh Mody rc = ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
1083a55e422eSRasesh Mody if (rc != ECORE_SUCCESS)
10845cdd769aSRasesh Mody return rc;
10855cdd769aSRasesh Mody }
10865cdd769aSRasesh Mody
10875cdd769aSRasesh Mody return rc;
10885cdd769aSRasesh Mody }
10895cdd769aSRasesh Mody
1090a55e422eSRasesh Mody static enum _ecore_status_t
ecore_eth_pf_rx_queue_stop(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid,bool b_eq_completion_only,bool b_cqe_completion)1091a55e422eSRasesh Mody ecore_eth_pf_rx_queue_stop(struct ecore_hwfn *p_hwfn,
1092a55e422eSRasesh Mody struct ecore_queue_cid *p_cid,
1093a55e422eSRasesh Mody bool b_eq_completion_only,
1094a55e422eSRasesh Mody bool b_cqe_completion)
10955cdd769aSRasesh Mody {
10965cdd769aSRasesh Mody struct rx_queue_stop_ramrod_data *p_ramrod = OSAL_NULL;
10975cdd769aSRasesh Mody struct ecore_spq_entry *p_ent = OSAL_NULL;
10985cdd769aSRasesh Mody struct ecore_sp_init_data init_data;
1099a55e422eSRasesh Mody enum _ecore_status_t rc;
11005cdd769aSRasesh Mody
11015cdd769aSRasesh Mody OSAL_MEMSET(&init_data, 0, sizeof(init_data));
1102a55e422eSRasesh Mody init_data.cid = p_cid->cid;
1103a55e422eSRasesh Mody init_data.opaque_fid = p_cid->opaque_fid;
11045cdd769aSRasesh Mody init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
11055cdd769aSRasesh Mody
11065cdd769aSRasesh Mody rc = ecore_sp_init_request(p_hwfn, &p_ent,
11075cdd769aSRasesh Mody ETH_RAMROD_RX_QUEUE_STOP,
11085cdd769aSRasesh Mody PROTOCOLID_ETH, &init_data);
11095cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
11105cdd769aSRasesh Mody return rc;
11115cdd769aSRasesh Mody
11125cdd769aSRasesh Mody p_ramrod = &p_ent->ramrod.rx_queue_stop;
1113a55e422eSRasesh Mody p_ramrod->vport_id = p_cid->abs.vport_id;
1114a55e422eSRasesh Mody p_ramrod->rx_queue_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
11155cdd769aSRasesh Mody
11165cdd769aSRasesh Mody /* Cleaning the queue requires the completion to arrive there.
11175cdd769aSRasesh Mody * In addition, VFs require the answer to come as eqe to PF.
11185cdd769aSRasesh Mody */
1119eb8e81adSRasesh Mody p_ramrod->complete_cqe_flg = ((p_cid->vfid == ECORE_QUEUE_CID_PF) &&
1120eb8e81adSRasesh Mody !b_eq_completion_only) ||
1121a55e422eSRasesh Mody b_cqe_completion;
1122eb8e81adSRasesh Mody p_ramrod->complete_event_flg = (p_cid->vfid != ECORE_QUEUE_CID_PF) ||
1123eb8e81adSRasesh Mody b_eq_completion_only;
11245cdd769aSRasesh Mody
1125a55e422eSRasesh Mody return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
1126a55e422eSRasesh Mody }
11275cdd769aSRasesh Mody
ecore_eth_rx_queue_stop(struct ecore_hwfn * p_hwfn,void * p_rxq,bool eq_completion_only,bool cqe_completion)1128a55e422eSRasesh Mody enum _ecore_status_t ecore_eth_rx_queue_stop(struct ecore_hwfn *p_hwfn,
1129a55e422eSRasesh Mody void *p_rxq,
1130a55e422eSRasesh Mody bool eq_completion_only,
1131a55e422eSRasesh Mody bool cqe_completion)
1132a55e422eSRasesh Mody {
1133a55e422eSRasesh Mody struct ecore_queue_cid *p_cid = (struct ecore_queue_cid *)p_rxq;
1134a55e422eSRasesh Mody enum _ecore_status_t rc = ECORE_NOTIMPL;
11355cdd769aSRasesh Mody
1136a55e422eSRasesh Mody if (IS_PF(p_hwfn->p_dev))
1137a55e422eSRasesh Mody rc = ecore_eth_pf_rx_queue_stop(p_hwfn, p_cid,
1138a55e422eSRasesh Mody eq_completion_only,
1139a55e422eSRasesh Mody cqe_completion);
1140a55e422eSRasesh Mody else
1141a55e422eSRasesh Mody rc = ecore_vf_pf_rxq_stop(p_hwfn, p_cid, cqe_completion);
1142a55e422eSRasesh Mody
1143a55e422eSRasesh Mody if (rc == ECORE_SUCCESS)
1144a55e422eSRasesh Mody ecore_eth_queue_cid_release(p_hwfn, p_cid);
11455cdd769aSRasesh Mody return rc;
11465cdd769aSRasesh Mody }
11475cdd769aSRasesh Mody
11485cdd769aSRasesh Mody enum _ecore_status_t
ecore_eth_txq_start_ramrod(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid,dma_addr_t pbl_addr,u16 pbl_size,u16 pq_id)1149a55e422eSRasesh Mody ecore_eth_txq_start_ramrod(struct ecore_hwfn *p_hwfn,
1150a55e422eSRasesh Mody struct ecore_queue_cid *p_cid,
1151a55e422eSRasesh Mody dma_addr_t pbl_addr, u16 pbl_size,
11525ef41193SRasesh Mody u16 pq_id)
11535cdd769aSRasesh Mody {
11545cdd769aSRasesh Mody struct tx_queue_start_ramrod_data *p_ramrod = OSAL_NULL;
11555cdd769aSRasesh Mody struct ecore_spq_entry *p_ent = OSAL_NULL;
11565cdd769aSRasesh Mody struct ecore_sp_init_data init_data;
11579455b556SRasesh Mody enum _ecore_status_t rc = ECORE_NOTIMPL;
11585cdd769aSRasesh Mody
11595cdd769aSRasesh Mody /* Get SPQ entry */
11605cdd769aSRasesh Mody OSAL_MEMSET(&init_data, 0, sizeof(init_data));
1161a55e422eSRasesh Mody init_data.cid = p_cid->cid;
1162a55e422eSRasesh Mody init_data.opaque_fid = p_cid->opaque_fid;
11635cdd769aSRasesh Mody init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
11645cdd769aSRasesh Mody
11655cdd769aSRasesh Mody rc = ecore_sp_init_request(p_hwfn, &p_ent,
11665cdd769aSRasesh Mody ETH_RAMROD_TX_QUEUE_START,
11675cdd769aSRasesh Mody PROTOCOLID_ETH, &init_data);
11685cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
11695cdd769aSRasesh Mody return rc;
11705cdd769aSRasesh Mody
11715cdd769aSRasesh Mody p_ramrod = &p_ent->ramrod.tx_queue_start;
1172a55e422eSRasesh Mody p_ramrod->vport_id = p_cid->abs.vport_id;
11735cdd769aSRasesh Mody
11746e4fcea9SRasesh Mody p_ramrod->sb_id = OSAL_CPU_TO_LE16(p_cid->sb_igu_id);
11756e4fcea9SRasesh Mody p_ramrod->sb_index = p_cid->sb_idx;
1176a55e422eSRasesh Mody p_ramrod->stats_counter_id = p_cid->abs.stats_id;
11775cdd769aSRasesh Mody
1178a55e422eSRasesh Mody p_ramrod->queue_zone_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
1179a55e422eSRasesh Mody p_ramrod->same_as_last_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
11805cdd769aSRasesh Mody
11815cdd769aSRasesh Mody p_ramrod->pbl_size = OSAL_CPU_TO_LE16(pbl_size);
118222d07d93SRasesh Mody DMA_REGPAIR_LE(p_ramrod->pbl_base_addr, pbl_addr);
11835cdd769aSRasesh Mody
11845cdd769aSRasesh Mody p_ramrod->qm_pq_id = OSAL_CPU_TO_LE16(pq_id);
11855cdd769aSRasesh Mody
11865cdd769aSRasesh Mody return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
11875cdd769aSRasesh Mody }
11885cdd769aSRasesh Mody
1189a55e422eSRasesh Mody static enum _ecore_status_t
ecore_eth_pf_tx_queue_start(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid,u8 tc,dma_addr_t pbl_addr,u16 pbl_size,void OSAL_IOMEM ** pp_doorbell)1190a55e422eSRasesh Mody ecore_eth_pf_tx_queue_start(struct ecore_hwfn *p_hwfn,
1191a55e422eSRasesh Mody struct ecore_queue_cid *p_cid,
119222d07d93SRasesh Mody u8 tc,
1193a55e422eSRasesh Mody dma_addr_t pbl_addr, u16 pbl_size,
11945cdd769aSRasesh Mody void OSAL_IOMEM * *pp_doorbell)
11955cdd769aSRasesh Mody {
119622d07d93SRasesh Mody enum _ecore_status_t rc;
119776d37490SRasesh Mody u16 pq_id;
11985cdd769aSRasesh Mody
119976d37490SRasesh Mody /* TODO - set tc in the pq_params for multi-cos.
120076d37490SRasesh Mody * If pacing is enabled then select queue according to
120176d37490SRasesh Mody * rate limiter availability otherwise select queue based
120276d37490SRasesh Mody * on multi cos.
120376d37490SRasesh Mody */
120476d37490SRasesh Mody if (IS_ECORE_PACING(p_hwfn))
120576d37490SRasesh Mody pq_id = ecore_get_cm_pq_idx_rl(p_hwfn, p_cid->rel.queue_id);
120676d37490SRasesh Mody else
120776d37490SRasesh Mody pq_id = ecore_get_cm_pq_idx_mcos(p_hwfn, tc);
120876d37490SRasesh Mody
120976d37490SRasesh Mody rc = ecore_eth_txq_start_ramrod(p_hwfn, p_cid, pbl_addr,
121076d37490SRasesh Mody pbl_size, pq_id);
1211a55e422eSRasesh Mody if (rc != ECORE_SUCCESS)
1212a55e422eSRasesh Mody return rc;
12135cdd769aSRasesh Mody
1214a55e422eSRasesh Mody /* Provide the caller with the necessary return values */
1215a55e422eSRasesh Mody *pp_doorbell = (u8 OSAL_IOMEM *)
1216a55e422eSRasesh Mody p_hwfn->doorbells +
1217a55e422eSRasesh Mody DB_ADDR(p_cid->cid, DQ_DEMS_LEGACY);
1218a55e422eSRasesh Mody
1219a55e422eSRasesh Mody return ECORE_SUCCESS;
1220a55e422eSRasesh Mody }
1221a55e422eSRasesh Mody
1222a55e422eSRasesh Mody enum _ecore_status_t
ecore_eth_tx_queue_start(struct ecore_hwfn * p_hwfn,u16 opaque_fid,struct ecore_queue_start_common_params * p_params,u8 tc,dma_addr_t pbl_addr,u16 pbl_size,struct ecore_txq_start_ret_params * p_ret_params)1223a55e422eSRasesh Mody ecore_eth_tx_queue_start(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
1224a55e422eSRasesh Mody struct ecore_queue_start_common_params *p_params,
1225a55e422eSRasesh Mody u8 tc,
1226a55e422eSRasesh Mody dma_addr_t pbl_addr, u16 pbl_size,
1227a55e422eSRasesh Mody struct ecore_txq_start_ret_params *p_ret_params)
1228a55e422eSRasesh Mody {
1229a55e422eSRasesh Mody struct ecore_queue_cid *p_cid;
1230a55e422eSRasesh Mody enum _ecore_status_t rc;
1231a55e422eSRasesh Mody
1232823a84aaSRasesh Mody p_cid = ecore_eth_queue_to_cid_pf(p_hwfn, opaque_fid, false, p_params);
1233a55e422eSRasesh Mody if (p_cid == OSAL_NULL)
1234a55e422eSRasesh Mody return ECORE_INVAL;
1235a55e422eSRasesh Mody
1236a55e422eSRasesh Mody if (IS_PF(p_hwfn->p_dev))
1237a55e422eSRasesh Mody rc = ecore_eth_pf_tx_queue_start(p_hwfn, p_cid, tc,
1238a55e422eSRasesh Mody pbl_addr, pbl_size,
1239a55e422eSRasesh Mody &p_ret_params->p_doorbell);
1240a55e422eSRasesh Mody else
1241a55e422eSRasesh Mody rc = ecore_vf_pf_txq_start(p_hwfn, p_cid,
1242a55e422eSRasesh Mody pbl_addr, pbl_size,
1243a55e422eSRasesh Mody &p_ret_params->p_doorbell);
12445cdd769aSRasesh Mody
12455cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
1246a55e422eSRasesh Mody ecore_eth_queue_cid_release(p_hwfn, p_cid);
1247a55e422eSRasesh Mody else
1248a55e422eSRasesh Mody p_ret_params->p_handle = (void *)p_cid;
12495cdd769aSRasesh Mody
12505cdd769aSRasesh Mody return rc;
12515cdd769aSRasesh Mody }
12525cdd769aSRasesh Mody
1253a55e422eSRasesh Mody static enum _ecore_status_t
ecore_eth_pf_tx_queue_stop(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)1254a55e422eSRasesh Mody ecore_eth_pf_tx_queue_stop(struct ecore_hwfn *p_hwfn,
1255a55e422eSRasesh Mody struct ecore_queue_cid *p_cid)
12565cdd769aSRasesh Mody {
12575cdd769aSRasesh Mody struct ecore_spq_entry *p_ent = OSAL_NULL;
12585cdd769aSRasesh Mody struct ecore_sp_init_data init_data;
1259a55e422eSRasesh Mody enum _ecore_status_t rc;
12605cdd769aSRasesh Mody
12615cdd769aSRasesh Mody OSAL_MEMSET(&init_data, 0, sizeof(init_data));
1262a55e422eSRasesh Mody init_data.cid = p_cid->cid;
1263a55e422eSRasesh Mody init_data.opaque_fid = p_cid->opaque_fid;
12645cdd769aSRasesh Mody init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
12655cdd769aSRasesh Mody
12665cdd769aSRasesh Mody rc = ecore_sp_init_request(p_hwfn, &p_ent,
12675cdd769aSRasesh Mody ETH_RAMROD_TX_QUEUE_STOP,
12685cdd769aSRasesh Mody PROTOCOLID_ETH, &init_data);
12695cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
12705cdd769aSRasesh Mody return rc;
12715cdd769aSRasesh Mody
1272a55e422eSRasesh Mody return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
1273a55e422eSRasesh Mody }
12745cdd769aSRasesh Mody
ecore_eth_tx_queue_stop(struct ecore_hwfn * p_hwfn,void * p_handle)1275a55e422eSRasesh Mody enum _ecore_status_t ecore_eth_tx_queue_stop(struct ecore_hwfn *p_hwfn,
1276a55e422eSRasesh Mody void *p_handle)
1277a55e422eSRasesh Mody {
1278a55e422eSRasesh Mody struct ecore_queue_cid *p_cid = (struct ecore_queue_cid *)p_handle;
1279a55e422eSRasesh Mody enum _ecore_status_t rc;
1280a55e422eSRasesh Mody
1281a55e422eSRasesh Mody if (IS_PF(p_hwfn->p_dev))
1282a55e422eSRasesh Mody rc = ecore_eth_pf_tx_queue_stop(p_hwfn, p_cid);
1283a55e422eSRasesh Mody else
1284a55e422eSRasesh Mody rc = ecore_vf_pf_txq_stop(p_hwfn, p_cid);
1285a55e422eSRasesh Mody
1286a55e422eSRasesh Mody if (rc == ECORE_SUCCESS)
1287a55e422eSRasesh Mody ecore_eth_queue_cid_release(p_hwfn, p_cid);
12885cdd769aSRasesh Mody return rc;
12895cdd769aSRasesh Mody }
12905cdd769aSRasesh Mody
12915cdd769aSRasesh Mody static enum eth_filter_action
ecore_filter_action(enum ecore_filter_opcode opcode)12925cdd769aSRasesh Mody ecore_filter_action(enum ecore_filter_opcode opcode)
12935cdd769aSRasesh Mody {
12945cdd769aSRasesh Mody enum eth_filter_action action = MAX_ETH_FILTER_ACTION;
12955cdd769aSRasesh Mody
12965cdd769aSRasesh Mody switch (opcode) {
12975cdd769aSRasesh Mody case ECORE_FILTER_ADD:
12985cdd769aSRasesh Mody action = ETH_FILTER_ACTION_ADD;
12995cdd769aSRasesh Mody break;
13005cdd769aSRasesh Mody case ECORE_FILTER_REMOVE:
13015cdd769aSRasesh Mody action = ETH_FILTER_ACTION_REMOVE;
13025cdd769aSRasesh Mody break;
13035cdd769aSRasesh Mody case ECORE_FILTER_FLUSH:
13045cdd769aSRasesh Mody action = ETH_FILTER_ACTION_REMOVE_ALL;
13055cdd769aSRasesh Mody break;
13065cdd769aSRasesh Mody default:
13075cdd769aSRasesh Mody action = MAX_ETH_FILTER_ACTION;
13085cdd769aSRasesh Mody }
13095cdd769aSRasesh Mody
13105cdd769aSRasesh Mody return action;
13115cdd769aSRasesh Mody }
13125cdd769aSRasesh Mody
13135cdd769aSRasesh Mody static enum _ecore_status_t
ecore_filter_ucast_common(struct ecore_hwfn * p_hwfn,u16 opaque_fid,struct ecore_filter_ucast * p_filter_cmd,struct vport_filter_update_ramrod_data ** pp_ramrod,struct ecore_spq_entry ** pp_ent,enum spq_mode comp_mode,struct ecore_spq_comp_cb * p_comp_data)13145cdd769aSRasesh Mody ecore_filter_ucast_common(struct ecore_hwfn *p_hwfn,
13155cdd769aSRasesh Mody u16 opaque_fid,
13165cdd769aSRasesh Mody struct ecore_filter_ucast *p_filter_cmd,
13175cdd769aSRasesh Mody struct vport_filter_update_ramrod_data **pp_ramrod,
13185cdd769aSRasesh Mody struct ecore_spq_entry **pp_ent,
13195cdd769aSRasesh Mody enum spq_mode comp_mode,
13205cdd769aSRasesh Mody struct ecore_spq_comp_cb *p_comp_data)
13215cdd769aSRasesh Mody {
13225cdd769aSRasesh Mody u8 vport_to_add_to = 0, vport_to_remove_from = 0;
13239455b556SRasesh Mody struct vport_filter_update_ramrod_data *p_ramrod;
13245cdd769aSRasesh Mody struct eth_filter_cmd *p_first_filter;
13255cdd769aSRasesh Mody struct eth_filter_cmd *p_second_filter;
13265cdd769aSRasesh Mody struct ecore_sp_init_data init_data;
13275cdd769aSRasesh Mody enum eth_filter_action action;
13285cdd769aSRasesh Mody enum _ecore_status_t rc;
13295cdd769aSRasesh Mody
13305cdd769aSRasesh Mody rc = ecore_fw_vport(p_hwfn, p_filter_cmd->vport_to_remove_from,
13315cdd769aSRasesh Mody &vport_to_remove_from);
13325cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
13335cdd769aSRasesh Mody return rc;
13345cdd769aSRasesh Mody
13355cdd769aSRasesh Mody rc = ecore_fw_vport(p_hwfn, p_filter_cmd->vport_to_add_to,
13365cdd769aSRasesh Mody &vport_to_add_to);
13375cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
13385cdd769aSRasesh Mody return rc;
13395cdd769aSRasesh Mody
13405cdd769aSRasesh Mody /* Get SPQ entry */
13415cdd769aSRasesh Mody OSAL_MEMSET(&init_data, 0, sizeof(init_data));
13425cdd769aSRasesh Mody init_data.cid = ecore_spq_get_cid(p_hwfn);
13435cdd769aSRasesh Mody init_data.opaque_fid = opaque_fid;
13445cdd769aSRasesh Mody init_data.comp_mode = comp_mode;
13455cdd769aSRasesh Mody init_data.p_comp_data = p_comp_data;
13465cdd769aSRasesh Mody
13475cdd769aSRasesh Mody rc = ecore_sp_init_request(p_hwfn, pp_ent,
13485cdd769aSRasesh Mody ETH_RAMROD_FILTERS_UPDATE,
13495cdd769aSRasesh Mody PROTOCOLID_ETH, &init_data);
13505cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
13515cdd769aSRasesh Mody return rc;
13525cdd769aSRasesh Mody
13535cdd769aSRasesh Mody *pp_ramrod = &(*pp_ent)->ramrod.vport_filter_update;
13545cdd769aSRasesh Mody p_ramrod = *pp_ramrod;
13555cdd769aSRasesh Mody p_ramrod->filter_cmd_hdr.rx = p_filter_cmd->is_rx_filter ? 1 : 0;
13565cdd769aSRasesh Mody p_ramrod->filter_cmd_hdr.tx = p_filter_cmd->is_tx_filter ? 1 : 0;
13575cdd769aSRasesh Mody
13585cdd769aSRasesh Mody #ifndef ASIC_ONLY
13595cdd769aSRasesh Mody if (CHIP_REV_IS_SLOW(p_hwfn->p_dev)) {
13605cdd769aSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
13615cdd769aSRasesh Mody "Non-Asic - prevent Tx filters\n");
13625cdd769aSRasesh Mody p_ramrod->filter_cmd_hdr.tx = 0;
13635cdd769aSRasesh Mody }
13645cdd769aSRasesh Mody #endif
13655cdd769aSRasesh Mody
13665cdd769aSRasesh Mody switch (p_filter_cmd->opcode) {
13675cdd769aSRasesh Mody case ECORE_FILTER_REPLACE:
13685cdd769aSRasesh Mody case ECORE_FILTER_MOVE:
13695cdd769aSRasesh Mody p_ramrod->filter_cmd_hdr.cmd_cnt = 2;
13705cdd769aSRasesh Mody break;
13715cdd769aSRasesh Mody default:
13725cdd769aSRasesh Mody p_ramrod->filter_cmd_hdr.cmd_cnt = 1;
13735cdd769aSRasesh Mody break;
13745cdd769aSRasesh Mody }
13755cdd769aSRasesh Mody
13765cdd769aSRasesh Mody p_first_filter = &p_ramrod->filter_cmds[0];
13775cdd769aSRasesh Mody p_second_filter = &p_ramrod->filter_cmds[1];
13785cdd769aSRasesh Mody
13795cdd769aSRasesh Mody switch (p_filter_cmd->type) {
13805cdd769aSRasesh Mody case ECORE_FILTER_MAC:
13815cdd769aSRasesh Mody p_first_filter->type = ETH_FILTER_TYPE_MAC;
13825cdd769aSRasesh Mody break;
13835cdd769aSRasesh Mody case ECORE_FILTER_VLAN:
13845cdd769aSRasesh Mody p_first_filter->type = ETH_FILTER_TYPE_VLAN;
13855cdd769aSRasesh Mody break;
13865cdd769aSRasesh Mody case ECORE_FILTER_MAC_VLAN:
13875cdd769aSRasesh Mody p_first_filter->type = ETH_FILTER_TYPE_PAIR;
13885cdd769aSRasesh Mody break;
13895cdd769aSRasesh Mody case ECORE_FILTER_INNER_MAC:
13905cdd769aSRasesh Mody p_first_filter->type = ETH_FILTER_TYPE_INNER_MAC;
13915cdd769aSRasesh Mody break;
13925cdd769aSRasesh Mody case ECORE_FILTER_INNER_VLAN:
13935cdd769aSRasesh Mody p_first_filter->type = ETH_FILTER_TYPE_INNER_VLAN;
13945cdd769aSRasesh Mody break;
13955cdd769aSRasesh Mody case ECORE_FILTER_INNER_PAIR:
13965cdd769aSRasesh Mody p_first_filter->type = ETH_FILTER_TYPE_INNER_PAIR;
13975cdd769aSRasesh Mody break;
13985cdd769aSRasesh Mody case ECORE_FILTER_INNER_MAC_VNI_PAIR:
13995cdd769aSRasesh Mody p_first_filter->type = ETH_FILTER_TYPE_INNER_MAC_VNI_PAIR;
14005cdd769aSRasesh Mody break;
14015cdd769aSRasesh Mody case ECORE_FILTER_MAC_VNI_PAIR:
14025cdd769aSRasesh Mody p_first_filter->type = ETH_FILTER_TYPE_MAC_VNI_PAIR;
14035cdd769aSRasesh Mody break;
14045cdd769aSRasesh Mody case ECORE_FILTER_VNI:
14055cdd769aSRasesh Mody p_first_filter->type = ETH_FILTER_TYPE_VNI;
14065cdd769aSRasesh Mody break;
140752d94b57SHarish Patil case ECORE_FILTER_UNUSED: /* @DPDK */
140852d94b57SHarish Patil p_first_filter->type = MAX_ETH_FILTER_TYPE;
140952d94b57SHarish Patil break;
14105cdd769aSRasesh Mody }
14115cdd769aSRasesh Mody
14125cdd769aSRasesh Mody if ((p_first_filter->type == ETH_FILTER_TYPE_MAC) ||
14135cdd769aSRasesh Mody (p_first_filter->type == ETH_FILTER_TYPE_PAIR) ||
14145cdd769aSRasesh Mody (p_first_filter->type == ETH_FILTER_TYPE_INNER_MAC) ||
14155cdd769aSRasesh Mody (p_first_filter->type == ETH_FILTER_TYPE_INNER_PAIR) ||
14165cdd769aSRasesh Mody (p_first_filter->type == ETH_FILTER_TYPE_INNER_MAC_VNI_PAIR) ||
14175cdd769aSRasesh Mody (p_first_filter->type == ETH_FILTER_TYPE_MAC_VNI_PAIR))
14185cdd769aSRasesh Mody ecore_set_fw_mac_addr(&p_first_filter->mac_msb,
14195cdd769aSRasesh Mody &p_first_filter->mac_mid,
14205cdd769aSRasesh Mody &p_first_filter->mac_lsb,
14215cdd769aSRasesh Mody (u8 *)p_filter_cmd->mac);
14225cdd769aSRasesh Mody
14235cdd769aSRasesh Mody if ((p_first_filter->type == ETH_FILTER_TYPE_VLAN) ||
14245cdd769aSRasesh Mody (p_first_filter->type == ETH_FILTER_TYPE_PAIR) ||
14255cdd769aSRasesh Mody (p_first_filter->type == ETH_FILTER_TYPE_INNER_VLAN) ||
14265cdd769aSRasesh Mody (p_first_filter->type == ETH_FILTER_TYPE_INNER_PAIR))
14275cdd769aSRasesh Mody p_first_filter->vlan_id = OSAL_CPU_TO_LE16(p_filter_cmd->vlan);
14285cdd769aSRasesh Mody
14295cdd769aSRasesh Mody if ((p_first_filter->type == ETH_FILTER_TYPE_INNER_MAC_VNI_PAIR) ||
14305cdd769aSRasesh Mody (p_first_filter->type == ETH_FILTER_TYPE_MAC_VNI_PAIR) ||
14315cdd769aSRasesh Mody (p_first_filter->type == ETH_FILTER_TYPE_VNI))
14325cdd769aSRasesh Mody p_first_filter->vni = OSAL_CPU_TO_LE32(p_filter_cmd->vni);
14335cdd769aSRasesh Mody
14345cdd769aSRasesh Mody if (p_filter_cmd->opcode == ECORE_FILTER_MOVE) {
14355cdd769aSRasesh Mody p_second_filter->type = p_first_filter->type;
14365cdd769aSRasesh Mody p_second_filter->mac_msb = p_first_filter->mac_msb;
14375cdd769aSRasesh Mody p_second_filter->mac_mid = p_first_filter->mac_mid;
14385cdd769aSRasesh Mody p_second_filter->mac_lsb = p_first_filter->mac_lsb;
14395cdd769aSRasesh Mody p_second_filter->vlan_id = p_first_filter->vlan_id;
14405cdd769aSRasesh Mody p_second_filter->vni = p_first_filter->vni;
14415cdd769aSRasesh Mody
14425cdd769aSRasesh Mody p_first_filter->action = ETH_FILTER_ACTION_REMOVE;
14435cdd769aSRasesh Mody
14445cdd769aSRasesh Mody p_first_filter->vport_id = vport_to_remove_from;
14455cdd769aSRasesh Mody
14465cdd769aSRasesh Mody p_second_filter->action = ETH_FILTER_ACTION_ADD;
14475cdd769aSRasesh Mody p_second_filter->vport_id = vport_to_add_to;
14485cdd769aSRasesh Mody } else if (p_filter_cmd->opcode == ECORE_FILTER_REPLACE) {
14495cdd769aSRasesh Mody p_first_filter->vport_id = vport_to_add_to;
14505cdd769aSRasesh Mody OSAL_MEMCPY(p_second_filter, p_first_filter,
14515cdd769aSRasesh Mody sizeof(*p_second_filter));
14525cdd769aSRasesh Mody p_first_filter->action = ETH_FILTER_ACTION_REMOVE_ALL;
14535cdd769aSRasesh Mody p_second_filter->action = ETH_FILTER_ACTION_ADD;
14545cdd769aSRasesh Mody } else {
14555cdd769aSRasesh Mody action = ecore_filter_action(p_filter_cmd->opcode);
14565cdd769aSRasesh Mody
14575cdd769aSRasesh Mody if (action == MAX_ETH_FILTER_ACTION) {
14585cdd769aSRasesh Mody DP_NOTICE(p_hwfn, true,
14595cdd769aSRasesh Mody "%d is not supported yet\n",
14605cdd769aSRasesh Mody p_filter_cmd->opcode);
14615cdd769aSRasesh Mody return ECORE_NOTIMPL;
14625cdd769aSRasesh Mody }
14635cdd769aSRasesh Mody
14645cdd769aSRasesh Mody p_first_filter->action = action;
14655cdd769aSRasesh Mody p_first_filter->vport_id =
14665cdd769aSRasesh Mody (p_filter_cmd->opcode == ECORE_FILTER_REMOVE) ?
14675cdd769aSRasesh Mody vport_to_remove_from : vport_to_add_to;
14685cdd769aSRasesh Mody }
14695cdd769aSRasesh Mody
14705cdd769aSRasesh Mody return ECORE_SUCCESS;
14715cdd769aSRasesh Mody }
14725cdd769aSRasesh Mody
14735cdd769aSRasesh Mody enum _ecore_status_t
ecore_sp_eth_filter_ucast(struct ecore_hwfn * p_hwfn,u16 opaque_fid,struct ecore_filter_ucast * p_filter_cmd,enum spq_mode comp_mode,struct ecore_spq_comp_cb * p_comp_data)14745cdd769aSRasesh Mody ecore_sp_eth_filter_ucast(struct ecore_hwfn *p_hwfn,
14755cdd769aSRasesh Mody u16 opaque_fid,
14765cdd769aSRasesh Mody struct ecore_filter_ucast *p_filter_cmd,
14775cdd769aSRasesh Mody enum spq_mode comp_mode,
14785cdd769aSRasesh Mody struct ecore_spq_comp_cb *p_comp_data)
14795cdd769aSRasesh Mody {
14805cdd769aSRasesh Mody struct vport_filter_update_ramrod_data *p_ramrod = OSAL_NULL;
14815cdd769aSRasesh Mody struct ecore_spq_entry *p_ent = OSAL_NULL;
14825cdd769aSRasesh Mody struct eth_filter_cmd_header *p_header;
14835cdd769aSRasesh Mody enum _ecore_status_t rc;
14845cdd769aSRasesh Mody
14855cdd769aSRasesh Mody rc = ecore_filter_ucast_common(p_hwfn, opaque_fid, p_filter_cmd,
14865cdd769aSRasesh Mody &p_ramrod, &p_ent,
14875cdd769aSRasesh Mody comp_mode, p_comp_data);
14885cdd769aSRasesh Mody if (rc != ECORE_SUCCESS) {
14895cdd769aSRasesh Mody DP_ERR(p_hwfn, "Uni. filter command failed %d\n", rc);
14905cdd769aSRasesh Mody return rc;
14915cdd769aSRasesh Mody }
14925cdd769aSRasesh Mody p_header = &p_ramrod->filter_cmd_hdr;
14935cdd769aSRasesh Mody p_header->assert_on_error = p_filter_cmd->assert_on_error;
14945cdd769aSRasesh Mody
14955cdd769aSRasesh Mody rc = ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
14965cdd769aSRasesh Mody if (rc != ECORE_SUCCESS) {
14975cdd769aSRasesh Mody DP_ERR(p_hwfn, "Unicast filter ADD command failed %d\n", rc);
14985cdd769aSRasesh Mody return rc;
14995cdd769aSRasesh Mody }
15005cdd769aSRasesh Mody
15015cdd769aSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
15025cdd769aSRasesh Mody "Unicast filter configured, opcode = %s, type = %s, cmd_cnt = %d, is_rx_filter = %d, is_tx_filter = %d\n",
15035cdd769aSRasesh Mody (p_filter_cmd->opcode == ECORE_FILTER_ADD) ? "ADD" :
15045cdd769aSRasesh Mody ((p_filter_cmd->opcode == ECORE_FILTER_REMOVE) ?
15055cdd769aSRasesh Mody "REMOVE" :
15065cdd769aSRasesh Mody ((p_filter_cmd->opcode == ECORE_FILTER_MOVE) ?
15075cdd769aSRasesh Mody "MOVE" : "REPLACE")),
15085cdd769aSRasesh Mody (p_filter_cmd->type == ECORE_FILTER_MAC) ? "MAC" :
15095cdd769aSRasesh Mody ((p_filter_cmd->type == ECORE_FILTER_VLAN) ?
15105cdd769aSRasesh Mody "VLAN" : "MAC & VLAN"),
15115cdd769aSRasesh Mody p_ramrod->filter_cmd_hdr.cmd_cnt,
15125cdd769aSRasesh Mody p_filter_cmd->is_rx_filter, p_filter_cmd->is_tx_filter);
15135cdd769aSRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
15145cdd769aSRasesh Mody "vport_to_add_to = %d, vport_to_remove_from = %d, mac = %2x:%2x:%2x:%2x:%2x:%2x, vlan = %d\n",
15155cdd769aSRasesh Mody p_filter_cmd->vport_to_add_to,
15165cdd769aSRasesh Mody p_filter_cmd->vport_to_remove_from,
15175cdd769aSRasesh Mody p_filter_cmd->mac[0], p_filter_cmd->mac[1],
15185cdd769aSRasesh Mody p_filter_cmd->mac[2], p_filter_cmd->mac[3],
15195cdd769aSRasesh Mody p_filter_cmd->mac[4], p_filter_cmd->mac[5],
15205cdd769aSRasesh Mody p_filter_cmd->vlan);
15215cdd769aSRasesh Mody
15225cdd769aSRasesh Mody return ECORE_SUCCESS;
15235cdd769aSRasesh Mody }
15245cdd769aSRasesh Mody
15255cdd769aSRasesh Mody /*******************************************************************************
15265cdd769aSRasesh Mody * Description:
15275cdd769aSRasesh Mody * Calculates crc 32 on a buffer
15285cdd769aSRasesh Mody * Note: crc32_length MUST be aligned to 8
15295cdd769aSRasesh Mody * Return:
15305cdd769aSRasesh Mody ******************************************************************************/
ecore_calc_crc32c(u8 * crc32_packet,u32 crc32_length,u32 crc32_seed)153130ecf673SRasesh Mody static u32 ecore_calc_crc32c(u8 *crc32_packet, u32 crc32_length, u32 crc32_seed)
15325cdd769aSRasesh Mody {
15335cdd769aSRasesh Mody u32 byte = 0, bit = 0, crc32_result = crc32_seed;
15345cdd769aSRasesh Mody u8 msb = 0, current_byte = 0;
15355cdd769aSRasesh Mody
15365cdd769aSRasesh Mody if ((crc32_packet == OSAL_NULL) ||
15375cdd769aSRasesh Mody (crc32_length == 0) || ((crc32_length % 8) != 0)) {
15385cdd769aSRasesh Mody return crc32_result;
15395cdd769aSRasesh Mody }
15405cdd769aSRasesh Mody
15415cdd769aSRasesh Mody for (byte = 0; byte < crc32_length; byte++) {
15425cdd769aSRasesh Mody current_byte = crc32_packet[byte];
15435cdd769aSRasesh Mody for (bit = 0; bit < 8; bit++) {
15445cdd769aSRasesh Mody msb = (u8)(crc32_result >> 31);
15455cdd769aSRasesh Mody crc32_result = crc32_result << 1;
15465cdd769aSRasesh Mody if (msb != (0x1 & (current_byte >> bit))) {
15475cdd769aSRasesh Mody crc32_result = crc32_result ^ CRC32_POLY;
15485cdd769aSRasesh Mody crc32_result |= 1;
15495cdd769aSRasesh Mody }
15505cdd769aSRasesh Mody }
15515cdd769aSRasesh Mody }
15525cdd769aSRasesh Mody
15535cdd769aSRasesh Mody return crc32_result;
15545cdd769aSRasesh Mody }
15555cdd769aSRasesh Mody
ecore_crc32c_le(u32 seed,u8 * mac)155630ecf673SRasesh Mody static u32 ecore_crc32c_le(u32 seed, u8 *mac)
15575cdd769aSRasesh Mody {
15585cdd769aSRasesh Mody u32 packet_buf[2] = { 0 };
15595cdd769aSRasesh Mody
15605cdd769aSRasesh Mody OSAL_MEMCPY((u8 *)(&packet_buf[0]), &mac[0], 6);
156130ecf673SRasesh Mody return ecore_calc_crc32c((u8 *)packet_buf, 8, seed);
15625cdd769aSRasesh Mody }
15635cdd769aSRasesh Mody
ecore_mcast_bin_from_mac(u8 * mac)15645cdd769aSRasesh Mody u8 ecore_mcast_bin_from_mac(u8 *mac)
15655cdd769aSRasesh Mody {
156630ecf673SRasesh Mody u32 crc = ecore_crc32c_le(ETH_MULTICAST_BIN_FROM_MAC_SEED, mac);
15675cdd769aSRasesh Mody
15685cdd769aSRasesh Mody return crc & 0xff;
15695cdd769aSRasesh Mody }
15705cdd769aSRasesh Mody
15715cdd769aSRasesh Mody static enum _ecore_status_t
ecore_sp_eth_filter_mcast(struct ecore_hwfn * p_hwfn,struct ecore_filter_mcast * p_filter_cmd,enum spq_mode comp_mode,struct ecore_spq_comp_cb * p_comp_data)15725cdd769aSRasesh Mody ecore_sp_eth_filter_mcast(struct ecore_hwfn *p_hwfn,
15735cdd769aSRasesh Mody struct ecore_filter_mcast *p_filter_cmd,
15745cdd769aSRasesh Mody enum spq_mode comp_mode,
15755cdd769aSRasesh Mody struct ecore_spq_comp_cb *p_comp_data)
15765cdd769aSRasesh Mody {
157722d07d93SRasesh Mody struct vport_update_ramrod_data *p_ramrod = OSAL_NULL;
1578413ecf29SHarish Patil u32 bins[ETH_MULTICAST_MAC_BINS_IN_REGS];
15795cdd769aSRasesh Mody struct ecore_spq_entry *p_ent = OSAL_NULL;
15805cdd769aSRasesh Mody struct ecore_sp_init_data init_data;
15815cdd769aSRasesh Mody u8 abs_vport_id = 0;
158222d07d93SRasesh Mody enum _ecore_status_t rc;
15835cdd769aSRasesh Mody int i;
15845cdd769aSRasesh Mody
158522d07d93SRasesh Mody if (p_filter_cmd->opcode == ECORE_FILTER_ADD)
15865cdd769aSRasesh Mody rc = ecore_fw_vport(p_hwfn,
158722d07d93SRasesh Mody p_filter_cmd->vport_to_add_to,
158822d07d93SRasesh Mody &abs_vport_id);
158922d07d93SRasesh Mody else
159022d07d93SRasesh Mody rc = ecore_fw_vport(p_hwfn,
159122d07d93SRasesh Mody p_filter_cmd->vport_to_remove_from,
159222d07d93SRasesh Mody &abs_vport_id);
15935cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
15945cdd769aSRasesh Mody return rc;
15955cdd769aSRasesh Mody
15965cdd769aSRasesh Mody /* Get SPQ entry */
15975cdd769aSRasesh Mody OSAL_MEMSET(&init_data, 0, sizeof(init_data));
15985cdd769aSRasesh Mody init_data.cid = ecore_spq_get_cid(p_hwfn);
15995cdd769aSRasesh Mody init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
16005cdd769aSRasesh Mody init_data.comp_mode = comp_mode;
16015cdd769aSRasesh Mody init_data.p_comp_data = p_comp_data;
16025cdd769aSRasesh Mody
16035cdd769aSRasesh Mody rc = ecore_sp_init_request(p_hwfn, &p_ent,
16045cdd769aSRasesh Mody ETH_RAMROD_VPORT_UPDATE,
16055cdd769aSRasesh Mody PROTOCOLID_ETH, &init_data);
16065cdd769aSRasesh Mody if (rc != ECORE_SUCCESS) {
16075cdd769aSRasesh Mody DP_ERR(p_hwfn, "Multi-cast command failed %d\n", rc);
16085cdd769aSRasesh Mody return rc;
16095cdd769aSRasesh Mody }
16105cdd769aSRasesh Mody
16115cdd769aSRasesh Mody p_ramrod = &p_ent->ramrod.vport_update;
16125cdd769aSRasesh Mody p_ramrod->common.update_approx_mcast_flg = 1;
16135cdd769aSRasesh Mody
16145cdd769aSRasesh Mody /* explicitly clear out the entire vector */
16155cdd769aSRasesh Mody OSAL_MEMSET(&p_ramrod->approx_mcast.bins,
16165cdd769aSRasesh Mody 0, sizeof(p_ramrod->approx_mcast.bins));
1617413ecf29SHarish Patil OSAL_MEMSET(bins, 0, sizeof(u32) * ETH_MULTICAST_MAC_BINS_IN_REGS);
16185cdd769aSRasesh Mody /* filter ADD op is explicit set op and it removes
16195cdd769aSRasesh Mody * any existing filters for the vport.
16205cdd769aSRasesh Mody */
16219455b556SRasesh Mody if (p_filter_cmd->opcode == ECORE_FILTER_ADD) {
16225cdd769aSRasesh Mody for (i = 0; i < p_filter_cmd->num_mc_addrs; i++) {
16235cdd769aSRasesh Mody u32 bit;
16245cdd769aSRasesh Mody
16255cdd769aSRasesh Mody bit = ecore_mcast_bin_from_mac(p_filter_cmd->mac[i]);
1626413ecf29SHarish Patil bins[bit / 32] |= 1 << (bit % 32);
16275cdd769aSRasesh Mody }
16285cdd769aSRasesh Mody
16295cdd769aSRasesh Mody /* Convert to correct endianity */
16305cdd769aSRasesh Mody for (i = 0; i < ETH_MULTICAST_MAC_BINS_IN_REGS; i++) {
16315cdd769aSRasesh Mody struct vport_update_ramrod_mcast *p_ramrod_bins;
16325cdd769aSRasesh Mody
16335cdd769aSRasesh Mody p_ramrod_bins = &p_ramrod->approx_mcast;
1634413ecf29SHarish Patil p_ramrod_bins->bins[i] = OSAL_CPU_TO_LE32(bins[i]);
16355cdd769aSRasesh Mody }
16365cdd769aSRasesh Mody }
16375cdd769aSRasesh Mody
16385cdd769aSRasesh Mody p_ramrod->common.vport_id = abs_vport_id;
16395cdd769aSRasesh Mody
16405cdd769aSRasesh Mody rc = ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
16415cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
16425cdd769aSRasesh Mody DP_ERR(p_hwfn, "Multicast filter command failed %d\n", rc);
16435cdd769aSRasesh Mody
16445cdd769aSRasesh Mody return rc;
16455cdd769aSRasesh Mody }
16465cdd769aSRasesh Mody
16475cdd769aSRasesh Mody enum _ecore_status_t
ecore_filter_mcast_cmd(struct ecore_dev * p_dev,struct ecore_filter_mcast * p_filter_cmd,enum spq_mode comp_mode,struct ecore_spq_comp_cb * p_comp_data)16485cdd769aSRasesh Mody ecore_filter_mcast_cmd(struct ecore_dev *p_dev,
16495cdd769aSRasesh Mody struct ecore_filter_mcast *p_filter_cmd,
16505cdd769aSRasesh Mody enum spq_mode comp_mode,
16515cdd769aSRasesh Mody struct ecore_spq_comp_cb *p_comp_data)
16525cdd769aSRasesh Mody {
16535cdd769aSRasesh Mody enum _ecore_status_t rc = ECORE_SUCCESS;
16545cdd769aSRasesh Mody int i;
16555cdd769aSRasesh Mody
16565cdd769aSRasesh Mody /* only ADD and REMOVE operations are supported for multi-cast */
16575cdd769aSRasesh Mody if ((p_filter_cmd->opcode != ECORE_FILTER_ADD &&
16585cdd769aSRasesh Mody (p_filter_cmd->opcode != ECORE_FILTER_REMOVE)) ||
16595cdd769aSRasesh Mody (p_filter_cmd->num_mc_addrs > ECORE_MAX_MC_ADDRS)) {
16605cdd769aSRasesh Mody return ECORE_INVAL;
16615cdd769aSRasesh Mody }
16625cdd769aSRasesh Mody
16635cdd769aSRasesh Mody for_each_hwfn(p_dev, i) {
16645cdd769aSRasesh Mody struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
16655cdd769aSRasesh Mody
166686a2265eSRasesh Mody if (IS_VF(p_dev)) {
166786a2265eSRasesh Mody ecore_vf_pf_filter_mcast(p_hwfn, p_filter_cmd);
166886a2265eSRasesh Mody continue;
166986a2265eSRasesh Mody }
167086a2265eSRasesh Mody
16715cdd769aSRasesh Mody rc = ecore_sp_eth_filter_mcast(p_hwfn,
16725cdd769aSRasesh Mody p_filter_cmd,
16735cdd769aSRasesh Mody comp_mode, p_comp_data);
16745cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
16755cdd769aSRasesh Mody break;
16765cdd769aSRasesh Mody }
16775cdd769aSRasesh Mody
16785cdd769aSRasesh Mody return rc;
16795cdd769aSRasesh Mody }
16805cdd769aSRasesh Mody
16815cdd769aSRasesh Mody enum _ecore_status_t
ecore_filter_ucast_cmd(struct ecore_dev * p_dev,struct ecore_filter_ucast * p_filter_cmd,enum spq_mode comp_mode,struct ecore_spq_comp_cb * p_comp_data)16825cdd769aSRasesh Mody ecore_filter_ucast_cmd(struct ecore_dev *p_dev,
16835cdd769aSRasesh Mody struct ecore_filter_ucast *p_filter_cmd,
16845cdd769aSRasesh Mody enum spq_mode comp_mode,
16855cdd769aSRasesh Mody struct ecore_spq_comp_cb *p_comp_data)
16865cdd769aSRasesh Mody {
16875cdd769aSRasesh Mody enum _ecore_status_t rc = ECORE_SUCCESS;
16885cdd769aSRasesh Mody int i;
16895cdd769aSRasesh Mody
16905cdd769aSRasesh Mody for_each_hwfn(p_dev, i) {
16915cdd769aSRasesh Mody struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
169222d07d93SRasesh Mody u16 opaque_fid;
16935cdd769aSRasesh Mody
169486a2265eSRasesh Mody if (IS_VF(p_dev)) {
169586a2265eSRasesh Mody rc = ecore_vf_pf_filter_ucast(p_hwfn, p_filter_cmd);
169686a2265eSRasesh Mody continue;
169786a2265eSRasesh Mody }
169886a2265eSRasesh Mody
169922d07d93SRasesh Mody opaque_fid = p_hwfn->hw_info.opaque_fid;
17005cdd769aSRasesh Mody rc = ecore_sp_eth_filter_ucast(p_hwfn,
170122d07d93SRasesh Mody opaque_fid,
17025cdd769aSRasesh Mody p_filter_cmd,
17035cdd769aSRasesh Mody comp_mode, p_comp_data);
17045cdd769aSRasesh Mody if (rc != ECORE_SUCCESS)
17055cdd769aSRasesh Mody break;
17065cdd769aSRasesh Mody }
17075cdd769aSRasesh Mody
17085cdd769aSRasesh Mody return rc;
17095cdd769aSRasesh Mody }
17105cdd769aSRasesh Mody
17115cdd769aSRasesh Mody /* Statistics related code */
__ecore_get_vport_pstats_addrlen(struct ecore_hwfn * p_hwfn,u32 * p_addr,u32 * p_len,u16 statistics_bin)17125cdd769aSRasesh Mody static void __ecore_get_vport_pstats_addrlen(struct ecore_hwfn *p_hwfn,
17135cdd769aSRasesh Mody u32 *p_addr, u32 *p_len,
17145cdd769aSRasesh Mody u16 statistics_bin)
17155cdd769aSRasesh Mody {
171686a2265eSRasesh Mody if (IS_PF(p_hwfn->p_dev)) {
17175cdd769aSRasesh Mody *p_addr = BAR0_MAP_REG_PSDM_RAM +
17185cdd769aSRasesh Mody PSTORM_QUEUE_STAT_OFFSET(statistics_bin);
17195cdd769aSRasesh Mody *p_len = sizeof(struct eth_pstorm_per_queue_stat);
172086a2265eSRasesh Mody } else {
172186a2265eSRasesh Mody struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
172286a2265eSRasesh Mody struct pfvf_acquire_resp_tlv *p_resp = &p_iov->acquire_resp;
172386a2265eSRasesh Mody
172486a2265eSRasesh Mody *p_addr = p_resp->pfdev_info.stats_info.pstats.address;
172586a2265eSRasesh Mody *p_len = p_resp->pfdev_info.stats_info.pstats.len;
172686a2265eSRasesh Mody }
17275cdd769aSRasesh Mody }
17285cdd769aSRasesh Mody
__ecore_get_vport_pstats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * p_stats,u16 statistics_bin)17295cdd769aSRasesh Mody static void __ecore_get_vport_pstats(struct ecore_hwfn *p_hwfn,
17305cdd769aSRasesh Mody struct ecore_ptt *p_ptt,
17315cdd769aSRasesh Mody struct ecore_eth_stats *p_stats,
17325cdd769aSRasesh Mody u16 statistics_bin)
17335cdd769aSRasesh Mody {
17345cdd769aSRasesh Mody struct eth_pstorm_per_queue_stat pstats;
17355cdd769aSRasesh Mody u32 pstats_addr = 0, pstats_len = 0;
17365cdd769aSRasesh Mody
17375cdd769aSRasesh Mody __ecore_get_vport_pstats_addrlen(p_hwfn, &pstats_addr, &pstats_len,
17385cdd769aSRasesh Mody statistics_bin);
17395cdd769aSRasesh Mody
17405cdd769aSRasesh Mody OSAL_MEMSET(&pstats, 0, sizeof(pstats));
17415cdd769aSRasesh Mody ecore_memcpy_from(p_hwfn, p_ptt, &pstats, pstats_addr, pstats_len);
17425cdd769aSRasesh Mody
17439c1aa3e1SRasesh Mody p_stats->common.tx_ucast_bytes +=
17449c1aa3e1SRasesh Mody HILO_64_REGPAIR(pstats.sent_ucast_bytes);
17459c1aa3e1SRasesh Mody p_stats->common.tx_mcast_bytes +=
17469c1aa3e1SRasesh Mody HILO_64_REGPAIR(pstats.sent_mcast_bytes);
17479c1aa3e1SRasesh Mody p_stats->common.tx_bcast_bytes +=
17489c1aa3e1SRasesh Mody HILO_64_REGPAIR(pstats.sent_bcast_bytes);
17499c1aa3e1SRasesh Mody p_stats->common.tx_ucast_pkts +=
17509c1aa3e1SRasesh Mody HILO_64_REGPAIR(pstats.sent_ucast_pkts);
17519c1aa3e1SRasesh Mody p_stats->common.tx_mcast_pkts +=
17529c1aa3e1SRasesh Mody HILO_64_REGPAIR(pstats.sent_mcast_pkts);
17539c1aa3e1SRasesh Mody p_stats->common.tx_bcast_pkts +=
17549c1aa3e1SRasesh Mody HILO_64_REGPAIR(pstats.sent_bcast_pkts);
17559c1aa3e1SRasesh Mody p_stats->common.tx_err_drop_pkts +=
17569c1aa3e1SRasesh Mody HILO_64_REGPAIR(pstats.error_drop_pkts);
17575cdd769aSRasesh Mody }
17585cdd769aSRasesh Mody
__ecore_get_vport_tstats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * p_stats)17595cdd769aSRasesh Mody static void __ecore_get_vport_tstats(struct ecore_hwfn *p_hwfn,
17605cdd769aSRasesh Mody struct ecore_ptt *p_ptt,
176130ecf673SRasesh Mody struct ecore_eth_stats *p_stats)
17625cdd769aSRasesh Mody {
17635cdd769aSRasesh Mody struct tstorm_per_port_stat tstats;
17645cdd769aSRasesh Mody u32 tstats_addr, tstats_len;
17655cdd769aSRasesh Mody
176686a2265eSRasesh Mody if (IS_PF(p_hwfn->p_dev)) {
17675cdd769aSRasesh Mody tstats_addr = BAR0_MAP_REG_TSDM_RAM +
17685cdd769aSRasesh Mody TSTORM_PORT_STAT_OFFSET(MFW_PORT(p_hwfn));
17695cdd769aSRasesh Mody tstats_len = sizeof(struct tstorm_per_port_stat);
177086a2265eSRasesh Mody } else {
177186a2265eSRasesh Mody struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
177286a2265eSRasesh Mody struct pfvf_acquire_resp_tlv *p_resp = &p_iov->acquire_resp;
177386a2265eSRasesh Mody
177486a2265eSRasesh Mody tstats_addr = p_resp->pfdev_info.stats_info.tstats.address;
177586a2265eSRasesh Mody tstats_len = p_resp->pfdev_info.stats_info.tstats.len;
177686a2265eSRasesh Mody }
17775cdd769aSRasesh Mody
17785cdd769aSRasesh Mody OSAL_MEMSET(&tstats, 0, sizeof(tstats));
17795cdd769aSRasesh Mody ecore_memcpy_from(p_hwfn, p_ptt, &tstats, tstats_addr, tstats_len);
17805cdd769aSRasesh Mody
17819c1aa3e1SRasesh Mody p_stats->common.mftag_filter_discards +=
17825cdd769aSRasesh Mody HILO_64_REGPAIR(tstats.mftag_filter_discard);
17839c1aa3e1SRasesh Mody p_stats->common.mac_filter_discards +=
17845cdd769aSRasesh Mody HILO_64_REGPAIR(tstats.eth_mac_filter_discard);
17852c0784ebSShahed Shaikh p_stats->common.gft_filter_drop +=
17862c0784ebSShahed Shaikh HILO_64_REGPAIR(tstats.eth_gft_drop_pkt);
17875cdd769aSRasesh Mody }
17885cdd769aSRasesh Mody
__ecore_get_vport_ustats_addrlen(struct ecore_hwfn * p_hwfn,u32 * p_addr,u32 * p_len,u16 statistics_bin)17895cdd769aSRasesh Mody static void __ecore_get_vport_ustats_addrlen(struct ecore_hwfn *p_hwfn,
17905cdd769aSRasesh Mody u32 *p_addr, u32 *p_len,
17915cdd769aSRasesh Mody u16 statistics_bin)
17925cdd769aSRasesh Mody {
179386a2265eSRasesh Mody if (IS_PF(p_hwfn->p_dev)) {
17945cdd769aSRasesh Mody *p_addr = BAR0_MAP_REG_USDM_RAM +
17955cdd769aSRasesh Mody USTORM_QUEUE_STAT_OFFSET(statistics_bin);
17965cdd769aSRasesh Mody *p_len = sizeof(struct eth_ustorm_per_queue_stat);
179786a2265eSRasesh Mody } else {
179886a2265eSRasesh Mody struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
179986a2265eSRasesh Mody struct pfvf_acquire_resp_tlv *p_resp = &p_iov->acquire_resp;
180086a2265eSRasesh Mody
180186a2265eSRasesh Mody *p_addr = p_resp->pfdev_info.stats_info.ustats.address;
180286a2265eSRasesh Mody *p_len = p_resp->pfdev_info.stats_info.ustats.len;
180386a2265eSRasesh Mody }
18045cdd769aSRasesh Mody }
18055cdd769aSRasesh Mody
__ecore_get_vport_ustats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * p_stats,u16 statistics_bin)18065cdd769aSRasesh Mody static void __ecore_get_vport_ustats(struct ecore_hwfn *p_hwfn,
18075cdd769aSRasesh Mody struct ecore_ptt *p_ptt,
18085cdd769aSRasesh Mody struct ecore_eth_stats *p_stats,
18095cdd769aSRasesh Mody u16 statistics_bin)
18105cdd769aSRasesh Mody {
18115cdd769aSRasesh Mody struct eth_ustorm_per_queue_stat ustats;
18125cdd769aSRasesh Mody u32 ustats_addr = 0, ustats_len = 0;
18135cdd769aSRasesh Mody
18145cdd769aSRasesh Mody __ecore_get_vport_ustats_addrlen(p_hwfn, &ustats_addr, &ustats_len,
18155cdd769aSRasesh Mody statistics_bin);
18165cdd769aSRasesh Mody
18175cdd769aSRasesh Mody OSAL_MEMSET(&ustats, 0, sizeof(ustats));
18185cdd769aSRasesh Mody ecore_memcpy_from(p_hwfn, p_ptt, &ustats, ustats_addr, ustats_len);
18195cdd769aSRasesh Mody
18209c1aa3e1SRasesh Mody p_stats->common.rx_ucast_bytes +=
18219c1aa3e1SRasesh Mody HILO_64_REGPAIR(ustats.rcv_ucast_bytes);
18229c1aa3e1SRasesh Mody p_stats->common.rx_mcast_bytes +=
18239c1aa3e1SRasesh Mody HILO_64_REGPAIR(ustats.rcv_mcast_bytes);
18249c1aa3e1SRasesh Mody p_stats->common.rx_bcast_bytes +=
18259c1aa3e1SRasesh Mody HILO_64_REGPAIR(ustats.rcv_bcast_bytes);
18269c1aa3e1SRasesh Mody p_stats->common.rx_ucast_pkts +=
18279c1aa3e1SRasesh Mody HILO_64_REGPAIR(ustats.rcv_ucast_pkts);
18289c1aa3e1SRasesh Mody p_stats->common.rx_mcast_pkts +=
18299c1aa3e1SRasesh Mody HILO_64_REGPAIR(ustats.rcv_mcast_pkts);
18309c1aa3e1SRasesh Mody p_stats->common.rx_bcast_pkts +=
18319c1aa3e1SRasesh Mody HILO_64_REGPAIR(ustats.rcv_bcast_pkts);
18325cdd769aSRasesh Mody }
18335cdd769aSRasesh Mody
__ecore_get_vport_mstats_addrlen(struct ecore_hwfn * p_hwfn,u32 * p_addr,u32 * p_len,u16 statistics_bin)18345cdd769aSRasesh Mody static void __ecore_get_vport_mstats_addrlen(struct ecore_hwfn *p_hwfn,
18355cdd769aSRasesh Mody u32 *p_addr, u32 *p_len,
18365cdd769aSRasesh Mody u16 statistics_bin)
18375cdd769aSRasesh Mody {
183886a2265eSRasesh Mody if (IS_PF(p_hwfn->p_dev)) {
18395cdd769aSRasesh Mody *p_addr = BAR0_MAP_REG_MSDM_RAM +
18405cdd769aSRasesh Mody MSTORM_QUEUE_STAT_OFFSET(statistics_bin);
18415cdd769aSRasesh Mody *p_len = sizeof(struct eth_mstorm_per_queue_stat);
184286a2265eSRasesh Mody } else {
184386a2265eSRasesh Mody struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
184486a2265eSRasesh Mody struct pfvf_acquire_resp_tlv *p_resp = &p_iov->acquire_resp;
184586a2265eSRasesh Mody
184686a2265eSRasesh Mody *p_addr = p_resp->pfdev_info.stats_info.mstats.address;
184786a2265eSRasesh Mody *p_len = p_resp->pfdev_info.stats_info.mstats.len;
184886a2265eSRasesh Mody }
18495cdd769aSRasesh Mody }
18505cdd769aSRasesh Mody
__ecore_get_vport_mstats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * p_stats,u16 statistics_bin)18515cdd769aSRasesh Mody static void __ecore_get_vport_mstats(struct ecore_hwfn *p_hwfn,
18525cdd769aSRasesh Mody struct ecore_ptt *p_ptt,
18535cdd769aSRasesh Mody struct ecore_eth_stats *p_stats,
18545cdd769aSRasesh Mody u16 statistics_bin)
18555cdd769aSRasesh Mody {
18565cdd769aSRasesh Mody struct eth_mstorm_per_queue_stat mstats;
18575cdd769aSRasesh Mody u32 mstats_addr = 0, mstats_len = 0;
18585cdd769aSRasesh Mody
18595cdd769aSRasesh Mody __ecore_get_vport_mstats_addrlen(p_hwfn, &mstats_addr, &mstats_len,
18605cdd769aSRasesh Mody statistics_bin);
18615cdd769aSRasesh Mody
18625cdd769aSRasesh Mody OSAL_MEMSET(&mstats, 0, sizeof(mstats));
18635cdd769aSRasesh Mody ecore_memcpy_from(p_hwfn, p_ptt, &mstats, mstats_addr, mstats_len);
18645cdd769aSRasesh Mody
18659c1aa3e1SRasesh Mody p_stats->common.no_buff_discards +=
18669c1aa3e1SRasesh Mody HILO_64_REGPAIR(mstats.no_buff_discard);
18679c1aa3e1SRasesh Mody p_stats->common.packet_too_big_discard +=
18685cdd769aSRasesh Mody HILO_64_REGPAIR(mstats.packet_too_big_discard);
18699c1aa3e1SRasesh Mody p_stats->common.ttl0_discard +=
18709c1aa3e1SRasesh Mody HILO_64_REGPAIR(mstats.ttl0_discard);
18719c1aa3e1SRasesh Mody p_stats->common.tpa_coalesced_pkts +=
18725cdd769aSRasesh Mody HILO_64_REGPAIR(mstats.tpa_coalesced_pkts);
18739c1aa3e1SRasesh Mody p_stats->common.tpa_coalesced_events +=
18745cdd769aSRasesh Mody HILO_64_REGPAIR(mstats.tpa_coalesced_events);
18759c1aa3e1SRasesh Mody p_stats->common.tpa_aborts_num +=
18769c1aa3e1SRasesh Mody HILO_64_REGPAIR(mstats.tpa_aborts_num);
18779c1aa3e1SRasesh Mody p_stats->common.tpa_coalesced_bytes +=
18785cdd769aSRasesh Mody HILO_64_REGPAIR(mstats.tpa_coalesced_bytes);
18795cdd769aSRasesh Mody }
18805cdd769aSRasesh Mody
__ecore_get_vport_port_stats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * p_stats)18815cdd769aSRasesh Mody static void __ecore_get_vport_port_stats(struct ecore_hwfn *p_hwfn,
18825cdd769aSRasesh Mody struct ecore_ptt *p_ptt,
18835cdd769aSRasesh Mody struct ecore_eth_stats *p_stats)
18845cdd769aSRasesh Mody {
18859c1aa3e1SRasesh Mody struct ecore_eth_stats_common *p_common = &p_stats->common;
18865cdd769aSRasesh Mody struct port_stats port_stats;
18875cdd769aSRasesh Mody int j;
18885cdd769aSRasesh Mody
18895cdd769aSRasesh Mody OSAL_MEMSET(&port_stats, 0, sizeof(port_stats));
18905cdd769aSRasesh Mody
18915cdd769aSRasesh Mody ecore_memcpy_from(p_hwfn, p_ptt, &port_stats,
18925cdd769aSRasesh Mody p_hwfn->mcp_info->port_addr +
18935cdd769aSRasesh Mody OFFSETOF(struct public_port, stats),
18945cdd769aSRasesh Mody sizeof(port_stats));
18955cdd769aSRasesh Mody
18969c1aa3e1SRasesh Mody p_common->rx_64_byte_packets += port_stats.eth.r64;
18979c1aa3e1SRasesh Mody p_common->rx_65_to_127_byte_packets += port_stats.eth.r127;
18989c1aa3e1SRasesh Mody p_common->rx_128_to_255_byte_packets += port_stats.eth.r255;
18999c1aa3e1SRasesh Mody p_common->rx_256_to_511_byte_packets += port_stats.eth.r511;
19009c1aa3e1SRasesh Mody p_common->rx_512_to_1023_byte_packets += port_stats.eth.r1023;
19019c1aa3e1SRasesh Mody p_common->rx_1024_to_1518_byte_packets += port_stats.eth.r1518;
19029c1aa3e1SRasesh Mody p_common->rx_crc_errors += port_stats.eth.rfcs;
19039c1aa3e1SRasesh Mody p_common->rx_mac_crtl_frames += port_stats.eth.rxcf;
19049c1aa3e1SRasesh Mody p_common->rx_pause_frames += port_stats.eth.rxpf;
19059c1aa3e1SRasesh Mody p_common->rx_pfc_frames += port_stats.eth.rxpp;
19069c1aa3e1SRasesh Mody p_common->rx_align_errors += port_stats.eth.raln;
19079c1aa3e1SRasesh Mody p_common->rx_carrier_errors += port_stats.eth.rfcr;
19089c1aa3e1SRasesh Mody p_common->rx_oversize_packets += port_stats.eth.rovr;
19099c1aa3e1SRasesh Mody p_common->rx_jabbers += port_stats.eth.rjbr;
19109c1aa3e1SRasesh Mody p_common->rx_undersize_packets += port_stats.eth.rund;
19119c1aa3e1SRasesh Mody p_common->rx_fragments += port_stats.eth.rfrg;
19129c1aa3e1SRasesh Mody p_common->tx_64_byte_packets += port_stats.eth.t64;
19139c1aa3e1SRasesh Mody p_common->tx_65_to_127_byte_packets += port_stats.eth.t127;
19149c1aa3e1SRasesh Mody p_common->tx_128_to_255_byte_packets += port_stats.eth.t255;
19159c1aa3e1SRasesh Mody p_common->tx_256_to_511_byte_packets += port_stats.eth.t511;
19169c1aa3e1SRasesh Mody p_common->tx_512_to_1023_byte_packets += port_stats.eth.t1023;
19179c1aa3e1SRasesh Mody p_common->tx_1024_to_1518_byte_packets += port_stats.eth.t1518;
19189c1aa3e1SRasesh Mody p_common->tx_pause_frames += port_stats.eth.txpf;
19199c1aa3e1SRasesh Mody p_common->tx_pfc_frames += port_stats.eth.txpp;
19209c1aa3e1SRasesh Mody p_common->rx_mac_bytes += port_stats.eth.rbyte;
19219c1aa3e1SRasesh Mody p_common->rx_mac_uc_packets += port_stats.eth.rxuca;
19229c1aa3e1SRasesh Mody p_common->rx_mac_mc_packets += port_stats.eth.rxmca;
19239c1aa3e1SRasesh Mody p_common->rx_mac_bc_packets += port_stats.eth.rxbca;
19249c1aa3e1SRasesh Mody p_common->rx_mac_frames_ok += port_stats.eth.rxpok;
19259c1aa3e1SRasesh Mody p_common->tx_mac_bytes += port_stats.eth.tbyte;
19269c1aa3e1SRasesh Mody p_common->tx_mac_uc_packets += port_stats.eth.txuca;
19279c1aa3e1SRasesh Mody p_common->tx_mac_mc_packets += port_stats.eth.txmca;
19289c1aa3e1SRasesh Mody p_common->tx_mac_bc_packets += port_stats.eth.txbca;
19299c1aa3e1SRasesh Mody p_common->tx_mac_ctrl_frames += port_stats.eth.txcf;
19305cdd769aSRasesh Mody for (j = 0; j < 8; j++) {
19319c1aa3e1SRasesh Mody p_common->brb_truncates += port_stats.brb.brb_truncate[j];
19329c1aa3e1SRasesh Mody p_common->brb_discards += port_stats.brb.brb_discard[j];
19339c1aa3e1SRasesh Mody }
19349c1aa3e1SRasesh Mody
19359c1aa3e1SRasesh Mody if (ECORE_IS_BB(p_hwfn->p_dev)) {
19369c1aa3e1SRasesh Mody struct ecore_eth_stats_bb *p_bb = &p_stats->bb;
19379c1aa3e1SRasesh Mody
19389c1aa3e1SRasesh Mody p_bb->rx_1519_to_1522_byte_packets +=
19399c1aa3e1SRasesh Mody port_stats.eth.u0.bb0.r1522;
19409c1aa3e1SRasesh Mody p_bb->rx_1519_to_2047_byte_packets +=
19419c1aa3e1SRasesh Mody port_stats.eth.u0.bb0.r2047;
19429c1aa3e1SRasesh Mody p_bb->rx_2048_to_4095_byte_packets +=
19439c1aa3e1SRasesh Mody port_stats.eth.u0.bb0.r4095;
19449c1aa3e1SRasesh Mody p_bb->rx_4096_to_9216_byte_packets +=
19459c1aa3e1SRasesh Mody port_stats.eth.u0.bb0.r9216;
19469c1aa3e1SRasesh Mody p_bb->rx_9217_to_16383_byte_packets +=
19479c1aa3e1SRasesh Mody port_stats.eth.u0.bb0.r16383;
19489c1aa3e1SRasesh Mody p_bb->tx_1519_to_2047_byte_packets +=
19499c1aa3e1SRasesh Mody port_stats.eth.u1.bb1.t2047;
19509c1aa3e1SRasesh Mody p_bb->tx_2048_to_4095_byte_packets +=
19519c1aa3e1SRasesh Mody port_stats.eth.u1.bb1.t4095;
19529c1aa3e1SRasesh Mody p_bb->tx_4096_to_9216_byte_packets +=
19539c1aa3e1SRasesh Mody port_stats.eth.u1.bb1.t9216;
19549c1aa3e1SRasesh Mody p_bb->tx_9217_to_16383_byte_packets +=
19559c1aa3e1SRasesh Mody port_stats.eth.u1.bb1.t16383;
19569c1aa3e1SRasesh Mody p_bb->tx_lpi_entry_count += port_stats.eth.u2.bb2.tlpiec;
19579c1aa3e1SRasesh Mody p_bb->tx_total_collisions += port_stats.eth.u2.bb2.tncl;
19589c1aa3e1SRasesh Mody } else {
19599c1aa3e1SRasesh Mody struct ecore_eth_stats_ah *p_ah = &p_stats->ah;
19609c1aa3e1SRasesh Mody
19619c1aa3e1SRasesh Mody p_ah->rx_1519_to_max_byte_packets +=
19629c1aa3e1SRasesh Mody port_stats.eth.u0.ah0.r1519_to_max;
19639c1aa3e1SRasesh Mody p_ah->tx_1519_to_max_byte_packets =
19649c1aa3e1SRasesh Mody port_stats.eth.u1.ah1.t1519_to_max;
19655cdd769aSRasesh Mody }
1966803a4cf0SRasesh Mody
1967803a4cf0SRasesh Mody p_common->link_change_count = ecore_rd(p_hwfn, p_ptt,
1968803a4cf0SRasesh Mody p_hwfn->mcp_info->port_addr +
1969803a4cf0SRasesh Mody OFFSETOF(struct public_port,
1970803a4cf0SRasesh Mody link_change_count));
19715cdd769aSRasesh Mody }
19725cdd769aSRasesh Mody
__ecore_get_vport_stats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * stats,u16 statistics_bin,bool b_get_port_stats)19735cdd769aSRasesh Mody void __ecore_get_vport_stats(struct ecore_hwfn *p_hwfn,
19745cdd769aSRasesh Mody struct ecore_ptt *p_ptt,
19755cdd769aSRasesh Mody struct ecore_eth_stats *stats,
19765cdd769aSRasesh Mody u16 statistics_bin, bool b_get_port_stats)
19775cdd769aSRasesh Mody {
19785cdd769aSRasesh Mody __ecore_get_vport_mstats(p_hwfn, p_ptt, stats, statistics_bin);
19795cdd769aSRasesh Mody __ecore_get_vport_ustats(p_hwfn, p_ptt, stats, statistics_bin);
198030ecf673SRasesh Mody __ecore_get_vport_tstats(p_hwfn, p_ptt, stats);
19815cdd769aSRasesh Mody __ecore_get_vport_pstats(p_hwfn, p_ptt, stats, statistics_bin);
19825cdd769aSRasesh Mody
19835cdd769aSRasesh Mody #ifndef ASIC_ONLY
19845cdd769aSRasesh Mody /* Avoid getting PORT stats for emulation. */
19855cdd769aSRasesh Mody if (CHIP_REV_IS_EMUL(p_hwfn->p_dev))
19865cdd769aSRasesh Mody return;
19875cdd769aSRasesh Mody #endif
19885cdd769aSRasesh Mody
19895cdd769aSRasesh Mody if (b_get_port_stats && p_hwfn->mcp_info)
19905cdd769aSRasesh Mody __ecore_get_vport_port_stats(p_hwfn, p_ptt, stats);
19915cdd769aSRasesh Mody }
19925cdd769aSRasesh Mody
_ecore_get_vport_stats(struct ecore_dev * p_dev,struct ecore_eth_stats * stats)19935cdd769aSRasesh Mody static void _ecore_get_vport_stats(struct ecore_dev *p_dev,
19945cdd769aSRasesh Mody struct ecore_eth_stats *stats)
19955cdd769aSRasesh Mody {
19965cdd769aSRasesh Mody u8 fw_vport = 0;
19975cdd769aSRasesh Mody int i;
19985cdd769aSRasesh Mody
19995cdd769aSRasesh Mody OSAL_MEMSET(stats, 0, sizeof(*stats));
20005cdd769aSRasesh Mody
20015cdd769aSRasesh Mody for_each_hwfn(p_dev, i) {
20025cdd769aSRasesh Mody struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
200386a2265eSRasesh Mody struct ecore_ptt *p_ptt = IS_PF(p_dev) ?
200486a2265eSRasesh Mody ecore_ptt_acquire(p_hwfn) : OSAL_NULL;
2005dd7b6aadSRasesh Mody bool b_get_port_stats;
20065cdd769aSRasesh Mody
200786a2265eSRasesh Mody if (IS_PF(p_dev)) {
20085cdd769aSRasesh Mody /* The main vport index is relative first */
20095cdd769aSRasesh Mody if (ecore_fw_vport(p_hwfn, 0, &fw_vport)) {
20105cdd769aSRasesh Mody DP_ERR(p_hwfn, "No vport available!\n");
20115cdd769aSRasesh Mody goto out;
20125cdd769aSRasesh Mody }
201386a2265eSRasesh Mody }
20145cdd769aSRasesh Mody
201586a2265eSRasesh Mody if (IS_PF(p_dev) && !p_ptt) {
20165cdd769aSRasesh Mody DP_ERR(p_hwfn, "Failed to acquire ptt\n");
20175cdd769aSRasesh Mody continue;
20185cdd769aSRasesh Mody }
20195cdd769aSRasesh Mody
2020dd7b6aadSRasesh Mody b_get_port_stats = IS_PF(p_dev) && IS_LEAD_HWFN(p_hwfn);
20215cdd769aSRasesh Mody __ecore_get_vport_stats(p_hwfn, p_ptt, stats, fw_vport,
2022dd7b6aadSRasesh Mody b_get_port_stats);
20235cdd769aSRasesh Mody
20245cdd769aSRasesh Mody out:
202522d07d93SRasesh Mody if (IS_PF(p_dev) && p_ptt)
20265cdd769aSRasesh Mody ecore_ptt_release(p_hwfn, p_ptt);
20275cdd769aSRasesh Mody }
20285cdd769aSRasesh Mody }
20295cdd769aSRasesh Mody
ecore_get_vport_stats(struct ecore_dev * p_dev,struct ecore_eth_stats * stats)20305cdd769aSRasesh Mody void ecore_get_vport_stats(struct ecore_dev *p_dev,
20315cdd769aSRasesh Mody struct ecore_eth_stats *stats)
20325cdd769aSRasesh Mody {
20335cdd769aSRasesh Mody u32 i;
20345cdd769aSRasesh Mody
20355cdd769aSRasesh Mody if (!p_dev) {
20365cdd769aSRasesh Mody OSAL_MEMSET(stats, 0, sizeof(*stats));
20375cdd769aSRasesh Mody return;
20385cdd769aSRasesh Mody }
20395cdd769aSRasesh Mody
20405cdd769aSRasesh Mody _ecore_get_vport_stats(p_dev, stats);
20415cdd769aSRasesh Mody
20425cdd769aSRasesh Mody if (!p_dev->reset_stats)
20435cdd769aSRasesh Mody return;
20445cdd769aSRasesh Mody
20455cdd769aSRasesh Mody /* Reduce the statistics baseline */
20465cdd769aSRasesh Mody for (i = 0; i < sizeof(struct ecore_eth_stats) / sizeof(u64); i++)
20475cdd769aSRasesh Mody ((u64 *)stats)[i] -= ((u64 *)p_dev->reset_stats)[i];
20485cdd769aSRasesh Mody }
20495cdd769aSRasesh Mody
20505cdd769aSRasesh Mody /* zeroes V-PORT specific portion of stats (Port stats remains untouched) */
ecore_reset_vport_stats(struct ecore_dev * p_dev)20515cdd769aSRasesh Mody void ecore_reset_vport_stats(struct ecore_dev *p_dev)
20525cdd769aSRasesh Mody {
20535cdd769aSRasesh Mody int i;
20545cdd769aSRasesh Mody
20555cdd769aSRasesh Mody for_each_hwfn(p_dev, i) {
20565cdd769aSRasesh Mody struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
20575cdd769aSRasesh Mody struct eth_mstorm_per_queue_stat mstats;
20585cdd769aSRasesh Mody struct eth_ustorm_per_queue_stat ustats;
20595cdd769aSRasesh Mody struct eth_pstorm_per_queue_stat pstats;
206086a2265eSRasesh Mody struct ecore_ptt *p_ptt = IS_PF(p_dev) ?
206186a2265eSRasesh Mody ecore_ptt_acquire(p_hwfn) : OSAL_NULL;
20625cdd769aSRasesh Mody u32 addr = 0, len = 0;
20635cdd769aSRasesh Mody
206486a2265eSRasesh Mody if (IS_PF(p_dev) && !p_ptt) {
20655cdd769aSRasesh Mody DP_ERR(p_hwfn, "Failed to acquire ptt\n");
20665cdd769aSRasesh Mody continue;
20675cdd769aSRasesh Mody }
20685cdd769aSRasesh Mody
20695cdd769aSRasesh Mody OSAL_MEMSET(&mstats, 0, sizeof(mstats));
20705cdd769aSRasesh Mody __ecore_get_vport_mstats_addrlen(p_hwfn, &addr, &len, 0);
20715cdd769aSRasesh Mody ecore_memcpy_to(p_hwfn, p_ptt, addr, &mstats, len);
20725cdd769aSRasesh Mody
20735cdd769aSRasesh Mody OSAL_MEMSET(&ustats, 0, sizeof(ustats));
20745cdd769aSRasesh Mody __ecore_get_vport_ustats_addrlen(p_hwfn, &addr, &len, 0);
20755cdd769aSRasesh Mody ecore_memcpy_to(p_hwfn, p_ptt, addr, &ustats, len);
20765cdd769aSRasesh Mody
20775cdd769aSRasesh Mody OSAL_MEMSET(&pstats, 0, sizeof(pstats));
20785cdd769aSRasesh Mody __ecore_get_vport_pstats_addrlen(p_hwfn, &addr, &len, 0);
20795cdd769aSRasesh Mody ecore_memcpy_to(p_hwfn, p_ptt, addr, &pstats, len);
20805cdd769aSRasesh Mody
208186a2265eSRasesh Mody if (IS_PF(p_dev))
20825cdd769aSRasesh Mody ecore_ptt_release(p_hwfn, p_ptt);
20835cdd769aSRasesh Mody }
20845cdd769aSRasesh Mody
20855cdd769aSRasesh Mody /* PORT statistics are not necessarily reset, so we need to
20865cdd769aSRasesh Mody * read and create a baseline for future statistics.
2087803a4cf0SRasesh Mody * Link change stat is maintained by MFW, return its value as is.
20885cdd769aSRasesh Mody */
20895cdd769aSRasesh Mody if (!p_dev->reset_stats)
20905cdd769aSRasesh Mody DP_INFO(p_dev, "Reset stats not allocated\n");
2091803a4cf0SRasesh Mody else {
20925cdd769aSRasesh Mody _ecore_get_vport_stats(p_dev, p_dev->reset_stats);
2093803a4cf0SRasesh Mody p_dev->reset_stats->common.link_change_count = 0;
2094803a4cf0SRasesh Mody }
20955cdd769aSRasesh Mody }
209653437002SHarish Patil
2097f5765f66SShahed Shaikh static enum gft_profile_type
ecore_arfs_mode_to_hsi(enum ecore_filter_config_mode mode)2098f5765f66SShahed Shaikh ecore_arfs_mode_to_hsi(enum ecore_filter_config_mode mode)
2099f5765f66SShahed Shaikh {
2100f5765f66SShahed Shaikh if (mode == ECORE_FILTER_CONFIG_MODE_5_TUPLE)
2101f5765f66SShahed Shaikh return GFT_PROFILE_TYPE_4_TUPLE;
2102f5765f66SShahed Shaikh
2103f5765f66SShahed Shaikh if (mode == ECORE_FILTER_CONFIG_MODE_IP_DEST)
2104f5765f66SShahed Shaikh return GFT_PROFILE_TYPE_IP_DST_ADDR;
2105f5765f66SShahed Shaikh
2106f5765f66SShahed Shaikh if (mode == ECORE_FILTER_CONFIG_MODE_TUNN_TYPE)
2107f5765f66SShahed Shaikh return GFT_PROFILE_TYPE_TUNNEL_TYPE;
2108f5765f66SShahed Shaikh
2109f5765f66SShahed Shaikh if (mode == ECORE_FILTER_CONFIG_MODE_IP_SRC)
2110f5765f66SShahed Shaikh return GFT_PROFILE_TYPE_IP_SRC_ADDR;
2111f5765f66SShahed Shaikh
2112f5765f66SShahed Shaikh return GFT_PROFILE_TYPE_L4_DST_PORT;
2113f5765f66SShahed Shaikh }
2114f5765f66SShahed Shaikh
ecore_arfs_mode_configure(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_arfs_config_params * p_cfg_params)211553437002SHarish Patil void ecore_arfs_mode_configure(struct ecore_hwfn *p_hwfn,
211653437002SHarish Patil struct ecore_ptt *p_ptt,
211753437002SHarish Patil struct ecore_arfs_config_params *p_cfg_params)
211853437002SHarish Patil {
2119*5018f1fcSJoyce Kong if (OSAL_GET_BIT(ECORE_MF_DISABLE_ARFS, &p_hwfn->p_dev->mf_bits))
2120a2dc43f3SRasesh Mody return;
2121a2dc43f3SRasesh Mody
2122f5765f66SShahed Shaikh if (p_cfg_params->mode != ECORE_FILTER_CONFIG_MODE_DISABLE) {
212340cf1e75SRasesh Mody ecore_gft_config(p_hwfn, p_ptt, p_hwfn->rel_pf_id,
212453437002SHarish Patil p_cfg_params->tcp,
212553437002SHarish Patil p_cfg_params->udp,
212653437002SHarish Patil p_cfg_params->ipv4,
212740cf1e75SRasesh Mody p_cfg_params->ipv6,
2128f5765f66SShahed Shaikh ecore_arfs_mode_to_hsi(p_cfg_params->mode));
212953437002SHarish Patil DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
213053437002SHarish Patil "tcp = %s, udp = %s, ipv4 = %s, ipv6 =%s\n",
213153437002SHarish Patil p_cfg_params->tcp ? "Enable" : "Disable",
213253437002SHarish Patil p_cfg_params->udp ? "Enable" : "Disable",
213353437002SHarish Patil p_cfg_params->ipv4 ? "Enable" : "Disable",
213453437002SHarish Patil p_cfg_params->ipv6 ? "Enable" : "Disable");
213553437002SHarish Patil } else {
213640cf1e75SRasesh Mody ecore_gft_disable(p_hwfn, p_ptt, p_hwfn->rel_pf_id);
213753437002SHarish Patil }
2138f5765f66SShahed Shaikh DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "Configured ARFS mode : %d\n",
2139f5765f66SShahed Shaikh (int)p_cfg_params->mode);
214053437002SHarish Patil }
214153437002SHarish Patil
214253437002SHarish Patil enum _ecore_status_t
ecore_configure_rfs_ntuple_filter(struct ecore_hwfn * p_hwfn,struct ecore_spq_comp_cb * p_cb,struct ecore_ntuple_filter_params * p_params)214353437002SHarish Patil ecore_configure_rfs_ntuple_filter(struct ecore_hwfn *p_hwfn,
214453437002SHarish Patil struct ecore_spq_comp_cb *p_cb,
21452c0784ebSShahed Shaikh struct ecore_ntuple_filter_params *p_params)
214653437002SHarish Patil {
214753437002SHarish Patil struct rx_update_gft_filter_data *p_ramrod = OSAL_NULL;
214853437002SHarish Patil struct ecore_spq_entry *p_ent = OSAL_NULL;
214953437002SHarish Patil struct ecore_sp_init_data init_data;
215053437002SHarish Patil u16 abs_rx_q_id = 0;
215153437002SHarish Patil u8 abs_vport_id = 0;
215253437002SHarish Patil enum _ecore_status_t rc = ECORE_NOTIMPL;
215353437002SHarish Patil
215453437002SHarish Patil /* Get SPQ entry */
215553437002SHarish Patil OSAL_MEMSET(&init_data, 0, sizeof(init_data));
215653437002SHarish Patil init_data.cid = ecore_spq_get_cid(p_hwfn);
215753437002SHarish Patil
215853437002SHarish Patil init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
215953437002SHarish Patil
216053437002SHarish Patil if (p_cb) {
216153437002SHarish Patil init_data.comp_mode = ECORE_SPQ_MODE_CB;
216253437002SHarish Patil init_data.p_comp_data = p_cb;
216353437002SHarish Patil } else {
216453437002SHarish Patil init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
216553437002SHarish Patil }
216653437002SHarish Patil
216753437002SHarish Patil rc = ecore_sp_init_request(p_hwfn, &p_ent,
216853437002SHarish Patil ETH_RAMROD_GFT_UPDATE_FILTER,
216953437002SHarish Patil PROTOCOLID_ETH, &init_data);
217053437002SHarish Patil if (rc != ECORE_SUCCESS)
217153437002SHarish Patil return rc;
217253437002SHarish Patil
217353437002SHarish Patil p_ramrod = &p_ent->ramrod.rx_update_gft;
217453437002SHarish Patil
21752c0784ebSShahed Shaikh DMA_REGPAIR_LE(p_ramrod->pkt_hdr_addr, p_params->addr);
21762c0784ebSShahed Shaikh p_ramrod->pkt_hdr_length = OSAL_CPU_TO_LE16(p_params->length);
217740cf1e75SRasesh Mody
21782c0784ebSShahed Shaikh if (p_params->b_is_drop) {
21792c0784ebSShahed Shaikh p_ramrod->vport_id = OSAL_CPU_TO_LE16(ETH_GFT_TRASHCAN_VPORT);
21802c0784ebSShahed Shaikh } else {
21812c0784ebSShahed Shaikh rc = ecore_fw_vport(p_hwfn, p_params->vport_id,
21822c0784ebSShahed Shaikh &abs_vport_id);
21832c0784ebSShahed Shaikh if (rc)
21842c0784ebSShahed Shaikh return rc;
21852c0784ebSShahed Shaikh
21862c0784ebSShahed Shaikh if (p_params->qid != ECORE_RFS_NTUPLE_QID_RSS) {
21872c0784ebSShahed Shaikh rc = ecore_fw_l2_queue(p_hwfn, p_params->qid,
21882c0784ebSShahed Shaikh &abs_rx_q_id);
21892c0784ebSShahed Shaikh if (rc)
21902c0784ebSShahed Shaikh return rc;
219140cf1e75SRasesh Mody
219240cf1e75SRasesh Mody p_ramrod->rx_qid_valid = 1;
219340cf1e75SRasesh Mody p_ramrod->rx_qid = OSAL_CPU_TO_LE16(abs_rx_q_id);
21942c0784ebSShahed Shaikh }
21952c0784ebSShahed Shaikh
21962c0784ebSShahed Shaikh p_ramrod->vport_id = OSAL_CPU_TO_LE16((u16)abs_vport_id);
21972c0784ebSShahed Shaikh }
219840cf1e75SRasesh Mody
219940cf1e75SRasesh Mody p_ramrod->flow_id_valid = 0;
220040cf1e75SRasesh Mody p_ramrod->flow_id = 0;
220140cf1e75SRasesh Mody
22022c0784ebSShahed Shaikh p_ramrod->filter_action = p_params->b_is_add ? GFT_ADD_FILTER
220353437002SHarish Patil : GFT_DELETE_FILTER;
220453437002SHarish Patil
220553437002SHarish Patil DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
220653437002SHarish Patil "V[%0x], Q[%04x] - %s filter from 0x%lx [length %04xb]\n",
220753437002SHarish Patil abs_vport_id, abs_rx_q_id,
22082c0784ebSShahed Shaikh p_params->b_is_add ? "Adding" : "Removing",
22092c0784ebSShahed Shaikh (unsigned long)p_params->addr, p_params->length);
221053437002SHarish Patil
221153437002SHarish Patil return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
221253437002SHarish Patil }
2213823a84aaSRasesh Mody
ecore_get_rxq_coalesce(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_queue_cid * p_cid,u16 * p_rx_coal)22149ed26bc7SRasesh Mody enum _ecore_status_t ecore_get_rxq_coalesce(struct ecore_hwfn *p_hwfn,
2215823a84aaSRasesh Mody struct ecore_ptt *p_ptt,
2216823a84aaSRasesh Mody struct ecore_queue_cid *p_cid,
2217823a84aaSRasesh Mody u16 *p_rx_coal)
2218823a84aaSRasesh Mody {
2219823a84aaSRasesh Mody u32 coalesce, address, is_valid;
2220823a84aaSRasesh Mody struct cau_sb_entry sb_entry;
2221823a84aaSRasesh Mody u8 timer_res;
2222823a84aaSRasesh Mody enum _ecore_status_t rc;
2223823a84aaSRasesh Mody
2224823a84aaSRasesh Mody rc = ecore_dmae_grc2host(p_hwfn, p_ptt, CAU_REG_SB_VAR_MEMORY +
2225823a84aaSRasesh Mody p_cid->sb_igu_id * sizeof(u64),
22263eed444aSRasesh Mody (u64)(osal_uintptr_t)&sb_entry, 2,
22273eed444aSRasesh Mody OSAL_NULL /* default parameters */);
2228823a84aaSRasesh Mody if (rc != ECORE_SUCCESS) {
2229823a84aaSRasesh Mody DP_ERR(p_hwfn, "dmae_grc2host failed %d\n", rc);
2230823a84aaSRasesh Mody return rc;
2231823a84aaSRasesh Mody }
2232823a84aaSRasesh Mody
2233823a84aaSRasesh Mody timer_res = GET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES0);
2234823a84aaSRasesh Mody
2235823a84aaSRasesh Mody address = BAR0_MAP_REG_USDM_RAM +
2236823a84aaSRasesh Mody USTORM_ETH_QUEUE_ZONE_OFFSET(p_cid->abs.queue_id);
2237823a84aaSRasesh Mody coalesce = ecore_rd(p_hwfn, p_ptt, address);
2238823a84aaSRasesh Mody
2239823a84aaSRasesh Mody is_valid = GET_FIELD(coalesce, COALESCING_TIMESET_VALID);
2240823a84aaSRasesh Mody if (!is_valid)
2241823a84aaSRasesh Mody return ECORE_INVAL;
2242823a84aaSRasesh Mody
2243823a84aaSRasesh Mody coalesce = GET_FIELD(coalesce, COALESCING_TIMESET_TIMESET);
2244823a84aaSRasesh Mody *p_rx_coal = (u16)(coalesce << timer_res);
2245823a84aaSRasesh Mody
2246823a84aaSRasesh Mody return ECORE_SUCCESS;
2247823a84aaSRasesh Mody }
2248823a84aaSRasesh Mody
ecore_get_txq_coalesce(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_queue_cid * p_cid,u16 * p_tx_coal)22499ed26bc7SRasesh Mody enum _ecore_status_t ecore_get_txq_coalesce(struct ecore_hwfn *p_hwfn,
2250823a84aaSRasesh Mody struct ecore_ptt *p_ptt,
2251823a84aaSRasesh Mody struct ecore_queue_cid *p_cid,
2252823a84aaSRasesh Mody u16 *p_tx_coal)
2253823a84aaSRasesh Mody {
2254823a84aaSRasesh Mody u32 coalesce, address, is_valid;
2255823a84aaSRasesh Mody struct cau_sb_entry sb_entry;
2256823a84aaSRasesh Mody u8 timer_res;
2257823a84aaSRasesh Mody enum _ecore_status_t rc;
2258823a84aaSRasesh Mody
2259823a84aaSRasesh Mody rc = ecore_dmae_grc2host(p_hwfn, p_ptt, CAU_REG_SB_VAR_MEMORY +
2260823a84aaSRasesh Mody p_cid->sb_igu_id * sizeof(u64),
22613eed444aSRasesh Mody (u64)(osal_uintptr_t)&sb_entry, 2,
22623eed444aSRasesh Mody OSAL_NULL /* default parameters */);
2263823a84aaSRasesh Mody if (rc != ECORE_SUCCESS) {
2264823a84aaSRasesh Mody DP_ERR(p_hwfn, "dmae_grc2host failed %d\n", rc);
2265823a84aaSRasesh Mody return rc;
2266823a84aaSRasesh Mody }
2267823a84aaSRasesh Mody
2268823a84aaSRasesh Mody timer_res = GET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES1);
2269823a84aaSRasesh Mody
2270823a84aaSRasesh Mody address = BAR0_MAP_REG_XSDM_RAM +
2271823a84aaSRasesh Mody XSTORM_ETH_QUEUE_ZONE_OFFSET(p_cid->abs.queue_id);
2272823a84aaSRasesh Mody coalesce = ecore_rd(p_hwfn, p_ptt, address);
2273823a84aaSRasesh Mody
2274823a84aaSRasesh Mody is_valid = GET_FIELD(coalesce, COALESCING_TIMESET_VALID);
2275823a84aaSRasesh Mody if (!is_valid)
2276823a84aaSRasesh Mody return ECORE_INVAL;
2277823a84aaSRasesh Mody
2278823a84aaSRasesh Mody coalesce = GET_FIELD(coalesce, COALESCING_TIMESET_TIMESET);
2279823a84aaSRasesh Mody *p_tx_coal = (u16)(coalesce << timer_res);
2280823a84aaSRasesh Mody
2281823a84aaSRasesh Mody return ECORE_SUCCESS;
2282823a84aaSRasesh Mody }
2283823a84aaSRasesh Mody
2284823a84aaSRasesh Mody enum _ecore_status_t
ecore_get_queue_coalesce(struct ecore_hwfn * p_hwfn,u16 * p_coal,void * handle)2285823a84aaSRasesh Mody ecore_get_queue_coalesce(struct ecore_hwfn *p_hwfn, u16 *p_coal,
2286823a84aaSRasesh Mody void *handle)
2287823a84aaSRasesh Mody {
2288823a84aaSRasesh Mody struct ecore_queue_cid *p_cid = (struct ecore_queue_cid *)handle;
2289823a84aaSRasesh Mody enum _ecore_status_t rc = ECORE_SUCCESS;
2290823a84aaSRasesh Mody struct ecore_ptt *p_ptt;
2291823a84aaSRasesh Mody
2292823a84aaSRasesh Mody if (IS_VF(p_hwfn->p_dev)) {
2293823a84aaSRasesh Mody rc = ecore_vf_pf_get_coalesce(p_hwfn, p_coal, p_cid);
2294823a84aaSRasesh Mody if (rc != ECORE_SUCCESS)
2295823a84aaSRasesh Mody DP_NOTICE(p_hwfn, false,
2296823a84aaSRasesh Mody "Unable to read queue calescing\n");
2297823a84aaSRasesh Mody
2298823a84aaSRasesh Mody return rc;
2299823a84aaSRasesh Mody }
2300823a84aaSRasesh Mody
2301823a84aaSRasesh Mody p_ptt = ecore_ptt_acquire(p_hwfn);
2302823a84aaSRasesh Mody if (!p_ptt)
2303823a84aaSRasesh Mody return ECORE_AGAIN;
2304823a84aaSRasesh Mody
2305823a84aaSRasesh Mody if (p_cid->b_is_rx) {
2306823a84aaSRasesh Mody rc = ecore_get_rxq_coalesce(p_hwfn, p_ptt, p_cid, p_coal);
2307823a84aaSRasesh Mody if (rc != ECORE_SUCCESS)
2308823a84aaSRasesh Mody goto out;
2309823a84aaSRasesh Mody } else {
2310823a84aaSRasesh Mody rc = ecore_get_txq_coalesce(p_hwfn, p_ptt, p_cid, p_coal);
2311823a84aaSRasesh Mody if (rc != ECORE_SUCCESS)
2312823a84aaSRasesh Mody goto out;
2313823a84aaSRasesh Mody }
2314823a84aaSRasesh Mody
2315823a84aaSRasesh Mody out:
2316823a84aaSRasesh Mody ecore_ptt_release(p_hwfn, p_ptt);
2317823a84aaSRasesh Mody
2318823a84aaSRasesh Mody return rc;
2319823a84aaSRasesh Mody }
232076d37490SRasesh Mody
232176d37490SRasesh Mody enum _ecore_status_t
ecore_eth_tx_queue_maxrate(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_queue_cid * p_cid,u32 rate)232276d37490SRasesh Mody ecore_eth_tx_queue_maxrate(struct ecore_hwfn *p_hwfn,
232376d37490SRasesh Mody struct ecore_ptt *p_ptt,
232476d37490SRasesh Mody struct ecore_queue_cid *p_cid, u32 rate)
232576d37490SRasesh Mody {
23263b307c55SRasesh Mody u16 rl_id;
232776d37490SRasesh Mody u8 vport;
232876d37490SRasesh Mody
232976d37490SRasesh Mody vport = (u8)ecore_get_qm_vport_idx_rl(p_hwfn, p_cid->rel.queue_id);
233076d37490SRasesh Mody
233176d37490SRasesh Mody DP_VERBOSE(p_hwfn, ECORE_MSG_LINK,
233276d37490SRasesh Mody "About to rate limit qm vport %d for queue %d with rate %d\n",
233376d37490SRasesh Mody vport, p_cid->rel.queue_id, rate);
233476d37490SRasesh Mody
23353b307c55SRasesh Mody rl_id = vport; /* The "rl_id" is set as the "vport_id" */
23363b307c55SRasesh Mody return ecore_init_global_rl(p_hwfn, p_ptt, rl_id, rate);
233776d37490SRasesh Mody }
23380b855a34SRasesh Mody
23390b855a34SRasesh Mody #define RSS_TSTORM_UPDATE_STATUS_MAX_POLL_COUNT 100
23400b855a34SRasesh Mody #define RSS_TSTORM_UPDATE_STATUS_POLL_PERIOD_US 1
23410b855a34SRasesh Mody
23420b855a34SRasesh Mody enum _ecore_status_t
ecore_update_eth_rss_ind_table_entry(struct ecore_hwfn * p_hwfn,u8 vport_id,u8 ind_table_index,u16 ind_table_value)23430b855a34SRasesh Mody ecore_update_eth_rss_ind_table_entry(struct ecore_hwfn *p_hwfn,
23440b855a34SRasesh Mody u8 vport_id,
23450b855a34SRasesh Mody u8 ind_table_index,
23460b855a34SRasesh Mody u16 ind_table_value)
23470b855a34SRasesh Mody {
23480b855a34SRasesh Mody struct eth_tstorm_rss_update_data update_data = { 0 };
23490b855a34SRasesh Mody void OSAL_IOMEM *addr = OSAL_NULL;
23500b855a34SRasesh Mody enum _ecore_status_t rc;
23510b855a34SRasesh Mody u8 abs_vport_id;
23520b855a34SRasesh Mody u32 cnt = 0;
23530b855a34SRasesh Mody
23540b855a34SRasesh Mody OSAL_BUILD_BUG_ON(sizeof(update_data) != sizeof(u64));
23550b855a34SRasesh Mody
23560b855a34SRasesh Mody rc = ecore_fw_vport(p_hwfn, vport_id, &abs_vport_id);
23570b855a34SRasesh Mody if (rc != ECORE_SUCCESS)
23580b855a34SRasesh Mody return rc;
23590b855a34SRasesh Mody
23603b307c55SRasesh Mody addr = (u8 *)p_hwfn->regview + GTT_BAR0_MAP_REG_TSDM_RAM +
23610b855a34SRasesh Mody TSTORM_ETH_RSS_UPDATE_OFFSET(p_hwfn->rel_pf_id);
23620b855a34SRasesh Mody
23630b855a34SRasesh Mody *(u64 *)(&update_data) = DIRECT_REG_RD64(p_hwfn, addr);
23640b855a34SRasesh Mody
23650b855a34SRasesh Mody for (cnt = 0; update_data.valid &&
23660b855a34SRasesh Mody cnt < RSS_TSTORM_UPDATE_STATUS_MAX_POLL_COUNT; cnt++) {
23670b855a34SRasesh Mody OSAL_UDELAY(RSS_TSTORM_UPDATE_STATUS_POLL_PERIOD_US);
23680b855a34SRasesh Mody *(u64 *)(&update_data) = DIRECT_REG_RD64(p_hwfn, addr);
23690b855a34SRasesh Mody }
23700b855a34SRasesh Mody
23710b855a34SRasesh Mody if (update_data.valid) {
23720b855a34SRasesh Mody DP_NOTICE(p_hwfn, true,
23730b855a34SRasesh Mody "rss update valid status is not clear! valid=0x%x vport id=%d ind_Table_idx=%d ind_table_value=%d.\n",
23740b855a34SRasesh Mody update_data.valid, vport_id, ind_table_index,
23750b855a34SRasesh Mody ind_table_value);
23760b855a34SRasesh Mody
23770b855a34SRasesh Mody return ECORE_AGAIN;
23780b855a34SRasesh Mody }
23790b855a34SRasesh Mody
23800b855a34SRasesh Mody update_data.valid = 1;
23810b855a34SRasesh Mody update_data.ind_table_index = ind_table_index;
23820b855a34SRasesh Mody update_data.ind_table_value = ind_table_value;
23830b855a34SRasesh Mody update_data.vport_id = abs_vport_id;
23840b855a34SRasesh Mody
23850b855a34SRasesh Mody DIRECT_REG_WR64(p_hwfn, addr, *(u64 *)(&update_data));
23860b855a34SRasesh Mody
23870b855a34SRasesh Mody return ECORE_SUCCESS;
23880b855a34SRasesh Mody }
2389