6 ////////////////////////////////////////////////////////
10 ////////////////////////////////////////////////////////
14 //#include <iointex.h>
20 #include <ntstrsafe.h>
23 #include <complib/cl_timer.h>
24 #include <complib/cl_qlist.h>
30 ////////////////////////////////////////////////////////
34 ////////////////////////////////////////////////////////
36 #define BITS_PER_LONG 32
38 #define HZ 1000000 /* 1 sec in usecs */
42 ////////////////////////////////////////////////////////
46 ////////////////////////////////////////////////////////
48 #define BUG_ON(exp) ASSERT(!(exp)) /* in Linux follows here panic() !*/
49 #define snprintf _snprintf
50 #define printk cl_dbg_out
51 #define KERN_ERR "err:"
52 #define KERN_WARNING "warn:"
53 #define KERN_DEBUG "dbg:"
56 #define wmb KeMemoryBarrier
57 #define rmb KeMemoryBarrier
58 #define mb KeMemoryBarrier
59 // TODO: can we make it empty ? I saw in Linux, it is an empty macro for x86 & x64
60 #define mmiowb KeMemoryBarrier
63 #define EXPORT_SYMBOL_GPL(a)
65 // gcc compiler attributes
72 #define __attribute_const__
74 #define unlikely(x) (x)
75 #define __attribute__(a)
79 #define container_of CONTAINING_RECORD
82 #define inline __inline
84 // new Linux event mechanism
85 #define complete(a) wake_up(a)
88 #define __constant_htons CL_HTON16
89 #define __constant_cpu_to_be32 CL_HTON32
92 #define __always_inline inline
94 ////////////////////////////////////////////////////////
98 ////////////////////////////////////////////////////////
101 typedef unsigned char u8, __u8;
102 typedef unsigned short int u16, __u16;
103 typedef unsigned int u32, __u32;
104 typedef unsigned __int64 u64, __u64;
105 typedef char s8, __s8;
106 typedef short int s16, __s16;
107 typedef int s32, __s32;
108 typedef __int64 s64, __s64;
117 typedef u64 io_addr_t;
120 typedef void (*MT_EMPTY_FUNC)();
122 // PCI BAR descriptor
123 typedef enum _hca_bar_type
133 typedef struct _hca_bar
141 struct msix_saved_info {
142 PVOID vca; /* MSI-X Vector Table card address */
143 PVOID mca; /* MSI-X Mask Table card address */
144 PVOID vsa; /* MSI-X Vector Table saved address */
145 PVOID msa; /* MSI-X Mask Table saved address */
146 ULONG vsz; /* MSI-X Vector Table size */
147 ULONG msz; /* MSI-X Mask Table size */
148 int num; /* number of supported MSI-X vectors */
149 int valid; /* the structure is valid */
153 KAFFINITY cpu; /* affinity of this MSI-X vector */
154 int eq_ix; /* EQ index in the array of EQs */
155 int ref_cnt; /* number of users */
158 // interface structure between Upper and Low Layers of the driver
161 // driver: OS/platform resources
162 BUS_INTERFACE_STANDARD bus_pci_ifc;
163 PCI_COMMON_CONFIG pci_cfg_space;
164 struct msix_saved_info msix_info;
165 struct msix_map* p_msix_map;
166 uplink_info_t uplink_info;
167 // driver: card resources
168 hca_bar_t bar[N_BARS];
169 CM_PARTIAL_RESOURCE_DESCRIPTOR int_info; /* HCA interrupt resources */
170 // driver: various objects and info
173 DMA_ADAPTER * p_dma_adapter; /* HCA adapter object */
174 DEVICE_OBJECT * p_self_do; /* mlx4_bus's FDO */
175 DEVICE_OBJECT * pdo; /* mlx4_bus's PDO */
176 // mlx4_ib: various objects and info
177 struct ib_device * ib_dev;
178 // mlx4_net: various objects and info
179 struct mlx4_dev * dev;
180 volatile long dpc_lock;
181 #ifdef USE_WDM_INTERRUPTS
182 PKINTERRUPT int_obj; /* HCA interrupt object */
183 KSPIN_LOCK isr_lock; /* lock for the ISR */
185 u8 n_msi_vectors_alloc;/* number of allocated MSI vectors */
186 u8 n_msi_vectors; /* number of MSI vectors; 0 - no MSI */
193 typedef void (*dpc_t)( struct _KDPC *, PVOID, PVOID, PVOID );
196 ////////////////////////////////////////////////////////
200 ////////////////////////////////////////////////////////
203 #define swab32(a) _byteswap_ulong((ULONG)(a))
204 #define cpu_to_be16(a) _byteswap_ushort((USHORT)(a))
205 #define be16_to_cpu(a) _byteswap_ushort((USHORT)(a))
206 #define cpu_to_be32(a) _byteswap_ulong((ULONG)(a))
207 #define be32_to_cpu(a) _byteswap_ulong((ULONG)(a))
208 #define cpu_to_be64(a) _byteswap_uint64((UINT64)(a))
209 #define be64_to_cpu(a) _byteswap_uint64((UINT64)(a))
210 #define be64_to_cpup(p) _byteswap_uint64(*(PUINT64)(p))
211 #define be32_to_cpup(p) _byteswap_ulong(*(PULONG)(p))
212 #define be16_to_cpup(p) _byteswap_ushort(*(PUSHORT)(p))
215 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
218 #define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
219 #define PTR_ALIGN(size) (((size) + sizeof(void*) - 1) & ~(sizeof(void*) - 1))
221 // there is a bug in Microsoft compiler, that when _byteswap_uint64() gets an expression
222 // it executes the expression but doesn't swap tte dwords
223 // So, there's a workaround
224 #ifdef BYTESWAP_UINT64_BUG_FIXED
225 #define CPU_2_BE64_PREP
226 #define CPU_2_BE64(x) cl_hton64(x)
228 #define CPU_2_BE64_PREP unsigned __int64 __tmp__
229 #define CPU_2_BE64(x) ( __tmp__ = x, cl_hton64(__tmp__) )
232 #define ERR_PTR(error) ((void*)(LONG_PTR)(error))
233 #define PTR_ERR(ptr) ((long)(LONG_PTR)(void*)(ptr))
234 //TODO: there are 2 assumptions here:
235 // - pointer can't be too big (around -1)
236 // - error can't be bigger than 1000
237 #define IS_ERR(ptr) ((ULONG_PTR)ptr > (ULONG_PTR)-1000L)
239 #define BITS_TO_LONGS(bits) \
240 (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
243 #define ETIMEDOUT (110)
248 #define PAGE_ALIGN(Va) ((u64)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)))
251 #define NEXT_PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
254 #define min_t(type,x,y) ((type)(x) < (type)(y) ? (type)(x) : (type)(y))
256 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
258 #define EXPORT_SYMBOL(name)
259 #ifndef USE_WDM_INTERRUPTS
260 #define free_irq(pdev)
263 static inline NTSTATUS errno_to_ntstatus(int err)
265 #define MAP_ERR(err,ntstatus) case err: status = ntstatus; break
269 return STATUS_SUCCESS;
274 MAP_ERR( ENOENT, STATUS_NOT_FOUND );
275 MAP_ERR( EAGAIN, STATUS_DEVICE_BUSY );
276 MAP_ERR( ENOMEM, STATUS_NO_MEMORY );
277 MAP_ERR( EACCES, STATUS_ACCESS_DENIED );
278 MAP_ERR( EFAULT, STATUS_DRIVER_INTERNAL_ERROR );
279 MAP_ERR( EBUSY, STATUS_INSUFFICIENT_RESOURCES );
280 MAP_ERR( ENODEV, STATUS_NOT_SUPPORTED );
281 MAP_ERR( EINVAL, STATUS_INVALID_PARAMETER );
282 MAP_ERR( ENOSYS, STATUS_NOT_SUPPORTED );
284 status = STATUS_UNSUCCESSFUL;
291 ////////////////////////////////////////////////////////
295 ////////////////////////////////////////////////////////
297 SIZE_T strlcpy(char *dest, const void *src, SIZE_T size);
302 ////////////////////////////////////////////////////////
306 ////////////////////////////////////////////////////////
311 #include <l2w_atomic.h>
313 #include <l2w_bitmap.h>
314 #include "l2w_debug.h"
315 #include <l2w_memory.h>
316 #include <l2w_umem.h>
317 #include <l2w_list.h>
319 #include <l2w_pcipool.h>
320 #include "l2w_radix.h"
321 #include <l2w_spinlock.h>
322 #include <l2w_sync.h>
323 #include <l2w_time.h>
327 static inline int mlx4_is_livefish(struct mlx4_dev *dev)
329 return !!(dev->flags & MLX4_FLAG_LIVEFISH);
332 static inline int mlx4_is_barred(struct mlx4_dev *dev)
334 return dev->flags & (MLX4_FLAG_RESET_CLIENT | MLX4_FLAG_RESET_DRIVER);
337 static inline int mlx4_is_in_reset(struct mlx4_dev *dev)
339 return dev->flags & MLX4_FLAG_RESET_STARTED;