Mention branches and keyring.
[releases.git] / 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 int rtw_change_ifname(struct adapter *padapter, const char *ifname)
112 {
113         struct net_device *pnetdev;
114         struct net_device *cur_pnetdev;
115         struct rereg_nd_name_data *rereg_priv;
116         int ret;
117
118         if (!padapter)
119                 goto error;
120
121         cur_pnetdev = padapter->pnetdev;
122         rereg_priv = &padapter->rereg_nd_name_priv;
123
124         /* free the old_pnetdev */
125         if (rereg_priv->old_pnetdev) {
126                 free_netdev(rereg_priv->old_pnetdev);
127                 rereg_priv->old_pnetdev = NULL;
128         }
129
130         if (!rtnl_is_locked())
131                 unregister_netdev(cur_pnetdev);
132         else
133                 unregister_netdevice(cur_pnetdev);
134
135         rereg_priv->old_pnetdev = cur_pnetdev;
136
137         pnetdev = rtw_init_netdev(padapter);
138         if (!pnetdev)
139                 goto error;
140
141         SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
142
143         rtw_init_netdev_name(pnetdev, ifname);
144
145         eth_hw_addr_set(pnetdev, padapter->eeprompriv.mac_addr);
146
147         if (!rtnl_is_locked())
148                 ret = register_netdev(pnetdev);
149         else
150                 ret = register_netdevice(pnetdev);
151
152         if (ret != 0)
153                 goto error;
154
155         return 0;
156
157 error:
158         return -1;
159 }
160
161 void rtw_buf_free(u8 **buf, u32 *buf_len)
162 {
163         if (!buf || !buf_len)
164                 return;
165
166         if (*buf) {
167                 *buf_len = 0;
168                 kfree(*buf);
169                 *buf = NULL;
170         }
171 }
172
173 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
174 {
175         u32 ori_len = 0, dup_len = 0;
176         u8 *ori = NULL;
177         u8 *dup = NULL;
178
179         if (!buf || !buf_len)
180                 return;
181
182         if (!src || !src_len)
183                 goto keep_ori;
184
185         /* duplicate src */
186         dup = rtw_malloc(src_len);
187         if (dup) {
188                 dup_len = src_len;
189                 memcpy(dup, src, dup_len);
190         }
191
192 keep_ori:
193         ori = *buf;
194         ori_len = *buf_len;
195
196         /* replace buf with dup */
197         *buf_len = 0;
198         *buf = dup;
199         *buf_len = dup_len;
200
201         /* free ori */
202         if (ori && ori_len > 0)
203                 kfree(ori);
204 }
205
206
207 /**
208  * rtw_cbuf_full - test if cbuf is full
209  * @cbuf: pointer of struct rtw_cbuf
210  *
211  * Returns: true if cbuf is full
212  */
213 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
214 {
215         return (cbuf->write == cbuf->read - 1) ? true : false;
216 }
217
218 /**
219  * rtw_cbuf_empty - test if cbuf is empty
220  * @cbuf: pointer of struct rtw_cbuf
221  *
222  * Returns: true if cbuf is empty
223  */
224 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
225 {
226         return (cbuf->write == cbuf->read) ? true : false;
227 }
228
229 /**
230  * rtw_cbuf_push - push a pointer into cbuf
231  * @cbuf: pointer of struct rtw_cbuf
232  * @buf: pointer to push in
233  *
234  * Lock free operation, be careful of the use scheme
235  * Returns: true push success
236  */
237 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
238 {
239         if (rtw_cbuf_full(cbuf))
240                 return _FAIL;
241
242         cbuf->bufs[cbuf->write] = buf;
243         cbuf->write = (cbuf->write + 1) % cbuf->size;
244
245         return _SUCCESS;
246 }
247
248 /**
249  * rtw_cbuf_pop - pop a pointer from cbuf
250  * @cbuf: pointer of struct rtw_cbuf
251  *
252  * Lock free operation, be careful of the use scheme
253  * Returns: pointer popped out
254  */
255 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
256 {
257         void *buf;
258         if (rtw_cbuf_empty(cbuf))
259                 return NULL;
260
261         buf = cbuf->bufs[cbuf->read];
262         cbuf->read = (cbuf->read + 1) % cbuf->size;
263
264         return buf;
265 }
266
267 /**
268  * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization
269  * @size: size of pointer
270  *
271  * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
272  */
273 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
274 {
275         struct rtw_cbuf *cbuf;
276
277         cbuf = rtw_malloc(struct_size(cbuf, bufs, size));
278
279         if (cbuf) {
280                 cbuf->write = cbuf->read = 0;
281                 cbuf->size = size;
282         }
283
284         return cbuf;
285 }