1 /* (c) Copyright 2002 - 2008 Atheros Communications Inc. */
4 * @defgroup adf_nbuf_public network buffer API
8 * @ingroup adf_nbuf_public
10 * This file defines the network buffer abstraction.
16 #include <adf_os_util.h>
17 #include <adf_os_types.h>
18 #include <adf_os_dma.h>
19 #include <adf_net_types.h>
20 #include <adf_nbuf_pvt.h>
23 * @brief Platform indepedent packet abstraction
25 typedef __adf_nbuf_t adf_nbuf_t;
28 * @brief invalid handle
30 #define ADF_NBUF_NULL __ADF_NBUF_NULL
32 * @brief Platform independent packet queue abstraction
34 typedef __adf_nbuf_queue_t adf_nbuf_queue_t;
37 * BUS/DMA mapping routines
41 * @brief Create a DMA map. This can later be used to map
42 * networking buffers. They :
43 * - need space in adf_drv's software descriptor
44 * - are typically created during adf_drv_create
45 * - need to be created before any API(adf_nbuf_map) that uses them
47 * @param[in] osdev os device
48 * @param[out] dmap map handle
50 * @return status of the operation
52 static inline a_status_t
53 adf_nbuf_dmamap_create(adf_os_device_t osdev,
54 adf_os_dma_map_t *dmap)
56 return (__adf_nbuf_dmamap_create(osdev, dmap));
61 * @brief Delete a dmap map
63 * @param[in] osdev os device
67 adf_nbuf_dmamap_destroy(adf_os_device_t osdev, adf_os_dma_map_t dmap)
69 __adf_nbuf_dmamap_destroy(osdev, dmap);
74 * @brief Map a buffer to local bus address space
76 * @param[in] osdev os device
77 * @param[in] bmap map handle
78 * @param[in] buf buf to be mapped
79 * @param[in] dir DMA direction
81 * @return status of the operation
83 static inline a_status_t
84 adf_nbuf_map(adf_os_device_t osdev,
85 adf_os_dma_map_t bmap,
89 return __adf_nbuf_map(osdev, bmap, buf, dir);
94 * @brief Unmap a previously mapped buf
96 * @param[in] osdev os device
97 * @param[in] bmap map handle
98 * @param[in] dir DMA direction
101 adf_nbuf_unmap(adf_os_device_t osdev,
102 adf_os_dma_map_t bmap,
103 adf_os_dma_dir_t dir)
105 __adf_nbuf_unmap(osdev, bmap, dir);
109 * @brief returns information about the mapped buf
111 * @param[in] bmap map handle
112 * @param[out] sg map info
115 adf_nbuf_dmamap_info(adf_os_dma_map_t bmap, adf_os_dmamap_info_t *sg)
117 __adf_nbuf_dmamap_info(bmap, sg);
123 * nbuf allocation rouines
128 * @brief Allocate adf_nbuf
130 * The nbuf created is guarenteed to have only 1 physical segment
132 * @param[in] hdl platform device object
133 * @param[in] size data buffer size for this adf_nbuf including max header
135 * @param[in] reserve headroom to start with.
136 * @param[in] align alignment for the start buffer.
138 * @return The new adf_nbuf instance or NULL if there's not enough memory.
140 static inline adf_nbuf_t
141 adf_nbuf_alloc(adf_os_size_t size,
145 return __adf_nbuf_alloc(size, reserve,align);
150 * @brief Free adf_nbuf
152 * @param[in] buf buffer to free
155 adf_nbuf_free(adf_nbuf_t buf)
157 __adf_nbuf_free(buf);
162 * @brief Reallocate such that there's required headroom in
163 * buf. Note that this can allocate a new buffer, or
164 * change geometry of the orignial buffer. The new buffer
165 * is returned in the (new_buf).
167 * @param[in] buf (older buffer)
168 * @param[in] headroom
170 * @return newly allocated buffer
172 static inline adf_nbuf_t
173 adf_nbuf_realloc_headroom(adf_nbuf_t buf, a_uint32_t headroom)
175 return (__adf_nbuf_realloc_headroom(buf, headroom));
180 * @brief expand the tailroom to the new tailroom, but the buffer
183 * @param[in] buf buffer
184 * @param[in] tailroom new tailroom
186 * @return expanded buffer or NULL on failure
188 static inline adf_nbuf_t
189 adf_nbuf_realloc_tailroom(adf_nbuf_t buf, a_uint32_t tailroom)
191 return (__adf_nbuf_realloc_tailroom(buf, tailroom));
196 * @brief this will expand both tail & head room for a given
197 * buffer, you may or may not get a new buffer.Use it
198 * only when its required to expand both. Otherwise use
199 * realloc (head/tail) will solve the purpose. Reason for
200 * having an extra API is that some OS do this in more
201 * optimized way, rather than calling realloc (head/tail)
204 * @param[in] buf buffer
205 * @param[in] headroom new headroom
206 * @param[in] tailroom new tailroom
208 * @return expanded buffer
210 static inline adf_nbuf_t
211 adf_nbuf_expand(adf_nbuf_t buf, a_uint32_t headroom, a_uint32_t tailroom)
213 return (__adf_nbuf_expand(buf,headroom,tailroom));
218 * @brief Copy src buffer into dst. This API is useful, for
219 * example, because most native buffer provide a way to
220 * copy a chain into a single buffer. Therefore as a side
221 * effect, it also "linearizes" a buffer (which is
222 * perhaps why you'll use it mostly). It creates a
225 * @param[in] buf source nbuf to copy from
227 * @return the new nbuf
229 static inline adf_nbuf_t
230 adf_nbuf_copy(adf_nbuf_t buf)
232 return(__adf_nbuf_copy(buf));
237 * @brief link two nbufs, the new buf is piggybacked into the
240 * @param[in] dst buffer to piggyback into
241 * @param[in] src buffer to put
243 * @return status of the call
246 adf_nbuf_cat(adf_nbuf_t dst,adf_nbuf_t src)
248 __adf_nbuf_cat(dst, src);
253 * @brief clone the nbuf (copy is readonly)
255 * @param[in] buf nbuf to clone from
257 * @return cloned buffer
259 static inline adf_nbuf_t
260 adf_nbuf_clone(adf_nbuf_t buf)
262 return(__adf_nbuf_clone(buf));
267 * @brief Create a version of the specified nbuf whose
268 * contents can be safely modified without affecting
269 * other users.If the nbuf is a clone then this function
270 * creates a new copy of the data. If the buffer is not
271 * a clone the original buffer is returned.
273 * @param[in] buf source nbuf to create a writable copy from
275 * @return new buffer which is writeable
277 static inline adf_nbuf_t
278 adf_nbuf_unshare(adf_nbuf_t buf)
280 return(__adf_nbuf_unshare(buf));
286 * nbuf manipulation routines
292 * @brief return the amount of headroom int the current nbuf
294 * @param[in] buf buffer
296 * @return amount of head room
298 static inline a_uint32_t
299 adf_nbuf_headroom(adf_nbuf_t buf)
301 return (__adf_nbuf_headroom(buf));
306 * @brief return the amount of tail space available
308 * @param[in] buf buffer
310 * @return amount of tail room
312 static inline a_uint32_t
313 adf_nbuf_tailroom(adf_nbuf_t buf)
315 return (__adf_nbuf_tailroom(buf));
320 * @brief Push data in the front
322 * @param[in] buf buf instance
323 * @param[in] size size to be pushed
325 * @return New data pointer of this buf after data has been pushed,
326 * or NULL if there is not enough room in this buf.
328 static inline a_uint8_t *
329 adf_nbuf_push_head(adf_nbuf_t buf, adf_os_size_t size)
331 return __adf_nbuf_push_head(buf, size);
336 * @brief Puts data in the end
338 * @param[in] buf buf instance
339 * @param[in] size size to be pushed
341 * @return data pointer of this buf where new data has to be
342 * put, or NULL if there is not enough room in this buf.
344 static inline a_uint8_t *
345 adf_nbuf_put_tail(adf_nbuf_t buf, adf_os_size_t size)
347 return __adf_nbuf_put_tail(buf, size);
352 * @brief pull data out from the front
354 * @param[in] buf buf instance
355 * @param[in] size size to be popped
357 * @return New data pointer of this buf after data has been popped,
358 * or NULL if there is not sufficient data to pull.
360 static inline a_uint8_t *
361 adf_nbuf_pull_head(adf_nbuf_t buf, adf_os_size_t size)
363 return __adf_nbuf_pull_head(buf, size);
369 * @brief trim data out from the end
371 * @param[in] buf buf instance
372 * @param[in] size size to be popped
377 adf_nbuf_trim_tail(adf_nbuf_t buf, adf_os_size_t size)
379 __adf_nbuf_trim_tail(buf, size);
384 * @brief Get the length of the buf
386 * @param[in] buf the buf instance
388 * @return The total length of this buf.
390 static inline adf_os_size_t
391 adf_nbuf_len(adf_nbuf_t buf)
393 return (__adf_nbuf_len(buf));
397 * @brief test whether the nbuf is cloned or not
399 * @param[in] buf buffer
401 * @return TRUE if it is cloned, else FALSE
403 static inline a_bool_t
404 adf_nbuf_is_cloned(adf_nbuf_t buf)
406 return (__adf_nbuf_is_cloned(buf));
416 * @brief return the frag pointer & length of the frag
418 * @param[in] buf buffer
419 * @param[out] sg this will return all the frags of the nbuf
423 adf_nbuf_frag_info(adf_nbuf_t buf, adf_os_sglist_t *sg)
425 __adf_nbuf_frag_info(buf, sg);
428 * @brief return the data pointer & length of the header
430 * @param[in] buf nbuf
431 * @param[out] addr data pointer
432 * @param[out] len length of the data
436 adf_nbuf_peek_header(adf_nbuf_t buf, a_uint8_t **addr, a_uint32_t *len)
438 __adf_nbuf_peek_header(buf, addr, len);
441 * nbuf private context routines
445 * @brief get the priv pointer from the nbuf'f private space
449 * @return data pointer to typecast into your priv structure
451 static inline a_uint8_t *
452 adf_nbuf_get_priv(adf_nbuf_t buf)
454 return (__adf_nbuf_get_priv(buf));
459 * nbuf queue routines
464 * @brief Initialize buf queue
466 * @param[in] head buf queue head
469 adf_nbuf_queue_init(adf_nbuf_queue_t *head)
471 __adf_nbuf_queue_init(head);
476 * @brief Append a nbuf to the tail of the buf queue
478 * @param[in] head buf queue head
482 adf_nbuf_queue_add(adf_nbuf_queue_t *head, adf_nbuf_t buf)
484 __adf_nbuf_queue_add(head, buf);
489 * @brief Retrieve a buf from the head of the buf queue
491 * @param[in] head buf queue head
493 * @return The head buf in the buf queue.
495 static inline adf_nbuf_t
496 adf_nbuf_queue_remove(adf_nbuf_queue_t *head)
498 return __adf_nbuf_queue_remove(head);
503 * @brief get the length of the queue
505 * @param[in] head buf queue head
507 * @return length of the queue
509 static inline a_uint32_t
510 adf_nbuf_queue_len(adf_nbuf_queue_t *head)
512 return __adf_nbuf_queue_len(head);
517 * @brief get the first guy/packet in the queue
519 * @param[in] head buf queue head
521 * @return first buffer in queue
523 static inline adf_nbuf_t
524 adf_nbuf_queue_first(adf_nbuf_queue_t *head)
526 return (__adf_nbuf_queue_first(head));
531 * @brief get the next guy/packet of the given buffer (or
534 * @param[in] buf buffer
536 * @return next buffer/packet
538 static inline adf_nbuf_t
539 adf_nbuf_queue_next(adf_nbuf_t buf)
541 return (__adf_nbuf_queue_next(buf));
546 * @brief Check if the buf queue is empty
548 * @param[in] nbq buf queue handle
550 * @return TRUE if queue is empty
551 * @return FALSE if queue is not emty
553 static inline a_bool_t
554 adf_nbuf_is_queue_empty(adf_nbuf_queue_t * nbq)
556 return __adf_nbuf_is_queue_empty(nbq);
562 * nbuf extension routines XXX
568 * @brief Gets the tx checksumming to be performed on this buf
570 * @param[in] buf buffer
571 * @param[out] hdr_off the (tcp) header start
572 * @param[out] where the checksum offset
574 static inline adf_net_cksum_type_t
575 adf_nbuf_tx_cksum_info(adf_nbuf_t buf, a_uint8_t **hdr_off, a_uint8_t **where)
577 return(__adf_nbuf_tx_cksum_info(buf, hdr_off, where));
582 * @brief Drivers that support hw checksumming use this to
583 * indicate checksum info to the stack.
585 * @param[in] buf buffer
586 * @param[in] cksum checksum
589 adf_nbuf_set_rx_cksum(adf_nbuf_t buf, adf_nbuf_rx_cksum_t *cksum)
591 __adf_nbuf_set_rx_cksum(buf, cksum);
596 * @brief Drivers that are capable of TCP Large segment offload
597 * use this to get the offload info out of an buf.
599 * @param[in] buf buffer
600 * @param[out] tso offload info
603 adf_nbuf_get_tso_info(adf_nbuf_t buf, adf_nbuf_tso_t *tso)
605 __adf_nbuf_get_tso_info(buf, tso);
610 adf_nbuf_set_vlan_info(adf_nbuf_t buf, adf_net_vlan_tag_t vlan_tag)
612 __adf_nbuf_set_vlan_info(buf, vlan_tag);
616 * @brief This function extracts the vid & priority from an
620 * @param[in] hdl net handle
621 * @param[in] buf buffer
622 * @param[in] vlan vlan header
624 * @return status of the operation
626 static inline a_status_t
627 adf_nbuf_get_vlan_info(adf_net_handle_t hdl, adf_nbuf_t buf,
628 adf_net_vlanhdr_t *vlan)
630 return __adf_nbuf_get_vlan_info(hdl, buf, vlan);
633 static inline adf_nbuf_t
634 adf_nbuf_create_frm_frag(adf_nbuf_queue_t *head)
636 return __adf_nbuf_create_frm_frag(head);
640 adf_nbuf_split_to_frag(adf_nbuf_t buf, adf_nbuf_queue_t *qhead)
642 return __adf_nbuf_split_to_frag(buf, qhead);