New upstream version 17.05.1
[deb_dpdk.git] / drivers / net / qede / qede_eth_if.c
1 /*
2  * Copyright (c) 2016 QLogic Corporation.
3  * All rights reserved.
4  * www.qlogic.com
5  *
6  * See LICENSE.qede_pmd for copyright and licensing details.
7  */
8
9 #include "qede_ethdev.h"
10
11 static int
12 qed_start_vport(struct ecore_dev *edev, struct qed_start_vport_params *p_params)
13 {
14         int rc, i;
15
16         for_each_hwfn(edev, i) {
17                 struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
18                 u8 tx_switching = 0;
19                 struct ecore_sp_vport_start_params start = { 0 };
20
21                 start.tpa_mode = p_params->enable_lro ? ECORE_TPA_MODE_RSC :
22                                 ECORE_TPA_MODE_NONE;
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.mtu = p_params->mtu;
33                 /* @DPDK - Disable FW placement */
34                 start.zero_placement_offset = 1;
35
36                 rc = ecore_sp_vport_start(p_hwfn, &start);
37                 if (rc) {
38                         DP_ERR(edev, "Failed to start VPORT\n");
39                         return rc;
40                 }
41
42                 DP_VERBOSE(edev, ECORE_MSG_SPQ,
43                            "Started V-PORT %d with MTU %d\n",
44                            p_params->vport_id, p_params->mtu);
45         }
46
47         ecore_reset_vport_stats(edev);
48
49         return 0;
50 }
51
52 static int qed_stop_vport(struct ecore_dev *edev, uint8_t vport_id)
53 {
54         int rc, i;
55
56         for_each_hwfn(edev, i) {
57                 struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
58                 rc = ecore_sp_vport_stop(p_hwfn,
59                                          p_hwfn->hw_info.opaque_fid, vport_id);
60
61                 if (rc) {
62                         DP_ERR(edev, "Failed to stop VPORT\n");
63                         return rc;
64                 }
65         }
66
67         return 0;
68 }
69
70 static int
71 qed_update_vport(struct ecore_dev *edev, struct qed_update_vport_params *params)
72 {
73         struct ecore_sp_vport_update_params sp_params;
74         struct ecore_rss_params sp_rss_params;
75         int rc, i;
76
77         memset(&sp_params, 0, sizeof(sp_params));
78         memset(&sp_rss_params, 0, sizeof(sp_rss_params));
79
80         /* Translate protocol params into sp params */
81         sp_params.vport_id = params->vport_id;
82         sp_params.update_vport_active_rx_flg = params->update_vport_active_flg;
83         sp_params.update_vport_active_tx_flg = params->update_vport_active_flg;
84         sp_params.vport_active_rx_flg = params->vport_active_flg;
85         sp_params.vport_active_tx_flg = params->vport_active_flg;
86         sp_params.update_inner_vlan_removal_flg =
87             params->update_inner_vlan_removal_flg;
88         sp_params.inner_vlan_removal_flg = params->inner_vlan_removal_flg;
89         sp_params.update_tx_switching_flg = params->update_tx_switching_flg;
90         sp_params.tx_switching_flg = params->tx_switching_flg;
91         sp_params.accept_any_vlan = params->accept_any_vlan;
92         sp_params.update_accept_any_vlan_flg =
93             params->update_accept_any_vlan_flg;
94         sp_params.mtu = params->mtu;
95         sp_params.sge_tpa_params = params->sge_tpa_params;
96
97         for_each_hwfn(edev, i) {
98                 struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
99
100                 sp_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
101                 rc = ecore_sp_vport_update(p_hwfn, &sp_params,
102                                            ECORE_SPQ_MODE_EBLOCK, NULL);
103                 if (rc) {
104                         DP_ERR(edev, "Failed to update VPORT\n");
105                         return rc;
106                 }
107
108                 DP_VERBOSE(edev, ECORE_MSG_SPQ,
109                            "Updated V-PORT %d: active_flag %d [update %d]\n",
110                            params->vport_id, params->vport_active_flg,
111                            params->update_vport_active_flg);
112         }
113
114         return 0;
115 }
116
117 static int
118 qed_start_rxq(struct ecore_dev *edev,
119               uint8_t rss_num,
120               struct ecore_queue_start_common_params *p_params,
121               uint16_t bd_max_bytes,
122               dma_addr_t bd_chain_phys_addr,
123               dma_addr_t cqe_pbl_addr,
124               uint16_t cqe_pbl_size,
125               struct ecore_rxq_start_ret_params *ret_params)
126 {
127         struct ecore_hwfn *p_hwfn;
128         int rc, hwfn_index;
129
130         hwfn_index = rss_num % edev->num_hwfns;
131         p_hwfn = &edev->hwfns[hwfn_index];
132
133         p_params->queue_id = p_params->queue_id / edev->num_hwfns;
134         p_params->stats_id = p_params->vport_id;
135
136         rc = ecore_eth_rx_queue_start(p_hwfn,
137                                       p_hwfn->hw_info.opaque_fid,
138                                       p_params,
139                                       bd_max_bytes,
140                                       bd_chain_phys_addr,
141                                       cqe_pbl_addr,
142                                       cqe_pbl_size,
143                                       ret_params);
144
145         if (rc) {
146                 DP_ERR(edev, "Failed to start RXQ#%d\n", p_params->queue_id);
147                 return rc;
148         }
149
150         DP_VERBOSE(edev, ECORE_MSG_SPQ,
151                    "Started RX-Q %d [rss_num %d] on V-PORT %d and SB %d\n",
152                    p_params->queue_id, rss_num, p_params->vport_id,
153                    p_params->sb);
154
155         return 0;
156 }
157
158 static int
159 qed_stop_rxq(struct ecore_dev *edev, uint8_t rss_id, void *handle)
160 {
161         int rc, hwfn_index;
162         struct ecore_hwfn *p_hwfn;
163
164         hwfn_index = rss_id % edev->num_hwfns;
165         p_hwfn = &edev->hwfns[hwfn_index];
166
167         rc = ecore_eth_rx_queue_stop(p_hwfn, handle, true, false);
168         if (rc) {
169                 DP_ERR(edev, "Failed to stop RXQ#%02x\n", rss_id);
170                 return rc;
171         }
172
173         return 0;
174 }
175
176 static int
177 qed_start_txq(struct ecore_dev *edev,
178               uint8_t rss_num,
179               struct ecore_queue_start_common_params *p_params,
180               dma_addr_t pbl_addr,
181               uint16_t pbl_size,
182               struct ecore_txq_start_ret_params *ret_params)
183 {
184         struct ecore_hwfn *p_hwfn;
185         int rc, hwfn_index;
186
187         hwfn_index = rss_num % edev->num_hwfns;
188         p_hwfn = &edev->hwfns[hwfn_index];
189
190         p_params->queue_id = p_params->queue_id / edev->num_hwfns;
191         p_params->stats_id = p_params->vport_id;
192
193         rc = ecore_eth_tx_queue_start(p_hwfn,
194                                       p_hwfn->hw_info.opaque_fid,
195                                       p_params, 0 /* tc */,
196                                       pbl_addr, pbl_size,
197                                       ret_params);
198
199         if (rc) {
200                 DP_ERR(edev, "Failed to start TXQ#%d\n", p_params->queue_id);
201                 return rc;
202         }
203
204         DP_VERBOSE(edev, ECORE_MSG_SPQ,
205                    "Started TX-Q %d [rss_num %d] on V-PORT %d and SB %d\n",
206                    p_params->queue_id, rss_num, p_params->vport_id,
207                    p_params->sb);
208
209         return 0;
210 }
211
212 static int
213 qed_stop_txq(struct ecore_dev *edev, uint8_t rss_id, void *handle)
214 {
215         struct ecore_hwfn *p_hwfn;
216         int rc, hwfn_index;
217
218         hwfn_index = rss_id % edev->num_hwfns;
219         p_hwfn = &edev->hwfns[hwfn_index];
220
221         rc = ecore_eth_tx_queue_stop(p_hwfn, handle);
222         if (rc) {
223                 DP_ERR(edev, "Failed to stop TXQ#%02x\n", rss_id);
224                 return rc;
225         }
226
227         return 0;
228 }
229
230 static int
231 qed_fp_cqe_completion(struct ecore_dev *edev,
232                       uint8_t rss_id, struct eth_slow_path_rx_cqe *cqe)
233 {
234         return ecore_eth_cqe_completion(&edev->hwfns[rss_id % edev->num_hwfns],
235                                         cqe);
236 }
237
238 static int qed_fastpath_stop(struct ecore_dev *edev)
239 {
240         ecore_hw_stop_fastpath(edev);
241
242         return 0;
243 }
244
245 static void qed_fastpath_start(struct ecore_dev *edev)
246 {
247         struct ecore_hwfn *p_hwfn;
248         int i;
249
250         for_each_hwfn(edev, i) {
251                 p_hwfn = &edev->hwfns[i];
252                 ecore_hw_start_fastpath(p_hwfn);
253         }
254 }
255
256 static void
257 qed_get_vport_stats(struct ecore_dev *edev, struct ecore_eth_stats *stats)
258 {
259         ecore_get_vport_stats(edev, stats);
260 }
261
262 int qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev,
263                                  enum qed_filter_rx_mode_type type)
264 {
265         struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
266         struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
267         struct ecore_filter_accept_flags flags;
268
269         memset(&flags, 0, sizeof(flags));
270
271         flags.update_rx_mode_config = 1;
272         flags.update_tx_mode_config = 1;
273         flags.rx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED |
274                                         ECORE_ACCEPT_MCAST_MATCHED |
275                                         ECORE_ACCEPT_BCAST;
276
277         flags.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED |
278                                  ECORE_ACCEPT_MCAST_MATCHED |
279                                  ECORE_ACCEPT_BCAST;
280
281         if (type == QED_FILTER_RX_MODE_TYPE_PROMISC) {
282                 flags.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED;
283                 if (IS_VF(edev)) {
284                         flags.tx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED;
285                         DP_INFO(edev, "Enabling Tx unmatched flag for VF\n");
286                 }
287         } else if (type == QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC) {
288                 flags.rx_accept_filter |= ECORE_ACCEPT_MCAST_UNMATCHED;
289         } else if (type == (QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC |
290                             QED_FILTER_RX_MODE_TYPE_PROMISC)) {
291                 flags.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED |
292                                           ECORE_ACCEPT_MCAST_UNMATCHED;
293         }
294
295         return ecore_filter_accept_cmd(edev, 0, flags, false, false,
296                                        ECORE_SPQ_MODE_CB, NULL);
297 }
298
299 static const struct qed_eth_ops qed_eth_ops_pass = {
300         INIT_STRUCT_FIELD(common, &qed_common_ops_pass),
301         INIT_STRUCT_FIELD(fill_dev_info, &qed_fill_eth_dev_info),
302         INIT_STRUCT_FIELD(vport_start, &qed_start_vport),
303         INIT_STRUCT_FIELD(vport_stop, &qed_stop_vport),
304         INIT_STRUCT_FIELD(vport_update, &qed_update_vport),
305         INIT_STRUCT_FIELD(q_rx_start, &qed_start_rxq),
306         INIT_STRUCT_FIELD(q_tx_start, &qed_start_txq),
307         INIT_STRUCT_FIELD(q_rx_stop, &qed_stop_rxq),
308         INIT_STRUCT_FIELD(q_tx_stop, &qed_stop_txq),
309         INIT_STRUCT_FIELD(eth_cqe_completion, &qed_fp_cqe_completion),
310         INIT_STRUCT_FIELD(fastpath_stop, &qed_fastpath_stop),
311         INIT_STRUCT_FIELD(fastpath_start, &qed_fastpath_start),
312         INIT_STRUCT_FIELD(get_vport_stats, &qed_get_vport_stats),
313 };
314
315 const struct qed_eth_ops *qed_get_eth_ops(void)
316 {
317         return &qed_eth_ops_pass;
318 }