1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2016-2020 Intel Corporation
5 #ifndef __DLB_OSDEP_H__
6 #define __DLB_OSDEP_H__
13 #include <rte_string_fns.h>
14 #include <rte_cycles.h>
17 #include <rte_spinlock.h>
18 #include "../dlb_main.h"
19 #include "dlb_resource.h"
20 #include "../../dlb_log.h"
21 #include "../../dlb_user.h"
24 #define DLB_PCI_REG_READ(reg) rte_read32((void *)reg)
25 #define DLB_PCI_REG_WRITE(reg, val) rte_write32(val, (void *)reg)
27 #define DLB_CSR_REG_ADDR(a, reg) ((void *)((uintptr_t)(a)->csr_kva + (reg)))
28 #define DLB_CSR_RD(hw, reg) \
29 DLB_PCI_REG_READ(DLB_CSR_REG_ADDR((hw), (reg)))
30 #define DLB_CSR_WR(hw, reg, val) \
31 DLB_PCI_REG_WRITE(DLB_CSR_REG_ADDR((hw), (reg)), (val))
33 #define DLB_FUNC_REG_ADDR(a, reg) ((void *)((uintptr_t)(a)->func_kva + (reg)))
34 #define DLB_FUNC_RD(hw, reg) \
35 DLB_PCI_REG_READ(DLB_FUNC_REG_ADDR((hw), (reg)))
36 #define DLB_FUNC_WR(hw, reg, val) \
37 DLB_PCI_REG_WRITE(DLB_FUNC_REG_ADDR((hw), (reg)), (val))
39 extern unsigned int dlb_unregister_timeout_s;
41 * os_queue_unregister_timeout_s() - timeout (in seconds) to wait for queue
42 * unregister acknowledgments.
44 static inline unsigned int os_queue_unregister_timeout_s(void)
46 return dlb_unregister_timeout_s;
49 static inline size_t os_strlcpy(char *dst, const char *src, size_t sz)
51 return rte_strlcpy(dst, src, sz);
55 * os_udelay() - busy-wait for a number of microseconds
56 * @usecs: delay duration.
58 static inline void os_udelay(int usecs)
64 * os_msleep() - sleep for a number of milliseconds
65 * @usecs: delay duration.
68 static inline void os_msleep(int msecs)
73 #define DLB_PP_BASE(__is_ldb) ((__is_ldb) ? DLB_LDB_PP_BASE : DLB_DIR_PP_BASE)
75 * os_map_producer_port() - map a producer port into the caller's address space
76 * @hw: dlb_hw handle for a particular device.
78 * @is_ldb: true for load-balanced port, false for a directed port
80 * This function maps the requested producer port memory into the caller's
84 * Returns the base address at which the PP memory was mapped, else NULL.
86 static inline void *os_map_producer_port(struct dlb_hw *hw,
94 pp_dma_base = (uintptr_t)hw->func_kva + DLB_PP_BASE(is_ldb);
95 addr = (pp_dma_base + (PAGE_SIZE * port_id));
97 return (void *)(uintptr_t)addr;
101 * os_unmap_producer_port() - unmap a producer port
102 * @addr: mapped producer port address
104 * This function undoes os_map_producer_port() by unmapping the producer port
105 * memory from the caller's address space.
108 * Returns the base address at which the PP memory was mapped, else NULL.
111 /* PFPMD - Nothing to do here, since memory was not actually mapped by us */
112 static inline void os_unmap_producer_port(struct dlb_hw *hw, void *addr)
119 * os_fence_hcw() - fence an HCW to ensure it arrives at the device
120 * @hw: dlb_hw handle for a particular device.
121 * @pp_addr: producer port address
123 static inline void os_fence_hcw(struct dlb_hw *hw, u64 *pp_addr)
127 /* To ensure outstanding HCWs reach the device, read the PP address. IA
128 * memory ordering prevents reads from passing older writes, and the
129 * mfence also ensures this.
133 *(volatile u64 *)pp_addr;
136 /* Map to PMDs logging interface */
137 #define DLB_ERR(dev, fmt, args...) \
138 DLB_LOG_ERR(fmt, ## args)
140 #define DLB_INFO(dev, fmt, args...) \
141 DLB_LOG_INFO(fmt, ## args)
143 #define DLB_DEBUG(dev, fmt, args...) \
144 DLB_LOG_DEBUG(fmt, ## args)
147 * DLB_HW_ERR() - log an error message
148 * @dlb: dlb_hw handle for a particular device.
149 * @...: variable string args.
151 #define DLB_HW_ERR(dlb, ...) do { \
153 DLB_ERR(dlb, __VA_ARGS__); \
157 * DLB_HW_INFO() - log an info message
158 * @dlb: dlb_hw handle for a particular device.
159 * @...: variable string args.
161 #define DLB_HW_INFO(dlb, ...) do { \
163 DLB_INFO(dlb, __VA_ARGS__); \
166 /*** scheduling functions ***/
168 /* The callback runs until it completes all outstanding QID->CQ
169 * map and unmap requests. To prevent deadlock, this function gives other
170 * threads a chance to grab the resource mutex and configure hardware.
172 static void *dlb_complete_queue_map_unmap(void *__args)
174 struct dlb_dev *dlb_dev = (struct dlb_dev *)__args;
178 rte_spinlock_lock(&dlb_dev->resource_mutex);
180 ret = dlb_finish_unmap_qid_procedures(&dlb_dev->hw);
181 ret += dlb_finish_map_qid_procedures(&dlb_dev->hw);
184 rte_spinlock_unlock(&dlb_dev->resource_mutex);
185 /* Relinquish the CPU so the application can process
186 * its CQs, so this function does not deadlock.
193 dlb_dev->worker_launched = false;
195 rte_spinlock_unlock(&dlb_dev->resource_mutex);
202 * os_schedule_work() - launch a thread to process pending map and unmap work
203 * @hw: dlb_hw handle for a particular device.
205 * This function launches a thread that will run until all pending
206 * map and unmap procedures are complete.
208 static inline void os_schedule_work(struct dlb_hw *hw)
210 struct dlb_dev *dlb_dev;
211 pthread_t complete_queue_map_unmap_thread;
214 dlb_dev = container_of(hw, struct dlb_dev, hw);
216 ret = rte_ctrl_thread_create(&complete_queue_map_unmap_thread,
217 "dlb_queue_unmap_waiter",
219 dlb_complete_queue_map_unmap,
223 "Could not create queue complete map/unmap thread, err=%d\n",
226 dlb_dev->worker_launched = true;
230 * os_worker_active() - query whether the map/unmap worker thread is active
231 * @hw: dlb_hw handle for a particular device.
233 * This function returns a boolean indicating whether a thread (launched by
234 * os_schedule_work()) is active. This function is used to determine
235 * whether or not to launch a worker thread.
237 static inline bool os_worker_active(struct dlb_hw *hw)
239 struct dlb_dev *dlb_dev;
241 dlb_dev = container_of(hw, struct dlb_dev, hw);
243 return dlb_dev->worker_launched;
247 * os_notify_user_space() - notify user space
248 * @hw: dlb_hw handle for a particular device.
249 * @domain_id: ID of domain to notify.
250 * @alert_id: alert ID.
251 * @aux_alert_data: additional alert data.
253 * This function notifies user space of an alert (such as a remote queue
254 * unregister or hardware alarm).
257 * Returns 0 upon success, <0 otherwise.
259 static inline int os_notify_user_space(struct dlb_hw *hw,
265 RTE_SET_USED(domain_id);
266 RTE_SET_USED(alert_id);
267 RTE_SET_USED(aux_alert_data);
269 /* Not called for PF PMD */
273 enum dlb_dev_revision {
282 * os_get_dev_revision() - query the device_revision
283 * @hw: dlb_hw handle for a particular device.
285 static inline enum dlb_dev_revision os_get_dev_revision(struct dlb_hw *hw)
287 uint32_t a, b, c, d, stepping;
291 __cpuid(0x1, a, b, c, d);
305 /* Treat all revisions >= 4 as B0 */
310 #endif /* __DLB_OSDEP_H__ */