1/*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef HDF_USB_DATA_FIFO_H
17#define HDF_USB_DATA_FIFO_H
18
19#include "hdf_base.h"
20#include "hdf_log.h"
21
22#ifndef MIN
23#define MIN(a, b) ((a) < (b) ? (a) : (b))
24#endif
25
26#ifndef MAX
27#define MAX(a, b) ((a) > (b) ? (a) : (b))
28#endif
29
30struct DataFifo {
31    uint32_t rdIdx;
32    uint32_t wrIdx;
33    uint32_t size;
34    void     *data;
35};
36
37/* DataFifo Helper function */
38static inline void DataFifoInit(struct DataFifo *fifo, uint32_t size, void *data)
39{
40    if (size == 0) {
41        HDF_LOGE("%{public}s: Fifo size is zero", __func__);
42        return;
43    }
44    fifo->rdIdx = 0;
45    fifo->wrIdx = 0;
46    fifo->size = size;
47    fifo->data = data;
48}
49
50static inline bool DataFifoIsInitialized(struct DataFifo *fifo)
51{
52    return fifo->size != 0;
53}
54
55static inline void DataFifoReset(struct DataFifo *fifo)
56{
57    fifo->rdIdx = fifo->wrIdx = 0;
58}
59
60static inline uint32_t DataFifoLen(struct DataFifo *fifo)
61{
62    return fifo->wrIdx - fifo->rdIdx;
63}
64
65static inline bool DataFifoIsEmpty(struct DataFifo *fifo)
66{
67    return fifo->wrIdx == fifo->rdIdx;
68}
69
70static inline bool DataFifoIsFull(struct DataFifo *fifo)
71{
72    return DataFifoLen(fifo) > (fifo->size - 1);
73}
74
75static inline uint32_t DataFifoAvailSize(struct DataFifo *fifo)
76{
77    return fifo->size - DataFifoLen(fifo);
78}
79
80static inline void DataFifoSkip(struct DataFifo *fifo, uint32_t size)
81{
82    fifo->rdIdx += size;
83}
84
85static inline uint32_t DataFifoWrite(struct DataFifo *fifo, uint8_t *data, uint32_t size)
86{
87    uint32_t mask = fifo->size - 1;
88    uint8_t *buf = (uint8_t *)fifo->data;
89    uint8_t *end;
90
91    size = MIN(size, DataFifoAvailSize(fifo));
92    end = data + size;
93    while (data < end) {
94        buf[fifo->wrIdx++ & mask] = *data++;
95    }
96    return size;
97}
98
99static inline uint32_t DataFifoRead(struct DataFifo *fifo, uint8_t *data, uint32_t size)
100{
101    uint32_t mask = fifo->size - 1;
102    uint8_t *buf = (uint8_t *)fifo->data;
103    uint8_t *end;
104
105    size = MIN(size, DataFifoLen(fifo));
106    end = data + size;
107    while (data < end) {
108        *data++ = buf[fifo->rdIdx++ & mask];
109    }
110    return size;
111}
112
113#endif /* HDF_USB_DATA_FIFO_H */
114