xref: /linux/drivers/staging/rtl8723bs/os_dep/osdep_service.c (revision 323bbfcf1ef8836d0d2ad9e2c1f1c684f0e3b5b3)
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 
9 /* Translate the OS dependent error_code to RTW_STATUS_CODE */
RTW_STATUS_CODE(int error_code)10 inline int RTW_STATUS_CODE(int error_code)
11 {
12 	if (error_code >= 0)
13 		return _SUCCESS;
14 	return _FAIL;
15 }
16 
_rtw_netif_rx(struct net_device * ndev,struct sk_buff * skb)17 inline int _rtw_netif_rx(struct net_device *ndev, struct sk_buff *skb)
18 {
19 	skb->dev = ndev;
20 	return netif_rx(skb);
21 }
22 
rtw_alloc_etherdev_with_old_priv(int sizeof_priv,void * old_priv)23 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
24 {
25 	struct net_device *pnetdev;
26 	struct rtw_netdev_priv_indicator *pnpi;
27 
28 	pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
29 	if (!pnetdev)
30 		goto RETURN;
31 
32 	pnpi = netdev_priv(pnetdev);
33 	pnpi->priv = old_priv;
34 	pnpi->sizeof_priv = sizeof_priv;
35 
36 RETURN:
37 	return pnetdev;
38 }
39 
rtw_alloc_etherdev(int sizeof_priv)40 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
41 {
42 	struct net_device *pnetdev;
43 	struct rtw_netdev_priv_indicator *pnpi;
44 
45 	pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
46 	if (!pnetdev)
47 		goto RETURN;
48 
49 	pnpi = netdev_priv(pnetdev);
50 
51 	pnpi->priv = vzalloc(sizeof_priv);
52 	if (!pnpi->priv) {
53 		free_netdev(pnetdev);
54 		pnetdev = NULL;
55 		goto RETURN;
56 	}
57 
58 	pnpi->sizeof_priv = sizeof_priv;
59 RETURN:
60 	return pnetdev;
61 }
62 
rtw_free_netdev(struct net_device * netdev)63 void rtw_free_netdev(struct net_device *netdev)
64 {
65 	struct rtw_netdev_priv_indicator *pnpi;
66 
67 	if (!netdev)
68 		goto RETURN;
69 
70 	pnpi = netdev_priv(netdev);
71 
72 	if (!pnpi->priv)
73 		goto RETURN;
74 
75 	vfree(pnpi->priv);
76 	free_netdev(netdev);
77 
78 RETURN:
79 	return;
80 }
81 
rtw_buf_free(u8 ** buf,u32 * buf_len)82 void rtw_buf_free(u8 **buf, u32 *buf_len)
83 {
84 	if (!buf || !buf_len)
85 		return;
86 
87 	if (*buf) {
88 		*buf_len = 0;
89 		kfree(*buf);
90 		*buf = NULL;
91 	}
92 }
93 
rtw_buf_update(u8 ** buf,u32 * buf_len,u8 * src,u32 src_len)94 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
95 {
96 	u32 ori_len = 0, dup_len = 0;
97 	u8 *ori = NULL;
98 	u8 *dup = NULL;
99 
100 	if (!buf || !buf_len)
101 		return;
102 
103 	if (!src || !src_len)
104 		goto keep_ori;
105 
106 	/* duplicate src */
107 	dup = kmemdup(src, src_len, GFP_ATOMIC);
108 	if (dup)
109 		dup_len = src_len;
110 
111 keep_ori:
112 	ori = *buf;
113 	ori_len = *buf_len;
114 
115 	/* replace buf with dup */
116 	*buf_len = 0;
117 	*buf = dup;
118 	*buf_len = dup_len;
119 
120 	/* free ori */
121 	if (ori && ori_len > 0)
122 		kfree(ori);
123 }
124 
125 /**
126  * rtw_cbuf_full - test if cbuf is full
127  * @cbuf: pointer of struct rtw_cbuf
128  *
129  * Returns: true if cbuf is full
130  */
rtw_cbuf_full(struct rtw_cbuf * cbuf)131 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
132 {
133 	return (cbuf->write == cbuf->read - 1) ? true : false;
134 }
135 
136 /**
137  * rtw_cbuf_empty - test if cbuf is empty
138  * @cbuf: pointer of struct rtw_cbuf
139  *
140  * Returns: true if cbuf is empty
141  */
rtw_cbuf_empty(struct rtw_cbuf * cbuf)142 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
143 {
144 	return (cbuf->write == cbuf->read) ? true : false;
145 }
146 
147 /**
148  * rtw_cbuf_push - push a pointer into cbuf
149  * @cbuf: pointer of struct rtw_cbuf
150  * @buf: pointer to push in
151  *
152  * Lock free operation, be careful of the use scheme
153  * Returns: true push success
154  */
rtw_cbuf_push(struct rtw_cbuf * cbuf,void * buf)155 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
156 {
157 	if (rtw_cbuf_full(cbuf))
158 		return _FAIL;
159 
160 	cbuf->bufs[cbuf->write] = buf;
161 	cbuf->write = (cbuf->write + 1) % cbuf->size;
162 
163 	return _SUCCESS;
164 }
165 
166 /**
167  * rtw_cbuf_pop - pop a pointer from cbuf
168  * @cbuf: pointer of struct rtw_cbuf
169  *
170  * Lock free operation, be careful of the use scheme
171  * Returns: pointer popped out
172  */
rtw_cbuf_pop(struct rtw_cbuf * cbuf)173 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
174 {
175 	void *buf;
176 
177 	if (rtw_cbuf_empty(cbuf))
178 		return NULL;
179 
180 	buf = cbuf->bufs[cbuf->read];
181 	cbuf->read = (cbuf->read + 1) % cbuf->size;
182 
183 	return buf;
184 }
185 
186 /**
187  * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization
188  * @size: size of pointer
189  *
190  * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
191  */
rtw_cbuf_alloc(u32 size)192 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
193 {
194 	struct rtw_cbuf *cbuf;
195 
196 	cbuf = kzalloc_flex(*cbuf, bufs, size);
197 	cbuf->size = size;
198 
199 	return cbuf;
200 }
201