net/bnxt: add hardware resource manager init code
[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
45 #define DRV_MODULE_NAME         "bnxt"
46 static const char bnxt_version[] =
47         "Broadcom Cumulus driver " DRV_MODULE_NAME "\n";
48
49 static struct rte_pci_id bnxt_pci_id_map[] = {
50 #define RTE_PCI_DEV_ID_DECL_BNXT(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
51 #include "rte_pci_dev_ids.h"
52         {.device_id = 0},
53 };
54
55 static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
56 {
57         struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
58
59         rte_free(eth_dev->data->mac_addrs);
60         bnxt_free_hwrm_resources(bp);
61 }
62
63 /*
64  * Initialization
65  */
66
67 static struct eth_dev_ops bnxt_dev_ops = {
68         .dev_close = bnxt_dev_close_op,
69 };
70
71 static bool bnxt_vf_pciid(uint16_t id)
72 {
73         if (id == BROADCOM_DEV_ID_57304_VF ||
74             id == BROADCOM_DEV_ID_57406_VF)
75                 return true;
76         return false;
77 }
78
79 static int bnxt_init_board(struct rte_eth_dev *eth_dev)
80 {
81         int rc;
82         struct bnxt *bp = eth_dev->data->dev_private;
83
84         /* enable device (incl. PCI PM wakeup), and bus-mastering */
85         if (!eth_dev->pci_dev->mem_resource[0].addr) {
86                 RTE_LOG(ERR, PMD,
87                         "Cannot find PCI device base address, aborting\n");
88                 rc = -ENODEV;
89                 goto init_err_disable;
90         }
91
92         bp->eth_dev = eth_dev;
93         bp->pdev = eth_dev->pci_dev;
94
95         bp->bar0 = (void *)eth_dev->pci_dev->mem_resource[0].addr;
96         if (!bp->bar0) {
97                 RTE_LOG(ERR, PMD, "Cannot map device registers, aborting\n");
98                 rc = -ENOMEM;
99                 goto init_err_release;
100         }
101         return 0;
102
103 init_err_release:
104         if (bp->bar0)
105                 bp->bar0 = NULL;
106
107 init_err_disable:
108
109         return rc;
110 }
111
112 static int
113 bnxt_dev_init(struct rte_eth_dev *eth_dev)
114 {
115         static int version_printed;
116         struct bnxt *bp;
117         int rc;
118
119         if (version_printed++ == 0)
120                 RTE_LOG(INFO, PMD, "%s", bnxt_version);
121
122         if (eth_dev->pci_dev->addr.function >= 2 &&
123                         eth_dev->pci_dev->addr.function < 4) {
124                 RTE_LOG(ERR, PMD, "Function not enabled %x:\n",
125                         eth_dev->pci_dev->addr.function);
126                 rc = -ENOMEM;
127                 goto error;
128         }
129
130         rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
131         bp = eth_dev->data->dev_private;
132
133         if (bnxt_vf_pciid(eth_dev->pci_dev->id.device_id))
134                 bp->flags |= BNXT_FLAG_VF;
135
136         rc = bnxt_init_board(eth_dev);
137         if (rc) {
138                 RTE_LOG(ERR, PMD,
139                         "Board initialization failed rc: %x\n", rc);
140                 goto error;
141         }
142         eth_dev->dev_ops = &bnxt_dev_ops;
143         /* eth_dev->rx_pkt_burst = &bnxt_recv_pkts; */
144         /* eth_dev->tx_pkt_burst = &bnxt_xmit_pkts; */
145
146         rc = bnxt_alloc_hwrm_resources(bp);
147         if (rc) {
148                 RTE_LOG(ERR, PMD,
149                         "hwrm resource allocation failure rc: %x\n", rc);
150                 goto error_free;
151         }
152         rc = bnxt_hwrm_ver_get(bp);
153         if (rc)
154                 goto error_free;
155         bnxt_hwrm_queue_qportcfg(bp);
156
157         /* Get the MAX capabilities for this function */
158         rc = bnxt_hwrm_func_qcaps(bp);
159         if (rc) {
160                 RTE_LOG(ERR, PMD, "hwrm query capability failure rc: %x\n", rc);
161                 goto error_free;
162         }
163         eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl",
164                                         ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR, 0);
165         if (eth_dev->data->mac_addrs == NULL) {
166                 RTE_LOG(ERR, PMD,
167                         "Failed to alloc %u bytes needed to store MAC addr tbl",
168                         ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR);
169                 rc = -ENOMEM;
170                 goto error_free;
171         }
172         /* Copy the permanent MAC from the qcap response address now. */
173         if (BNXT_PF(bp))
174                 memcpy(bp->mac_addr, bp->pf.mac_addr, sizeof(bp->mac_addr));
175         else
176                 memcpy(bp->mac_addr, bp->vf.mac_addr, sizeof(bp->mac_addr));
177         memcpy(&eth_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
178
179         return -EPERM;
180
181 error_free:
182         bnxt_dev_close_op(eth_dev);
183 error:
184         return rc;
185 }
186
187 static int
188 bnxt_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused) {
189         return 0;
190 }
191
192 static struct eth_driver bnxt_rte_pmd = {
193         .pci_drv = {
194                     .name = "rte_" DRV_MODULE_NAME "_pmd",
195                     .id_table = bnxt_pci_id_map,
196                     .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
197                     },
198         .eth_dev_init = bnxt_dev_init,
199         .eth_dev_uninit = bnxt_dev_uninit,
200         .dev_private_size = sizeof(struct bnxt),
201 };
202
203 static int bnxt_rte_pmd_init(const char *name, const char *params __rte_unused)
204 {
205         RTE_LOG(INFO, PMD, "bnxt_rte_pmd_init() called for %s\n", name);
206         rte_eth_driver_register(&bnxt_rte_pmd);
207         return 0;
208 }
209
210 static struct rte_driver bnxt_pmd_drv = {
211         .name = "eth_bnxt",
212         .type = PMD_PDEV,
213         .init = bnxt_rte_pmd_init,
214 };
215
216 PMD_REGISTER_DRIVER(bnxt_pmd_drv);