1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, v.1, (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://opensource.org/licenses/CDDL-1.0.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2014-2017 Cavium, Inc.
24 * The contents of this file are subject to the terms of the Common Development
25 * and Distribution License, v.1, (the "License").
26
27 * You may not use this file except in compliance with the License.
28
29 * You can obtain a copy of the License at available
30 * at http://opensource.org/licenses/CDDL-1.0
31
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
34 */
35
36 #include "bcm_osal.h"
37
38 #include "ecore.h"
39 #include "ecore_status.h"
40 #include "ecore_hsi_eth.h"
41 #include "ecore_chain.h"
42 #include "ecore_spq.h"
43 #include "ecore_init_fw_funcs.h"
44 #include "ecore_cxt.h"
45 #include "ecore_l2.h"
46 #include "ecore_sp_commands.h"
47 #include "ecore_gtt_reg_addr.h"
48 #include "ecore_iro.h"
49 #include "reg_addr.h"
50 #include "ecore_int.h"
51 #include "ecore_hw.h"
52 #include "ecore_vf.h"
53 #include "ecore_sriov.h"
54 #include "ecore_mcp.h"
55
56 #define ECORE_MAX_SGES_NUM 16
57 #define CRC32_POLY 0x1edc6f41
58
59 struct ecore_l2_info {
60 u32 queues;
61 unsigned long **pp_qid_usage;
62
63 /* The lock is meant to synchronize access to the qid usage */
64 osal_mutex_t lock;
65 };
66
ecore_l2_alloc(struct ecore_hwfn * p_hwfn)67 enum _ecore_status_t ecore_l2_alloc(struct ecore_hwfn *p_hwfn)
68 {
69 struct ecore_l2_info *p_l2_info;
70 unsigned long **pp_qids;
71 u32 i;
72
73 if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
74 return ECORE_SUCCESS;
75
76 p_l2_info = OSAL_VZALLOC(p_hwfn->p_dev, sizeof(*p_l2_info));
77 if (!p_l2_info)
78 return ECORE_NOMEM;
79 p_hwfn->p_l2_info = p_l2_info;
80
81 if (IS_PF(p_hwfn->p_dev)) {
82 p_l2_info->queues = RESC_NUM(p_hwfn, ECORE_L2_QUEUE);
83 } else {
84 u8 rx = 0, tx = 0;
85
86 ecore_vf_get_num_rxqs(p_hwfn, &rx);
87 ecore_vf_get_num_txqs(p_hwfn, &tx);
88
89 p_l2_info->queues = (u32)OSAL_MAX_T(u8, rx, tx);
90 }
91
92 pp_qids = OSAL_VZALLOC(p_hwfn->p_dev,
93 sizeof(unsigned long *) *
94 p_l2_info->queues);
95 if (pp_qids == OSAL_NULL)
96 return ECORE_NOMEM;
97 p_l2_info->pp_qid_usage = pp_qids;
98
99 for (i = 0; i < p_l2_info->queues; i++) {
100 pp_qids[i] = OSAL_VZALLOC(p_hwfn->p_dev,
101 MAX_QUEUES_PER_QZONE / 8);
102 if (pp_qids[i] == OSAL_NULL)
103 return ECORE_NOMEM;
104 }
105
106 #ifdef CONFIG_ECORE_LOCK_ALLOC
107 OSAL_MUTEX_ALLOC(p_hwfn, &p_l2_info->lock);
108 #endif
109
110 return ECORE_SUCCESS;
111 }
112
ecore_l2_setup(struct ecore_hwfn * p_hwfn)113 void ecore_l2_setup(struct ecore_hwfn *p_hwfn)
114 {
115 if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
116 return;
117
118 OSAL_MUTEX_INIT(&p_hwfn->p_l2_info->lock);
119 }
120
ecore_l2_free(struct ecore_hwfn * p_hwfn)121 void ecore_l2_free(struct ecore_hwfn *p_hwfn)
122 {
123 u32 i;
124
125 if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
126 return;
127
128 if (p_hwfn->p_l2_info == OSAL_NULL)
129 return;
130
131 if (p_hwfn->p_l2_info->pp_qid_usage == OSAL_NULL)
132 goto out_l2_info;
133
134 /* Free until hit first uninitialized entry */
135 for (i = 0; i < p_hwfn->p_l2_info->queues; i++) {
136 if (p_hwfn->p_l2_info->pp_qid_usage[i] == OSAL_NULL)
137 break;
138 OSAL_VFREE(p_hwfn->p_dev,
139 p_hwfn->p_l2_info->pp_qid_usage[i]);
140 }
141
142 #ifdef CONFIG_ECORE_LOCK_ALLOC
143 /* Lock is last to initialize, if everything else was */
144 if (i == p_hwfn->p_l2_info->queues)
145 OSAL_MUTEX_DEALLOC(&p_hwfn->p_l2_info->lock);
146 #endif
147
148 OSAL_VFREE(p_hwfn->p_dev, p_hwfn->p_l2_info->pp_qid_usage);
149
150 out_l2_info:
151 OSAL_VFREE(p_hwfn->p_dev, p_hwfn->p_l2_info);
152 p_hwfn->p_l2_info = OSAL_NULL;
153 }
154
155 /* TODO - we'll need locking around these... */
ecore_eth_queue_qid_usage_add(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)156 static bool ecore_eth_queue_qid_usage_add(struct ecore_hwfn *p_hwfn,
157 struct ecore_queue_cid *p_cid)
158 {
159 struct ecore_l2_info *p_l2_info = p_hwfn->p_l2_info;
160 u16 queue_id = p_cid->rel.queue_id;
161 bool b_rc = true;
162 u8 first;
163
164 OSAL_MUTEX_ACQUIRE(&p_l2_info->lock);
165
166 if (queue_id > p_l2_info->queues) {
167 DP_NOTICE(p_hwfn, true,
168 "Requested to increase usage for qzone %04x out of %08x\n",
169 queue_id, p_l2_info->queues);
170 b_rc = false;
171 goto out;
172 }
173
174 first = (u8)OSAL_FIND_FIRST_ZERO_BIT(p_l2_info->pp_qid_usage[queue_id],
175 MAX_QUEUES_PER_QZONE);
176 if (first >= MAX_QUEUES_PER_QZONE) {
177 b_rc = false;
178 goto out;
179 }
180
181 OSAL_SET_BIT(first, p_l2_info->pp_qid_usage[queue_id]);
182 p_cid->qid_usage_idx = first;
183
184 out:
185 OSAL_MUTEX_RELEASE(&p_l2_info->lock);
186 return b_rc;
187 }
188
ecore_eth_queue_qid_usage_del(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)189 static void ecore_eth_queue_qid_usage_del(struct ecore_hwfn *p_hwfn,
190 struct ecore_queue_cid *p_cid)
191 {
192 OSAL_MUTEX_ACQUIRE(&p_hwfn->p_l2_info->lock);
193
194 OSAL_CLEAR_BIT(p_cid->qid_usage_idx,
195 p_hwfn->p_l2_info->pp_qid_usage[p_cid->rel.queue_id]);
196
197 OSAL_MUTEX_RELEASE(&p_hwfn->p_l2_info->lock);
198 }
199
ecore_eth_queue_cid_release(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)200 void ecore_eth_queue_cid_release(struct ecore_hwfn *p_hwfn,
201 struct ecore_queue_cid *p_cid)
202 {
203 bool b_legacy_vf = !!(p_cid->vf_legacy &
204 ECORE_QCID_LEGACY_VF_CID);
205
206 /* VFs' CIDs are 0-based in PF-view, and uninitialized on VF.
207 * For legacy vf-queues, the CID doesn't go through here.
208 */
209 if (IS_PF(p_hwfn->p_dev) && !b_legacy_vf)
210 _ecore_cxt_release_cid(p_hwfn, p_cid->cid, p_cid->vfid);
211
212 /* VFs maintain the index inside queue-zone on their own */
213 if (p_cid->vfid == ECORE_QUEUE_CID_PF)
214 ecore_eth_queue_qid_usage_del(p_hwfn, p_cid);
215
216 OSAL_VFREE(p_hwfn->p_dev, p_cid);
217 }
218
219 /* The internal is only meant to be directly called by PFs initializeing CIDs
220 * for their VFs.
221 */
222 static struct ecore_queue_cid *
_ecore_eth_queue_to_cid(struct ecore_hwfn * p_hwfn,u16 opaque_fid,u32 cid,struct ecore_queue_start_common_params * p_params,struct ecore_queue_cid_vf_params * p_vf_params)223 _ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn,
224 u16 opaque_fid, u32 cid,
225 struct ecore_queue_start_common_params *p_params,
226 struct ecore_queue_cid_vf_params *p_vf_params)
227 {
228 struct ecore_queue_cid *p_cid;
229 enum _ecore_status_t rc;
230
231 p_cid = OSAL_VZALLOC(p_hwfn->p_dev, sizeof(*p_cid));
232 if (p_cid == OSAL_NULL)
233 return OSAL_NULL;
234
235 p_cid->opaque_fid = opaque_fid;
236 p_cid->cid = cid;
237 p_cid->p_owner = p_hwfn;
238
239 /* Fill in parameters */
240 p_cid->rel.vport_id = p_params->vport_id;
241 p_cid->rel.queue_id = p_params->queue_id;
242 p_cid->rel.stats_id = p_params->stats_id;
243 p_cid->sb_igu_id = p_params->p_sb->igu_sb_id;
244 p_cid->sb_idx = p_params->sb_idx;
245
246 /* Fill-in bits related to VFs' queues if information was provided */
247 if (p_vf_params != OSAL_NULL) {
248 p_cid->vfid = p_vf_params->vfid;
249 p_cid->vf_qid = p_vf_params->vf_qid;
250 p_cid->vf_legacy = p_vf_params->vf_legacy;
251 } else {
252 p_cid->vfid = ECORE_QUEUE_CID_PF;
253 }
254
255 /* Don't try calculating the absolute indices for VFs */
256 if (IS_VF(p_hwfn->p_dev)) {
257 p_cid->abs = p_cid->rel;
258
259 goto out;
260 }
261
262 /* Calculate the engine-absolute indices of the resources.
263 * The would guarantee they're valid later on.
264 * In some cases [SBs] we already have the right values.
265 */
266 rc = ecore_fw_vport(p_hwfn, p_cid->rel.vport_id, &p_cid->abs.vport_id);
267 if (rc != ECORE_SUCCESS)
268 goto fail;
269
270 rc = ecore_fw_l2_queue(p_hwfn, p_cid->rel.queue_id,
271 &p_cid->abs.queue_id);
272 if (rc != ECORE_SUCCESS)
273 goto fail;
274
275 /* In case of a PF configuring its VF's queues, the stats-id is already
276 * absolute [since there's a single index that's suitable per-VF].
277 */
278 if (p_cid->vfid == ECORE_QUEUE_CID_PF) {
279 rc = ecore_fw_vport(p_hwfn, p_cid->rel.stats_id,
280 &p_cid->abs.stats_id);
281 if (rc != ECORE_SUCCESS)
282 goto fail;
283 } else {
284 p_cid->abs.stats_id = p_cid->rel.stats_id;
285 }
286
287 out:
288 /* VF-images have provided the qid_usage_idx on their own.
289 * Otherwise, we need to allocate a unique one.
290 */
291 if (!p_vf_params) {
292 if (!ecore_eth_queue_qid_usage_add(p_hwfn, p_cid))
293 goto fail;
294 } else {
295 p_cid->qid_usage_idx = p_vf_params->qid_usage_idx;
296 }
297
298 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
299 "opaque_fid: %04x CID %08x vport %02x [%02x] qzone %04x.%02x [%04x] stats %02x [%02x] SB %04x PI %02x\n",
300 p_cid->opaque_fid, p_cid->cid,
301 p_cid->rel.vport_id, p_cid->abs.vport_id,
302 p_cid->rel.queue_id, p_cid->qid_usage_idx,
303 p_cid->abs.queue_id,
304 p_cid->rel.stats_id, p_cid->abs.stats_id,
305 p_cid->sb_igu_id, p_cid->sb_idx);
306
307 return p_cid;
308
309 fail:
310 OSAL_VFREE(p_hwfn->p_dev, p_cid);
311 return OSAL_NULL;
312 }
313
314 struct ecore_queue_cid *
ecore_eth_queue_to_cid(struct ecore_hwfn * p_hwfn,u16 opaque_fid,struct ecore_queue_start_common_params * p_params,struct ecore_queue_cid_vf_params * p_vf_params)315 ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
316 struct ecore_queue_start_common_params *p_params,
317 struct ecore_queue_cid_vf_params *p_vf_params)
318 {
319 struct ecore_queue_cid *p_cid;
320 u8 vfid = ECORE_CXT_PF_CID;
321 bool b_legacy_vf = false;
322 u32 cid = 0;
323
324 /* In case of legacy VFs, The CID can be derived from the additional
325 * VF parameters - the VF assumes queue X uses CID X, so we can simply
326 * use the vf_qid for this purpose as well.
327 */
328 if (p_vf_params) {
329 vfid = p_vf_params->vfid;
330
331 if (p_vf_params->vf_legacy &
332 ECORE_QCID_LEGACY_VF_CID) {
333 b_legacy_vf = true;
334 cid = p_vf_params->vf_qid;
335 }
336 }
337
338 /* Get a unique firmware CID for this queue, in case it's a PF.
339 * VF's don't need a CID as the queue configuration will be done
340 * by PF.
341 */
342 if (IS_PF(p_hwfn->p_dev) && !b_legacy_vf) {
343 if (_ecore_cxt_acquire_cid(p_hwfn, PROTOCOLID_ETH,
344 &cid, vfid) != ECORE_SUCCESS) {
345 DP_NOTICE(p_hwfn, true, "Failed to acquire cid\n");
346 return OSAL_NULL;
347 }
348 }
349
350 p_cid = _ecore_eth_queue_to_cid(p_hwfn, opaque_fid, cid,
351 p_params, p_vf_params);
352 if ((p_cid == OSAL_NULL) && IS_PF(p_hwfn->p_dev) && !b_legacy_vf)
353 _ecore_cxt_release_cid(p_hwfn, cid, vfid);
354
355 return p_cid;
356 }
357
358 static struct ecore_queue_cid *
ecore_eth_queue_to_cid_pf(struct ecore_hwfn * p_hwfn,u16 opaque_fid,struct ecore_queue_start_common_params * p_params)359 ecore_eth_queue_to_cid_pf(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
360 struct ecore_queue_start_common_params *p_params)
361 {
362 return ecore_eth_queue_to_cid(p_hwfn, opaque_fid, p_params, OSAL_NULL);
363 }
364
ecore_sp_eth_vport_start(struct ecore_hwfn * p_hwfn,struct ecore_sp_vport_start_params * p_params)365 enum _ecore_status_t ecore_sp_eth_vport_start(struct ecore_hwfn *p_hwfn,
366 struct ecore_sp_vport_start_params *p_params)
367 {
368 struct vport_start_ramrod_data *p_ramrod = OSAL_NULL;
369 struct ecore_spq_entry *p_ent = OSAL_NULL;
370 struct ecore_sp_init_data init_data;
371 u16 rx_mode = 0, tx_err = 0;
372 u8 abs_vport_id = 0;
373 enum _ecore_status_t rc = ECORE_NOTIMPL;
374
375 rc = ecore_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
376 if (rc != ECORE_SUCCESS)
377 return rc;
378
379 /* Get SPQ entry */
380 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
381 init_data.cid = ecore_spq_get_cid(p_hwfn);
382 init_data.opaque_fid = p_params->opaque_fid;
383 init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
384
385 rc = ecore_sp_init_request(p_hwfn, &p_ent,
386 ETH_RAMROD_VPORT_START,
387 PROTOCOLID_ETH, &init_data);
388 if (rc != ECORE_SUCCESS)
389 return rc;
390
391 p_ramrod = &p_ent->ramrod.vport_start;
392 p_ramrod->vport_id = abs_vport_id;
393
394 p_ramrod->mtu = OSAL_CPU_TO_LE16(p_params->mtu);
395 p_ramrod->inner_vlan_removal_en = p_params->remove_inner_vlan;
396 p_ramrod->handle_ptp_pkts = p_params->handle_ptp_pkts;
397 p_ramrod->drop_ttl0_en = p_params->drop_ttl0;
398 p_ramrod->untagged = p_params->only_untagged;
399 p_ramrod->zero_placement_offset = p_params->zero_placement_offset;
400
401 SET_FIELD(rx_mode, ETH_VPORT_RX_MODE_UCAST_DROP_ALL, 1);
402 SET_FIELD(rx_mode, ETH_VPORT_RX_MODE_MCAST_DROP_ALL, 1);
403
404 p_ramrod->rx_mode.state = OSAL_CPU_TO_LE16(rx_mode);
405
406 /* Handle requests for strict behavior on transmission errors */
407 SET_FIELD(tx_err, ETH_TX_ERR_VALS_ILLEGAL_VLAN_MODE,
408 p_params->b_err_illegal_vlan_mode ?
409 ETH_TX_ERR_ASSERT_MALICIOUS : 0);
410 SET_FIELD(tx_err, ETH_TX_ERR_VALS_PACKET_TOO_SMALL,
411 p_params->b_err_small_pkt ?
412 ETH_TX_ERR_ASSERT_MALICIOUS : 0);
413 SET_FIELD(tx_err, ETH_TX_ERR_VALS_ANTI_SPOOFING_ERR,
414 p_params->b_err_anti_spoof ?
415 ETH_TX_ERR_ASSERT_MALICIOUS : 0);
416 SET_FIELD(tx_err, ETH_TX_ERR_VALS_ILLEGAL_INBAND_TAGS,
417 p_params->b_err_illegal_inband_mode ?
418 ETH_TX_ERR_ASSERT_MALICIOUS : 0);
419 SET_FIELD(tx_err, ETH_TX_ERR_VALS_VLAN_INSERTION_W_INBAND_TAG,
420 p_params->b_err_vlan_insert_with_inband ?
421 ETH_TX_ERR_ASSERT_MALICIOUS : 0);
422 SET_FIELD(tx_err, ETH_TX_ERR_VALS_MTU_VIOLATION,
423 p_params->b_err_big_pkt ?
424 ETH_TX_ERR_ASSERT_MALICIOUS : 0);
425 SET_FIELD(tx_err, ETH_TX_ERR_VALS_ILLEGAL_CONTROL_FRAME,
426 p_params->b_err_ctrl_frame ?
427 ETH_TX_ERR_ASSERT_MALICIOUS : 0);
428 p_ramrod->tx_err_behav.values = OSAL_CPU_TO_LE16(tx_err);
429
430 /* TPA related fields */
431 OSAL_MEMSET(&p_ramrod->tpa_param, 0,
432 sizeof(struct eth_vport_tpa_param));
433 p_ramrod->tpa_param.max_buff_num = p_params->max_buffers_per_cqe;
434
435 switch (p_params->tpa_mode) {
436 case ECORE_TPA_MODE_GRO:
437 p_ramrod->tpa_param.tpa_max_aggs_num = ETH_TPA_MAX_AGGS_NUM;
438 p_ramrod->tpa_param.tpa_max_size = (u16)-1;
439 p_ramrod->tpa_param.tpa_min_size_to_cont = p_params->mtu/2;
440 p_ramrod->tpa_param.tpa_min_size_to_start = p_params->mtu/2;
441 p_ramrod->tpa_param.tpa_ipv4_en_flg = 1;
442 p_ramrod->tpa_param.tpa_ipv6_en_flg = 1;
443 p_ramrod->tpa_param.tpa_ipv4_tunn_en_flg = 1;
444 p_ramrod->tpa_param.tpa_ipv6_tunn_en_flg = 1;
445 p_ramrod->tpa_param.tpa_pkt_split_flg = 1;
446 p_ramrod->tpa_param.tpa_gro_consistent_flg = 1;
447 break;
448 default:
449 break;
450 }
451
452 p_ramrod->tx_switching_en = p_params->tx_switching;
453 #ifndef ASIC_ONLY
454 if (CHIP_REV_IS_SLOW(p_hwfn->p_dev))
455 p_ramrod->tx_switching_en = 0;
456 #endif
457
458 p_ramrod->ctl_frame_mac_check_en = !!p_params->check_mac;
459 p_ramrod->ctl_frame_ethtype_check_en = !!p_params->check_ethtype;
460
461 /* Software Function ID in hwfn (PFs are 0 - 15, VFs are 16 - 135) */
462 p_ramrod->sw_fid = ecore_concrete_to_sw_fid(p_hwfn->p_dev,
463 p_params->concrete_fid);
464
465 return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
466 }
467
ecore_sp_vport_start(struct ecore_hwfn * p_hwfn,struct ecore_sp_vport_start_params * p_params)468 enum _ecore_status_t ecore_sp_vport_start(struct ecore_hwfn *p_hwfn,
469 struct ecore_sp_vport_start_params *p_params)
470 {
471 if (IS_VF(p_hwfn->p_dev))
472 return ecore_vf_pf_vport_start(p_hwfn, p_params->vport_id,
473 p_params->mtu,
474 p_params->remove_inner_vlan,
475 p_params->tpa_mode,
476 p_params->max_buffers_per_cqe,
477 p_params->only_untagged);
478
479 return ecore_sp_eth_vport_start(p_hwfn, p_params);
480 }
481
482 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)483 ecore_sp_vport_update_rss(struct ecore_hwfn *p_hwfn,
484 struct vport_update_ramrod_data *p_ramrod,
485 struct ecore_rss_params *p_rss)
486 {
487 struct eth_vport_rss_config *p_config;
488 int i, table_size;
489 enum _ecore_status_t rc = ECORE_SUCCESS;
490
491 if (!p_rss) {
492 p_ramrod->common.update_rss_flg = 0;
493 return rc;
494 }
495 p_config = &p_ramrod->rss_config;
496
497 OSAL_BUILD_BUG_ON(ECORE_RSS_IND_TABLE_SIZE !=
498 ETH_RSS_IND_TABLE_ENTRIES_NUM);
499
500 rc = ecore_fw_rss_eng(p_hwfn, p_rss->rss_eng_id,
501 &p_config->rss_id);
502 if (rc != ECORE_SUCCESS)
503 return rc;
504
505 p_ramrod->common.update_rss_flg = p_rss->update_rss_config;
506 p_config->update_rss_capabilities = p_rss->update_rss_capabilities;
507 p_config->update_rss_ind_table = p_rss->update_rss_ind_table;
508 p_config->update_rss_key = p_rss->update_rss_key;
509
510 p_config->rss_mode = p_rss->rss_enable ?
511 ETH_VPORT_RSS_MODE_REGULAR :
512 ETH_VPORT_RSS_MODE_DISABLED;
513
514 p_config->capabilities = 0;
515
516 SET_FIELD(p_config->capabilities,
517 ETH_VPORT_RSS_CONFIG_IPV4_CAPABILITY,
518 !!(p_rss->rss_caps & ECORE_RSS_IPV4));
519 SET_FIELD(p_config->capabilities,
520 ETH_VPORT_RSS_CONFIG_IPV6_CAPABILITY,
521 !!(p_rss->rss_caps & ECORE_RSS_IPV6));
522 SET_FIELD(p_config->capabilities,
523 ETH_VPORT_RSS_CONFIG_IPV4_TCP_CAPABILITY,
524 !!(p_rss->rss_caps & ECORE_RSS_IPV4_TCP));
525 SET_FIELD(p_config->capabilities,
526 ETH_VPORT_RSS_CONFIG_IPV6_TCP_CAPABILITY,
527 !!(p_rss->rss_caps & ECORE_RSS_IPV6_TCP));
528 SET_FIELD(p_config->capabilities,
529 ETH_VPORT_RSS_CONFIG_IPV4_UDP_CAPABILITY,
530 !!(p_rss->rss_caps & ECORE_RSS_IPV4_UDP));
531 SET_FIELD(p_config->capabilities,
532 ETH_VPORT_RSS_CONFIG_IPV6_UDP_CAPABILITY,
533 !!(p_rss->rss_caps & ECORE_RSS_IPV6_UDP));
534 p_config->tbl_size = p_rss->rss_table_size_log;
535 p_config->capabilities =
536 OSAL_CPU_TO_LE16(p_config->capabilities);
537
538 DP_VERBOSE(p_hwfn, ECORE_MSG_IFUP,
539 "update rss flag %d, rss_mode = %d, update_caps = %d, capabilities = %d, update_ind = %d, update_rss_key = %d\n",
540 p_ramrod->common.update_rss_flg,
541 p_config->rss_mode,
542 p_config->update_rss_capabilities,
543 p_config->capabilities,
544 p_config->update_rss_ind_table,
545 p_config->update_rss_key);
546
547 table_size = OSAL_MIN_T(int, ECORE_RSS_IND_TABLE_SIZE,
548 1 << p_config->tbl_size);
549 for (i = 0; i < table_size; i++) {
550 struct ecore_queue_cid *p_queue = p_rss->rss_ind_table[i];
551
552 if (!p_queue)
553 return ECORE_INVAL;
554
555 p_config->indirection_table[i] =
556 OSAL_CPU_TO_LE16(p_queue->abs.queue_id);
557 }
558
559 DP_VERBOSE(p_hwfn, ECORE_MSG_IFUP,
560 "Configured RSS indirection table [%d entries]:\n",
561 table_size);
562 for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i += 0x10) {
563 DP_VERBOSE(p_hwfn, ECORE_MSG_IFUP,
564 "%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n",
565 OSAL_LE16_TO_CPU(p_config->indirection_table[i]),
566 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 1]),
567 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 2]),
568 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 3]),
569 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 4]),
570 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 5]),
571 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 6]),
572 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 7]),
573 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 8]),
574 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 9]),
575 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 10]),
576 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 11]),
577 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 12]),
578 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 13]),
579 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 14]),
580 OSAL_LE16_TO_CPU(p_config->indirection_table[i + 15]));
581 }
582
583 for (i = 0; i < 10; i++)
584 p_config->rss_key[i] = OSAL_CPU_TO_LE32(p_rss->rss_key[i]);
585
586 return rc;
587 }
588
589 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)590 ecore_sp_update_accept_mode(struct ecore_hwfn *p_hwfn,
591 struct vport_update_ramrod_data *p_ramrod,
592 struct ecore_filter_accept_flags accept_flags)
593 {
594 p_ramrod->common.update_rx_mode_flg =
595 accept_flags.update_rx_mode_config;
596 p_ramrod->common.update_tx_mode_flg =
597 accept_flags.update_tx_mode_config;
598
599 #ifndef ASIC_ONLY
600 /* On B0 emulation we cannot enable Tx, since this would cause writes
601 * to PVFC HW block which isn't implemented in emulation.
602 */
603 if (CHIP_REV_IS_SLOW(p_hwfn->p_dev)) {
604 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
605 "Non-Asic - prevent Tx mode in vport update\n");
606 p_ramrod->common.update_tx_mode_flg = 0;
607 }
608 #endif
609
610 /* Set Rx mode accept flags */
611 if (p_ramrod->common.update_rx_mode_flg) {
612 u8 accept_filter = accept_flags.rx_accept_filter;
613 u16 state = 0;
614
615 SET_FIELD(state, ETH_VPORT_RX_MODE_UCAST_DROP_ALL,
616 !(!!(accept_filter & ECORE_ACCEPT_UCAST_MATCHED) ||
617 !!(accept_filter & ECORE_ACCEPT_UCAST_UNMATCHED)));
618
619 SET_FIELD(state, ETH_VPORT_RX_MODE_UCAST_ACCEPT_UNMATCHED,
620 !!(accept_filter & ECORE_ACCEPT_UCAST_UNMATCHED));
621
622 SET_FIELD(state, ETH_VPORT_RX_MODE_MCAST_DROP_ALL,
623 !(!!(accept_filter & ECORE_ACCEPT_MCAST_MATCHED) ||
624 !!(accept_filter & ECORE_ACCEPT_MCAST_UNMATCHED)));
625
626 SET_FIELD(state, ETH_VPORT_RX_MODE_MCAST_ACCEPT_ALL,
627 (!!(accept_filter & ECORE_ACCEPT_MCAST_MATCHED) &&
628 !!(accept_filter & ECORE_ACCEPT_MCAST_UNMATCHED)));
629
630 SET_FIELD(state, ETH_VPORT_RX_MODE_BCAST_ACCEPT_ALL,
631 !!(accept_filter & ECORE_ACCEPT_BCAST));
632
633 p_ramrod->rx_mode.state = OSAL_CPU_TO_LE16(state);
634 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
635 "vport[%02x] p_ramrod->rx_mode.state = 0x%x\n",
636 p_ramrod->common.vport_id, state);
637 }
638
639 /* Set Tx mode accept flags */
640 if (p_ramrod->common.update_tx_mode_flg) {
641 u8 accept_filter = accept_flags.tx_accept_filter;
642 u16 state = 0;
643
644 SET_FIELD(state, ETH_VPORT_TX_MODE_UCAST_DROP_ALL,
645 !!(accept_filter & ECORE_ACCEPT_NONE));
646
647 SET_FIELD(state, ETH_VPORT_TX_MODE_MCAST_DROP_ALL,
648 !!(accept_filter & ECORE_ACCEPT_NONE));
649
650 SET_FIELD(state, ETH_VPORT_TX_MODE_MCAST_ACCEPT_ALL,
651 (!!(accept_filter & ECORE_ACCEPT_MCAST_MATCHED) &&
652 !!(accept_filter & ECORE_ACCEPT_MCAST_UNMATCHED)));
653
654 SET_FIELD(state, ETH_VPORT_TX_MODE_BCAST_ACCEPT_ALL,
655 !!(accept_filter & ECORE_ACCEPT_BCAST));
656
657 p_ramrod->tx_mode.state = OSAL_CPU_TO_LE16(state);
658 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
659 "vport[%02x] p_ramrod->tx_mode.state = 0x%x\n",
660 p_ramrod->common.vport_id, state);
661 }
662 }
663
664 static void
ecore_sp_vport_update_sge_tpa(struct ecore_hwfn * p_hwfn,struct vport_update_ramrod_data * p_ramrod,struct ecore_sge_tpa_params * p_params)665 ecore_sp_vport_update_sge_tpa(struct ecore_hwfn *p_hwfn,
666 struct vport_update_ramrod_data *p_ramrod,
667 struct ecore_sge_tpa_params *p_params)
668 {
669 struct eth_vport_tpa_param *p_tpa;
670
671 if (!p_params) {
672 p_ramrod->common.update_tpa_param_flg = 0;
673 p_ramrod->common.update_tpa_en_flg = 0;
674 p_ramrod->common.update_tpa_param_flg = 0;
675 return;
676 }
677
678 p_ramrod->common.update_tpa_en_flg = p_params->update_tpa_en_flg;
679 p_tpa = &p_ramrod->tpa_param;
680 p_tpa->tpa_ipv4_en_flg = p_params->tpa_ipv4_en_flg;
681 p_tpa->tpa_ipv6_en_flg = p_params->tpa_ipv6_en_flg;
682 p_tpa->tpa_ipv4_tunn_en_flg = p_params->tpa_ipv4_tunn_en_flg;
683 p_tpa->tpa_ipv6_tunn_en_flg = p_params->tpa_ipv6_tunn_en_flg;
684
685 p_ramrod->common.update_tpa_param_flg = p_params->update_tpa_param_flg;
686 p_tpa->max_buff_num = p_params->max_buffers_per_cqe;
687 p_tpa->tpa_pkt_split_flg = p_params->tpa_pkt_split_flg;
688 p_tpa->tpa_hdr_data_split_flg = p_params->tpa_hdr_data_split_flg;
689 p_tpa->tpa_gro_consistent_flg = p_params->tpa_gro_consistent_flg;
690 p_tpa->tpa_max_aggs_num = p_params->tpa_max_aggs_num;
691 p_tpa->tpa_max_size = p_params->tpa_max_size;
692 p_tpa->tpa_min_size_to_start = p_params->tpa_min_size_to_start;
693 p_tpa->tpa_min_size_to_cont = p_params->tpa_min_size_to_cont;
694 }
695
696 static void
ecore_sp_update_mcast_bin(struct ecore_hwfn * p_hwfn,struct vport_update_ramrod_data * p_ramrod,struct ecore_sp_vport_update_params * p_params)697 ecore_sp_update_mcast_bin(struct ecore_hwfn *p_hwfn,
698 struct vport_update_ramrod_data *p_ramrod,
699 struct ecore_sp_vport_update_params *p_params)
700 {
701 int i;
702
703 OSAL_MEMSET(&p_ramrod->approx_mcast.bins, 0,
704 sizeof(p_ramrod->approx_mcast.bins));
705
706 if (!p_params->update_approx_mcast_flg)
707 return;
708
709 p_ramrod->common.update_approx_mcast_flg = 1;
710 for (i = 0; i < ETH_MULTICAST_MAC_BINS_IN_REGS; i++) {
711 u32 *p_bins = (u32 *)p_params->bins;
712
713 p_ramrod->approx_mcast.bins[i] = OSAL_CPU_TO_LE32(p_bins[i]);
714 }
715 }
716
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)717 enum _ecore_status_t ecore_sp_vport_update(struct ecore_hwfn *p_hwfn,
718 struct ecore_sp_vport_update_params *p_params,
719 enum spq_mode comp_mode,
720 struct ecore_spq_comp_cb *p_comp_data)
721 {
722 struct ecore_rss_params *p_rss_params = p_params->rss_params;
723 struct vport_update_ramrod_data_cmn *p_cmn;
724 struct ecore_sp_init_data init_data;
725 struct vport_update_ramrod_data *p_ramrod = OSAL_NULL;
726 struct ecore_spq_entry *p_ent = OSAL_NULL;
727 u8 abs_vport_id = 0, val;
728 enum _ecore_status_t rc = ECORE_NOTIMPL;
729
730 if (IS_VF(p_hwfn->p_dev)) {
731 rc = ecore_vf_pf_vport_update(p_hwfn, p_params);
732 return rc;
733 }
734
735 rc = ecore_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
736 if (rc != ECORE_SUCCESS)
737 return rc;
738
739 /* Get SPQ entry */
740 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
741 init_data.cid = ecore_spq_get_cid(p_hwfn);
742 init_data.opaque_fid = p_params->opaque_fid;
743 init_data.comp_mode = comp_mode;
744 init_data.p_comp_data = p_comp_data;
745
746 rc = ecore_sp_init_request(p_hwfn, &p_ent,
747 ETH_RAMROD_VPORT_UPDATE,
748 PROTOCOLID_ETH, &init_data);
749 if (rc != ECORE_SUCCESS)
750 return rc;
751
752 /* Copy input params to ramrod according to FW struct */
753 p_ramrod = &p_ent->ramrod.vport_update;
754 p_cmn = &p_ramrod->common;
755
756 p_cmn->vport_id = abs_vport_id;
757
758 p_cmn->rx_active_flg = p_params->vport_active_rx_flg;
759 p_cmn->update_rx_active_flg = p_params->update_vport_active_rx_flg;
760 p_cmn->tx_active_flg = p_params->vport_active_tx_flg;
761 p_cmn->update_tx_active_flg = p_params->update_vport_active_tx_flg;
762
763 p_cmn->accept_any_vlan = p_params->accept_any_vlan;
764 val = p_params->update_accept_any_vlan_flg;
765 p_cmn->update_accept_any_vlan_flg = val;
766
767 p_cmn->inner_vlan_removal_en = p_params->inner_vlan_removal_flg;
768 val = p_params->update_inner_vlan_removal_flg;
769 p_cmn->update_inner_vlan_removal_en_flg = val;
770
771 p_cmn->default_vlan_en = p_params->default_vlan_enable_flg;
772 val = p_params->update_default_vlan_enable_flg;
773 p_cmn->update_default_vlan_en_flg = val;
774
775 p_cmn->default_vlan = OSAL_CPU_TO_LE16(p_params->default_vlan);
776 p_cmn->update_default_vlan_flg = p_params->update_default_vlan_flg;
777
778 p_cmn->silent_vlan_removal_en = p_params->silent_vlan_removal_flg;
779
780 p_ramrod->common.tx_switching_en = p_params->tx_switching_flg;
781 #ifndef ASIC_ONLY
782 if (CHIP_REV_IS_FPGA(p_hwfn->p_dev))
783 if (p_ramrod->common.tx_switching_en ||
784 p_ramrod->common.update_tx_switching_en_flg) {
785 DP_NOTICE(p_hwfn, false, "FPGA - why are we seeing tx-switching? Overriding it\n");
786 p_ramrod->common.tx_switching_en = 0;
787 p_ramrod->common.update_tx_switching_en_flg = 1;
788 }
789 #endif
790 p_cmn->update_tx_switching_en_flg = p_params->update_tx_switching_flg;
791
792 p_cmn->anti_spoofing_en = p_params->anti_spoofing_en;
793 val = p_params->update_anti_spoofing_en_flg;
794 p_ramrod->common.update_anti_spoofing_en_flg = val;
795
796 rc = ecore_sp_vport_update_rss(p_hwfn, p_ramrod, p_rss_params);
797 if (rc != ECORE_SUCCESS) {
798 /* Return spq entry which is taken in ecore_sp_init_request()*/
799 ecore_spq_return_entry(p_hwfn, p_ent);
800 return rc;
801 }
802
803 /* Update mcast bins for VFs, PF doesn't use this functionality */
804 ecore_sp_update_mcast_bin(p_hwfn, p_ramrod, p_params);
805
806 ecore_sp_update_accept_mode(p_hwfn, p_ramrod, p_params->accept_flags);
807 ecore_sp_vport_update_sge_tpa(p_hwfn, p_ramrod,
808 p_params->sge_tpa_params);
809 return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
810 }
811
ecore_sp_vport_stop(struct ecore_hwfn * p_hwfn,u16 opaque_fid,u8 vport_id)812 enum _ecore_status_t ecore_sp_vport_stop(struct ecore_hwfn *p_hwfn,
813 u16 opaque_fid,
814 u8 vport_id)
815 {
816 struct vport_stop_ramrod_data *p_ramrod;
817 struct ecore_sp_init_data init_data;
818 struct ecore_spq_entry *p_ent;
819 u8 abs_vport_id = 0;
820 enum _ecore_status_t rc;
821
822 if (IS_VF(p_hwfn->p_dev))
823 return ecore_vf_pf_vport_stop(p_hwfn);
824
825 rc = ecore_fw_vport(p_hwfn, vport_id, &abs_vport_id);
826 if (rc != ECORE_SUCCESS)
827 return rc;
828
829 /* Get SPQ entry */
830 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
831 init_data.cid = ecore_spq_get_cid(p_hwfn);
832 init_data.opaque_fid = opaque_fid;
833 init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
834
835 rc = ecore_sp_init_request(p_hwfn, &p_ent,
836 ETH_RAMROD_VPORT_STOP,
837 PROTOCOLID_ETH, &init_data);
838 if (rc != ECORE_SUCCESS)
839 return rc;
840
841 p_ramrod = &p_ent->ramrod.vport_stop;
842 p_ramrod->vport_id = abs_vport_id;
843
844 return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
845 }
846
847 static enum _ecore_status_t
ecore_vf_pf_accept_flags(struct ecore_hwfn * p_hwfn,struct ecore_filter_accept_flags * p_accept_flags)848 ecore_vf_pf_accept_flags(struct ecore_hwfn *p_hwfn,
849 struct ecore_filter_accept_flags *p_accept_flags)
850 {
851 struct ecore_sp_vport_update_params s_params;
852
853 OSAL_MEMSET(&s_params, 0, sizeof(s_params));
854 OSAL_MEMCPY(&s_params.accept_flags, p_accept_flags,
855 sizeof(struct ecore_filter_accept_flags));
856
857 return ecore_vf_pf_vport_update(p_hwfn, &s_params);
858 }
859
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)860 enum _ecore_status_t ecore_filter_accept_cmd(struct ecore_dev *p_dev,
861 u8 vport,
862 struct ecore_filter_accept_flags accept_flags,
863 u8 update_accept_any_vlan,
864 u8 accept_any_vlan,
865 enum spq_mode comp_mode,
866 struct ecore_spq_comp_cb *p_comp_data)
867 {
868 struct ecore_sp_vport_update_params vport_update_params;
869 int i, rc;
870
871 /* Prepare and send the vport rx_mode change */
872 OSAL_MEMSET(&vport_update_params, 0, sizeof(vport_update_params));
873 vport_update_params.vport_id = vport;
874 vport_update_params.accept_flags = accept_flags;
875 vport_update_params.update_accept_any_vlan_flg = update_accept_any_vlan;
876 vport_update_params.accept_any_vlan = accept_any_vlan;
877
878 for_each_hwfn(p_dev, i) {
879 struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
880
881 vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
882
883 if (IS_VF(p_dev)) {
884 rc = ecore_vf_pf_accept_flags(p_hwfn, &accept_flags);
885 if (rc != ECORE_SUCCESS)
886 return rc;
887 continue;
888 }
889
890 rc = ecore_sp_vport_update(p_hwfn, &vport_update_params,
891 comp_mode, p_comp_data);
892 if (rc != ECORE_SUCCESS) {
893 DP_ERR(p_dev, "Update rx_mode failed %d\n", rc);
894 return rc;
895 }
896
897 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
898 "Accept filter configured, flags = [Rx]%x [Tx]%x\n",
899 accept_flags.rx_accept_filter,
900 accept_flags.tx_accept_filter);
901
902 if (update_accept_any_vlan)
903 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
904 "accept_any_vlan=%d configured\n",
905 accept_any_vlan);
906 }
907
908 return 0;
909 }
910
911 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)912 ecore_eth_rxq_start_ramrod(struct ecore_hwfn *p_hwfn,
913 struct ecore_queue_cid *p_cid,
914 u16 bd_max_bytes,
915 dma_addr_t bd_chain_phys_addr,
916 dma_addr_t cqe_pbl_addr,
917 u16 cqe_pbl_size)
918 {
919 struct rx_queue_start_ramrod_data *p_ramrod = OSAL_NULL;
920 struct ecore_spq_entry *p_ent = OSAL_NULL;
921 struct ecore_sp_init_data init_data;
922 enum _ecore_status_t rc = ECORE_NOTIMPL;
923
924 DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "opaque_fid=0x%x, cid=0x%x, rx_qzone=0x%x, vport_id=0x%x, sb_id=0x%x\n",
925 p_cid->opaque_fid, p_cid->cid, p_cid->abs.queue_id,
926 p_cid->abs.vport_id, p_cid->sb_igu_id);
927
928 /* Get SPQ entry */
929 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
930 init_data.cid = p_cid->cid;
931 init_data.opaque_fid = p_cid->opaque_fid;
932 init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
933
934 rc = ecore_sp_init_request(p_hwfn, &p_ent,
935 ETH_RAMROD_RX_QUEUE_START,
936 PROTOCOLID_ETH, &init_data);
937 if (rc != ECORE_SUCCESS)
938 return rc;
939
940 p_ramrod = &p_ent->ramrod.rx_queue_start;
941
942 p_ramrod->sb_id = OSAL_CPU_TO_LE16(p_cid->sb_igu_id);
943 p_ramrod->sb_index = p_cid->sb_idx;
944 p_ramrod->vport_id = p_cid->abs.vport_id;
945 p_ramrod->stats_counter_id = p_cid->abs.stats_id;
946 p_ramrod->rx_queue_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
947 p_ramrod->complete_cqe_flg = 0;
948 p_ramrod->complete_event_flg = 1;
949
950 p_ramrod->bd_max_bytes = OSAL_CPU_TO_LE16(bd_max_bytes);
951 DMA_REGPAIR_LE(p_ramrod->bd_base, bd_chain_phys_addr);
952
953 p_ramrod->num_of_pbl_pages = OSAL_CPU_TO_LE16(cqe_pbl_size);
954 DMA_REGPAIR_LE(p_ramrod->cqe_pbl_addr, cqe_pbl_addr);
955
956 if (p_cid->vfid != ECORE_QUEUE_CID_PF) {
957 bool b_legacy_vf = !!(p_cid->vf_legacy &
958 ECORE_QCID_LEGACY_VF_RX_PROD);
959
960 p_ramrod->vf_rx_prod_index = p_cid->vf_qid;
961 DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "Queue%s is meant for VF rxq[%02x]\n",
962 b_legacy_vf ? " [legacy]" : "",
963 p_cid->vf_qid);
964 p_ramrod->vf_rx_prod_use_zone_a = b_legacy_vf;
965 }
966
967 return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
968 }
969
970 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)971 ecore_eth_pf_rx_queue_start(struct ecore_hwfn *p_hwfn,
972 struct ecore_queue_cid *p_cid,
973 u16 bd_max_bytes,
974 dma_addr_t bd_chain_phys_addr,
975 dma_addr_t cqe_pbl_addr,
976 u16 cqe_pbl_size,
977 void OSAL_IOMEM **pp_prod)
978 {
979 u32 init_prod_val = 0;
980
981 *pp_prod = (u8 OSAL_IOMEM*)
982 p_hwfn->regview +
983 GTT_BAR0_MAP_REG_MSDM_RAM +
984 MSTORM_ETH_PF_PRODS_OFFSET(p_cid->abs.queue_id);
985
986 /* Init the rcq, rx bd and rx sge (if valid) producers to 0 */
987 __internal_ram_wr(p_hwfn, *pp_prod, sizeof(u32),
988 (u32 *)(&init_prod_val));
989
990 return ecore_eth_rxq_start_ramrod(p_hwfn, p_cid,
991 bd_max_bytes,
992 bd_chain_phys_addr,
993 cqe_pbl_addr, cqe_pbl_size);
994 }
995
996 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)997 ecore_eth_rx_queue_start(struct ecore_hwfn *p_hwfn,
998 u16 opaque_fid,
999 struct ecore_queue_start_common_params *p_params,
1000 u16 bd_max_bytes,
1001 dma_addr_t bd_chain_phys_addr,
1002 dma_addr_t cqe_pbl_addr,
1003 u16 cqe_pbl_size,
1004 struct ecore_rxq_start_ret_params *p_ret_params)
1005 {
1006 struct ecore_queue_cid *p_cid;
1007 enum _ecore_status_t rc;
1008
1009 /* Allocate a CID for the queue */
1010 p_cid = ecore_eth_queue_to_cid_pf(p_hwfn, opaque_fid, p_params);
1011 if (p_cid == OSAL_NULL)
1012 return ECORE_NOMEM;
1013
1014 if (IS_PF(p_hwfn->p_dev))
1015 rc = ecore_eth_pf_rx_queue_start(p_hwfn, p_cid,
1016 bd_max_bytes,
1017 bd_chain_phys_addr,
1018 cqe_pbl_addr, cqe_pbl_size,
1019 &p_ret_params->p_prod);
1020 else
1021 rc = ecore_vf_pf_rxq_start(p_hwfn, p_cid,
1022 bd_max_bytes,
1023 bd_chain_phys_addr,
1024 cqe_pbl_addr,
1025 cqe_pbl_size,
1026 &p_ret_params->p_prod);
1027
1028 /* Provide the caller with a reference to as handler */
1029 if (rc != ECORE_SUCCESS)
1030 ecore_eth_queue_cid_release(p_hwfn, p_cid);
1031 else
1032 p_ret_params->p_handle = (void *)p_cid;
1033
1034 return rc;
1035 }
1036
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)1037 enum _ecore_status_t ecore_sp_eth_rx_queues_update(struct ecore_hwfn *p_hwfn,
1038 void **pp_rxq_handles,
1039 u8 num_rxqs,
1040 u8 complete_cqe_flg,
1041 u8 complete_event_flg,
1042 enum spq_mode comp_mode,
1043 struct ecore_spq_comp_cb *p_comp_data)
1044 {
1045 struct rx_queue_update_ramrod_data *p_ramrod = OSAL_NULL;
1046 struct ecore_spq_entry *p_ent = OSAL_NULL;
1047 struct ecore_sp_init_data init_data;
1048 struct ecore_queue_cid *p_cid;
1049 enum _ecore_status_t rc = ECORE_NOTIMPL;
1050 u8 i;
1051
1052 #ifndef LINUX_REMOVE
1053 if (IS_VF(p_hwfn->p_dev))
1054 return ecore_vf_pf_rxqs_update(p_hwfn,
1055 (struct ecore_queue_cid **)
1056 pp_rxq_handles,
1057 num_rxqs,
1058 complete_cqe_flg,
1059 complete_event_flg);
1060 #endif
1061
1062 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
1063 init_data.comp_mode = comp_mode;
1064 init_data.p_comp_data = p_comp_data;
1065
1066 for (i = 0; i < num_rxqs; i++) {
1067 p_cid = ((struct ecore_queue_cid **)pp_rxq_handles)[i];
1068
1069 /* Get SPQ entry */
1070 init_data.cid = p_cid->cid;
1071 init_data.opaque_fid = p_cid->opaque_fid;
1072
1073 rc = ecore_sp_init_request(p_hwfn, &p_ent,
1074 ETH_RAMROD_RX_QUEUE_UPDATE,
1075 PROTOCOLID_ETH, &init_data);
1076 if (rc != ECORE_SUCCESS)
1077 return rc;
1078
1079 p_ramrod = &p_ent->ramrod.rx_queue_update;
1080 p_ramrod->vport_id = p_cid->abs.vport_id;
1081
1082 p_ramrod->rx_queue_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
1083 p_ramrod->complete_cqe_flg = complete_cqe_flg;
1084 p_ramrod->complete_event_flg = complete_event_flg;
1085
1086 rc = ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
1087 if (rc != ECORE_SUCCESS)
1088 return rc;
1089 }
1090
1091 return rc;
1092 }
1093
1094 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)1095 ecore_eth_pf_rx_queue_stop(struct ecore_hwfn *p_hwfn,
1096 struct ecore_queue_cid *p_cid,
1097 bool b_eq_completion_only,
1098 bool b_cqe_completion)
1099 {
1100 struct rx_queue_stop_ramrod_data *p_ramrod = OSAL_NULL;
1101 struct ecore_spq_entry *p_ent = OSAL_NULL;
1102 struct ecore_sp_init_data init_data;
1103 enum _ecore_status_t rc;
1104
1105 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
1106 init_data.cid = p_cid->cid;
1107 init_data.opaque_fid = p_cid->opaque_fid;
1108 init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
1109
1110 rc = ecore_sp_init_request(p_hwfn, &p_ent,
1111 ETH_RAMROD_RX_QUEUE_STOP,
1112 PROTOCOLID_ETH, &init_data);
1113 if (rc != ECORE_SUCCESS)
1114 return rc;
1115
1116 p_ramrod = &p_ent->ramrod.rx_queue_stop;
1117 p_ramrod->vport_id = p_cid->abs.vport_id;
1118 p_ramrod->rx_queue_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
1119
1120 /* Cleaning the queue requires the completion to arrive there.
1121 * In addition, VFs require the answer to come as eqe to PF.
1122 */
1123 p_ramrod->complete_cqe_flg = ((p_cid->vfid == ECORE_QUEUE_CID_PF) &&
1124 !b_eq_completion_only) ||
1125 b_cqe_completion;
1126 p_ramrod->complete_event_flg = (p_cid->vfid != ECORE_QUEUE_CID_PF) ||
1127 b_eq_completion_only;
1128
1129 return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
1130 }
1131
ecore_eth_rx_queue_stop(struct ecore_hwfn * p_hwfn,void * p_rxq,bool eq_completion_only,bool cqe_completion)1132 enum _ecore_status_t ecore_eth_rx_queue_stop(struct ecore_hwfn *p_hwfn,
1133 void *p_rxq,
1134 bool eq_completion_only,
1135 bool cqe_completion)
1136 {
1137 struct ecore_queue_cid *p_cid = (struct ecore_queue_cid *)p_rxq;
1138 enum _ecore_status_t rc = ECORE_NOTIMPL;
1139
1140 if (IS_PF(p_hwfn->p_dev))
1141 rc = ecore_eth_pf_rx_queue_stop(p_hwfn, p_cid,
1142 eq_completion_only,
1143 cqe_completion);
1144 else
1145 rc = ecore_vf_pf_rxq_stop(p_hwfn, p_cid, cqe_completion);
1146
1147 if (rc == ECORE_SUCCESS)
1148 ecore_eth_queue_cid_release(p_hwfn, p_cid);
1149 return rc;
1150 }
1151
1152 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)1153 ecore_eth_txq_start_ramrod(struct ecore_hwfn *p_hwfn,
1154 struct ecore_queue_cid *p_cid,
1155 dma_addr_t pbl_addr, u16 pbl_size,
1156 u16 pq_id)
1157 {
1158 struct tx_queue_start_ramrod_data *p_ramrod = OSAL_NULL;
1159 struct ecore_spq_entry *p_ent = OSAL_NULL;
1160 struct ecore_sp_init_data init_data;
1161 enum _ecore_status_t rc = ECORE_NOTIMPL;
1162
1163 /* Get SPQ entry */
1164 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
1165 init_data.cid = p_cid->cid;
1166 init_data.opaque_fid = p_cid->opaque_fid;
1167 init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
1168
1169 rc = ecore_sp_init_request(p_hwfn, &p_ent,
1170 ETH_RAMROD_TX_QUEUE_START,
1171 PROTOCOLID_ETH, &init_data);
1172 if (rc != ECORE_SUCCESS)
1173 return rc;
1174
1175 p_ramrod = &p_ent->ramrod.tx_queue_start;
1176 p_ramrod->vport_id = p_cid->abs.vport_id;
1177
1178 p_ramrod->sb_id = OSAL_CPU_TO_LE16(p_cid->sb_igu_id);
1179 p_ramrod->sb_index = p_cid->sb_idx;
1180 p_ramrod->stats_counter_id = p_cid->abs.stats_id;
1181
1182 p_ramrod->queue_zone_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
1183 p_ramrod->same_as_last_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
1184
1185 p_ramrod->pbl_size = OSAL_CPU_TO_LE16(pbl_size);
1186 DMA_REGPAIR_LE(p_ramrod->pbl_base_addr, pbl_addr);
1187
1188 p_ramrod->qm_pq_id = OSAL_CPU_TO_LE16(pq_id);
1189
1190 return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
1191 }
1192
1193 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)1194 ecore_eth_pf_tx_queue_start(struct ecore_hwfn *p_hwfn,
1195 struct ecore_queue_cid *p_cid,
1196 u8 tc,
1197 dma_addr_t pbl_addr, u16 pbl_size,
1198 void OSAL_IOMEM **pp_doorbell)
1199 {
1200 enum _ecore_status_t rc;
1201
1202 /* TODO - set tc in the pq_params for multi-cos */
1203 rc = ecore_eth_txq_start_ramrod(p_hwfn, p_cid,
1204 pbl_addr, pbl_size,
1205 ecore_get_cm_pq_idx_mcos(p_hwfn, tc));
1206 if (rc != ECORE_SUCCESS)
1207 return rc;
1208
1209 /* Provide the caller with the necessary return values */
1210 *pp_doorbell = (u8 OSAL_IOMEM *)
1211 p_hwfn->doorbells +
1212 DB_ADDR(p_cid->cid, DQ_DEMS_LEGACY);
1213
1214 return ECORE_SUCCESS;
1215 }
1216
1217 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)1218 ecore_eth_tx_queue_start(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
1219 struct ecore_queue_start_common_params *p_params,
1220 u8 tc,
1221 dma_addr_t pbl_addr, u16 pbl_size,
1222 struct ecore_txq_start_ret_params *p_ret_params)
1223 {
1224 struct ecore_queue_cid *p_cid;
1225 enum _ecore_status_t rc;
1226
1227 p_cid = ecore_eth_queue_to_cid_pf(p_hwfn, opaque_fid, p_params);
1228 if (p_cid == OSAL_NULL)
1229 return ECORE_INVAL;
1230
1231 if (IS_PF(p_hwfn->p_dev))
1232 rc = ecore_eth_pf_tx_queue_start(p_hwfn, p_cid, tc,
1233 pbl_addr, pbl_size,
1234 &p_ret_params->p_doorbell);
1235 else
1236 rc = ecore_vf_pf_txq_start(p_hwfn, p_cid,
1237 pbl_addr, pbl_size,
1238 &p_ret_params->p_doorbell);
1239
1240 if (rc != ECORE_SUCCESS)
1241 ecore_eth_queue_cid_release(p_hwfn, p_cid);
1242 else
1243 p_ret_params->p_handle = (void *)p_cid;
1244
1245 return rc;
1246 }
1247
1248 static enum _ecore_status_t
ecore_eth_pf_tx_queue_stop(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)1249 ecore_eth_pf_tx_queue_stop(struct ecore_hwfn *p_hwfn,
1250 struct ecore_queue_cid *p_cid)
1251 {
1252 struct ecore_spq_entry *p_ent = OSAL_NULL;
1253 struct ecore_sp_init_data init_data;
1254 enum _ecore_status_t rc;
1255
1256 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
1257 init_data.cid = p_cid->cid;
1258 init_data.opaque_fid = p_cid->opaque_fid;
1259 init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
1260
1261 rc = ecore_sp_init_request(p_hwfn, &p_ent,
1262 ETH_RAMROD_TX_QUEUE_STOP,
1263 PROTOCOLID_ETH, &init_data);
1264 if (rc != ECORE_SUCCESS)
1265 return rc;
1266
1267 return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
1268 }
1269
ecore_eth_tx_queue_stop(struct ecore_hwfn * p_hwfn,void * p_handle)1270 enum _ecore_status_t ecore_eth_tx_queue_stop(struct ecore_hwfn *p_hwfn,
1271 void *p_handle)
1272 {
1273 struct ecore_queue_cid *p_cid = (struct ecore_queue_cid *)p_handle;
1274 enum _ecore_status_t rc;
1275
1276 if (IS_PF(p_hwfn->p_dev))
1277 rc = ecore_eth_pf_tx_queue_stop(p_hwfn, p_cid);
1278 else
1279 rc = ecore_vf_pf_txq_stop(p_hwfn, p_cid);
1280
1281 if (rc == ECORE_SUCCESS)
1282 ecore_eth_queue_cid_release(p_hwfn, p_cid);
1283 return rc;
1284 }
1285
ecore_filter_action(enum ecore_filter_opcode opcode)1286 static enum eth_filter_action ecore_filter_action(enum ecore_filter_opcode opcode)
1287 {
1288 enum eth_filter_action action = MAX_ETH_FILTER_ACTION;
1289
1290 switch (opcode) {
1291 case ECORE_FILTER_ADD:
1292 action = ETH_FILTER_ACTION_ADD;
1293 break;
1294 case ECORE_FILTER_REMOVE:
1295 action = ETH_FILTER_ACTION_REMOVE;
1296 break;
1297 case ECORE_FILTER_FLUSH:
1298 action = ETH_FILTER_ACTION_REMOVE_ALL;
1299 break;
1300 default:
1301 action = MAX_ETH_FILTER_ACTION;
1302 }
1303
1304 return action;
1305 }
1306
1307 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)1308 ecore_filter_ucast_common(struct ecore_hwfn *p_hwfn,
1309 u16 opaque_fid,
1310 struct ecore_filter_ucast *p_filter_cmd,
1311 struct vport_filter_update_ramrod_data **pp_ramrod,
1312 struct ecore_spq_entry **pp_ent,
1313 enum spq_mode comp_mode,
1314 struct ecore_spq_comp_cb *p_comp_data)
1315 {
1316 u8 vport_to_add_to = 0, vport_to_remove_from = 0;
1317 struct vport_filter_update_ramrod_data *p_ramrod;
1318 struct eth_filter_cmd *p_first_filter;
1319 struct eth_filter_cmd *p_second_filter;
1320 struct ecore_sp_init_data init_data;
1321 enum eth_filter_action action;
1322 enum _ecore_status_t rc;
1323
1324 rc = ecore_fw_vport(p_hwfn, p_filter_cmd->vport_to_remove_from,
1325 &vport_to_remove_from);
1326 if (rc != ECORE_SUCCESS)
1327 return rc;
1328
1329 rc = ecore_fw_vport(p_hwfn, p_filter_cmd->vport_to_add_to,
1330 &vport_to_add_to);
1331 if (rc != ECORE_SUCCESS)
1332 return rc;
1333
1334 /* Get SPQ entry */
1335 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
1336 init_data.cid = ecore_spq_get_cid(p_hwfn);
1337 init_data.opaque_fid = opaque_fid;
1338 init_data.comp_mode = comp_mode;
1339 init_data.p_comp_data = p_comp_data;
1340
1341 rc = ecore_sp_init_request(p_hwfn, pp_ent,
1342 ETH_RAMROD_FILTERS_UPDATE,
1343 PROTOCOLID_ETH, &init_data);
1344 if (rc != ECORE_SUCCESS)
1345 return rc;
1346
1347 *pp_ramrod = &(*pp_ent)->ramrod.vport_filter_update;
1348 p_ramrod = *pp_ramrod;
1349 p_ramrod->filter_cmd_hdr.rx = p_filter_cmd->is_rx_filter ? 1 : 0;
1350 p_ramrod->filter_cmd_hdr.tx = p_filter_cmd->is_tx_filter ? 1 : 0;
1351
1352 #ifndef ASIC_ONLY
1353 if (CHIP_REV_IS_SLOW(p_hwfn->p_dev)) {
1354 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1355 "Non-Asic - prevent Tx filters\n");
1356 p_ramrod->filter_cmd_hdr.tx = 0;
1357 }
1358
1359 #endif
1360
1361 switch (p_filter_cmd->opcode) {
1362 case ECORE_FILTER_REPLACE:
1363 case ECORE_FILTER_MOVE:
1364 p_ramrod->filter_cmd_hdr.cmd_cnt = 2; break;
1365 default:
1366 p_ramrod->filter_cmd_hdr.cmd_cnt = 1; break;
1367 }
1368
1369 p_first_filter = &p_ramrod->filter_cmds[0];
1370 p_second_filter = &p_ramrod->filter_cmds[1];
1371
1372 switch (p_filter_cmd->type) {
1373 case ECORE_FILTER_MAC:
1374 p_first_filter->type = ETH_FILTER_TYPE_MAC; break;
1375 case ECORE_FILTER_VLAN:
1376 p_first_filter->type = ETH_FILTER_TYPE_VLAN; break;
1377 case ECORE_FILTER_MAC_VLAN:
1378 p_first_filter->type = ETH_FILTER_TYPE_PAIR; break;
1379 case ECORE_FILTER_INNER_MAC:
1380 p_first_filter->type = ETH_FILTER_TYPE_INNER_MAC; break;
1381 case ECORE_FILTER_INNER_VLAN:
1382 p_first_filter->type = ETH_FILTER_TYPE_INNER_VLAN; break;
1383 case ECORE_FILTER_INNER_PAIR:
1384 p_first_filter->type = ETH_FILTER_TYPE_INNER_PAIR; break;
1385 case ECORE_FILTER_INNER_MAC_VNI_PAIR:
1386 p_first_filter->type = ETH_FILTER_TYPE_INNER_MAC_VNI_PAIR;
1387 break;
1388 case ECORE_FILTER_MAC_VNI_PAIR:
1389 p_first_filter->type = ETH_FILTER_TYPE_MAC_VNI_PAIR; break;
1390 case ECORE_FILTER_VNI:
1391 p_first_filter->type = ETH_FILTER_TYPE_VNI; break;
1392 }
1393
1394 if ((p_first_filter->type == ETH_FILTER_TYPE_MAC) ||
1395 (p_first_filter->type == ETH_FILTER_TYPE_PAIR) ||
1396 (p_first_filter->type == ETH_FILTER_TYPE_INNER_MAC) ||
1397 (p_first_filter->type == ETH_FILTER_TYPE_INNER_PAIR) ||
1398 (p_first_filter->type == ETH_FILTER_TYPE_INNER_MAC_VNI_PAIR) ||
1399 (p_first_filter->type == ETH_FILTER_TYPE_MAC_VNI_PAIR))
1400 ecore_set_fw_mac_addr(&p_first_filter->mac_msb,
1401 &p_first_filter->mac_mid,
1402 &p_first_filter->mac_lsb,
1403 (u8 *)p_filter_cmd->mac);
1404
1405 if ((p_first_filter->type == ETH_FILTER_TYPE_VLAN) ||
1406 (p_first_filter->type == ETH_FILTER_TYPE_PAIR) ||
1407 (p_first_filter->type == ETH_FILTER_TYPE_INNER_VLAN) ||
1408 (p_first_filter->type == ETH_FILTER_TYPE_INNER_PAIR))
1409 p_first_filter->vlan_id = OSAL_CPU_TO_LE16(p_filter_cmd->vlan);
1410
1411 if ((p_first_filter->type == ETH_FILTER_TYPE_INNER_MAC_VNI_PAIR) ||
1412 (p_first_filter->type == ETH_FILTER_TYPE_MAC_VNI_PAIR) ||
1413 (p_first_filter->type == ETH_FILTER_TYPE_VNI))
1414 p_first_filter->vni = OSAL_CPU_TO_LE32(p_filter_cmd->vni);
1415
1416 if (p_filter_cmd->opcode == ECORE_FILTER_MOVE) {
1417 p_second_filter->type = p_first_filter->type;
1418 p_second_filter->mac_msb = p_first_filter->mac_msb;
1419 p_second_filter->mac_mid = p_first_filter->mac_mid;
1420 p_second_filter->mac_lsb = p_first_filter->mac_lsb;
1421 p_second_filter->vlan_id = p_first_filter->vlan_id;
1422 p_second_filter->vni = p_first_filter->vni;
1423
1424 p_first_filter->action = ETH_FILTER_ACTION_REMOVE;
1425
1426 p_first_filter->vport_id = vport_to_remove_from;
1427
1428 p_second_filter->action = ETH_FILTER_ACTION_ADD;
1429 p_second_filter->vport_id = vport_to_add_to;
1430 } else if (p_filter_cmd->opcode == ECORE_FILTER_REPLACE) {
1431 p_first_filter->vport_id = vport_to_add_to;
1432 OSAL_MEMCPY(p_second_filter, p_first_filter,
1433 sizeof(*p_second_filter));
1434 p_first_filter->action = ETH_FILTER_ACTION_REMOVE_ALL;
1435 p_second_filter->action = ETH_FILTER_ACTION_ADD;
1436 } else {
1437 action = ecore_filter_action(p_filter_cmd->opcode);
1438
1439 if (action == MAX_ETH_FILTER_ACTION) {
1440 DP_NOTICE(p_hwfn, true,
1441 "%d is not supported yet\n",
1442 p_filter_cmd->opcode);
1443 return ECORE_NOTIMPL;
1444 }
1445
1446 p_first_filter->action = action;
1447 p_first_filter->vport_id =
1448 (p_filter_cmd->opcode == ECORE_FILTER_REMOVE) ?
1449 vport_to_remove_from : vport_to_add_to;
1450 }
1451
1452 return ECORE_SUCCESS;
1453 }
1454
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)1455 enum _ecore_status_t ecore_sp_eth_filter_ucast(struct ecore_hwfn *p_hwfn,
1456 u16 opaque_fid,
1457 struct ecore_filter_ucast *p_filter_cmd,
1458 enum spq_mode comp_mode,
1459 struct ecore_spq_comp_cb *p_comp_data)
1460 {
1461 struct vport_filter_update_ramrod_data *p_ramrod = OSAL_NULL;
1462 struct ecore_spq_entry *p_ent = OSAL_NULL;
1463 struct eth_filter_cmd_header *p_header;
1464 enum _ecore_status_t rc;
1465
1466 rc = ecore_filter_ucast_common(p_hwfn, opaque_fid, p_filter_cmd,
1467 &p_ramrod, &p_ent,
1468 comp_mode, p_comp_data);
1469 if (rc != ECORE_SUCCESS) {
1470 DP_ERR(p_hwfn, "Uni. filter command failed %d\n", rc);
1471 return rc;
1472 }
1473 p_header = &p_ramrod->filter_cmd_hdr;
1474 p_header->assert_on_error = p_filter_cmd->assert_on_error;
1475
1476 rc = ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
1477 if (rc != ECORE_SUCCESS) {
1478 DP_ERR(p_hwfn,
1479 "Unicast filter ADD command failed %d\n",
1480 rc);
1481 return rc;
1482 }
1483
1484 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1485 "Unicast filter configured, opcode = %s, type = %s, cmd_cnt = %d, is_rx_filter = %d, is_tx_filter = %d\n",
1486 (p_filter_cmd->opcode == ECORE_FILTER_ADD) ? "ADD" :
1487 ((p_filter_cmd->opcode == ECORE_FILTER_REMOVE) ?
1488 "REMOVE" :
1489 ((p_filter_cmd->opcode == ECORE_FILTER_MOVE) ?
1490 "MOVE" : "REPLACE")),
1491 (p_filter_cmd->type == ECORE_FILTER_MAC) ? "MAC" :
1492 ((p_filter_cmd->type == ECORE_FILTER_VLAN) ?
1493 "VLAN" : "MAC & VLAN"),
1494 p_ramrod->filter_cmd_hdr.cmd_cnt,
1495 p_filter_cmd->is_rx_filter,
1496 p_filter_cmd->is_tx_filter);
1497 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1498 "vport_to_add_to = %d, vport_to_remove_from = %d, mac = %2x:%2x:%2x:%2x:%2x:%2x, vlan = %d\n",
1499 p_filter_cmd->vport_to_add_to,
1500 p_filter_cmd->vport_to_remove_from,
1501 p_filter_cmd->mac[0], p_filter_cmd->mac[1],
1502 p_filter_cmd->mac[2], p_filter_cmd->mac[3],
1503 p_filter_cmd->mac[4], p_filter_cmd->mac[5],
1504 p_filter_cmd->vlan);
1505
1506 return ECORE_SUCCESS;
1507 }
1508
1509 /*******************************************************************************
1510 * Description:
1511 * Calculates crc 32 on a buffer
1512 * Note: crc32_length MUST be aligned to 8
1513 * Return:
1514 ******************************************************************************/
ecore_calc_crc32c(u8 * crc32_packet,u32 crc32_length,u32 crc32_seed,u8 complement)1515 static u32 ecore_calc_crc32c(u8 *crc32_packet,
1516 u32 crc32_length,
1517 u32 crc32_seed,
1518 u8 complement)
1519 {
1520 u32 byte = 0, bit = 0, crc32_result = crc32_seed;
1521 u8 msb = 0, current_byte = 0;
1522
1523 if ((crc32_packet == OSAL_NULL) ||
1524 (crc32_length == 0) ||
1525 ((crc32_length % 8) != 0)) {
1526 return crc32_result;
1527 }
1528
1529 for (byte = 0; byte < crc32_length; byte++) {
1530 current_byte = crc32_packet[byte];
1531 for (bit = 0; bit < 8; bit++) {
1532 msb = (u8)(crc32_result >> 31);
1533 crc32_result = crc32_result << 1;
1534 if (msb != (0x1 & (current_byte >> bit))) {
1535 crc32_result = crc32_result ^ CRC32_POLY;
1536 crc32_result |= 1; /*crc32_result[0] = 1;*/
1537 }
1538 }
1539 }
1540
1541 return crc32_result;
1542 }
1543
ecore_crc32c_le(u32 seed,u8 * mac,u32 len)1544 static u32 ecore_crc32c_le(u32 seed, u8 *mac, u32 len)
1545 {
1546 u32 packet_buf[2] = {0};
1547
1548 OSAL_MEMCPY((u8 *)(&packet_buf[0]), &mac[0], 6);
1549 return ecore_calc_crc32c((u8 *)packet_buf, 8, seed, 0);
1550 }
1551
ecore_mcast_bin_from_mac(u8 * mac)1552 u8 ecore_mcast_bin_from_mac(u8 *mac)
1553 {
1554 u32 crc = ecore_crc32c_le(ETH_MULTICAST_BIN_FROM_MAC_SEED,
1555 mac, ETH_ALEN);
1556
1557 return crc & 0xff;
1558 }
1559
1560 static enum _ecore_status_t
ecore_sp_eth_filter_mcast(struct ecore_hwfn * p_hwfn,u16 opaque_fid,struct ecore_filter_mcast * p_filter_cmd,enum spq_mode comp_mode,struct ecore_spq_comp_cb * p_comp_data)1561 ecore_sp_eth_filter_mcast(struct ecore_hwfn *p_hwfn,
1562 u16 opaque_fid,
1563 struct ecore_filter_mcast *p_filter_cmd,
1564 enum spq_mode comp_mode,
1565 struct ecore_spq_comp_cb *p_comp_data)
1566 {
1567 unsigned long bins[ETH_MULTICAST_MAC_BINS_IN_REGS];
1568 struct vport_update_ramrod_data *p_ramrod = OSAL_NULL;
1569 struct ecore_spq_entry *p_ent = OSAL_NULL;
1570 struct ecore_sp_init_data init_data;
1571 u8 abs_vport_id = 0;
1572 enum _ecore_status_t rc;
1573 int i;
1574
1575 if (p_filter_cmd->opcode == ECORE_FILTER_ADD)
1576 rc = ecore_fw_vport(p_hwfn, p_filter_cmd->vport_to_add_to,
1577 &abs_vport_id);
1578 else
1579 rc = ecore_fw_vport(p_hwfn, p_filter_cmd->vport_to_remove_from,
1580 &abs_vport_id);
1581 if (rc != ECORE_SUCCESS)
1582 return rc;
1583
1584 /* Get SPQ entry */
1585 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
1586 init_data.cid = ecore_spq_get_cid(p_hwfn);
1587 init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
1588 init_data.comp_mode = comp_mode;
1589 init_data.p_comp_data = p_comp_data;
1590
1591 rc = ecore_sp_init_request(p_hwfn, &p_ent,
1592 ETH_RAMROD_VPORT_UPDATE,
1593 PROTOCOLID_ETH, &init_data);
1594 if (rc != ECORE_SUCCESS) {
1595 DP_ERR(p_hwfn, "Multi-cast command failed %d\n", rc);
1596 return rc;
1597 }
1598
1599 p_ramrod = &p_ent->ramrod.vport_update;
1600 p_ramrod->common.update_approx_mcast_flg = 1;
1601
1602 /* explicitly clear out the entire vector */
1603 OSAL_MEMSET(&p_ramrod->approx_mcast.bins,
1604 0, sizeof(p_ramrod->approx_mcast.bins));
1605 OSAL_MEMSET(bins, 0, sizeof(unsigned long) *
1606 ETH_MULTICAST_MAC_BINS_IN_REGS);
1607 /* filter ADD op is explicit set op and it removes
1608 * any existing filters for the vport.
1609 */
1610 if (p_filter_cmd->opcode == ECORE_FILTER_ADD) {
1611 for (i = 0; i < p_filter_cmd->num_mc_addrs; i++) {
1612 u32 bit;
1613
1614 bit = ecore_mcast_bin_from_mac(p_filter_cmd->mac[i]);
1615 OSAL_SET_BIT(bit, bins);
1616 }
1617
1618 /* Convert to correct endianity */
1619 for (i = 0; i < ETH_MULTICAST_MAC_BINS_IN_REGS; i++) {
1620 struct vport_update_ramrod_mcast *p_ramrod_bins;
1621 u32 *p_bins = (u32 *)bins;
1622
1623 p_ramrod_bins = &p_ramrod->approx_mcast;
1624 p_ramrod_bins->bins[i] = OSAL_CPU_TO_LE32(p_bins[i]);
1625 }
1626 }
1627
1628 p_ramrod->common.vport_id = abs_vport_id;
1629
1630 rc = ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
1631 if (rc != ECORE_SUCCESS)
1632 DP_ERR(p_hwfn, "Multicast filter command failed %d\n", rc);
1633
1634 return rc;
1635 }
1636
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)1637 enum _ecore_status_t ecore_filter_mcast_cmd(struct ecore_dev *p_dev,
1638 struct ecore_filter_mcast *p_filter_cmd,
1639 enum spq_mode comp_mode,
1640 struct ecore_spq_comp_cb *p_comp_data)
1641 {
1642 enum _ecore_status_t rc = ECORE_SUCCESS;
1643 int i;
1644
1645 /* only ADD and REMOVE operations are supported for multi-cast */
1646 if ((p_filter_cmd->opcode != ECORE_FILTER_ADD &&
1647 (p_filter_cmd->opcode != ECORE_FILTER_REMOVE)) ||
1648 (p_filter_cmd->num_mc_addrs > ECORE_MAX_MC_ADDRS)) {
1649 return ECORE_INVAL;
1650 }
1651
1652 for_each_hwfn(p_dev, i) {
1653 struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
1654 u16 opaque_fid;
1655
1656 if (IS_VF(p_dev)) {
1657 ecore_vf_pf_filter_mcast(p_hwfn, p_filter_cmd);
1658 continue;
1659 }
1660
1661 opaque_fid = p_hwfn->hw_info.opaque_fid;
1662 rc = ecore_sp_eth_filter_mcast(p_hwfn,
1663 opaque_fid,
1664 p_filter_cmd,
1665 comp_mode,
1666 p_comp_data);
1667 if (rc != ECORE_SUCCESS)
1668 break;
1669 }
1670
1671 return rc;
1672 }
1673
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)1674 enum _ecore_status_t ecore_filter_ucast_cmd(struct ecore_dev *p_dev,
1675 struct ecore_filter_ucast *p_filter_cmd,
1676 enum spq_mode comp_mode,
1677 struct ecore_spq_comp_cb *p_comp_data)
1678 {
1679 enum _ecore_status_t rc = ECORE_SUCCESS;
1680 int i;
1681
1682 for_each_hwfn(p_dev, i) {
1683 struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
1684 u16 opaque_fid;
1685
1686 if (IS_VF(p_dev)) {
1687 rc = ecore_vf_pf_filter_ucast(p_hwfn, p_filter_cmd);
1688 continue;
1689 }
1690
1691 opaque_fid = p_hwfn->hw_info.opaque_fid;
1692 rc = ecore_sp_eth_filter_ucast(p_hwfn,
1693 opaque_fid,
1694 p_filter_cmd,
1695 comp_mode,
1696 p_comp_data);
1697 if (rc != ECORE_SUCCESS)
1698 break;
1699 }
1700
1701 return rc;
1702 }
1703
1704 /* Statistics related code */
__ecore_get_vport_pstats_addrlen(struct ecore_hwfn * p_hwfn,u32 * p_addr,u32 * p_len,u16 statistics_bin)1705 static void __ecore_get_vport_pstats_addrlen(struct ecore_hwfn *p_hwfn,
1706 u32 *p_addr, u32 *p_len,
1707 u16 statistics_bin)
1708 {
1709 if (IS_PF(p_hwfn->p_dev)) {
1710 *p_addr = BAR0_MAP_REG_PSDM_RAM +
1711 PSTORM_QUEUE_STAT_OFFSET(statistics_bin);
1712 *p_len = sizeof(struct eth_pstorm_per_queue_stat);
1713 } else {
1714 struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
1715 struct pfvf_acquire_resp_tlv *p_resp = &p_iov->acquire_resp;
1716
1717 *p_addr = p_resp->pfdev_info.stats_info.pstats.address;
1718 *p_len = p_resp->pfdev_info.stats_info.pstats.len;
1719 }
1720 }
1721
__ecore_get_vport_pstats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * p_stats,u16 statistics_bin)1722 static void __ecore_get_vport_pstats(struct ecore_hwfn *p_hwfn,
1723 struct ecore_ptt *p_ptt,
1724 struct ecore_eth_stats *p_stats,
1725 u16 statistics_bin)
1726 {
1727 struct eth_pstorm_per_queue_stat pstats;
1728 u32 pstats_addr = 0, pstats_len = 0;
1729
1730 __ecore_get_vport_pstats_addrlen(p_hwfn, &pstats_addr, &pstats_len,
1731 statistics_bin);
1732
1733 OSAL_MEMSET(&pstats, 0, sizeof(pstats));
1734 ecore_memcpy_from(p_hwfn, p_ptt, &pstats,
1735 pstats_addr, pstats_len);
1736
1737 p_stats->common.tx_ucast_bytes +=
1738 HILO_64_REGPAIR(pstats.sent_ucast_bytes);
1739 p_stats->common.tx_mcast_bytes +=
1740 HILO_64_REGPAIR(pstats.sent_mcast_bytes);
1741 p_stats->common.tx_bcast_bytes +=
1742 HILO_64_REGPAIR(pstats.sent_bcast_bytes);
1743 p_stats->common.tx_ucast_pkts +=
1744 HILO_64_REGPAIR(pstats.sent_ucast_pkts);
1745 p_stats->common.tx_mcast_pkts +=
1746 HILO_64_REGPAIR(pstats.sent_mcast_pkts);
1747 p_stats->common.tx_bcast_pkts +=
1748 HILO_64_REGPAIR(pstats.sent_bcast_pkts);
1749 p_stats->common.tx_err_drop_pkts +=
1750 HILO_64_REGPAIR(pstats.error_drop_pkts);
1751 }
1752
__ecore_get_vport_tstats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * p_stats,u16 statistics_bin)1753 static void __ecore_get_vport_tstats(struct ecore_hwfn *p_hwfn,
1754 struct ecore_ptt *p_ptt,
1755 struct ecore_eth_stats *p_stats,
1756 u16 statistics_bin)
1757 {
1758 struct tstorm_per_port_stat tstats;
1759 u32 tstats_addr, tstats_len;
1760
1761 if (IS_PF(p_hwfn->p_dev)) {
1762 tstats_addr = BAR0_MAP_REG_TSDM_RAM +
1763 TSTORM_PORT_STAT_OFFSET(MFW_PORT(p_hwfn));
1764 tstats_len = sizeof(struct tstorm_per_port_stat);
1765 } else {
1766 struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
1767 struct pfvf_acquire_resp_tlv *p_resp = &p_iov->acquire_resp;
1768
1769 tstats_addr = p_resp->pfdev_info.stats_info.tstats.address;
1770 tstats_len = p_resp->pfdev_info.stats_info.tstats.len;
1771 }
1772
1773 OSAL_MEMSET(&tstats, 0, sizeof(tstats));
1774 ecore_memcpy_from(p_hwfn, p_ptt, &tstats,
1775 tstats_addr, tstats_len);
1776
1777 p_stats->common.mftag_filter_discards +=
1778 HILO_64_REGPAIR(tstats.mftag_filter_discard);
1779 p_stats->common.mac_filter_discards +=
1780 HILO_64_REGPAIR(tstats.eth_mac_filter_discard);
1781 }
1782
__ecore_get_vport_ustats_addrlen(struct ecore_hwfn * p_hwfn,u32 * p_addr,u32 * p_len,u16 statistics_bin)1783 static void __ecore_get_vport_ustats_addrlen(struct ecore_hwfn *p_hwfn,
1784 u32 *p_addr, u32 *p_len,
1785 u16 statistics_bin)
1786 {
1787 if (IS_PF(p_hwfn->p_dev)) {
1788 *p_addr = BAR0_MAP_REG_USDM_RAM +
1789 USTORM_QUEUE_STAT_OFFSET(statistics_bin);
1790 *p_len = sizeof(struct eth_ustorm_per_queue_stat);
1791 } else {
1792 struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
1793 struct pfvf_acquire_resp_tlv *p_resp = &p_iov->acquire_resp;
1794
1795 *p_addr = p_resp->pfdev_info.stats_info.ustats.address;
1796 *p_len = p_resp->pfdev_info.stats_info.ustats.len;
1797 }
1798 }
1799
__ecore_get_vport_ustats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * p_stats,u16 statistics_bin)1800 static void __ecore_get_vport_ustats(struct ecore_hwfn *p_hwfn,
1801 struct ecore_ptt *p_ptt,
1802 struct ecore_eth_stats *p_stats,
1803 u16 statistics_bin)
1804 {
1805 struct eth_ustorm_per_queue_stat ustats;
1806 u32 ustats_addr = 0, ustats_len = 0;
1807
1808 __ecore_get_vport_ustats_addrlen(p_hwfn, &ustats_addr, &ustats_len,
1809 statistics_bin);
1810
1811 OSAL_MEMSET(&ustats, 0, sizeof(ustats));
1812 ecore_memcpy_from(p_hwfn, p_ptt, &ustats,
1813 ustats_addr, ustats_len);
1814
1815 p_stats->common.rx_ucast_bytes +=
1816 HILO_64_REGPAIR(ustats.rcv_ucast_bytes);
1817 p_stats->common.rx_mcast_bytes +=
1818 HILO_64_REGPAIR(ustats.rcv_mcast_bytes);
1819 p_stats->common.rx_bcast_bytes +=
1820 HILO_64_REGPAIR(ustats.rcv_bcast_bytes);
1821 p_stats->common.rx_ucast_pkts +=
1822 HILO_64_REGPAIR(ustats.rcv_ucast_pkts);
1823 p_stats->common.rx_mcast_pkts +=
1824 HILO_64_REGPAIR(ustats.rcv_mcast_pkts);
1825 p_stats->common.rx_bcast_pkts +=
1826 HILO_64_REGPAIR(ustats.rcv_bcast_pkts);
1827 }
1828
__ecore_get_vport_mstats_addrlen(struct ecore_hwfn * p_hwfn,u32 * p_addr,u32 * p_len,u16 statistics_bin)1829 static void __ecore_get_vport_mstats_addrlen(struct ecore_hwfn *p_hwfn,
1830 u32 *p_addr, u32 *p_len,
1831 u16 statistics_bin)
1832 {
1833 if (IS_PF(p_hwfn->p_dev)) {
1834 *p_addr = BAR0_MAP_REG_MSDM_RAM +
1835 MSTORM_QUEUE_STAT_OFFSET(statistics_bin);
1836 *p_len = sizeof(struct eth_mstorm_per_queue_stat);
1837 } else {
1838 struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
1839 struct pfvf_acquire_resp_tlv *p_resp = &p_iov->acquire_resp;
1840
1841 *p_addr = p_resp->pfdev_info.stats_info.mstats.address;
1842 *p_len = p_resp->pfdev_info.stats_info.mstats.len;
1843 }
1844 }
1845
__ecore_get_vport_mstats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * p_stats,u16 statistics_bin)1846 static void __ecore_get_vport_mstats(struct ecore_hwfn *p_hwfn,
1847 struct ecore_ptt *p_ptt,
1848 struct ecore_eth_stats *p_stats,
1849 u16 statistics_bin)
1850 {
1851 struct eth_mstorm_per_queue_stat mstats;
1852 u32 mstats_addr = 0, mstats_len = 0;
1853
1854 __ecore_get_vport_mstats_addrlen(p_hwfn, &mstats_addr, &mstats_len,
1855 statistics_bin);
1856
1857 OSAL_MEMSET(&mstats, 0, sizeof(mstats));
1858 ecore_memcpy_from(p_hwfn, p_ptt, &mstats,
1859 mstats_addr, mstats_len);
1860
1861 p_stats->common.no_buff_discards +=
1862 HILO_64_REGPAIR(mstats.no_buff_discard);
1863 p_stats->common.packet_too_big_discard +=
1864 HILO_64_REGPAIR(mstats.packet_too_big_discard);
1865 p_stats->common.ttl0_discard +=
1866 HILO_64_REGPAIR(mstats.ttl0_discard);
1867 p_stats->common.tpa_coalesced_pkts +=
1868 HILO_64_REGPAIR(mstats.tpa_coalesced_pkts);
1869 p_stats->common.tpa_coalesced_events +=
1870 HILO_64_REGPAIR(mstats.tpa_coalesced_events);
1871 p_stats->common.tpa_aborts_num +=
1872 HILO_64_REGPAIR(mstats.tpa_aborts_num);
1873 p_stats->common.tpa_coalesced_bytes +=
1874 HILO_64_REGPAIR(mstats.tpa_coalesced_bytes);
1875 }
1876
__ecore_get_vport_port_stats(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_eth_stats * p_stats)1877 static void __ecore_get_vport_port_stats(struct ecore_hwfn *p_hwfn,
1878 struct ecore_ptt *p_ptt,
1879 struct ecore_eth_stats *p_stats)
1880 {
1881 struct ecore_eth_stats_common *p_common = &p_stats->common;
1882 struct port_stats port_stats;
1883 int j;
1884
1885 OSAL_MEMSET(&port_stats, 0, sizeof(port_stats));
1886
1887 ecore_memcpy_from(p_hwfn, p_ptt, &port_stats,
1888 p_hwfn->mcp_info->port_addr +
1889 offsetof(struct public_port, stats),
1890 sizeof(port_stats));
1891
1892 p_common->rx_64_byte_packets += port_stats.eth.r64;
1893 p_common->rx_65_to_127_byte_packets += port_stats.eth.r127;
1894 p_common->rx_128_to_255_byte_packets += port_stats.eth.r255;
1895 p_common->rx_256_to_511_byte_packets += port_stats.eth.r511;
1896 p_common->rx_512_to_1023_byte_packets += port_stats.eth.r1023;
1897 p_common->rx_1024_to_1518_byte_packets += port_stats.eth.r1518;
1898 p_common->rx_crc_errors += port_stats.eth.rfcs;
1899 p_common->rx_mac_crtl_frames += port_stats.eth.rxcf;
1900 p_common->rx_pause_frames += port_stats.eth.rxpf;
1901 p_common->rx_pfc_frames += port_stats.eth.rxpp;
1902 p_common->rx_align_errors += port_stats.eth.raln;
1903 p_common->rx_carrier_errors += port_stats.eth.rfcr;
1904 p_common->rx_oversize_packets += port_stats.eth.rovr;
1905 p_common->rx_jabbers += port_stats.eth.rjbr;
1906 p_common->rx_undersize_packets += port_stats.eth.rund;
1907 p_common->rx_fragments += port_stats.eth.rfrg;
1908 p_common->tx_64_byte_packets += port_stats.eth.t64;
1909 p_common->tx_65_to_127_byte_packets += port_stats.eth.t127;
1910 p_common->tx_128_to_255_byte_packets += port_stats.eth.t255;
1911 p_common->tx_256_to_511_byte_packets += port_stats.eth.t511;
1912 p_common->tx_512_to_1023_byte_packets += port_stats.eth.t1023;
1913 p_common->tx_1024_to_1518_byte_packets += port_stats.eth.t1518;
1914 p_common->tx_pause_frames += port_stats.eth.txpf;
1915 p_common->tx_pfc_frames += port_stats.eth.txpp;
1916 p_common->rx_mac_bytes += port_stats.eth.rbyte;
1917 p_common->rx_mac_uc_packets += port_stats.eth.rxuca;
1918 p_common->rx_mac_mc_packets += port_stats.eth.rxmca;
1919 p_common->rx_mac_bc_packets += port_stats.eth.rxbca;
1920 p_common->rx_mac_frames_ok += port_stats.eth.rxpok;
1921 p_common->tx_mac_bytes += port_stats.eth.tbyte;
1922 p_common->tx_mac_uc_packets += port_stats.eth.txuca;
1923 p_common->tx_mac_mc_packets += port_stats.eth.txmca;
1924 p_common->tx_mac_bc_packets += port_stats.eth.txbca;
1925 p_common->tx_mac_ctrl_frames += port_stats.eth.txcf;
1926 for (j = 0; j < 8; j++) {
1927 p_common->brb_truncates += port_stats.brb.brb_truncate[j];
1928 p_common->brb_discards += port_stats.brb.brb_discard[j];
1929 }
1930
1931 if (ECORE_IS_BB(p_hwfn->p_dev)) {
1932 struct ecore_eth_stats_bb *p_bb = &p_stats->bb;
1933
1934 p_bb->rx_1519_to_1522_byte_packets +=
1935 port_stats.eth.u0.bb0.r1522;
1936 p_bb->rx_1519_to_2047_byte_packets +=
1937 port_stats.eth.u0.bb0.r2047;
1938 p_bb->rx_2048_to_4095_byte_packets +=
1939 port_stats.eth.u0.bb0.r4095;
1940 p_bb->rx_4096_to_9216_byte_packets +=
1941 port_stats.eth.u0.bb0.r9216;
1942 p_bb->rx_9217_to_16383_byte_packets +=
1943 port_stats.eth.u0.bb0.r16383;
1944 p_bb->tx_1519_to_2047_byte_packets +=
1945 port_stats.eth.u1.bb1.t2047;
1946 p_bb->tx_2048_to_4095_byte_packets +=
1947 port_stats.eth.u1.bb1.t4095;
1948 p_bb->tx_4096_to_9216_byte_packets +=
1949 port_stats.eth.u1.bb1.t9216;
1950 p_bb->tx_9217_to_16383_byte_packets +=
1951 port_stats.eth.u1.bb1.t16383;
1952 p_bb->tx_lpi_entry_count += port_stats.eth.u2.bb2.tlpiec;
1953 p_bb->tx_total_collisions += port_stats.eth.u2.bb2.tncl;
1954 } else {
1955 struct ecore_eth_stats_ah *p_ah = &p_stats->ah;
1956
1957 p_ah->rx_1519_to_max_byte_packets +=
1958 port_stats.eth.u0.ah0.r1519_to_max;
1959 p_ah->tx_1519_to_max_byte_packets =
1960 port_stats.eth.u1.ah1.t1519_to_max;
1961 }
1962 }
1963
__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)1964 void __ecore_get_vport_stats(struct ecore_hwfn *p_hwfn,
1965 struct ecore_ptt *p_ptt,
1966 struct ecore_eth_stats *stats,
1967 u16 statistics_bin, bool b_get_port_stats)
1968 {
1969 __ecore_get_vport_mstats(p_hwfn, p_ptt, stats, statistics_bin);
1970 __ecore_get_vport_ustats(p_hwfn, p_ptt, stats, statistics_bin);
1971 __ecore_get_vport_tstats(p_hwfn, p_ptt, stats, statistics_bin);
1972 __ecore_get_vport_pstats(p_hwfn, p_ptt, stats, statistics_bin);
1973
1974 #ifndef ASIC_ONLY
1975 /* Avoid getting PORT stats for emulation.*/
1976 if (CHIP_REV_IS_EMUL(p_hwfn->p_dev))
1977 return;
1978 #endif
1979
1980 if (b_get_port_stats && p_hwfn->mcp_info)
1981 __ecore_get_vport_port_stats(p_hwfn, p_ptt, stats);
1982 }
1983
_ecore_get_vport_stats(struct ecore_dev * p_dev,struct ecore_eth_stats * stats)1984 static void _ecore_get_vport_stats(struct ecore_dev *p_dev,
1985 struct ecore_eth_stats *stats)
1986 {
1987 u8 fw_vport = 0;
1988 int i;
1989
1990 OSAL_MEMSET(stats, 0, sizeof(*stats));
1991
1992 for_each_hwfn(p_dev, i) {
1993 struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
1994 struct ecore_ptt *p_ptt = IS_PF(p_dev) ?
1995 ecore_ptt_acquire(p_hwfn) : OSAL_NULL;
1996
1997 if (IS_PF(p_dev)) {
1998 /* The main vport index is relative first */
1999 if (ecore_fw_vport(p_hwfn, 0, &fw_vport)) {
2000 DP_ERR(p_hwfn, "No vport available!\n");
2001 goto out;
2002 }
2003 }
2004
2005 if (IS_PF(p_dev) && !p_ptt) {
2006 DP_ERR(p_hwfn, "Failed to acquire ptt\n");
2007 continue;
2008 }
2009
2010 __ecore_get_vport_stats(p_hwfn, p_ptt, stats, fw_vport,
2011 IS_PF(p_dev) ? true : false);
2012
2013 out:
2014 if (IS_PF(p_dev) && p_ptt)
2015 ecore_ptt_release(p_hwfn, p_ptt);
2016 }
2017 }
2018
ecore_get_vport_stats(struct ecore_dev * p_dev,struct ecore_eth_stats * stats)2019 void ecore_get_vport_stats(struct ecore_dev *p_dev,
2020 struct ecore_eth_stats *stats)
2021 {
2022 u32 i;
2023
2024 if (!p_dev) {
2025 OSAL_MEMSET(stats, 0, sizeof(*stats));
2026 return;
2027 }
2028
2029 _ecore_get_vport_stats(p_dev, stats);
2030
2031 if (!p_dev->reset_stats)
2032 return;
2033
2034 /* Reduce the statistics baseline */
2035 for (i = 0; i < sizeof(struct ecore_eth_stats) / sizeof(u64); i++)
2036 ((u64 *)stats)[i] -= ((u64 *)p_dev->reset_stats)[i];
2037 }
2038
2039 /* zeroes V-PORT specific portion of stats (Port stats remains untouched) */
ecore_reset_vport_stats(struct ecore_dev * p_dev)2040 void ecore_reset_vport_stats(struct ecore_dev *p_dev)
2041 {
2042 int i;
2043
2044 for_each_hwfn(p_dev, i) {
2045 struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
2046 struct eth_mstorm_per_queue_stat mstats;
2047 struct eth_ustorm_per_queue_stat ustats;
2048 struct eth_pstorm_per_queue_stat pstats;
2049 struct ecore_ptt *p_ptt = IS_PF(p_dev) ?
2050 ecore_ptt_acquire(p_hwfn) : OSAL_NULL;
2051 u32 addr = 0, len = 0;
2052
2053 if (IS_PF(p_dev) && !p_ptt) {
2054 DP_ERR(p_hwfn, "Failed to acquire ptt\n");
2055 continue;
2056 }
2057
2058 OSAL_MEMSET(&mstats, 0, sizeof(mstats));
2059 __ecore_get_vport_mstats_addrlen(p_hwfn, &addr, &len, 0);
2060 ecore_memcpy_to(p_hwfn, p_ptt, addr, &mstats, len);
2061
2062 OSAL_MEMSET(&ustats, 0, sizeof(ustats));
2063 __ecore_get_vport_ustats_addrlen(p_hwfn, &addr, &len, 0);
2064 ecore_memcpy_to(p_hwfn, p_ptt, addr, &ustats, len);
2065
2066 OSAL_MEMSET(&pstats, 0, sizeof(pstats));
2067 __ecore_get_vport_pstats_addrlen(p_hwfn, &addr, &len, 0);
2068 ecore_memcpy_to(p_hwfn, p_ptt, addr, &pstats, len);
2069
2070 if (IS_PF(p_dev))
2071 ecore_ptt_release(p_hwfn, p_ptt);
2072 }
2073
2074 /* PORT statistics are not necessarily reset, so we need to
2075 * read and create a baseline for future statistics.
2076 */
2077 if (!p_dev->reset_stats)
2078 DP_INFO(p_dev, "Reset stats not allocated\n");
2079 else
2080 _ecore_get_vport_stats(p_dev, p_dev->reset_stats);
2081 }
2082
ecore_arfs_mode_configure(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_arfs_config_params * p_cfg_params)2083 void ecore_arfs_mode_configure(struct ecore_hwfn *p_hwfn,
2084 struct ecore_ptt *p_ptt,
2085 struct ecore_arfs_config_params *p_cfg_params)
2086 {
2087 if (p_cfg_params->arfs_enable) {
2088 ecore_set_rfs_mode_enable(p_hwfn, p_ptt, p_hwfn->rel_pf_id,
2089 p_cfg_params->tcp,
2090 p_cfg_params->udp,
2091 p_cfg_params->ipv4,
2092 p_cfg_params->ipv6);
2093 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
2094 "tcp = %s, udp = %s, ipv4 = %s, ipv6 =%s\n",
2095 p_cfg_params->tcp ? "Enable" : "Disable",
2096 p_cfg_params->udp ? "Enable" : "Disable",
2097 p_cfg_params->ipv4 ? "Enable" : "Disable",
2098 p_cfg_params->ipv6 ? "Enable" : "Disable");
2099 } else {
2100 ecore_set_rfs_mode_disable(p_hwfn, p_ptt, p_hwfn->rel_pf_id);
2101 }
2102 DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "Configured ARFS mode : %s\n",
2103 p_cfg_params->arfs_enable ? "Enable" : "Disable");
2104 }
2105
2106 enum _ecore_status_t
ecore_configure_rfs_ntuple_filter(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_spq_comp_cb * p_cb,dma_addr_t p_addr,u16 length,u16 qid,u8 vport_id,bool b_is_add)2107 ecore_configure_rfs_ntuple_filter(struct ecore_hwfn *p_hwfn,
2108 struct ecore_ptt *p_ptt,
2109 struct ecore_spq_comp_cb *p_cb,
2110 dma_addr_t p_addr, u16 length,
2111 u16 qid, u8 vport_id,
2112 bool b_is_add)
2113 {
2114 struct rx_update_gft_filter_data *p_ramrod = OSAL_NULL;
2115 struct ecore_spq_entry *p_ent = OSAL_NULL;
2116 struct ecore_sp_init_data init_data;
2117 u16 abs_rx_q_id = 0;
2118 u8 abs_vport_id = 0;
2119 enum _ecore_status_t rc = ECORE_NOTIMPL;
2120
2121 rc = ecore_fw_vport(p_hwfn, vport_id, &abs_vport_id);
2122 if (rc != ECORE_SUCCESS)
2123 return rc;
2124
2125 rc = ecore_fw_l2_queue(p_hwfn, qid, &abs_rx_q_id);
2126 if (rc != ECORE_SUCCESS)
2127 return rc;
2128
2129 /* Get SPQ entry */
2130 OSAL_MEMSET(&init_data, 0, sizeof(init_data));
2131 init_data.cid = ecore_spq_get_cid(p_hwfn);
2132
2133 init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
2134
2135 if (p_cb) {
2136 init_data.comp_mode = ECORE_SPQ_MODE_CB;
2137 init_data.p_comp_data = p_cb;
2138 } else {
2139 init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
2140 }
2141
2142 rc = ecore_sp_init_request(p_hwfn, &p_ent,
2143 ETH_RAMROD_GFT_UPDATE_FILTER,
2144 PROTOCOLID_ETH, &init_data);
2145 if (rc != ECORE_SUCCESS)
2146 return rc;
2147
2148 p_ramrod = &p_ent->ramrod.rx_update_gft;
2149
2150 DMA_REGPAIR_LE(p_ramrod->pkt_hdr_addr, p_addr);
2151 p_ramrod->pkt_hdr_length = OSAL_CPU_TO_LE16(length);
2152 p_ramrod->rx_qid_or_action_icid = OSAL_CPU_TO_LE16(abs_rx_q_id);
2153 p_ramrod->vport_id = abs_vport_id;
2154 p_ramrod->filter_type = RFS_FILTER_TYPE;
2155 p_ramrod->filter_action = b_is_add ? GFT_ADD_FILTER
2156 : GFT_DELETE_FILTER;
2157
2158 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
2159 "V[%0x], Q[%04x] - %s filter from 0x%llx [length %04xb]\n",
2160 abs_vport_id, abs_rx_q_id,
2161 b_is_add ? "Adding" : "Removing",
2162 (u64)p_addr, length);
2163
2164 return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
2165 }
2166