Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-block.git] / drivers / staging / rtl8723bs / os_dep / osdep_service.c
CommitLineData
58391efd 1// SPDX-License-Identifier: GPL-2.0
554c0a3a
HG
2/******************************************************************************
3 *
4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 *
554c0a3a
HG
6 ******************************************************************************/
7
8
9#define _OSDEP_SERVICE_C_
10
11#include <drv_types.h>
12#include <rtw_debug.h>
13
14/*
15* Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
16* @return: one of RTW_STATUS_CODE
17*/
18inline int RTW_STATUS_CODE(int error_code)
19{
20 if (error_code >= 0)
21 return _SUCCESS;
22 return _FAIL;
23}
24
35628c4a 25void *_rtw_malloc(u32 sz)
554c0a3a 26{
35628c4a 27 return kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
554c0a3a
HG
28}
29
35628c4a 30void *_rtw_zmalloc(u32 sz)
554c0a3a 31{
35628c4a 32 void *pbuf = _rtw_malloc(sz);
554c0a3a 33
35628c4a 34 if (pbuf)
554c0a3a 35 memset(pbuf, 0, sz);
554c0a3a
HG
36
37 return pbuf;
38}
39
40inline struct sk_buff *_rtw_skb_alloc(u32 sz)
41{
42 return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
43}
44
45inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb)
46{
47 return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
48}
49
50inline struct sk_buff *_rtw_skb_clone(struct sk_buff *skb)
51{
52 return skb_clone(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
53}
54
55inline int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb)
56{
57 skb->dev = ndev;
58 return netif_rx(skb);
59}
60
554c0a3a
HG
61void _rtw_init_queue(struct __queue *pqueue)
62{
63 INIT_LIST_HEAD(&(pqueue->queue));
64
65 spin_lock_init(&(pqueue->lock));
66}
67
554c0a3a
HG
68struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
69{
70 struct net_device *pnetdev;
71 struct rtw_netdev_priv_indicator *pnpi;
72
73 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
74 if (!pnetdev)
75 goto RETURN;
76
77 pnpi = netdev_priv(pnetdev);
a89ba681
HK
78 pnpi->priv = old_priv;
79 pnpi->sizeof_priv = sizeof_priv;
554c0a3a
HG
80
81RETURN:
82 return pnetdev;
83}
84
85struct net_device *rtw_alloc_etherdev(int sizeof_priv)
86{
87 struct net_device *pnetdev;
88 struct rtw_netdev_priv_indicator *pnpi;
89
90 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
91 if (!pnetdev)
92 goto RETURN;
93
94 pnpi = netdev_priv(pnetdev);
95
96 pnpi->priv = vzalloc(sizeof_priv);
97 if (!pnpi->priv) {
98 free_netdev(pnetdev);
99 pnetdev = NULL;
100 goto RETURN;
101 }
102
a89ba681 103 pnpi->sizeof_priv = sizeof_priv;
554c0a3a
HG
104RETURN:
105 return pnetdev;
106}
107
fdd1b243 108void rtw_free_netdev(struct net_device *netdev)
554c0a3a
HG
109{
110 struct rtw_netdev_priv_indicator *pnpi;
111
112 if (!netdev)
113 goto RETURN;
114
115 pnpi = netdev_priv(netdev);
116
117 if (!pnpi->priv)
118 goto RETURN;
119
120 vfree(pnpi->priv);
121 free_netdev(netdev);
122
123RETURN:
124 return;
125}
126
127int rtw_change_ifname(struct adapter *padapter, const char *ifname)
128{
129 struct net_device *pnetdev;
130 struct net_device *cur_pnetdev;
131 struct rereg_nd_name_data *rereg_priv;
132 int ret;
133
134 if (!padapter)
135 goto error;
136
137 cur_pnetdev = padapter->pnetdev;
138 rereg_priv = &padapter->rereg_nd_name_priv;
139
140 /* free the old_pnetdev */
141 if (rereg_priv->old_pnetdev) {
142 free_netdev(rereg_priv->old_pnetdev);
143 rereg_priv->old_pnetdev = NULL;
144 }
145
146 if (!rtnl_is_locked())
147 unregister_netdev(cur_pnetdev);
148 else
149 unregister_netdevice(cur_pnetdev);
150
a89ba681 151 rereg_priv->old_pnetdev = cur_pnetdev;
554c0a3a
HG
152
153 pnetdev = rtw_init_netdev(padapter);
154 if (!pnetdev) {
155 ret = -1;
156 goto error;
157 }
158
159 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
160
161 rtw_init_netdev_name(pnetdev, ifname);
162
163 memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
164
165 if (!rtnl_is_locked())
166 ret = register_netdev(pnetdev);
167 else
168 ret = register_netdevice(pnetdev);
169
170 if (ret != 0) {
171 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("register_netdev() failed\n"));
172 goto error;
173 }
174
175 return 0;
176
177error:
178
179 return -1;
180
181}
182
554c0a3a
HG
183void rtw_buf_free(u8 **buf, u32 *buf_len)
184{
554c0a3a
HG
185 if (!buf || !buf_len)
186 return;
187
554c0a3a
HG
188 if (*buf) {
189 *buf_len = 0;
190 kfree(*buf);
191 *buf = NULL;
192 }
193}
194
195void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
196{
197 u32 ori_len = 0, dup_len = 0;
198 u8 *ori = NULL;
199 u8 *dup = NULL;
200
201 if (!buf || !buf_len)
202 return;
203
204 if (!src || !src_len)
205 goto keep_ori;
206
207 /* duplicate src */
208 dup = rtw_malloc(src_len);
209 if (dup) {
210 dup_len = src_len;
211 memcpy(dup, src, dup_len);
212 }
213
214keep_ori:
215 ori = *buf;
216 ori_len = *buf_len;
217
218 /* replace buf with dup */
219 *buf_len = 0;
220 *buf = dup;
221 *buf_len = dup_len;
222
223 /* free ori */
224 if (ori && ori_len > 0)
225 kfree(ori);
226}
227
228
229/**
230 * rtw_cbuf_full - test if cbuf is full
231 * @cbuf: pointer of struct rtw_cbuf
232 *
233 * Returns: true if cbuf is full
234 */
235inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
236{
a89ba681 237 return (cbuf->write == cbuf->read - 1) ? true : false;
554c0a3a
HG
238}
239
240/**
241 * rtw_cbuf_empty - test if cbuf is empty
242 * @cbuf: pointer of struct rtw_cbuf
243 *
244 * Returns: true if cbuf is empty
245 */
246inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
247{
a89ba681 248 return (cbuf->write == cbuf->read) ? true : false;
554c0a3a
HG
249}
250
251/**
252 * rtw_cbuf_push - push a pointer into cbuf
253 * @cbuf: pointer of struct rtw_cbuf
254 * @buf: pointer to push in
255 *
256 * Lock free operation, be careful of the use scheme
257 * Returns: true push success
258 */
259bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
260{
261 if (rtw_cbuf_full(cbuf))
262 return _FAIL;
263
264 DBG_871X("%s on %u\n", __func__, cbuf->write);
265 cbuf->bufs[cbuf->write] = buf;
a89ba681 266 cbuf->write = (cbuf->write + 1) % cbuf->size;
554c0a3a
HG
267
268 return _SUCCESS;
269}
270
271/**
272 * rtw_cbuf_pop - pop a pointer from cbuf
273 * @cbuf: pointer of struct rtw_cbuf
274 *
275 * Lock free operation, be careful of the use scheme
276 * Returns: pointer popped out
277 */
278void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
279{
280 void *buf;
281 if (rtw_cbuf_empty(cbuf))
282 return NULL;
283
284 DBG_871X("%s on %u\n", __func__, cbuf->read);
285 buf = cbuf->bufs[cbuf->read];
a89ba681 286 cbuf->read = (cbuf->read + 1) % cbuf->size;
554c0a3a
HG
287
288 return buf;
289}
290
291/**
292 * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization
293 * @size: size of pointer
294 *
295 * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
296 */
297struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
298{
299 struct rtw_cbuf *cbuf;
300
2ef2b7c2 301 cbuf = rtw_malloc(sizeof(*cbuf) + sizeof(void *) * size);
554c0a3a
HG
302
303 if (cbuf) {
304 cbuf->write = cbuf->read = 0;
305 cbuf->size = size;
306 }
307
308 return cbuf;
309}