2 * Copyright (c) 2016 QLogic Corporation.
6 * See LICENSE.qede_pmd for copyright and licensing details.
9 #include "qede_ethdev.h"
12 qed_start_vport(struct ecore_dev *edev, struct qed_start_vport_params *p_params)
16 for_each_hwfn(edev, i) {
17 struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
19 struct ecore_sp_vport_start_params start = { 0 };
21 start.tpa_mode = p_params->gro_enable ? ECORE_TPA_MODE_GRO :
23 start.remove_inner_vlan = p_params->remove_inner_vlan;
24 start.tx_switching = tx_switching;
25 start.only_untagged = false; /* untagged only */
26 start.drop_ttl0 = p_params->drop_ttl0;
27 start.concrete_fid = p_hwfn->hw_info.concrete_fid;
28 start.opaque_fid = p_hwfn->hw_info.opaque_fid;
29 start.concrete_fid = p_hwfn->hw_info.concrete_fid;
30 start.handle_ptp_pkts = p_params->handle_ptp_pkts;
31 start.vport_id = p_params->vport_id;
32 start.max_buffers_per_cqe = 16; /* TODO-is this right */
33 start.mtu = p_params->mtu;
34 /* @DPDK - Disable FW placement */
35 start.zero_placement_offset = 1;
37 rc = ecore_sp_vport_start(p_hwfn, &start);
39 DP_ERR(edev, "Failed to start VPORT\n");
43 ecore_hw_start_fastpath(p_hwfn);
45 DP_VERBOSE(edev, ECORE_MSG_SPQ,
46 "Started V-PORT %d with MTU %d\n",
47 p_params->vport_id, p_params->mtu);
50 ecore_reset_vport_stats(edev);
55 static int qed_stop_vport(struct ecore_dev *edev, uint8_t vport_id)
59 for_each_hwfn(edev, i) {
60 struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
61 rc = ecore_sp_vport_stop(p_hwfn,
62 p_hwfn->hw_info.opaque_fid, vport_id);
65 DP_ERR(edev, "Failed to stop VPORT\n");
74 qed_update_vport(struct ecore_dev *edev, struct qed_update_vport_params *params)
76 struct ecore_sp_vport_update_params sp_params;
77 struct ecore_rss_params sp_rss_params;
80 memset(&sp_params, 0, sizeof(sp_params));
81 memset(&sp_rss_params, 0, sizeof(sp_rss_params));
83 /* Translate protocol params into sp params */
84 sp_params.vport_id = params->vport_id;
85 sp_params.update_vport_active_rx_flg = params->update_vport_active_flg;
86 sp_params.update_vport_active_tx_flg = params->update_vport_active_flg;
87 sp_params.vport_active_rx_flg = params->vport_active_flg;
88 sp_params.vport_active_tx_flg = params->vport_active_flg;
89 sp_params.update_inner_vlan_removal_flg =
90 params->update_inner_vlan_removal_flg;
91 sp_params.inner_vlan_removal_flg = params->inner_vlan_removal_flg;
92 sp_params.update_tx_switching_flg = params->update_tx_switching_flg;
93 sp_params.tx_switching_flg = params->tx_switching_flg;
94 sp_params.accept_any_vlan = params->accept_any_vlan;
95 sp_params.update_accept_any_vlan_flg =
96 params->update_accept_any_vlan_flg;
98 /* RSS - is a bit tricky, since upper-layer isn't familiar with hwfns.
99 * We need to re-fix the rss values per engine for CMT.
102 if (edev->num_hwfns > 1 && params->update_rss_flg) {
103 struct qed_update_vport_rss_params *rss = ¶ms->rss_params;
106 /* Find largest entry, since it's possible RSS needs to
107 * be disabled [in case only 1 queue per-hwfn]
109 for (k = 0; k < ECORE_RSS_IND_TABLE_SIZE; k++)
110 max = (max > rss->rss_ind_table[k]) ?
111 max : rss->rss_ind_table[k];
113 /* Either fix RSS values or disable RSS */
114 if (edev->num_hwfns < max + 1) {
115 int divisor = (max + edev->num_hwfns - 1) /
118 DP_VERBOSE(edev, ECORE_MSG_SPQ,
119 "CMT - fixing RSS values (modulo %02x)\n",
122 for (k = 0; k < ECORE_RSS_IND_TABLE_SIZE; k++)
123 rss->rss_ind_table[k] =
124 rss->rss_ind_table[k] % divisor;
126 DP_VERBOSE(edev, ECORE_MSG_SPQ,
127 "CMT - 1 queue per-hwfn; Disabling RSS\n");
128 params->update_rss_flg = 0;
132 /* Now, update the RSS configuration for actual configuration */
133 if (params->update_rss_flg) {
134 sp_rss_params.update_rss_config = 1;
135 sp_rss_params.rss_enable = 1;
136 sp_rss_params.update_rss_capabilities = 1;
137 sp_rss_params.update_rss_ind_table = 1;
138 sp_rss_params.update_rss_key = 1;
139 sp_rss_params.rss_caps = ECORE_RSS_IPV4 | ECORE_RSS_IPV6 |
140 ECORE_RSS_IPV4_TCP | ECORE_RSS_IPV6_TCP;
141 sp_rss_params.rss_table_size_log = 7; /* 2^7 = 128 */
142 rte_memcpy(sp_rss_params.rss_ind_table,
143 params->rss_params.rss_ind_table,
144 ECORE_RSS_IND_TABLE_SIZE * sizeof(uint16_t));
145 rte_memcpy(sp_rss_params.rss_key, params->rss_params.rss_key,
146 ECORE_RSS_KEY_SIZE * sizeof(uint32_t));
148 sp_params.rss_params = &sp_rss_params;
150 for_each_hwfn(edev, i) {
151 struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
153 sp_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
154 rc = ecore_sp_vport_update(p_hwfn, &sp_params,
155 ECORE_SPQ_MODE_EBLOCK, NULL);
157 DP_ERR(edev, "Failed to update VPORT\n");
161 DP_VERBOSE(edev, ECORE_MSG_SPQ,
162 "Updated V-PORT %d: active_flag %d [update %d]\n",
163 params->vport_id, params->vport_active_flg,
164 params->update_vport_active_flg);
171 qed_start_rxq(struct ecore_dev *edev,
172 uint8_t rss_id, uint8_t rx_queue_id,
173 uint8_t vport_id, uint16_t sb,
174 uint8_t sb_index, uint16_t bd_max_bytes,
175 dma_addr_t bd_chain_phys_addr,
176 dma_addr_t cqe_pbl_addr,
177 uint16_t cqe_pbl_size, void OSAL_IOMEM * *pp_prod)
179 struct ecore_hwfn *p_hwfn;
182 hwfn_index = rss_id % edev->num_hwfns;
183 p_hwfn = &edev->hwfns[hwfn_index];
185 rc = ecore_sp_eth_rx_queue_start(p_hwfn,
186 p_hwfn->hw_info.opaque_fid,
187 rx_queue_id / edev->num_hwfns,
194 cqe_pbl_addr, cqe_pbl_size, pp_prod);
197 DP_ERR(edev, "Failed to start RXQ#%d\n", rx_queue_id);
201 DP_VERBOSE(edev, ECORE_MSG_SPQ,
202 "Started RX-Q %d [rss %d] on V-PORT %d and SB %d\n",
203 rx_queue_id, rss_id, vport_id, sb);
209 qed_stop_rxq(struct ecore_dev *edev, struct qed_stop_rxq_params *params)
212 struct ecore_hwfn *p_hwfn;
214 hwfn_index = params->rss_id % edev->num_hwfns;
215 p_hwfn = &edev->hwfns[hwfn_index];
217 rc = ecore_sp_eth_rx_queue_stop(p_hwfn,
218 params->rx_queue_id / edev->num_hwfns,
219 params->eq_completion_only, false);
221 DP_ERR(edev, "Failed to stop RXQ#%d\n", params->rx_queue_id);
229 qed_start_txq(struct ecore_dev *edev,
230 uint8_t rss_id, uint16_t tx_queue_id,
231 uint8_t vport_id, uint16_t sb,
234 uint16_t pbl_size, void OSAL_IOMEM * *pp_doorbell)
236 struct ecore_hwfn *p_hwfn;
239 hwfn_index = rss_id % edev->num_hwfns;
240 p_hwfn = &edev->hwfns[hwfn_index];
242 rc = ecore_sp_eth_tx_queue_start(p_hwfn,
243 p_hwfn->hw_info.opaque_fid,
244 tx_queue_id / edev->num_hwfns,
249 pbl_addr, pbl_size, pp_doorbell);
252 DP_ERR(edev, "Failed to start TXQ#%d\n", tx_queue_id);
256 DP_VERBOSE(edev, ECORE_MSG_SPQ,
257 "Started TX-Q %d [rss %d] on V-PORT %d and SB %d\n",
258 tx_queue_id, rss_id, vport_id, sb);
264 qed_stop_txq(struct ecore_dev *edev, struct qed_stop_txq_params *params)
266 struct ecore_hwfn *p_hwfn;
269 hwfn_index = params->rss_id % edev->num_hwfns;
270 p_hwfn = &edev->hwfns[hwfn_index];
272 rc = ecore_sp_eth_tx_queue_stop(p_hwfn,
273 params->tx_queue_id / edev->num_hwfns);
275 DP_ERR(edev, "Failed to stop TXQ#%d\n", params->tx_queue_id);
283 qed_fp_cqe_completion(struct ecore_dev *edev,
284 uint8_t rss_id, struct eth_slow_path_rx_cqe *cqe)
286 return ecore_eth_cqe_completion(&edev->hwfns[rss_id % edev->num_hwfns],
290 static int qed_fastpath_stop(struct ecore_dev *edev)
292 ecore_hw_stop_fastpath(edev);
298 qed_get_vport_stats(struct ecore_dev *edev, struct ecore_eth_stats *stats)
300 ecore_get_vport_stats(edev, stats);
304 qed_configure_filter_ucast(struct ecore_dev *edev,
305 struct qed_filter_ucast_params *params)
307 struct ecore_filter_ucast ucast;
309 if (!params->vlan_valid && !params->mac_valid) {
310 DP_NOTICE(edev, true,
311 "Tried configuring a unicast filter,"
312 "but both MAC and VLAN are not set\n");
316 memset(&ucast, 0, sizeof(ucast));
317 switch (params->type) {
318 case QED_FILTER_XCAST_TYPE_ADD:
319 ucast.opcode = ECORE_FILTER_ADD;
321 case QED_FILTER_XCAST_TYPE_DEL:
322 ucast.opcode = ECORE_FILTER_REMOVE;
324 case QED_FILTER_XCAST_TYPE_REPLACE:
325 ucast.opcode = ECORE_FILTER_REPLACE;
328 DP_NOTICE(edev, true, "Unknown unicast filter type %d\n",
332 if (params->vlan_valid && params->mac_valid) {
333 ucast.type = ECORE_FILTER_MAC_VLAN;
334 ether_addr_copy((struct ether_addr *)¶ms->mac,
335 (struct ether_addr *)&ucast.mac);
336 ucast.vlan = params->vlan;
337 } else if (params->mac_valid) {
338 ucast.type = ECORE_FILTER_MAC;
339 ether_addr_copy((struct ether_addr *)¶ms->mac,
340 (struct ether_addr *)&ucast.mac);
342 ucast.type = ECORE_FILTER_VLAN;
343 ucast.vlan = params->vlan;
346 ucast.is_rx_filter = true;
347 ucast.is_tx_filter = true;
349 return ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
353 qed_configure_filter_mcast(struct ecore_dev *edev,
354 struct qed_filter_mcast_params *params)
356 struct ecore_filter_mcast mcast;
359 memset(&mcast, 0, sizeof(mcast));
360 switch (params->type) {
361 case QED_FILTER_XCAST_TYPE_ADD:
362 mcast.opcode = ECORE_FILTER_ADD;
364 case QED_FILTER_XCAST_TYPE_DEL:
365 mcast.opcode = ECORE_FILTER_REMOVE;
368 DP_NOTICE(edev, true, "Unknown multicast filter type %d\n",
372 mcast.num_mc_addrs = params->num;
373 for (i = 0; i < mcast.num_mc_addrs; i++)
374 ether_addr_copy((struct ether_addr *)¶ms->mac[i],
375 (struct ether_addr *)&mcast.mac[i]);
377 return ecore_filter_mcast_cmd(edev, &mcast, ECORE_SPQ_MODE_CB, NULL);
381 qed_configure_filter_rx_mode(struct ecore_dev *edev,
382 enum qed_filter_rx_mode_type type)
384 struct ecore_filter_accept_flags accept_flags;
386 memset(&accept_flags, 0, sizeof(accept_flags));
388 accept_flags.update_rx_mode_config = 1;
389 accept_flags.update_tx_mode_config = 1;
390 accept_flags.rx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED |
391 ECORE_ACCEPT_MCAST_MATCHED |
393 accept_flags.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED |
394 ECORE_ACCEPT_MCAST_MATCHED |
397 if (type == QED_FILTER_RX_MODE_TYPE_PROMISC)
398 accept_flags.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED;
399 else if (type == QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC)
400 accept_flags.rx_accept_filter |= ECORE_ACCEPT_MCAST_UNMATCHED;
401 else if (type == (QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC |
402 QED_FILTER_RX_MODE_TYPE_PROMISC))
403 accept_flags.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED |
404 ECORE_ACCEPT_MCAST_UNMATCHED;
406 return ecore_filter_accept_cmd(edev, 0, accept_flags, false, false,
407 ECORE_SPQ_MODE_CB, NULL);
411 qed_configure_filter(struct ecore_dev *edev, struct qed_filter_params *params)
413 switch (params->type) {
414 case QED_FILTER_TYPE_UCAST:
415 return qed_configure_filter_ucast(edev, ¶ms->filter.ucast);
416 case QED_FILTER_TYPE_MCAST:
417 return qed_configure_filter_mcast(edev, ¶ms->filter.mcast);
418 case QED_FILTER_TYPE_RX_MODE:
419 return qed_configure_filter_rx_mode(edev,
423 DP_NOTICE(edev, true, "Unknown filter type %d\n",
429 static const struct qed_eth_ops qed_eth_ops_pass = {
430 INIT_STRUCT_FIELD(common, &qed_common_ops_pass),
431 INIT_STRUCT_FIELD(fill_dev_info, &qed_fill_eth_dev_info),
432 INIT_STRUCT_FIELD(vport_start, &qed_start_vport),
433 INIT_STRUCT_FIELD(vport_stop, &qed_stop_vport),
434 INIT_STRUCT_FIELD(vport_update, &qed_update_vport),
435 INIT_STRUCT_FIELD(q_rx_start, &qed_start_rxq),
436 INIT_STRUCT_FIELD(q_tx_start, &qed_start_txq),
437 INIT_STRUCT_FIELD(q_rx_stop, &qed_stop_rxq),
438 INIT_STRUCT_FIELD(q_tx_stop, &qed_stop_txq),
439 INIT_STRUCT_FIELD(eth_cqe_completion, &qed_fp_cqe_completion),
440 INIT_STRUCT_FIELD(fastpath_stop, &qed_fastpath_stop),
441 INIT_STRUCT_FIELD(get_vport_stats, &qed_get_vport_stats),
442 INIT_STRUCT_FIELD(filter_config, &qed_configure_filter),
445 uint32_t qed_get_protocol_version(enum qed_protocol protocol)
448 case QED_PROTOCOL_ETH:
449 return QED_ETH_INTERFACE_VERSION;
455 const struct qed_eth_ops *qed_get_eth_ops(void)
457 return &qed_eth_ops_pass;