GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / staging / rtl8723bs / os_dep / osdep_service.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #include <drv_types.h>
8 #include <rtw_debug.h>
9
10 /*
11 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
12 * @return: one of RTW_STATUS_CODE
13 */
14 inline int RTW_STATUS_CODE(int error_code)
15 {
16         if (error_code >= 0)
17                 return _SUCCESS;
18         return _FAIL;
19 }
20
21 void *_rtw_malloc(u32 sz)
22 {
23         return kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
24 }
25
26 void *_rtw_zmalloc(u32 sz)
27 {
28         void *pbuf = _rtw_malloc(sz);
29
30         if (pbuf)
31                 memset(pbuf, 0, sz);
32
33         return pbuf;
34 }
35
36 inline struct sk_buff *_rtw_skb_alloc(u32 sz)
37 {
38         return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
39 }
40
41 inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb)
42 {
43         return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
44 }
45
46 inline int _rtw_netif_rx(struct net_device *ndev, struct sk_buff *skb)
47 {
48         skb->dev = ndev;
49         return netif_rx(skb);
50 }
51
52 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
53 {
54         struct net_device *pnetdev;
55         struct rtw_netdev_priv_indicator *pnpi;
56
57         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
58         if (!pnetdev)
59                 goto RETURN;
60
61         pnpi = netdev_priv(pnetdev);
62         pnpi->priv = old_priv;
63         pnpi->sizeof_priv = sizeof_priv;
64
65 RETURN:
66         return pnetdev;
67 }
68
69 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
70 {
71         struct net_device *pnetdev;
72         struct rtw_netdev_priv_indicator *pnpi;
73
74         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
75         if (!pnetdev)
76                 goto RETURN;
77
78         pnpi = netdev_priv(pnetdev);
79
80         pnpi->priv = vzalloc(sizeof_priv);
81         if (!pnpi->priv) {
82                 free_netdev(pnetdev);
83                 pnetdev = NULL;
84                 goto RETURN;
85         }
86
87         pnpi->sizeof_priv = sizeof_priv;
88 RETURN:
89         return pnetdev;
90 }
91
92 void rtw_free_netdev(struct net_device *netdev)
93 {
94         struct rtw_netdev_priv_indicator *pnpi;
95
96         if (!netdev)
97                 goto RETURN;
98
99         pnpi = netdev_priv(netdev);
100
101         if (!pnpi->priv)
102                 goto RETURN;
103
104         vfree(pnpi->priv);
105         free_netdev(netdev);
106
107 RETURN:
108         return;
109 }
110
111 void rtw_buf_free(u8 **buf, u32 *buf_len)
112 {
113         if (!buf || !buf_len)
114                 return;
115
116         if (*buf) {
117                 *buf_len = 0;
118                 kfree(*buf);
119                 *buf = NULL;
120         }
121 }
122
123 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
124 {
125         u32 ori_len = 0, dup_len = 0;
126         u8 *ori = NULL;
127         u8 *dup = NULL;
128
129         if (!buf || !buf_len)
130                 return;
131
132         if (!src || !src_len)
133                 goto keep_ori;
134
135         /* duplicate src */
136         dup = rtw_malloc(src_len);
137         if (dup) {
138                 dup_len = src_len;
139                 memcpy(dup, src, dup_len);
140         }
141
142 keep_ori:
143         ori = *buf;
144         ori_len = *buf_len;
145
146         /* replace buf with dup */
147         *buf_len = 0;
148         *buf = dup;
149         *buf_len = dup_len;
150
151         /* free ori */
152         if (ori && ori_len > 0)
153                 kfree(ori);
154 }
155
156
157 /**
158  * rtw_cbuf_full - test if cbuf is full
159  * @cbuf: pointer of struct rtw_cbuf
160  *
161  * Returns: true if cbuf is full
162  */
163 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
164 {
165         return (cbuf->write == cbuf->read - 1) ? true : false;
166 }
167
168 /**
169  * rtw_cbuf_empty - test if cbuf is empty
170  * @cbuf: pointer of struct rtw_cbuf
171  *
172  * Returns: true if cbuf is empty
173  */
174 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
175 {
176         return (cbuf->write == cbuf->read) ? true : false;
177 }
178
179 /**
180  * rtw_cbuf_push - push a pointer into cbuf
181  * @cbuf: pointer of struct rtw_cbuf
182  * @buf: pointer to push in
183  *
184  * Lock free operation, be careful of the use scheme
185  * Returns: true push success
186  */
187 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
188 {
189         if (rtw_cbuf_full(cbuf))
190                 return _FAIL;
191
192         cbuf->bufs[cbuf->write] = buf;
193         cbuf->write = (cbuf->write + 1) % cbuf->size;
194
195         return _SUCCESS;
196 }
197
198 /**
199  * rtw_cbuf_pop - pop a pointer from cbuf
200  * @cbuf: pointer of struct rtw_cbuf
201  *
202  * Lock free operation, be careful of the use scheme
203  * Returns: pointer popped out
204  */
205 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
206 {
207         void *buf;
208         if (rtw_cbuf_empty(cbuf))
209                 return NULL;
210
211         buf = cbuf->bufs[cbuf->read];
212         cbuf->read = (cbuf->read + 1) % cbuf->size;
213
214         return buf;
215 }
216
217 /**
218  * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization
219  * @size: size of pointer
220  *
221  * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
222  */
223 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
224 {
225         struct rtw_cbuf *cbuf;
226
227         cbuf = rtw_malloc(struct_size(cbuf, bufs, size));
228
229         if (cbuf) {
230                 cbuf->write = cbuf->read = 0;
231                 cbuf->size = size;
232         }
233
234         return cbuf;
235 }