4ace5432a089f8a6fd76326299eba0cb57a007cf
[dpdk.git] / drivers / net / bnxt / bnxt_ethdev.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) Broadcom Limited.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Broadcom Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <inttypes.h>
35 #include <stdbool.h>
36
37 #include <rte_dev.h>
38 #include <rte_ethdev.h>
39 #include <rte_malloc.h>
40 #include <rte_cycles.h>
41
42 #include "bnxt.h"
43 #include "bnxt_hwrm.h"
44 #include "bnxt_rxq.h"
45 #include "bnxt_stats.h"
46 #include "bnxt_txq.h"
47 #include "bnxt_txr.h"
48
49 #define DRV_MODULE_NAME         "bnxt"
50 static const char bnxt_version[] =
51         "Broadcom Cumulus driver " DRV_MODULE_NAME "\n";
52
53 static struct rte_pci_id bnxt_pci_id_map[] = {
54 #define RTE_PCI_DEV_ID_DECL_BNXT(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
55 #include "rte_pci_dev_ids.h"
56         {.device_id = 0},
57 };
58
59 static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
60 {
61         struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
62
63         rte_free(eth_dev->data->mac_addrs);
64         bnxt_free_hwrm_resources(bp);
65 }
66
67 /*
68  * Device configuration and status function
69  */
70
71 static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
72                                   struct rte_eth_dev_info *dev_info)
73 {
74         struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
75         uint16_t max_vnics, i, j, vpool, vrxq;
76
77         /* MAC Specifics */
78         dev_info->max_mac_addrs = MAX_NUM_MAC_ADDR;
79         dev_info->max_hash_mac_addrs = 0;
80
81         /* PF/VF specifics */
82         if (BNXT_PF(bp)) {
83                 dev_info->max_rx_queues = bp->pf.max_rx_rings;
84                 dev_info->max_tx_queues = bp->pf.max_tx_rings;
85                 dev_info->max_vfs = bp->pf.active_vfs;
86                 dev_info->reta_size = bp->pf.max_rsscos_ctx;
87                 max_vnics = bp->pf.max_vnics;
88         } else {
89                 dev_info->max_rx_queues = bp->vf.max_rx_rings;
90                 dev_info->max_tx_queues = bp->vf.max_tx_rings;
91                 dev_info->reta_size = bp->vf.max_rsscos_ctx;
92                 max_vnics = bp->vf.max_vnics;
93         }
94
95         /* Fast path specifics */
96         dev_info->min_rx_bufsize = 1;
97         dev_info->max_rx_pktlen = BNXT_MAX_MTU + ETHER_HDR_LEN + ETHER_CRC_LEN
98                                   + VLAN_TAG_SIZE;
99         dev_info->rx_offload_capa = 0;
100         dev_info->tx_offload_capa = DEV_TX_OFFLOAD_IPV4_CKSUM |
101                                         DEV_TX_OFFLOAD_TCP_CKSUM |
102                                         DEV_TX_OFFLOAD_UDP_CKSUM |
103                                         DEV_TX_OFFLOAD_TCP_TSO;
104
105         /* *INDENT-OFF* */
106         dev_info->default_rxconf = (struct rte_eth_rxconf) {
107                 .rx_thresh = {
108                         .pthresh = 8,
109                         .hthresh = 8,
110                         .wthresh = 0,
111                 },
112                 .rx_free_thresh = 32,
113                 .rx_drop_en = 0,
114         };
115
116         dev_info->default_txconf = (struct rte_eth_txconf) {
117                 .tx_thresh = {
118                         .pthresh = 32,
119                         .hthresh = 0,
120                         .wthresh = 0,
121                 },
122                 .tx_free_thresh = 32,
123                 .tx_rs_thresh = 32,
124                 .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
125                              ETH_TXQ_FLAGS_NOOFFLOADS,
126         };
127         /* *INDENT-ON* */
128
129         /*
130          * TODO: default_rxconf, default_txconf, rx_desc_lim, and tx_desc_lim
131          *       need further investigation.
132          */
133
134         /* VMDq resources */
135         vpool = 64; /* ETH_64_POOLS */
136         vrxq = 128; /* ETH_VMDQ_DCB_NUM_QUEUES */
137         for (i = 0; i < 4; vpool >>= 1, i++) {
138                 if (max_vnics > vpool) {
139                         for (j = 0; j < 5; vrxq >>= 1, j++) {
140                                 if (dev_info->max_rx_queues > vrxq) {
141                                         if (vpool > vrxq)
142                                                 vpool = vrxq;
143                                         goto found;
144                                 }
145                         }
146                         /* Not enough resources to support VMDq */
147                         break;
148                 }
149         }
150         /* Not enough resources to support VMDq */
151         vpool = 0;
152         vrxq = 0;
153 found:
154         dev_info->max_vmdq_pools = vpool;
155         dev_info->vmdq_queue_num = vrxq;
156
157         dev_info->vmdq_pool_base = 0;
158         dev_info->vmdq_queue_base = 0;
159 }
160
161 /* Configure the device based on the configuration provided */
162 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
163 {
164         struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
165         int rc;
166
167         bp->rx_queues = (void *)eth_dev->data->rx_queues;
168         bp->tx_queues = (void *)eth_dev->data->tx_queues;
169
170         /* Inherit new configurations */
171         bp->rx_nr_rings = eth_dev->data->nb_rx_queues;
172         bp->tx_nr_rings = eth_dev->data->nb_tx_queues;
173         bp->rx_cp_nr_rings = bp->rx_nr_rings;
174         bp->tx_cp_nr_rings = bp->tx_nr_rings;
175
176         if (eth_dev->data->dev_conf.rxmode.jumbo_frame)
177                 eth_dev->data->mtu =
178                                 eth_dev->data->dev_conf.rxmode.max_rx_pkt_len -
179                                 ETHER_HDR_LEN - ETHER_CRC_LEN - VLAN_TAG_SIZE;
180         rc = bnxt_set_hwrm_link_config(bp, true);
181         return rc;
182 }
183
184 /*
185  * Initialization
186  */
187
188 static struct eth_dev_ops bnxt_dev_ops = {
189         .dev_infos_get = bnxt_dev_info_get_op,
190         .dev_close = bnxt_dev_close_op,
191         .dev_configure = bnxt_dev_configure_op,
192         .stats_get = bnxt_stats_get_op,
193         .stats_reset = bnxt_stats_reset_op,
194         .rx_queue_setup = bnxt_rx_queue_setup_op,
195         .rx_queue_release = bnxt_rx_queue_release_op,
196         .tx_queue_setup = bnxt_tx_queue_setup_op,
197         .tx_queue_release = bnxt_tx_queue_release_op,
198 };
199
200 static bool bnxt_vf_pciid(uint16_t id)
201 {
202         if (id == BROADCOM_DEV_ID_57304_VF ||
203             id == BROADCOM_DEV_ID_57406_VF)
204                 return true;
205         return false;
206 }
207
208 static int bnxt_init_board(struct rte_eth_dev *eth_dev)
209 {
210         int rc;
211         struct bnxt *bp = eth_dev->data->dev_private;
212
213         /* enable device (incl. PCI PM wakeup), and bus-mastering */
214         if (!eth_dev->pci_dev->mem_resource[0].addr) {
215                 RTE_LOG(ERR, PMD,
216                         "Cannot find PCI device base address, aborting\n");
217                 rc = -ENODEV;
218                 goto init_err_disable;
219         }
220
221         bp->eth_dev = eth_dev;
222         bp->pdev = eth_dev->pci_dev;
223
224         bp->bar0 = (void *)eth_dev->pci_dev->mem_resource[0].addr;
225         if (!bp->bar0) {
226                 RTE_LOG(ERR, PMD, "Cannot map device registers, aborting\n");
227                 rc = -ENOMEM;
228                 goto init_err_release;
229         }
230         return 0;
231
232 init_err_release:
233         if (bp->bar0)
234                 bp->bar0 = NULL;
235
236 init_err_disable:
237
238         return rc;
239 }
240
241 static int
242 bnxt_dev_init(struct rte_eth_dev *eth_dev)
243 {
244         static int version_printed;
245         struct bnxt *bp;
246         int rc;
247
248         if (version_printed++ == 0)
249                 RTE_LOG(INFO, PMD, "%s", bnxt_version);
250
251         if (eth_dev->pci_dev->addr.function >= 2 &&
252                         eth_dev->pci_dev->addr.function < 4) {
253                 RTE_LOG(ERR, PMD, "Function not enabled %x:\n",
254                         eth_dev->pci_dev->addr.function);
255                 rc = -ENOMEM;
256                 goto error;
257         }
258
259         rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
260         bp = eth_dev->data->dev_private;
261
262         if (bnxt_vf_pciid(eth_dev->pci_dev->id.device_id))
263                 bp->flags |= BNXT_FLAG_VF;
264
265         rc = bnxt_init_board(eth_dev);
266         if (rc) {
267                 RTE_LOG(ERR, PMD,
268                         "Board initialization failed rc: %x\n", rc);
269                 goto error;
270         }
271         eth_dev->dev_ops = &bnxt_dev_ops;
272         /* eth_dev->rx_pkt_burst = &bnxt_recv_pkts; */
273         eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
274
275         rc = bnxt_alloc_hwrm_resources(bp);
276         if (rc) {
277                 RTE_LOG(ERR, PMD,
278                         "hwrm resource allocation failure rc: %x\n", rc);
279                 goto error_free;
280         }
281         rc = bnxt_hwrm_ver_get(bp);
282         if (rc)
283                 goto error_free;
284         bnxt_hwrm_queue_qportcfg(bp);
285
286         /* Get the MAX capabilities for this function */
287         rc = bnxt_hwrm_func_qcaps(bp);
288         if (rc) {
289                 RTE_LOG(ERR, PMD, "hwrm query capability failure rc: %x\n", rc);
290                 goto error_free;
291         }
292         eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl",
293                                         ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR, 0);
294         if (eth_dev->data->mac_addrs == NULL) {
295                 RTE_LOG(ERR, PMD,
296                         "Failed to alloc %u bytes needed to store MAC addr tbl",
297                         ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR);
298                 rc = -ENOMEM;
299                 goto error_free;
300         }
301         /* Copy the permanent MAC from the qcap response address now. */
302         if (BNXT_PF(bp))
303                 memcpy(bp->mac_addr, bp->pf.mac_addr, sizeof(bp->mac_addr));
304         else
305                 memcpy(bp->mac_addr, bp->vf.mac_addr, sizeof(bp->mac_addr));
306         memcpy(&eth_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
307
308         rc = bnxt_hwrm_func_driver_register(bp, 0,
309                                             bp->pf.vf_req_fwd);
310         if (rc) {
311                 RTE_LOG(ERR, PMD,
312                         "Failed to register driver");
313                 rc = -EBUSY;
314                 goto error_free;
315         }
316
317         RTE_LOG(INFO, PMD,
318                 DRV_MODULE_NAME " found at mem %" PRIx64 ", node addr %pM\n",
319                 eth_dev->pci_dev->mem_resource[0].phys_addr,
320                 eth_dev->pci_dev->mem_resource[0].addr);
321
322         return 0;
323
324 error_free:
325         eth_dev->driver->eth_dev_uninit(eth_dev);
326 error:
327         return rc;
328 }
329
330 static int
331 bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
332         struct bnxt *bp = eth_dev->data->dev_private;
333         int rc;
334
335         if (eth_dev->data->mac_addrs)
336                 rte_free(eth_dev->data->mac_addrs);
337         rc = bnxt_hwrm_func_driver_unregister(bp, 0);
338         bnxt_free_hwrm_resources(bp);
339         return rc;
340 }
341
342 static struct eth_driver bnxt_rte_pmd = {
343         .pci_drv = {
344                     .name = "rte_" DRV_MODULE_NAME "_pmd",
345                     .id_table = bnxt_pci_id_map,
346                     .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
347                     },
348         .eth_dev_init = bnxt_dev_init,
349         .eth_dev_uninit = bnxt_dev_uninit,
350         .dev_private_size = sizeof(struct bnxt),
351 };
352
353 static int bnxt_rte_pmd_init(const char *name, const char *params __rte_unused)
354 {
355         RTE_LOG(INFO, PMD, "bnxt_rte_pmd_init() called for %s\n", name);
356         rte_eth_driver_register(&bnxt_rte_pmd);
357         return 0;
358 }
359
360 static struct rte_driver bnxt_pmd_drv = {
361         .name = "eth_bnxt",
362         .type = PMD_PDEV,
363         .init = bnxt_rte_pmd_init,
364 };
365
366 PMD_REGISTER_DRIVER(bnxt_pmd_drv);