BAL and Maple Release 2.2
Signed-off-by: Shad Ansari <developer@Carbon.local>
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_buf.c b/bcm68620_release/release/host_driver/utils/bcmolt_buf.c
new file mode 100644
index 0000000..cb57fe9
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_buf.c
@@ -0,0 +1,247 @@
+/*
+<:copyright-BRCM:2016:DUAL/GPL:standard
+
+ Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
+ */
+
+#include "bcmolt_buf.h"
+#include "bcmos_system.h"
+
+/** Initalize a bcmolt_buf stream
+ *
+ * \param buf
+ * \param size
+ * \param start
+ * \param endian Endianness of numbers in the resulting stream
+ */
+void bcmolt_buf_init(bcmolt_buf *buf, uint32_t size, uint8_t *start, bcmos_endian endian)
+{
+ buf->len = size;
+ buf->curr = start;
+ buf->start = start;
+ buf->free = NULL;
+ buf->bh = NULL;
+ /* Currently, we only support reading/writing numbers in a single endianness. */
+ BUG_ON(endian != BCMOLT_BUF_ENDIAN_FIXED);
+}
+
+/** Allocate data buffer and initialize bcmolt_buf stream
+ *
+ * \param buf
+ * \param size
+ * \param endian Endianness of numbers in the resulting stream
+ * \return BCM_ERR_OK or BCM_ERR_NOMEM
+ */
+bcmos_errno bcmolt_buf_alloc(bcmolt_buf *buf, uint32_t size, bcmos_endian endian)
+{
+ buf->start = bcmos_alloc(size);
+ if (buf->start == NULL)
+ {
+ return BCM_ERR_NOMEM;
+ }
+ bcmolt_buf_init(buf, size, buf->start, endian);
+ return BCM_ERR_OK;
+}
+
+/** Release data buffer pointed by bcmolt_buf stream
+ * \param[in,out] buf
+ */
+void bcmolt_buf_free(bcmolt_buf *buf)
+{
+ if (buf->start != NULL)
+ {
+ if (buf->free)
+ {
+ buf->free(buf->bh);
+ buf->free = NULL;
+ buf->bh = NULL;
+ }
+ else
+ {
+ bcmos_free(buf->start);
+ }
+ buf->start = NULL;
+ }
+ buf->len = 0;
+ buf->curr = NULL;
+}
+
+/** Read from the buffer
+ *
+ * \param buf bcmolt_buf instance
+ * \param to Where to read to
+ * \param len Number of bytes to copy
+ *
+ * \return BCMOS_TRUE if successfully copied
+ */
+bcmos_bool bcmolt_buf_read(bcmolt_buf *buf, void *to, size_t len)
+{
+ if ((buf->start + buf->len) >= (buf->curr + len))
+ {
+ memcpy(to, buf->curr, len);
+ buf->curr += len;
+ return BCMOS_TRUE;
+ }
+
+ return BCMOS_FALSE;
+}
+
+/** Transfer bytes from one buf to another
+ *
+ * \param *from Source buffer
+ * \param *to Destination buffer
+ * \param bytes Number of bytes to transfer
+ * \return BCMOS_TRUE if successfully transferred
+ */
+bcmos_bool bcmolt_buf_transfer_bytes(bcmolt_buf *from, bcmolt_buf *to, uint32_t bytes)
+{
+ uint8_t tmp[256];
+ uint32_t toRead;
+ while (bytes != 0)
+ {
+ toRead = bytes > sizeof(tmp) ? sizeof(tmp) : bytes;
+ if (!bcmolt_buf_read(from, tmp, toRead) || !bcmolt_buf_write(to, tmp, toRead))
+ {
+ return BCMOS_FALSE;
+ }
+
+ bytes -= toRead;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/** Write to the buffer
+ *
+ * \param buf bcmolt_buf instance
+ * \param from Source, to copy from
+ * \param len Number of bytes to copy
+ *
+ * \return BCMOS_TRUE if successfully copied
+ */
+bcmos_bool bcmolt_buf_write(bcmolt_buf *buf, const void *from, size_t len)
+{
+ if ((buf->start + buf->len) >= (buf->curr + len))
+ {
+ memcpy(buf->curr, from, len);
+ buf->curr += len;
+ return BCMOS_TRUE;
+ }
+ else
+ {
+ return BCMOS_FALSE;
+ }
+}
+
+/** Move the current pointer to a given position in the buffer
+ *
+ * \param pos Byte position in the buffer to move the current pointer to
+ *
+ * \param *buf Input buffer
+ * \return BCMOS_FALSE if len takes us past the end of buffer
+ */
+bcmos_bool bcmolt_buf_set_pos(bcmolt_buf *buf, uint32_t pos)
+{
+ if (pos <= buf->len)
+ {
+ buf->curr = buf->start + pos;
+ return BCMOS_TRUE;
+ }
+
+ return BCMOS_FALSE;
+}
+
+/** Move the current pointer ahead by given number of bytes
+ *
+ * \param buf bcmolt_buf instance
+ * \param len Number of bytes to skip
+ *
+ * \return BCMOS_FALSE if len takes us past the end of buffer
+ */
+bcmos_bool bcmolt_buf_skip(bcmolt_buf *buf, uint32_t len)
+{
+ if ((buf->start + buf->len) >= (buf->curr + len))
+ {
+ buf->curr += len;
+ return BCMOS_TRUE;
+ }
+
+ return BCMOS_FALSE;
+}
+
+/** Move the current pointer back by given number of bytes
+ *
+ * \param buf bcmolt_buf instance
+ * \param len Number of bytes to go back
+ *
+ * \return BCMOS_FALSE if len takes us past the start of buffer
+ */
+bcmos_bool bcmolt_buf_rewind(bcmolt_buf *buf, uint32_t len)
+{
+ if (buf->curr >= (buf->start + len))
+ {
+ buf->curr -= len;
+ return BCMOS_TRUE;
+ }
+
+ return BCMOS_FALSE;
+}
+
+/** Reads a boolean from a buffer
+ *
+ * \param *buf
+ * \param *val
+ */
+bcmos_bool bcmolt_buf_read_bool(bcmolt_buf *buf, bcmos_bool *val)
+{
+ /* this function isn't inlined like the rest because it's too complex to inline cleanly */
+ uint8_t tmp;
+ if (bcmolt_buf_read_u8(buf, &tmp))
+ {
+ *val = (tmp != 0);
+ return BCMOS_TRUE;
+ }
+ else
+ {
+ return BCMOS_FALSE;
+ }
+}
+
+
+#ifdef __KERNEL__
+EXPORT_SYMBOL(bcmolt_buf_init);
+EXPORT_SYMBOL(bcmolt_buf_alloc);
+EXPORT_SYMBOL(bcmolt_buf_free);
+EXPORT_SYMBOL(bcmolt_buf_read);
+EXPORT_SYMBOL(bcmolt_buf_transfer_bytes);
+EXPORT_SYMBOL(bcmolt_buf_write);
+EXPORT_SYMBOL(bcmolt_buf_set_pos);
+EXPORT_SYMBOL(bcmolt_buf_skip);
+EXPORT_SYMBOL(bcmolt_buf_rewind);
+EXPORT_SYMBOL(bcmolt_buf_read_bool);
+
+MODULE_LICENSE("Dual BSD/GPL");
+#endif