1Ecore Operating System Abstraction Layer (osal) documentation 2============================================================= 3 4Introduction 5============ 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. 9 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. 13 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. 18 19* - as always, there are a couple of exceptions. 20 21Time related osals 22================== 23- OSAL_UDELAY(int) 24 The function should delay for said amount of micro-seconds. 25 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). 30 31Memory related osals 32==================== 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. 39 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. 43 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'. 47 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. 54 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. 58 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. 62 63- void OSAL_MEM_ZERO(void* memory, u32 size) 64 Set `size' bytes starting at the address pointed by `memory' with 0s. 65 66- void OSAL_MEMCPY(void* dst, void* src, u32 size) 67 Copy `size' bytes from address pointed by `src' to address pointed by `dst'. 68 69- void OSAL_MEMSET(void *s, int c, u32 size) 70 Set `size' bytes starting at the address pointed to by s with c. 71 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. 78 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. 81 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]. 86 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]. 89 90Memory Access related osals 91=========================== 92Notice - these do not begin with the OSAL convention. 93 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. 98 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. 102 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. 109 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] 113 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. 117 118Synchronization related osals 119============================= 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 122to - MUTEX_ALLOC(), MUTEX_DEALLOC(), SPIN_LOCK_ALLOC(), SPIN_LOCK_DEALLOC(). 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]. 125 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. 130 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. 134 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. 141 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. 145 146- void OSAL_MUTEX_INIT(osal_mutex_t*) 147- void OSAL_SPIN_LOCK_INIT(osal_spinlock_t*) 148 Initializes the given spinlock/mutex. 149 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. 159 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. 170 171osal_dpc_t - a variable representing a non-sleepable context, used by 172 bcm_osal_dpc_* calls. 173 174- osal_dpc_t OSAL_DPC_ALLOC(struct ecore_hwfn) 175 Allocates the dpc. 176 177- void OSAL_DPC_INIT(osal_dpc_t dpc, struct ecore_hwfn) 178 Initializes the dpc. 179 180- void OSAL_DPC_SYNC(struct ecore_hwfn *p_hwfn) 181 Make sure all slowpath OS dpc's are synced/flushed. 182 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. 187 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'. 195 196Linked List osals 197================= 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. 203 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]. 207 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'. 211 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. 218 219 E.g., a short example of list functions uses: 220 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; 227 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 */ 233 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] 237 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. 241 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 253 OSAL_LIST_FIRST_ENTRY]. 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. 261 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. 266 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. 271 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. 274 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. 277 278PCI access osals 279================ 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. 297 298Memory Barriers 299=============== 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) 306 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. 315 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. 322 323Bit operations 324============== 325- void OSAL_SET_BIT(u8 bit, unsigned long *bitmap) 326 Set a bit in a bitmap; Logically *bitmap |= (1ULL << bit) 327 328- void OSAL_CLEAR_BIT(u8 bit, unsigned long *bitmap) 329 Clears a bit in a bitmap; Logically *bitmap &= ~(1ULL << bit) 330 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)) 334 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) 339 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) 344 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)) 349 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. 355 356- int OSAL_BITMAP_WEIGHT(u32 *bitmap, u32 nbits) 357 Returns the Hamming weight (number of set bits) in the bitmap. 358 359Endianess 360========= 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. 364 365- __be64 OSAL_CPU_TO_BE64(u64 val) 366 convert a u64 val into big-endian format 367 368- u32 OSAL_BE32_TO_CPU(u32 val) 369 convert a 32-bit value in big-endian format into current architecture. 370 371- __be16 OSAL_CPU_TO_BE16(u16 val) 372 convert a u16 val into big-endian format. 373 374- u16 OSAL_BE16_TO_CPU(u16 val) 375 convert a 16-bit value in big-endian format into current architecture. 376 377- u32 OSAL_CPU_TO_LE32(u32 val) 378 convert a 32-bit value from native byte ordering to little endian format. 379 380- u16 OSAL_CPU_TO_LE16(u16 val) 381 convert a 16-bit value from native byte ordering to little endian format. 382 383- u32 OSAL_LE32_TO_CPU(u32 val) 384 convert a 32-bit little endian value to native byte ordering. 385 386- u16 OSAL_LE16_TO_CPU(u32 val) 387 convert a 16-bit little endian value to native byte ordering. 388 389Physical link 390============= 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. 398 399Single Root IOV 400=============== 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. 410 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. 418 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]. 424 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. 433 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. 440 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. 448 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. 460 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. 465 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. 471 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. 475 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. 481 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. 489 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. 494 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. 500 501- u8 OSAL_IOV_GET_OS_TYPE() 502 Called on PF side - should return a VFPF_ACQUIRE_OS_* value matching 503 the OS hypervisor type. 504 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. 510 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. 516 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]. 529 530HW errors & Recovery 531==================== 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. 536 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. 541 542Unzipping functionality related osal 543==================================== 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. 550 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. 553 554String handling related osals 555============================= 556- int OSAL_SPRINTF(char *str, const char *format, ...) 557 Write a formatted output to a string pointed to by str. 558 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. 562 563- u32 OSAL_STRLEN(const char *str) 564 Return the length of the string pointed to by str, excluding the terminating null byte ('\0'). 565 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. 568 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. 572 573- int OSAL_STRCMP(const char *str1, const char *str2) 574 Compares the string pointed by str1 to the string pointed by str2. 575 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. 581 582Miscellaneous 583============= 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. 587 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. 591 592OSAL_NULL - Null value defintion. 593 594OSAL_INLINE - The specifier instructs the compiler to insert a copy of the 595 function body into each place the function is called. 596 597OSAL_BUILD_BUG_ON(condition) - Break compilation if the "condition" is true. 598 599OSAL_PAGE_SIZE - Macro for the page size value i.e., number of bytes in a 600 memory page. 601 602OSAL_CACHE_LINE_SIZE - Macro for the cache line size value in bytes. 603 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. 611 612OSAL_UNLIKELY(condition) - An instruction to the compiler to emit instructions 613 in the favor of "condition" value likely to be false (zero). 614 615- type OSAL_MIN_T(type, val1, val2) 616 Returns the minimum of (val1, val2) which are of data type "type". 617 618- type OSAL_MAX_T(type, val1, val2) 619 Returns the maximum of (val1, val2) which are of data type "type". 620 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. 623 624- u32 OSAL_NUM_ACTIVE_CPU() 625 Returns the number of active CPUs on the machine 626 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. 630 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']. 635 636- u32 OSAL_ROUNDUP_POW_OF_TWO(u32) 637 Return a round-up to closest value which is a power of 2. 638 639- u32 OSAL_LOG2(u32) 640 Returns a log on a 2-basis of the value. 641 642- void OSAL_ASSERT(bool cond) 643 Should perform some sort of panic in case `cond' is false. 644 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. 648 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. 652 653- void OSAL_WARN(bool condition, const char *format, ...) 654 Should cause a warning [at least on debug mode] if hit. 655 656- void OSAL_BEFORE_PF_START(struct file, engine id) 657 Perform some action just before first interaction with FW. 658 659- void OSAL_AFTER_PF_STOP(struct file, engine id) 660 Perform some action just aftter last interaction with FW. 661 662- u32 ARRAY_SIZE(array[]) 663 Returns the number of elements in an array. 664 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. 671 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. 677 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. 681 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. 684 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. 687 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. 692 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'). 696 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. 701 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. 706 707NVRAM related osals 708=================== 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. 712 713Management changes related osals 714================================ 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. 721 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. 729 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. 734