bus/dpaa: introduce NXP DPAA bus driver skeleton
[dpdk.git] / drivers / bus / dpaa / dpaa_bus.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright 2017 NXP.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of NXP nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /* System headers */
33 #include <stdio.h>
34 #include <inttypes.h>
35 #include <unistd.h>
36 #include <limits.h>
37 #include <sched.h>
38 #include <signal.h>
39 #include <pthread.h>
40 #include <sys/types.h>
41 #include <sys/syscall.h>
42
43 #include <rte_config.h>
44 #include <rte_byteorder.h>
45 #include <rte_common.h>
46 #include <rte_interrupts.h>
47 #include <rte_log.h>
48 #include <rte_debug.h>
49 #include <rte_pci.h>
50 #include <rte_atomic.h>
51 #include <rte_branch_prediction.h>
52 #include <rte_memory.h>
53 #include <rte_memzone.h>
54 #include <rte_tailq.h>
55 #include <rte_eal.h>
56 #include <rte_alarm.h>
57 #include <rte_ether.h>
58 #include <rte_ethdev.h>
59 #include <rte_malloc.h>
60 #include <rte_ring.h>
61 #include <rte_bus.h>
62
63 #include <rte_dpaa_bus.h>
64 #include <rte_dpaa_logs.h>
65
66 int dpaa_logtype_bus;
67
68 struct rte_dpaa_bus rte_dpaa_bus;
69
70 static inline void
71 dpaa_add_to_device_list(struct rte_dpaa_device *dev)
72 {
73         TAILQ_INSERT_TAIL(&rte_dpaa_bus.device_list, dev, next);
74 }
75
76 static inline void
77 dpaa_remove_from_device_list(struct rte_dpaa_device *dev)
78 {
79         TAILQ_INSERT_TAIL(&rte_dpaa_bus.device_list, dev, next);
80 }
81
82 static int
83 rte_dpaa_bus_scan(void)
84 {
85         BUS_INIT_FUNC_TRACE();
86
87         return 0;
88 }
89
90 /* register a dpaa bus based dpaa driver */
91 void
92 rte_dpaa_driver_register(struct rte_dpaa_driver *driver)
93 {
94         RTE_VERIFY(driver);
95
96         BUS_INIT_FUNC_TRACE();
97
98         TAILQ_INSERT_TAIL(&rte_dpaa_bus.driver_list, driver, next);
99         /* Update Bus references */
100         driver->dpaa_bus = &rte_dpaa_bus;
101 }
102
103 /* un-register a dpaa bus based dpaa driver */
104 void
105 rte_dpaa_driver_unregister(struct rte_dpaa_driver *driver)
106 {
107         struct rte_dpaa_bus *dpaa_bus;
108
109         BUS_INIT_FUNC_TRACE();
110
111         dpaa_bus = driver->dpaa_bus;
112
113         TAILQ_REMOVE(&dpaa_bus->driver_list, driver, next);
114         /* Update Bus references */
115         driver->dpaa_bus = NULL;
116 }
117
118 static int
119 rte_dpaa_device_match(struct rte_dpaa_driver *drv,
120                       struct rte_dpaa_device *dev)
121 {
122         int ret = -1;
123
124         BUS_INIT_FUNC_TRACE();
125
126         if (!drv || !dev) {
127                 DPAA_BUS_DEBUG("Invalid drv or dev received.");
128                 return ret;
129         }
130
131         if (drv->drv_type == dev->device_type) {
132                 DPAA_BUS_INFO("Device: %s matches for driver: %s",
133                               dev->name, drv->driver.name);
134                 ret = 0; /* Found a match */
135         }
136
137         return ret;
138 }
139
140 static int
141 rte_dpaa_bus_probe(void)
142 {
143         int ret = -1;
144         struct rte_dpaa_device *dev;
145         struct rte_dpaa_driver *drv;
146
147         BUS_INIT_FUNC_TRACE();
148
149         /* For each registered driver, and device, call the driver->probe */
150         TAILQ_FOREACH(dev, &rte_dpaa_bus.device_list, next) {
151                 TAILQ_FOREACH(drv, &rte_dpaa_bus.driver_list, next) {
152                         ret = rte_dpaa_device_match(drv, dev);
153                         if (ret)
154                                 continue;
155
156                         if (!drv->probe)
157                                 continue;
158
159                         ret = drv->probe(drv, dev);
160                         if (ret)
161                                 DPAA_BUS_ERR("Unable to probe.\n");
162                         break;
163                 }
164         }
165         return 0;
166 }
167
168 static struct rte_device *
169 rte_dpaa_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
170                      const void *data)
171 {
172         struct rte_dpaa_device *dev;
173
174         TAILQ_FOREACH(dev, &rte_dpaa_bus.device_list, next) {
175                 if (start && &dev->device == start) {
176                         start = NULL;  /* starting point found */
177                         continue;
178                 }
179
180                 if (cmp(&dev->device, data) == 0)
181                         return &dev->device;
182         }
183
184         return NULL;
185 }
186
187 struct rte_dpaa_bus rte_dpaa_bus = {
188         .bus = {
189                 .scan = rte_dpaa_bus_scan,
190                 .probe = rte_dpaa_bus_probe,
191                 .find_device = rte_dpaa_find_device,
192         },
193         .device_list = TAILQ_HEAD_INITIALIZER(rte_dpaa_bus.device_list),
194         .driver_list = TAILQ_HEAD_INITIALIZER(rte_dpaa_bus.driver_list),
195         .device_count = 0,
196 };
197
198 RTE_REGISTER_BUS(FSL_DPAA_BUS_NAME, rte_dpaa_bus.bus);
199
200 RTE_INIT(dpaa_init_log);
201 static void
202 dpaa_init_log(void)
203 {
204         dpaa_logtype_bus = rte_log_register("bus.dpaa");
205         if (dpaa_logtype_bus >= 0)
206                 rte_log_set_level(dpaa_logtype_bus, RTE_LOG_NOTICE);
207 }