2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted (subject to the limitations in the
7 * disclaimer below) provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
17 * * Neither the name of Qualcomm Atheros nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 * @defgroup adf_nbuf_public network buffer API
40 * @ingroup adf_nbuf_public
42 * This file defines the network buffer abstraction.
48 #include <adf_os_util.h>
49 #include <adf_os_types.h>
50 #include <adf_os_dma.h>
51 #include <adf_net_types.h>
52 #include <adf_nbuf_pvt.h>
55 * @brief Platform indepedent packet abstraction
57 typedef __adf_nbuf_t adf_nbuf_t;
60 * @brief invalid handle
62 #define ADF_NBUF_NULL __ADF_NBUF_NULL
64 * @brief Platform independent packet queue abstraction
66 typedef __adf_nbuf_queue_t adf_nbuf_queue_t;
69 * BUS/DMA mapping routines
73 * @brief Create a DMA map. This can later be used to map
74 * networking buffers. They :
75 * - need space in adf_drv's software descriptor
76 * - are typically created during adf_drv_create
77 * - need to be created before any API(adf_nbuf_map) that uses them
79 * @param[in] osdev os device
80 * @param[out] dmap map handle
82 * @return status of the operation
84 static inline a_status_t
85 adf_nbuf_dmamap_create(adf_os_device_t osdev,
86 adf_os_dma_map_t *dmap)
88 return (__adf_nbuf_dmamap_create(osdev, dmap));
93 * @brief Delete a dmap map
95 * @param[in] osdev os device
99 adf_nbuf_dmamap_destroy(adf_os_device_t osdev, adf_os_dma_map_t dmap)
101 __adf_nbuf_dmamap_destroy(osdev, dmap);
106 * @brief Map a buffer to local bus address space
108 * @param[in] osdev os device
109 * @param[in] bmap map handle
110 * @param[in] buf buf to be mapped
111 * @param[in] dir DMA direction
113 * @return status of the operation
115 static inline a_status_t
116 adf_nbuf_map(adf_os_device_t osdev,
117 adf_os_dma_map_t bmap,
119 adf_os_dma_dir_t dir)
121 return __adf_nbuf_map(osdev, bmap, buf, dir);
126 * @brief Unmap a previously mapped buf
128 * @param[in] osdev os device
129 * @param[in] bmap map handle
130 * @param[in] dir DMA direction
133 adf_nbuf_unmap(adf_os_device_t osdev,
134 adf_os_dma_map_t bmap,
135 adf_os_dma_dir_t dir)
137 __adf_nbuf_unmap(osdev, bmap, dir);
141 * @brief returns information about the mapped buf
143 * @param[in] bmap map handle
144 * @param[out] sg map info
147 adf_nbuf_dmamap_info(adf_os_dma_map_t bmap, adf_os_dmamap_info_t *sg)
149 __adf_nbuf_dmamap_info(bmap, sg);
155 * nbuf allocation rouines
160 * @brief Allocate adf_nbuf
162 * The nbuf created is guarenteed to have only 1 physical segment
164 * @param[in] hdl platform device object
165 * @param[in] size data buffer size for this adf_nbuf including max header
167 * @param[in] reserve headroom to start with.
168 * @param[in] align alignment for the start buffer.
170 * @return The new adf_nbuf instance or NULL if there's not enough memory.
172 static inline adf_nbuf_t
173 adf_nbuf_alloc(adf_os_size_t size,
177 return __adf_nbuf_alloc(size, reserve,align);
182 * @brief Free adf_nbuf
184 * @param[in] buf buffer to free
187 adf_nbuf_free(adf_nbuf_t buf)
189 __adf_nbuf_free(buf);
194 * @brief Reallocate such that there's required headroom in
195 * buf. Note that this can allocate a new buffer, or
196 * change geometry of the orignial buffer. The new buffer
197 * is returned in the (new_buf).
199 * @param[in] buf (older buffer)
200 * @param[in] headroom
202 * @return newly allocated buffer
204 static inline adf_nbuf_t
205 adf_nbuf_realloc_headroom(adf_nbuf_t buf, a_uint32_t headroom)
207 return (__adf_nbuf_realloc_headroom(buf, headroom));
212 * @brief expand the tailroom to the new tailroom, but the buffer
215 * @param[in] buf buffer
216 * @param[in] tailroom new tailroom
218 * @return expanded buffer or NULL on failure
220 static inline adf_nbuf_t
221 adf_nbuf_realloc_tailroom(adf_nbuf_t buf, a_uint32_t tailroom)
223 return (__adf_nbuf_realloc_tailroom(buf, tailroom));
228 * @brief this will expand both tail & head room for a given
229 * buffer, you may or may not get a new buffer.Use it
230 * only when its required to expand both. Otherwise use
231 * realloc (head/tail) will solve the purpose. Reason for
232 * having an extra API is that some OS do this in more
233 * optimized way, rather than calling realloc (head/tail)
236 * @param[in] buf buffer
237 * @param[in] headroom new headroom
238 * @param[in] tailroom new tailroom
240 * @return expanded buffer
242 static inline adf_nbuf_t
243 adf_nbuf_expand(adf_nbuf_t buf, a_uint32_t headroom, a_uint32_t tailroom)
245 return (__adf_nbuf_expand(buf,headroom,tailroom));
250 * @brief Copy src buffer into dst. This API is useful, for
251 * example, because most native buffer provide a way to
252 * copy a chain into a single buffer. Therefore as a side
253 * effect, it also "linearizes" a buffer (which is
254 * perhaps why you'll use it mostly). It creates a
257 * @param[in] buf source nbuf to copy from
259 * @return the new nbuf
261 static inline adf_nbuf_t
262 adf_nbuf_copy(adf_nbuf_t buf)
264 return(__adf_nbuf_copy(buf));
269 * @brief link two nbufs, the new buf is piggybacked into the
272 * @param[in] dst buffer to piggyback into
273 * @param[in] src buffer to put
275 * @return status of the call
278 adf_nbuf_cat(adf_nbuf_t dst,adf_nbuf_t src)
280 __adf_nbuf_cat(dst, src);
285 * @brief clone the nbuf (copy is readonly)
287 * @param[in] buf nbuf to clone from
289 * @return cloned buffer
291 static inline adf_nbuf_t
292 adf_nbuf_clone(adf_nbuf_t buf)
294 return(__adf_nbuf_clone(buf));
299 * @brief Create a version of the specified nbuf whose
300 * contents can be safely modified without affecting
301 * other users.If the nbuf is a clone then this function
302 * creates a new copy of the data. If the buffer is not
303 * a clone the original buffer is returned.
305 * @param[in] buf source nbuf to create a writable copy from
307 * @return new buffer which is writeable
309 static inline adf_nbuf_t
310 adf_nbuf_unshare(adf_nbuf_t buf)
312 return(__adf_nbuf_unshare(buf));
318 * nbuf manipulation routines
324 * @brief return the amount of headroom int the current nbuf
326 * @param[in] buf buffer
328 * @return amount of head room
330 static inline a_uint32_t
331 adf_nbuf_headroom(adf_nbuf_t buf)
333 return (__adf_nbuf_headroom(buf));
338 * @brief return the amount of tail space available
340 * @param[in] buf buffer
342 * @return amount of tail room
344 static inline a_uint32_t
345 adf_nbuf_tailroom(adf_nbuf_t buf)
347 return (__adf_nbuf_tailroom(buf));
352 * @brief Push data in the front
354 * @param[in] buf buf instance
355 * @param[in] size size to be pushed
357 * @return New data pointer of this buf after data has been pushed,
358 * or NULL if there is not enough room in this buf.
360 static inline a_uint8_t *
361 adf_nbuf_push_head(adf_nbuf_t buf, adf_os_size_t size)
363 return __adf_nbuf_push_head(buf, size);
368 * @brief Puts data in the end
370 * @param[in] buf buf instance
371 * @param[in] size size to be pushed
373 * @return data pointer of this buf where new data has to be
374 * put, or NULL if there is not enough room in this buf.
376 static inline a_uint8_t *
377 adf_nbuf_put_tail(adf_nbuf_t buf, adf_os_size_t size)
379 return __adf_nbuf_put_tail(buf, size);
384 * @brief pull data out from the front
386 * @param[in] buf buf instance
387 * @param[in] size size to be popped
389 * @return New data pointer of this buf after data has been popped,
390 * or NULL if there is not sufficient data to pull.
392 static inline a_uint8_t *
393 adf_nbuf_pull_head(adf_nbuf_t buf, adf_os_size_t size)
395 return __adf_nbuf_pull_head(buf, size);
401 * @brief trim data out from the end
403 * @param[in] buf buf instance
404 * @param[in] size size to be popped
409 adf_nbuf_trim_tail(adf_nbuf_t buf, adf_os_size_t size)
411 __adf_nbuf_trim_tail(buf, size);
416 * @brief Get the length of the buf
418 * @param[in] buf the buf instance
420 * @return The total length of this buf.
422 static inline adf_os_size_t
423 adf_nbuf_len(adf_nbuf_t buf)
425 return (__adf_nbuf_len(buf));
429 * @brief test whether the nbuf is cloned or not
431 * @param[in] buf buffer
433 * @return TRUE if it is cloned, else FALSE
435 static inline a_bool_t
436 adf_nbuf_is_cloned(adf_nbuf_t buf)
438 return (__adf_nbuf_is_cloned(buf));
448 * @brief return the frag pointer & length of the frag
450 * @param[in] buf buffer
451 * @param[out] sg this will return all the frags of the nbuf
455 adf_nbuf_frag_info(adf_nbuf_t buf, adf_os_sglist_t *sg)
457 __adf_nbuf_frag_info(buf, sg);
460 * @brief return the data pointer & length of the header
462 * @param[in] buf nbuf
463 * @param[out] addr data pointer
464 * @param[out] len length of the data
468 adf_nbuf_peek_header(adf_nbuf_t buf, a_uint8_t **addr, a_uint32_t *len)
470 __adf_nbuf_peek_header(buf, addr, len);
473 * nbuf private context routines
477 * @brief get the priv pointer from the nbuf'f private space
481 * @return data pointer to typecast into your priv structure
483 static inline a_uint8_t *
484 adf_nbuf_get_priv(adf_nbuf_t buf)
486 return (__adf_nbuf_get_priv(buf));
491 * nbuf queue routines
496 * @brief Initialize buf queue
498 * @param[in] head buf queue head
501 adf_nbuf_queue_init(adf_nbuf_queue_t *head)
503 __adf_nbuf_queue_init(head);
508 * @brief Append a nbuf to the tail of the buf queue
510 * @param[in] head buf queue head
514 adf_nbuf_queue_add(adf_nbuf_queue_t *head, adf_nbuf_t buf)
516 __adf_nbuf_queue_add(head, buf);
521 * @brief Retrieve a buf from the head of the buf queue
523 * @param[in] head buf queue head
525 * @return The head buf in the buf queue.
527 static inline adf_nbuf_t
528 adf_nbuf_queue_remove(adf_nbuf_queue_t *head)
530 return __adf_nbuf_queue_remove(head);
535 * @brief get the length of the queue
537 * @param[in] head buf queue head
539 * @return length of the queue
541 static inline a_uint32_t
542 adf_nbuf_queue_len(adf_nbuf_queue_t *head)
544 return __adf_nbuf_queue_len(head);
549 * @brief get the first guy/packet in the queue
551 * @param[in] head buf queue head
553 * @return first buffer in queue
555 static inline adf_nbuf_t
556 adf_nbuf_queue_first(adf_nbuf_queue_t *head)
558 return (__adf_nbuf_queue_first(head));
563 * @brief get the next guy/packet of the given buffer (or
566 * @param[in] buf buffer
568 * @return next buffer/packet
570 static inline adf_nbuf_t
571 adf_nbuf_queue_next(adf_nbuf_t buf)
573 return (__adf_nbuf_queue_next(buf));
578 * @brief Check if the buf queue is empty
580 * @param[in] nbq buf queue handle
582 * @return TRUE if queue is empty
583 * @return FALSE if queue is not emty
585 static inline a_bool_t
586 adf_nbuf_is_queue_empty(adf_nbuf_queue_t * nbq)
588 return __adf_nbuf_is_queue_empty(nbq);
594 * nbuf extension routines XXX
600 * @brief Gets the tx checksumming to be performed on this buf
602 * @param[in] buf buffer
603 * @param[out] hdr_off the (tcp) header start
604 * @param[out] where the checksum offset
606 static inline adf_net_cksum_type_t
607 adf_nbuf_tx_cksum_info(adf_nbuf_t buf, a_uint8_t **hdr_off, a_uint8_t **where)
609 return(__adf_nbuf_tx_cksum_info(buf, hdr_off, where));
614 * @brief Drivers that support hw checksumming use this to
615 * indicate checksum info to the stack.
617 * @param[in] buf buffer
618 * @param[in] cksum checksum
621 adf_nbuf_set_rx_cksum(adf_nbuf_t buf, adf_nbuf_rx_cksum_t *cksum)
623 __adf_nbuf_set_rx_cksum(buf, cksum);
628 * @brief Drivers that are capable of TCP Large segment offload
629 * use this to get the offload info out of an buf.
631 * @param[in] buf buffer
632 * @param[out] tso offload info
635 adf_nbuf_get_tso_info(adf_nbuf_t buf, adf_nbuf_tso_t *tso)
637 __adf_nbuf_get_tso_info(buf, tso);
642 adf_nbuf_set_vlan_info(adf_nbuf_t buf, adf_net_vlan_tag_t vlan_tag)
644 __adf_nbuf_set_vlan_info(buf, vlan_tag);
648 * @brief This function extracts the vid & priority from an
652 * @param[in] hdl net handle
653 * @param[in] buf buffer
654 * @param[in] vlan vlan header
656 * @return status of the operation
658 static inline a_status_t
659 adf_nbuf_get_vlan_info(adf_net_handle_t hdl, adf_nbuf_t buf,
660 adf_net_vlanhdr_t *vlan)
662 return __adf_nbuf_get_vlan_info(hdl, buf, vlan);
665 static inline adf_nbuf_t
666 adf_nbuf_create_frm_frag(adf_nbuf_queue_t *head)
668 return __adf_nbuf_create_frm_frag(head);
672 adf_nbuf_split_to_frag(adf_nbuf_t buf, adf_nbuf_queue_t *qhead)
674 return __adf_nbuf_split_to_frag(buf, qhead);