1Ecore Operating System Abstraction Layer (osal) documentation
6This document contains the osal information - functions utilized by the ecore
7which the various parties incorporating the ecore into their own sourcecode
8need to implement in order for the ecore to function.
10Everything osal should be prefixed with osal*. Structures should be prefixed by
11lowercase `osal_' and be lowercase themselves, while functions should be
12prefixed with upper case letters `OSAL_' and be uppercased.
14Notice that some are very trivial, and can be easily replaced by a single
15function call or preprocessor macro. Also notice some are weakly-typed, or
16include values [e.g., struct types] that should probably be implemented
17as preprocessor macros.
19* - as always, there are a couple of exceptions.
21Time related osals
23- OSAL_UDELAY(int)
24	The function should delay for said amount of micro-seconds.
26- OSAL_MSLEEP(int)
27	The function should sleep for said amount of mili-seconds, releasing the CPU.
28	(The existing of such a call in a flow demands the flow to be run from a
29	context supporting sleep).
31Memory related osals
33- void* OSAL_ALLOC(struct *ecore_dev, u32 mode, u32 size)
34	Allocate `size' memory for said device. The mode comes from linux's GFP_*
35	defines [Notice this means you need to define those values, at least
36	KERNEL & ATOMIC even if you don't need them on your OS].
37	Return value should be NULL if allocation fails, and otherwise return the
38	pointer to allocated memory.
40- void* OSAL_ZALLOC(struct *ecore_dev, u32 mode, u32 size)
41	Like OSAL_ALLOC, only the memory [if succesfully allocated] should be set
42	to 0s.
44- void* OSAL_CALLOC(struct *ecore_dev, u32 mode, u32 num, u32 elem_size)
45	Like OSAL_ALLOC, only this allocates memory sufficient for `num' elements,
46	each of size `elem_size'.
48- void* OSAL_VZALLOC(struct *ecore_dev, u32 size)
49	Allocate `size' memory for said device, but as opposed to OSAL_ALLOC,
50	the allocated memory is only virtually contiguous and not necessarily
51	physically contiguous. Content of memory should be zeroed.
52	Return value should be NULL if allocation fails, and otherwise return the
53	pointer to allocated memory.
55- void OSAL_FREE(struct *ecore_dev, void* memory)
56	frees a memory previously dynamically allocated by OSAL_([Z|C]?)ALLOC.
57	Notice this should succeed even if the pointer is NULL.
59- void OSAL_VFREE(struct *ecore_dev, void* memory)
60	frees a memory previously dynamically allocated by OSAL_VZALLOC.
61	Notice this should succeed even if the pointer is NULL.
63- void OSAL_MEM_ZERO(void* memory, u32 size)
64	Set `size' bytes starting at the address pointed by `memory' with 0s.
66- void OSAL_MEMCPY(void* dst, void* src, u32 size)
67	Copy `size' bytes from address pointed by `src' to address pointed by `dst'.
69- void OSAL_MEMSET(void *s, int c, u32  size)
70	Set `size' bytes starting at the address pointed to by s with c.
72- int OSAL_MEMCMP(void *s1, void *s2, u32 n)
73	Comapre the first n bytes of memory areas s1 and s2.
74	The function returns an integer less than, equal to, or
75	greater than zero if the first n bytes of s1 is found, respectively,
76	to be less than, to match, or be greater than the first n bytes of
77	s2.
79dma_addr_t - this variable type should be defined as a variable that can contain
80	physical addresses. It's utilized in OSAL_DMA_* functions.
82- void* OSAL_DMA_ALLOC_COHERENT(struct *ecore_dev, dma_addr_t *phys, u32 size)
83	Allocate `size' bytes of DMA-able memory [which will later be accessed by
84	our HW]. The physical address will by filled in `phys' [NULL if allocation
85	fails], and the virtual address will return [NULL if allocation fails].
87- void OSAL_DMA_FREE_COHERENT(struct *ecore_dev, void* virt, dma_addr_t *phys, u32 size)
88	Frees previously allocated memory [via OSAL_DMA_ALLOC_COHERENT].
90Memory Access related osals
92Notice - these do not begin with the OSAL convention.
94- void REG_WR(struct *ecore_hwfn, u32 addr, u32 value)
95- void REG_WR16(struct *ecore_hwfn, u32 addr, u16 value)
96	These should perform the memory write toward chip. Address is an offset
97	inside the Bar.
99- void DOORBELL(struct *ecore_hwfn, u32 addr, u32 value)
100	This should perform memory write toward chip. Addrees is an offset
101	inside the doorbell bar.
103- void DIRECT_REG_WR(struct *ecore_hwfn, u32 addr, u32 value)
104	Perform a memory write toward chip. Address is absolute [i.e., includes
105	bar offset in memory].
106	Notice most ecore clients don't need the ecore_hwfn; Notice that unless
107	ECORE_CONFIG_DIRECT_HWFN is set during compilation, this function will
108	be called sometimes when the ecore_hwfn is set to be OSAL_NULL.
110- void DIRECT_REG_RD(struct *ecore_hwfn, u32 addr)
111	Perform a memory read from chip. Address is absolute.
112	[Same comment as for DIRECT_REG_WR]
114- u32 REG_RD(struct *ecore_hwfn, u32 addr)
115	This should perform the memory read from chip. Address is an offset
116	inside the Bar.
118Synchronization related osals
120For most upper-layer driver there's no need to allocate memory for lock primitives -
121for such upper-layer drivers, it should suffice to give an empty implementations
123In case this is actually needed, the ecore should also be compile with the
124CONFIG_ECORE_LOCK_ALLOC flag [since sometimes flows diverge a bit].
126osal_spinlock_t - a type of variable [struct] which is used as a spinlock in the
127		  various OSAL_SPIN_* calls. Spinlock assumes locking is blocking
128		  and interrupt disabling on all CPUs, protecting an exclusive
129		  critical section.
131osal_mutex_t - a type of variable [struct] which is used as a mutex in the
132	       various OSAL_MUTEX_* calls. Mutices assume locking is sleeping,
133	       protecting an exclusive critical section.
135- void OSAL_MUTEX_ALLOC(struct ecore_hwfn*, osal_mutex*)
136- void OSAL_SPIN_LOCK_ALLOC(struct ecore_hwfn*, osal_spinlock_t*)
137	Used to allocate [if upper-layer needs to] the spinlock/mutex.
138	NOTICE - counter-intuitively ecore assuumes this always succeeds.
139	But upper-layer can assume this will only be called by rescource alloc &
140	init schemes [and not dynamically], and thus prepare the memory before-hand.
142- void OSAL_MUTEX_DEALLOC(osal_mutex*)
143- void OSAL_SPIN_LOCK_DEALLOC(osal_spinlock_t*)
144	Used to free any previously allocated memory of the spinlock/mutex.
146- void OSAL_MUTEX_INIT(osal_mutex_t*)
147- void OSAL_SPIN_LOCK_INIT(osal_spinlock_t*)
148	Initializes the given spinlock/mutex.
150- void OSAL_MUTEX_ACQUIRE(osal_mutex_t*)
151- void OSAL_SPIN_LOCK(osal_spinlock_t*)
152	Wait until spinlock/mutex is exclusively held - blocking for spinlocks,
153	sleeping for mutices.
154- void OSAL_SPIN_LOCK_IRQSAVE(osal_spinlock_t*, flags)
155	Wait until spinlock/mutex is exclusively held - blocking for spinlocks,
156	sleeping for mutices. Use the type of spinlock that also syncronizes
157	with irqs. Relevant only for some OSs, in most cases an implementation
158	that is identical to OSAL_SPIN_LOCK will suffice.
160- OSAL_MUTEX_RELEASE(osal_mutex_t*)
161- void OSAL_SPIN_UNLOCK(osal_spinlock_t*)
162	Release a held spinlock/mutex [no logic necessary for checking whether
163	it's already locked; that's the caller's responsibility].
164- void OSAL_SPIN_UNLOCK_IRQSAVE(osal_spinlock_t*, flags)
165	Release a held spinlock/mutex [no logic necessary for checking whether
166	it's already locked; that's the caller's responsibility]. Should be
167	called on a lock that was taken using OSAL_SPIN_LOCK_IRQSAVE.
168	Relevant only for some OSs, in most cases an implementation
169	that is identical to OSAL_SPIN_LOCK will suffice.
171osal_dpc_t - a variable representing a non-sleepable context, used by
172	     bcm_osal_dpc_* calls.
174- osal_dpc_t OSAL_DPC_ALLOC(struct ecore_hwfn)
175	Allocates the dpc.
177- void OSAL_DPC_INIT(osal_dpc_t dpc, struct ecore_hwfn)
178	Initializes the dpc.
180- void OSAL_DPC_SYNC(struct ecore_hwfn *p_hwfn)
181	Make sure all slowpath OS dpc's are synced/flushed.
183- void OSAL_POLL_MODE_DPC(struct ecore_hnfn*)
184	Polls ecore_int_sp_dpc during blocking ramrods if needed.  Used when
185	no other thread will service the sp dpc, such as with single threaded
186	systems.
188Notice that the DPC interface from ecore is probably the worst [or at least
189one-of the worst] implementation in the API - this API does not determine
190when the DPC will run and what will run in its context.
191At the moment, the only DPC used by the ecore is sp_dpc in ecore_int.c, and
192the missing logic here is that it should somehow be connected by the upper
193layer to the slowpath interrupt ISR [either directly or indirectly], and that
194it should run [or call in some manner] `ecore_int_sp_dpc'.
196Linked List osals
198osal_list_t - this struct is the linked-list root, i.e., from it the linked
199	      list can be travelled; Most OSAL_LIST_* functions will require
200	      such an anchor to be passed.
201osal_list_entry_t - each struct which will be added to a list should contain
202		    such a field.
204- void OSAL_LIST_INIT(osal_list_t*)
205	Initializes the list passed to the function [so it can be utilized
206	later on by other OSAL_LIST_* calls].
208- void OSAL_LIST_PUSH_HEAD(osal_list_entry_t *entry, osal_list_t *list)
209- void OSAL_LIST_PUSH_TAIL(osal_list_entry_t *entry, osal_list_t *list)
210	Add `entry' to the beginning/end of a list anchored by `list'.
212- type* OSAL_LIST_FIRST_ENTRY(osal_list_t*, type, name_of_list_field)
213	[Notice - this is weakly typed and should probably only be
214	implemented as a macro]
215	Assume the first entry in the list is of type `type', and that
216	the osal_list_t entry inside it is named `name_of_list_field'.
217	Return a pointer to that entry.
219	E.g., a short example of list functions uses:
221	struct foo {
222		osal_struct_t list_head;
223		int x;
224	};
225	osal_struct_list_t root;
226	struct foo foo1, *tmp_foo;
228	OSAL_LIST_INIT(&root)
229	foo1.x = 10;
230	OSAL_LIST_PUSH_HEAD(&foo1.head, &root);
231	tmp_foo = OSAL_LIST_FIRST_ENTRY(&root, struct foo, list_head)
232	/* tmp_foo now points to foo1 */
234- void OSAL_LIST_REMOVE_ENTRY(osal_list_entry_t *entry, osal_list_t *list)
235	Removes `entry' from `list' [Notice no need to check that entry is
236	part of list; That's the caller's responsiblity]
238- bool OSAL_LIST_IS_EMPTY(osal_list_t*)
239	return true iff the list passed to the function contains at least one
240	element.
242- void OSAL_LIST_FOR_EACH_ENTRY(type *entry, osal_list_t* list,
243				type, name_of_list_field)
244- void OSAL_LIST_FOR_EACH_ENTRY_SAFE(type *entry, type *tmp_entry,
245				     osal_list_t* list,
246				     type, name_of_list_field)
247	[This is a loop macro, which opens a new statement block and should
248	 probably be implemented as a preprocessor macro]
249	In every iteration of this for-loop `entry' will be filled with the
250	subsequent entry from the list anchored at `list'. The type of the
251	elements of the list and the name of the osal_list_entry_t fields
252	they contain should be explicitly stated [as is the case in
254	The 'SAFE' variant requires an additional temporary variable which
255	points to the same type as `entry' (`tmp_entry'), and is safe in the
256	sense that `entry' can be removed from the list and the iteration
257	logic should not break.
258	If breaking from the loop one can assume `tmp_entry' would point to
259	the element it pointed to while breaking. But no assumption can be
260	made on its value assuming the iteration runs on all list elements.
262 - void OSAL_LIST_INSERT_ENTRY_BEFORE(type *new_entry, type *entry,
263                                                            osal_list_t* list)
264   Insert a new entry before the specified entry in the list,
265   or insert at head of list if specified entry is 0.
267- void OSAL_LIST_INSERT_ENTRY_AFTER(type *new_entry, type *entry,
268                                                            osal_list_t* list)
269   Insert a new entry after the specified entry in the list,
270   or insert at tail of list if specified entry is 0.
272- void OSAL_LIST_SPLICE_INIT(osal_list_t* new_list, osal_list_t* list)
273   Update new_list by splicing list to the head of new_list.
275- void OSAL_LIST_SPLICE_TAIL_INIT(osal_list_t* new_list, osal_list_t* list)
276   Update new_list by splicing list to the tail of new_list.
278PCI access osals
280- void OSAL_PCI_READ_CONFIG_BYTE(struct *ecore_dev, u32 address, u8 *dst)
281- void OSAL_PCI_READ_CONFIG_WORD(struct *ecore_dev, u32 address, u16 *dst)
282- void OSAL_PCI_READ_CONFIG_DWORD(struct *ecore_dev, u32 address, u32 *dst)
283	Read the appropraite data size and fill in `dst' from offset
284	`address' in the device's configuration space.
285- void OSAL_PCI_WRITE_CONFIG_WORD(struct *ecore_dev, u32 address, u16 val)
286	Write the given value at the offset `address' in the device's
287	configuration space.
288- int OSAL_PCI_FIND_CAPABILITY(struct *ecore_dev, u16 pcie_id)
289	Returns the offset in the PCI configuration space of the PCIe capability
290	`pcie_id', or 0 if no such if capability is found.
291- int OSAL_PCI_FIND_EXT_CAPABILITY(struct *ecore_dev, u16 pcie_id)
292	Returns the offset in the PCI configuration space of the PCIe extended
293	capability `pcie_id', or 0 if no such if capability is found.
294- u32 OSAL_BAR_SIZE(struct *ecore_dev, u8 bar_id)
295	Returns the PCI bar size of the bar specified by `bar_id' - id 0 refers
296	to the regview bar and id 1 to the doorbell bar.
298Memory Barriers
300- void OSAL_MMIOWB(strcut *ecore_dev)
301- void OSAL_BARRIER(struct *ecore_dev)
302- void OSAL_SMP_RMB(struct *ecore_dev)
303- void OSAL_SMP_WMB(struct *ecore_dev)
304- void OSAL_RMB(struct *ecore_dev)
305- void OSAL_WMB(struct *ecore_dev)
307Memory barriers mostly follow the linux's definition of memory barriers,
308as can be found in the linux kernel under `Documentation/memory-barriers.txt'.
309It's possible that certain Operating systems will not require all of said
310memory barriers, e.g., if there's no need to support weak-memory ordered
311system with the OS; In such a case, they should implement the barriers as
312empty functions.
313Also notice that on most implementations the ecore_dev pointer isn't needed for
314the barrier implementation.
316- void OSAL_DMA_SYNC(struct *ecore_dev, void* addr, u32 size, bool is_post)
317	Used in upper-layer drivers that need to sync memory and caches
318	surrounding a dma transaction; This will be called with
319	'is_post == false' prior to the DMA transaction, and 'is_post == true'
320	following it.
321	`addr' will be the physical address of the source buffer.
323Bit operations
325- void OSAL_SET_BIT(u8 bit, unsigned long *bitmap)
326	Set a bit in a bitmap; Logically *bitmap |= (1ULL << bit)
328- void OSAL_CLEAR_BIT(u8 bit, unsigned long *bitmap)
329	Clears a bit in a bitmap; Logically *bitmap &= ~(1ULL << bit)
331- bool OSAL_TEST_BIT(u8 bit, unsigned long *bitmap)
332	Tests whether a bit is set in a bitmap.
333	Logically !!(*bitmap & (1ULL << bit))
335- bool OSAL_TEST_AND_CLEAR_BIT(u8 bit, unsigned long *bitmap)
336	Tests whether a bit is set in a bitmap and clears it.
337	Logically returns !!(*bitmap & (1ULL << bit)) and then performs
338	*bitmap &= ~(1ULL << bit)
340- bool OSAL_TEST_AND_FLIP_BIT(u8 bit, unsigned long *bitmap)
341	Tests whether a bit is set in a bitmap and flips it.
342	Logically returns !!(*bitmap & (1ULL << bit)) and then performs
343	*bitmap ^= (1ULL << bit)
345- u8 OSAL_FIND_FIRST_ZERO_BIT(unsigned long *bitmap, u8 length)
346	Returns the bit-index of the first non-set bit in a bitmap of
347	length `length'. Logically, returns min bit s.t.
348	(bit < length) && !(*bitmap & (1ULL << bit))
350- u8 OSAL_FIND_FIRST_BIT(unsigned long *bitmap, u8 length)
351        Returns the bit-index of the first non-set bit in a bitmap of
352        length `length'. Logically, returns min bit s.t.
353        (bit < length) && (*bitmap & (1ULL << bit)).
354	In case no bit is set, should return length.
356- int OSAL_BITMAP_WEIGHT(u32 *bitmap, u32 nbits)
357	Returns the Hamming weight (number of set bits) in the bitmap.
361OSAL_BE32 - a variable representing a 32-bit data in BE format.
362- __be32 OSAL_CPU_TO_BE32(u32 val)
363	convert a u32 val into big-endian format.
365- __be64 OSAL_CPU_TO_BE64(u64 val)
366	convert a u64 val into big-endian format
368- u32 OSAL_BE32_TO_CPU(u32 val)
369	convert a 32-bit value in big-endian format into current architecture.
371- __be16 OSAL_CPU_TO_BE16(u16 val)
372	convert a u16 val into big-endian format.
374- u16 OSAL_BE16_TO_CPU(u16 val)
375	convert a 16-bit value in big-endian format into current architecture.
377- u32 OSAL_CPU_TO_LE32(u32 val)
378	convert a 32-bit value from native byte ordering to little endian format.
380- u16 OSAL_CPU_TO_LE16(u16 val)
381	convert a 16-bit value from native byte ordering to little endian format.
383- u32 OSAL_LE32_TO_CPU(u32 val)
384	convert a 32-bit little endian value to native byte ordering.
386- u16 OSAL_LE16_TO_CPU(u32 val)
387	convert a 16-bit little endian value to native byte ordering.
389Physical link
391- void OSAL_LINK_UPDATE(struct ecore_hwfn*)
392	ecore uses this callback to inform upper-layer driver that a link
393	change has been informed by the MFW, and the link state is parsed
394	inside the hwfn->mcp_info->link_output.
395	Notice this is called from non-sleepable context, so it's possible
396	upper layer driver will have to schedule in its implementation to
397	process the change in some other context.
399Single Root IOV
401- ? OSAL_VF_SEND_MSG2PF(struct *ecore_dev, u8* done, union vfpf_tlvs *msg,
402			union pfvf_tlvs *reply_addr, u32 msg_size,
403			u32 reply_size)
404	This should be implemented by drivers utilizing a SW channel
405	[as opposed to the ecore hw_channel] for sending messages from VF
406	to PF. This should send a buffer pointed by `msg' of length `msg_size'
407	to the PF, where the PF's answer should be written to `reply_addr'
408	of maximum size `reply_size'. Writing to `done' should signal the
409	transaction is complete.
411- int OSAL_PF_VF_MSG(struct ecore_hwfn*, u8 relative_vfid)
412	This should be implemented by drivers utilizing the HW channel
413	for sending messages from VF to PF. This is called on the PF by
414	ecore on the EQ-handling context to signal to upper-layer that
415	the vf with the relative vfid has sent a message, and allow the
416	upper-layer to handle the request. Should return 0 on success,
417	non-zero otherwise.
419- void OSAL_PF_VF_MALICIOUS(struct ecore_hwfn*, u8 relative_vfid)
420	This indicates to ecore-client that the specific VF is now considered
421	malicious by FW. Exact implication may vary [I.e., it's possible that
422	the hw-channel is still operational or it might be disabled, depending
423	on the exact nature of the vf maliciousness].
425- enum _ecore_status OSAL_IOV_CHK_UCAST(struct *ecore_hwfn,
426					int vfid,
427					struct ecore_filter_ucast *params)
428	Called on the PF whenever the VF requests to configure a unicast
429	filter, to allow the upper layer to decide whether to allow the
430	unicast configuration or not. Should return ECORE_SUCCESS if
431	configuration is allowed, ECORE_EXISTS if it's already configured
432	and ECORE_INVAL if its forbidden.
434- enum _ecore_status
435  OSAL_IOV_PRE_START_VPORT(struct *ecore_hwfn,
436			   int relative_vf_id,
437			   struct ecore_sp_vport_start_params *params)
438	Called on the PF before starting a VF's vport, to check the
439	OS-specific setting for that vport.
441- void OSAL_IOV_POST_START_VPORT(struct *ecore_hwfn,
442				 int relative_vf_id,
443				 u8 vport_id,
444				 u16 opaque_fid)
445	Called on the PF after succesfully starting a VF's vport,
446	to allow the upper layer the chance of doing some additional
447	OS-specific work.
449- enum _ecore_status_t
450  OSAL_IOV_VF_VPORT_UPDATE(struct *ecore_hwfn, u8 relative_vfid,
451			   struct *ecore_sp_vport_update_params,
452			   u16 *p_tlvs_mask)
453 	Called on PF side to allow upper-client to manipulate the configuration
454        of a vport update request by VF.
455        `p_tlv_mask' is a bit mask of ECORE_IOV_VP_UPDATE_* values, and it's
456        the ecore-client responsibility to clear bits which are NOT to be
457	configured.
458	If the ecore-client wants to fail the configuaration altogether, it
459	should return a value other than ECORE_SUCCESS.
461- void OSAL_IOV_VF_VPORT_STOP(struct ecore_hwfn *p_hwfn,
462			       struct ecore_vf_info *vf)
463 	Called on PF side to allow upper-client to to execute required operations
464        before closing vport.
466- void OSAL_VF_FLR_UPDATE(struct *ecore_hwfn)
467	Called on PF side to indicate MFW signaled some of the PF's
468	vfs were Function Level Resetted. When this is called,
469	pending_flr field in the PF's iov information should be set
470	to be a bitmask of all relative VFIDs that need FLR.
472- void OSAL_IOV_VF_CLEANUP(struct *ecore_hwfn, u8 relative_vfid)
473	Called on PF side to indicate that VF has been cleaned, to allow
474	ecore-client the change of cleaning any database it had for that vf.
476- void OSAL_VF_FILL_ACQUIRE_RESC_REQ(struct ecore_hwfn *p_hwfn,
477                                     struct vf_pf_resc_request *p_resc_req,
478				     struct ecore_vf_acquire_sw_info *p_sw_info)
479        Called on the VF before sending acquire messgae to the PF,
480        to allow the upper layer to fill the num of requested resources.
482- enum _ecore_status_t
483  OSAL_VF_UPDATE_ACQUIRE_RESC_RESP(struct ecore_hwfn *p_hwfn,
484                                   struct pf_vf_resc *p_resc_resp)
485        Called on the VF after acquire response has recieved to update
486        upper layer with the acquired resources. The upper layer should
487        return error in case there is a problem with the amount of acquired
488        resources, otherwise success.
490- enum _ecore_status_t
491  OSAL_IOV_VF_ACQUIRE(struct ecore_hwfn *p_hwfn, u8 relative_vfid)
492	Called on PF side while processing a VF acquisition message, to allow
493        the ecore-client to prevent the acquisition if required.
495- enum _ecore_status_t
496  OSAL_VF_CQE_COMPLETION(struct ecore_hwfn *p_hwfn,
497                         struct eth_slow_path_rx_cqe *cqe,
498                         enum protocol_type protocol)
499        Called on the VF to let the upper layer chance to handle the cqe.
502	Called on PF side - should return a VFPF_ACQUIRE_OS_* value matching
503	the OS hypervisor type.
505- void OSAL_IOV_VF_MSG_TYPE(struct ecore_hwfn *p_hwfn,
506                            u8 vf_id,
507                            int vf_msg_type)
508	Called on PF side to indicate  the VF to PF TLV Request type send by VF in
509	the MailBox request through HW Channel.
511- void OSAL_IOV_PF_RESP_TYPE(struct ecore_hwfn *p_hwfn,
512                             u8 vf_id,
513                             enum ecore_iov_pf_to_vf_status pf_resp_type)
514	Called on PF side to indicate the PF to VF Response type after the processing
515        of VF Mailbox request through HW Channel.
517- int OSAL_PF_VALIDATE_MODIFY_TUNN_CONFIG(struct ecore_hwfn *p_hwfn,
518					  u16 *feature_mask, bool *update,
519					  struct ecore_tunnel_info *p_tun)
520	Called on PF side to validate and modify VF's requested tunnel mode,
521	classes and udp ports based on update masks/flags. In case PF modifies
522	VF requested data then it should still return an error
523	to indicate to VF flow. Finally, If any tunnel configuration update
524	is required then they must set "true" in "update" address.
525	PF should also set the features in "feature_mask" which are enabled
526	or requested from VF to be enabled and can be kept intact
527	[i.e they can no longer be modified further by PF in terms of tunn
528	mode or tun classes].
530HW errors & Recovery
532- void OSAL_SCHEDULE_RECOVERY_HANDLER(struct ecore_hwfn* p_hwfn)
533	ecore uses this callback to inform the upper-layer driver that a process
534	kill indication has been received from the MFW, and that a recovery
535	handler should be scheduled to handle the recovery flow.
537- void OSAL_HW_ERROR_OCCURRED(struct ecore_hwfn *p_hwfn,
538			      enum ecore_hw_err_type err_type)
539	ecore uses this callback to inform the upper-layer driver about an error
540	in the HW/FW.
542Unzipping functionality related osal
544- u32 OSAL_UNZIP_DATA(struct ecore_hwfn *p_hwfn, u32 input_len, u8 *input_buf,
545		      u32 max_size, u8 *unzip_buf)
546	Unzip zipped data of length "input_len" present in "input_buf" and
547	write unzipped data into "unzip_buf". "max_size" is max length of unzipped
548	data which can be written into "unzip_buf".
549	returns the length of unzipped data in dwords, in case of failure returns 0.
551Note -	All drivers has to define/set CONFIG_ECORE_ZIPPED_FW to take zipped
552	firmware file and implement their own functionality to unzip data.
554String handling related osals
556- int OSAL_SPRINTF(char *str, const char *format, ...)
557	Write a formatted output to a string pointed to by str.
559- int OSAL_SNPRINTF(char *str, osal_size_t n, const char *format, ...)
560	Write a formatted output to a string pointed to by str, taking n as the maximum number of characters to write.
561	The remaining characters are discarded and not stored, but counted for the value returned by the function.
563- u32 OSAL_STRLEN(const char *str)
564	Return the length of the string pointed to by str, excluding the terminating null byte ('\0').
566- char *OSAL_STRCPY(char *dest, const char *src)
567	Copy the string pointed to by src, including the terminating null byte ('\0'), to the buffer  pointed to by dest.
569- char *OSAL_STRNCPY(char *dest, const char *src, osal_size_t n)
570	Copies up to n characters from the string pointed to by src to dest.
571	In the case where the length of src is less than that of n, the remainder of dest will be padded with null bytes.
573- int OSAL_STRCMP(const char *str1, const char *str2)
574	Compares the string pointed by str1 to the string pointed by str2.
576- int OSAL_STRTOUL(const char *str, unsigned int base, unsigned long *res)
577	Converts a string pointed by str to an unsigned long.
578	The string base can be given explicitly, or "0" can be provided and then it will be automatically detected with the conventional semantics
579	(begins with 0x - the number will be parsed as a hexadecimal, if it otherwise begins with 0 - octal, otherwise - decimal).
580	The the result of the conversion is written to the variable pointed by res.
584osal_size_t  - The type is used to store the result of sizeof operator.
585		On certain platfroms it is typedefed to __SIZE_TYPE__, a
586		compiler predefined macro.
588osal_int_ptr_t - Integer type large enough to hold a pointer. The data type is
589	          useful for casting pointers when we want to do address
590	          arithmetic.
592OSAL_NULL -  Null value defintion.
594OSAL_INLINE - The specifier instructs the compiler to insert a copy of the
595	       function body into each place the function is called.
597OSAL_BUILD_BUG_ON(condition) - Break compilation if the "condition" is true.
599OSAL_PAGE_SIZE - Macro for the page size value i.e., number of bytes in a
600	          memory page.
602OSAL_CACHE_LINE_SIZE - Macro for the cache line size value in bytes.
604OSAL_IOMEM - Annotation used to mark pointers to I/O memory. It is used by
605	      Sparse, a tool used to find possible coding faults in the
606	      kernel. The annotation is ignored in the normal compilation.
607	      When checking the code with sparse, however, developers will see
608	      a whole new set of warnings caused by code which mixes normal
609	      pointers with OSAL_IOMEM pointers, or which dereferences those
610	      pointers.
612OSAL_UNLIKELY(condition) -  An instruction to the compiler to emit instructions
613	     in the favor of "condition" value likely to be false (zero).
615- type OSAL_MIN_T(type, val1, val2)
616	Returns the minimum of (val1, val2) which are of data type "type".
618- type OSAL_MAX_T(type, val1, val2)
619	Returns the maximum of (val1, val2) which are of data type "type".
621- u32* OSAL_REG_ADDR(struct *ecore_hwfn, u32 hw_offset)
622	Returns the memory address value of the device at the offset hw_offset.
625	Returns the number of active CPUs on the machine
627- u32 DIV_ROUND_UP(u32 size, u32 divisor_size)
628	Returns number of elements required of `divisor_size' each,
629        required to hold at least `size' data.
631- u32 ROUNDUP(u32 size, u32 divisor_size)
632	Returns DIV_ROUND_UP * divisor_size [how much memory will be
633	required for holding `size' data, if we can only allocate
634	in granularity of `divisor_size'].
637	Return a round-up to closest value which is a power of 2.
639- u32 OSAL_LOG2(u32)
640	Returns a log on a 2-basis of the value.
642- void OSAL_ASSERT(bool cond)
643	Should perform some sort of panic in case `cond' is false.
645- u32 OFFSETOF(struct, field)
646	returns the offset in bytes of field inside struct.
647	TBD - isn't it ANSI-C? If so, can be removed from ecore.
649- void PRINT(void *dp_ctx, char *format_string, ...)
650- void PRINT_ERR(void *dp_ctx, char *format_string, ...)
651	Macros used by the ecore debug facilities to print verbose & error logs.
653- void OSAL_WARN(bool condition, const char *format, ...)
654	Should cause a warning [at least on debug mode] if hit.
656- void OSAL_BEFORE_PF_START(struct file, engine id)
657	Perform some action just before first interaction with FW.
659- void OSAL_AFTER_PF_STOP(struct file, engine id)
660	Perform some action just aftter last interaction with FW.
662- u32 ARRAY_SIZE(array[])
663	Returns the number of elements in an array.
665- osal_uintptr_t - Used for casting pointer to integer value.
666	Some 32 bit OS complains about "cast from pointer to integer of different size". As on those platform
667	integers and pointers are of different sizes. Due to this fact we couldn't use any generic data type in
668	ecore to cast pointer to integer data type which can be appropriate for both 32 bit and 64 bit platform
669	for all OS distributions, as a data type size on each OS distribution may vary. So this osal serves the
670	purpose of to define OS specific data type cast which can be used on both 32 bit and 64 bit platform.
672- void OSAL_GET_PROTOCOL_STATS(struct *ecore_dev, enum ecore_mcp_protocol_type type,
673			       union ecore_mcp_protocol_stats *stats);
674	Call from the ecore to get the statististics of a protocol driver. Ecore client
675	need to populate the requested statistics. If the PF has more than one function,
676	driver should return the statistics sum of all the interfaces under the PF.
678- int OSAL_SLOWPATH_IRQ_REQ(struct ecore_hwfn *p_hwfn)
679	Call from ecore to the upper layer driver to request IRQs for the slowpath
680	interrupts handling.
682- u32 OSAL_GET_RDMA_SB_ID(struct ecore_hwfn *p_hwfn, u32 relative_sb_id)
683	Call from ecore to obtain real SB ID from upper layer.
685- void OSAL_DCBX_AEN(struct ecore_hwfn *p_hwfn, enum ecore_mib_read_type mib_type)
686	Call from ecore to notify the dcbx related asynchronous events from the MFW.
688- u32 OSAL_CRC32(u32 crc, u8 *buf, osal_size_t length)
689	Compute a CRC-32 value using a Castagnoli polynomial.
690	`crc' is the previous value for the checksum, and `buf' shall point to
691	an array of `length' bytes of data to be added to this checksum.
693- void OSAL_CRC8_POPULATE(u8 table[CRC8_TABLE_SIZE], u8 polynomial)
694	Fill the provided crc table for given polynomial in reverse bit order (msb first).
695	The table size is 256 ('CRC8_TABLE_SIZE').
697- u8 OSAL_CRC8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, osal_size_t nbytes, u8 crc)
698	Calculate a crc8 over the given input data.
699	`table' is the crc table used for calculation, `pdata' is a pointer to data buffer,
700	`nbytes' is the size of the data buffer, and `crc' is the previous returned crc8 value.
702- s64 OSAL_DIV_S64(s64 value, s64 base)
703	Some distros [32-bit] are having problems with direct division of 64-bit variables.
704	This should logically return (value / base), and for distros that don't care about this
705	sort of issues it can be defined to be exactly that.
707NVRAM related osals
709- bool OSAL_NVM_IS_ACCESS_ENABLED(struct ecore_hwfn *p_hwfn)
710        This osal allows to upper layer decide if it is allowed to access
711        the NVRAM.
713Management changes related osals
715- int OSAL_MFW_TLV_REQ(struct ecore_hwfn *p_hwfn)
716	Called to inform that MFW has requested for TLVs. We are in the interrupt
717	context here, ecore client need to schedule a thread/bottom-half context
718	to handle this task, and return the control immediately.
719	The bottom-half thread will need to invoke ecore_mfw_process_tlv_req()
720	for further processing of the TLV request.
722- int OSAL_MFW_FILL_TLV_DATA(struct ecore_hwfn *p_hwfn, enum ecore_mfw_tlv_type type,
723                             union ecore_mfw_tlv_data *data)
724	Called from ecore to get the TLV values of a given type. Ecore client
725	need to fill in the values for all the fields that it's aware of, and
726	also need to set the flags associated with the respective fields. For instance,
727	if client sets value for 'npi_enabled' field, it needs to set the flag
728	'npiv_enabled_set' to true.
730- void OSAL_HW_INFO_CHANGE(struct ecore_hwfn *p_hwfn, enum ecore_hw_info_change)
731	Called after management has changed some property of a hw_info field.
732	The enum value indicates which field has changed. This is a FYI kind of
733	notification - direct HW/FW changes [if applicable] were already done.