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