net/qede/base: update
[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->gro_enable ? ECORE_TPA_MODE_GRO :
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.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;
36
37                 rc = ecore_sp_vport_start(p_hwfn, &start);
38                 if (rc) {
39                         DP_ERR(edev, "Failed to start VPORT\n");
40                         return rc;
41                 }
42
43                 ecore_hw_start_fastpath(p_hwfn);
44
45                 DP_VERBOSE(edev, ECORE_MSG_SPQ,
46                            "Started V-PORT %d with MTU %d\n",
47                            p_params->vport_id, p_params->mtu);
48         }
49
50         ecore_reset_vport_stats(edev);
51
52         return 0;
53 }
54
55 static int qed_stop_vport(struct ecore_dev *edev, uint8_t vport_id)
56 {
57         int rc, i;
58
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);
63
64                 if (rc) {
65                         DP_ERR(edev, "Failed to stop VPORT\n");
66                         return rc;
67                 }
68         }
69
70         return 0;
71 }
72
73 static int
74 qed_update_vport(struct ecore_dev *edev, struct qed_update_vport_params *params)
75 {
76         struct ecore_sp_vport_update_params sp_params;
77         struct ecore_rss_params sp_rss_params;
78         int rc, i;
79
80         memset(&sp_params, 0, sizeof(sp_params));
81         memset(&sp_rss_params, 0, sizeof(sp_rss_params));
82
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;
97
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.
100          */
101
102         if (edev->num_hwfns > 1 && params->update_rss_flg) {
103                 struct qed_update_vport_rss_params *rss = &params->rss_params;
104                 int k, max = 0;
105
106                 /* Find largest entry, since it's possible RSS needs to
107                  * be disabled [in case only 1 queue per-hwfn]
108                  */
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];
112
113                 /* Either fix RSS values or disable RSS */
114                 if (edev->num_hwfns < max + 1) {
115                         int divisor = (max + edev->num_hwfns - 1) /
116                             edev->num_hwfns;
117
118                         DP_VERBOSE(edev, ECORE_MSG_SPQ,
119                                    "CMT - fixing RSS values (modulo %02x)\n",
120                                    divisor);
121
122                         for (k = 0; k < ECORE_RSS_IND_TABLE_SIZE; k++)
123                                 rss->rss_ind_table[k] =
124                                     rss->rss_ind_table[k] % divisor;
125                 } else {
126                         DP_VERBOSE(edev, ECORE_MSG_SPQ,
127                                    "CMT - 1 queue per-hwfn; Disabling RSS\n");
128                         params->update_rss_flg = 0;
129                 }
130         }
131
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));
147         }
148         sp_params.rss_params = &sp_rss_params;
149
150         for_each_hwfn(edev, i) {
151                 struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
152
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);
156                 if (rc) {
157                         DP_ERR(edev, "Failed to update VPORT\n");
158                         return rc;
159                 }
160
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);
165         }
166
167         return 0;
168 }
169
170 static int
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)
178 {
179         struct ecore_hwfn *p_hwfn;
180         int rc, hwfn_index;
181
182         hwfn_index = rss_id % edev->num_hwfns;
183         p_hwfn = &edev->hwfns[hwfn_index];
184
185         rc = ecore_sp_eth_rx_queue_start(p_hwfn,
186                                          p_hwfn->hw_info.opaque_fid,
187                                          rx_queue_id / edev->num_hwfns,
188                                          vport_id,
189                                          vport_id,
190                                          sb,
191                                          sb_index,
192                                          bd_max_bytes,
193                                          bd_chain_phys_addr,
194                                          cqe_pbl_addr, cqe_pbl_size, pp_prod);
195
196         if (rc) {
197                 DP_ERR(edev, "Failed to start RXQ#%d\n", rx_queue_id);
198                 return rc;
199         }
200
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);
204
205         return 0;
206 }
207
208 static int
209 qed_stop_rxq(struct ecore_dev *edev, struct qed_stop_rxq_params *params)
210 {
211         int rc, hwfn_index;
212         struct ecore_hwfn *p_hwfn;
213
214         hwfn_index = params->rss_id % edev->num_hwfns;
215         p_hwfn = &edev->hwfns[hwfn_index];
216
217         rc = ecore_sp_eth_rx_queue_stop(p_hwfn,
218                                         params->rx_queue_id / edev->num_hwfns,
219                                         params->eq_completion_only, false);
220         if (rc) {
221                 DP_ERR(edev, "Failed to stop RXQ#%d\n", params->rx_queue_id);
222                 return rc;
223         }
224
225         return 0;
226 }
227
228 static int
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,
232               uint8_t sb_index,
233               dma_addr_t pbl_addr,
234               uint16_t pbl_size, void OSAL_IOMEM * *pp_doorbell)
235 {
236         struct ecore_hwfn *p_hwfn;
237         int rc, hwfn_index;
238
239         hwfn_index = rss_id % edev->num_hwfns;
240         p_hwfn = &edev->hwfns[hwfn_index];
241
242         rc = ecore_sp_eth_tx_queue_start(p_hwfn,
243                                          p_hwfn->hw_info.opaque_fid,
244                                          tx_queue_id / edev->num_hwfns,
245                                          vport_id,
246                                          vport_id,
247                                          sb,
248                                          sb_index,
249                                          0 /* tc */,
250                                          pbl_addr, pbl_size, pp_doorbell);
251
252         if (rc) {
253                 DP_ERR(edev, "Failed to start TXQ#%d\n", tx_queue_id);
254                 return rc;
255         }
256
257         DP_VERBOSE(edev, ECORE_MSG_SPQ,
258                    "Started TX-Q %d [rss %d] on V-PORT %d and SB %d\n",
259                    tx_queue_id, rss_id, vport_id, sb);
260
261         return 0;
262 }
263
264 static int
265 qed_stop_txq(struct ecore_dev *edev, struct qed_stop_txq_params *params)
266 {
267         struct ecore_hwfn *p_hwfn;
268         int rc, hwfn_index;
269
270         hwfn_index = params->rss_id % edev->num_hwfns;
271         p_hwfn = &edev->hwfns[hwfn_index];
272
273         rc = ecore_sp_eth_tx_queue_stop(p_hwfn,
274                                         params->tx_queue_id / edev->num_hwfns);
275         if (rc) {
276                 DP_ERR(edev, "Failed to stop TXQ#%d\n", params->tx_queue_id);
277                 return rc;
278         }
279
280         return 0;
281 }
282
283 static int
284 qed_fp_cqe_completion(struct ecore_dev *edev,
285                       uint8_t rss_id, struct eth_slow_path_rx_cqe *cqe)
286 {
287         return ecore_eth_cqe_completion(&edev->hwfns[rss_id % edev->num_hwfns],
288                                         cqe);
289 }
290
291 static int qed_fastpath_stop(struct ecore_dev *edev)
292 {
293         ecore_hw_stop_fastpath(edev);
294
295         return 0;
296 }
297
298 static void
299 qed_get_vport_stats(struct ecore_dev *edev, struct ecore_eth_stats *stats)
300 {
301         ecore_get_vport_stats(edev, stats);
302 }
303
304 static int
305 qed_configure_filter_ucast(struct ecore_dev *edev,
306                            struct qed_filter_ucast_params *params)
307 {
308         struct ecore_filter_ucast ucast;
309
310         if (!params->vlan_valid && !params->mac_valid) {
311                 DP_NOTICE(edev, true,
312                           "Tried configuring a unicast filter,"
313                           "but both MAC and VLAN are not set\n");
314                 return -EINVAL;
315         }
316
317         memset(&ucast, 0, sizeof(ucast));
318         switch (params->type) {
319         case QED_FILTER_XCAST_TYPE_ADD:
320                 ucast.opcode = ECORE_FILTER_ADD;
321                 break;
322         case QED_FILTER_XCAST_TYPE_DEL:
323                 ucast.opcode = ECORE_FILTER_REMOVE;
324                 break;
325         case QED_FILTER_XCAST_TYPE_REPLACE:
326                 ucast.opcode = ECORE_FILTER_REPLACE;
327                 break;
328         default:
329                 DP_NOTICE(edev, true, "Unknown unicast filter type %d\n",
330                           params->type);
331         }
332
333         if (params->vlan_valid && params->mac_valid) {
334                 ucast.type = ECORE_FILTER_MAC_VLAN;
335                 ether_addr_copy((struct ether_addr *)&params->mac,
336                                 (struct ether_addr *)&ucast.mac);
337                 ucast.vlan = params->vlan;
338         } else if (params->mac_valid) {
339                 ucast.type = ECORE_FILTER_MAC;
340                 ether_addr_copy((struct ether_addr *)&params->mac,
341                                 (struct ether_addr *)&ucast.mac);
342         } else {
343                 ucast.type = ECORE_FILTER_VLAN;
344                 ucast.vlan = params->vlan;
345         }
346
347         ucast.is_rx_filter = true;
348         ucast.is_tx_filter = true;
349
350         return ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
351 }
352
353 static int
354 qed_configure_filter_mcast(struct ecore_dev *edev,
355                            struct qed_filter_mcast_params *params)
356 {
357         struct ecore_filter_mcast mcast;
358         int i;
359
360         memset(&mcast, 0, sizeof(mcast));
361         switch (params->type) {
362         case QED_FILTER_XCAST_TYPE_ADD:
363                 mcast.opcode = ECORE_FILTER_ADD;
364                 break;
365         case QED_FILTER_XCAST_TYPE_DEL:
366                 mcast.opcode = ECORE_FILTER_REMOVE;
367                 break;
368         default:
369                 DP_NOTICE(edev, true, "Unknown multicast filter type %d\n",
370                           params->type);
371         }
372
373         mcast.num_mc_addrs = params->num;
374         for (i = 0; i < mcast.num_mc_addrs; i++)
375                 ether_addr_copy((struct ether_addr *)&params->mac[i],
376                                 (struct ether_addr *)&mcast.mac[i]);
377
378         return ecore_filter_mcast_cmd(edev, &mcast, ECORE_SPQ_MODE_CB, NULL);
379 }
380
381 int qed_configure_filter_rx_mode(struct ecore_dev *edev,
382                                  enum qed_filter_rx_mode_type type)
383 {
384         struct ecore_filter_accept_flags flags;
385
386         memset(&flags, 0, sizeof(flags));
387
388         flags.update_rx_mode_config = 1;
389         flags.update_tx_mode_config = 1;
390         flags.rx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED |
391                                         ECORE_ACCEPT_MCAST_MATCHED |
392                                         ECORE_ACCEPT_BCAST;
393
394         flags.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED |
395                                  ECORE_ACCEPT_MCAST_MATCHED |
396                                  ECORE_ACCEPT_BCAST;
397
398         if (type == QED_FILTER_RX_MODE_TYPE_PROMISC) {
399                 flags.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED;
400                 if (IS_VF(edev)) {
401                         flags.tx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED;
402                         DP_INFO(edev, "Enabling Tx unmatched flag for VF\n");
403                 }
404         } else if (type == QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC) {
405                 flags.rx_accept_filter |= ECORE_ACCEPT_MCAST_UNMATCHED;
406         } else if (type == (QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC |
407                             QED_FILTER_RX_MODE_TYPE_PROMISC)) {
408                 flags.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED |
409                                           ECORE_ACCEPT_MCAST_UNMATCHED;
410         }
411
412         return ecore_filter_accept_cmd(edev, 0, flags, false, false,
413                                        ECORE_SPQ_MODE_CB, NULL);
414 }
415
416 static int
417 qed_configure_filter(struct ecore_dev *edev, struct qed_filter_params *params)
418 {
419         switch (params->type) {
420         case QED_FILTER_TYPE_UCAST:
421                 return qed_configure_filter_ucast(edev, &params->filter.ucast);
422         case QED_FILTER_TYPE_MCAST:
423                 return qed_configure_filter_mcast(edev, &params->filter.mcast);
424         case QED_FILTER_TYPE_RX_MODE:
425                 return qed_configure_filter_rx_mode(edev,
426                                                     params->filter.
427                                                     accept_flags);
428         default:
429                 DP_NOTICE(edev, true, "Unknown filter type %d\n",
430                           (int)params->type);
431                 return -EINVAL;
432         }
433 }
434
435 static const struct qed_eth_ops qed_eth_ops_pass = {
436         INIT_STRUCT_FIELD(common, &qed_common_ops_pass),
437         INIT_STRUCT_FIELD(fill_dev_info, &qed_fill_eth_dev_info),
438         INIT_STRUCT_FIELD(vport_start, &qed_start_vport),
439         INIT_STRUCT_FIELD(vport_stop, &qed_stop_vport),
440         INIT_STRUCT_FIELD(vport_update, &qed_update_vport),
441         INIT_STRUCT_FIELD(q_rx_start, &qed_start_rxq),
442         INIT_STRUCT_FIELD(q_tx_start, &qed_start_txq),
443         INIT_STRUCT_FIELD(q_rx_stop, &qed_stop_rxq),
444         INIT_STRUCT_FIELD(q_tx_stop, &qed_stop_txq),
445         INIT_STRUCT_FIELD(eth_cqe_completion, &qed_fp_cqe_completion),
446         INIT_STRUCT_FIELD(fastpath_stop, &qed_fastpath_stop),
447         INIT_STRUCT_FIELD(get_vport_stats, &qed_get_vport_stats),
448         INIT_STRUCT_FIELD(filter_config, &qed_configure_filter),
449 };
450
451 uint32_t qed_get_protocol_version(enum qed_protocol protocol)
452 {
453         switch (protocol) {
454         case QED_PROTOCOL_ETH:
455                 return QED_ETH_INTERFACE_VERSION;
456         default:
457                 return 0;
458         }
459 }
460
461 const struct qed_eth_ops *qed_get_eth_ops(void)
462 {
463         return &qed_eth_ops_pass;
464 }